[MNG-3891] Modify maven-toolchain to look in ${maven.home}/conf/toolchains.xml and in ${user.home}/.m2/toolchains.xml

Also added new cmdline option: -gt / --global-toolchains
This commit is contained in:
Robert Scholte 2014-12-25 14:55:02 +01:00
parent 226e6385d6
commit ceae922653
17 changed files with 925 additions and 8 deletions

View File

@ -43,7 +43,7 @@ public FileSource( File file )
{
if ( file == null )
{
throw new IllegalArgumentException( "no POM file specified" );
throw new IllegalArgumentException( "no file specified" );
}
this.file = file.getAbsoluteFile();
}

View File

@ -84,6 +84,8 @@ public class DefaultMavenExecutionRequest
private File userToolchainsFile;
private File globalToolchainsFile;
// ----------------------------------------------------------------------------
// Request
// ----------------------------------------------------------------------------
@ -169,6 +171,7 @@ public static MavenExecutionRequest copy( MavenExecutionRequest original )
copy.setUserSettingsFile( original.getUserSettingsFile() );
copy.setGlobalSettingsFile( original.getGlobalSettingsFile() );
copy.setUserToolchainsFile( original.getUserToolchainsFile() );
copy.setGlobalToolchainsFile( original.getGlobalToolchainsFile() );
copy.setBaseDirectory( ( original.getBaseDirectory() != null ) ? new File( original.getBaseDirectory() ) : null );
copy.setGoals( original.getGoals() );
copy.setRecursive( original.isRecursive() );
@ -931,6 +934,19 @@ public MavenExecutionRequest setUserToolchainsFile( File userToolchainsFile )
return this;
}
@Override
public File getGlobalToolchainsFile()
{
return globalToolchainsFile;
}
@Override
public MavenExecutionRequest setGlobalToolchainsFile( File globalToolchainsFile )
{
this.globalToolchainsFile = globalToolchainsFile;
return this;
}
public MavenExecutionRequest addRemoteRepository( ArtifactRepository repository )
{

View File

@ -348,6 +348,22 @@ public interface MavenExecutionRequest
MavenExecutionRequest setUserToolchainsFile( File userToolchainsFile );
/**
*
*
* @return the global toolchains file
* @since 3.2.6
*/
File getGlobalToolchainsFile();
/**
*
* @param globalToolchainsFile the global toolchains file
* @return this request
* @since 3.2.6
*/
MavenExecutionRequest setGlobalToolchainsFile( File globalToolchainsFile );
ExecutionListener getExecutionListener();
MavenExecutionRequest setExecutionListener( ExecutionListener executionListener );

View File

@ -19,11 +19,16 @@
* under the License.
*/
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.maven.building.FileSource;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.toolchain.building.DefaultToolchainsBuildingRequest;
import org.apache.maven.toolchain.building.ToolchainsBuildingException;
import org.apache.maven.toolchain.building.ToolchainsBuildingResult;
import org.apache.maven.toolchain.model.PersistedToolchains;
import org.apache.maven.toolchain.model.ToolchainModel;
import org.codehaus.plexus.component.annotations.Component;
@ -31,6 +36,7 @@
/**
* @author mkleint
* @author Robert Scholte
*/
@Component( role = ToolchainManagerPrivate.class )
public class DefaultToolchainManagerPrivate
@ -39,12 +45,36 @@ public class DefaultToolchainManagerPrivate
{
@Requirement
private ToolchainsBuilder toolchainsBuilder;
private org.apache.maven.toolchain.building.ToolchainsBuilder toolchainsBuilder;
public ToolchainPrivate[] getToolchainsForType( String type, MavenSession context )
throws MisconfiguredToolchainException
{
PersistedToolchains pers = toolchainsBuilder.build( context.getRequest().getUserToolchainsFile() );
DefaultToolchainsBuildingRequest buildRequest = new DefaultToolchainsBuildingRequest();
File globalToolchainsFile = context.getRequest().getGlobalToolchainsFile();
if ( globalToolchainsFile != null && globalToolchainsFile.isFile() )
{
buildRequest.setGlobalToolchainsSource( new FileSource( globalToolchainsFile ) );
}
File userToolchainsFile = context.getRequest().getUserToolchainsFile();
if ( userToolchainsFile != null && userToolchainsFile.isFile() )
{
buildRequest.setUserToolchainsSource( new FileSource( userToolchainsFile ) );
}
ToolchainsBuildingResult buildResult;
try
{
buildResult = toolchainsBuilder.build( buildRequest );
}
catch ( ToolchainsBuildingException e )
{
throw new MisconfiguredToolchainException( e.getMessage(), e );
}
PersistedToolchains pers = buildResult.getEffectiveToolchains();
List<ToolchainPrivate> toRet = new ArrayList<ToolchainPrivate>();

View File

@ -32,7 +32,10 @@
/**
* @author Benjamin Bentmann
*
* @deprecated instead use {@link org.apache.maven.toolchain.building.DefaultToolchainsBuilder}
*/
@Deprecated
@Component( role = ToolchainsBuilder.class, hint = "default" )
public class DefaultToolchainsBuilder
implements ToolchainsBuilder

View File

@ -0,0 +1,136 @@
package org.apache.maven.toolchain.building;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import javax.inject.Inject;
import javax.inject.Named;
import org.apache.maven.building.Problem;
import org.apache.maven.building.ProblemCollector;
import org.apache.maven.building.ProblemCollectorFactory;
import org.apache.maven.building.Source;
import org.apache.maven.toolchain.building.io.ToolchainsParseException;
import org.apache.maven.toolchain.building.io.ToolchainsReader;
import org.apache.maven.toolchain.merge.MavenToolchainMerger;
import org.apache.maven.toolchain.model.PersistedToolchains;
import org.apache.maven.toolchain.model.TrackableBase;
/**
*
* @author Robert Scholte
* @since 3.2.6
*/
@Named
public class DefaultToolchainsBuilder
implements ToolchainsBuilder
{
private MavenToolchainMerger toolchainsMerger = new MavenToolchainMerger();
@Inject
private ToolchainsReader toolchainsReader;
@Override
public ToolchainsBuildingResult build( ToolchainsBuildingRequest request )
throws ToolchainsBuildingException
{
ProblemCollector problems = ProblemCollectorFactory.newInstance( null );
PersistedToolchains globalToolchains = readToolchains( request.getGlobalToolchainsSource() , request, problems );
PersistedToolchains userToolchains = readToolchains( request.getUserToolchainsSource(), request, problems );
toolchainsMerger.merge( userToolchains, globalToolchains, TrackableBase.GLOBAL_LEVEL );
problems.setSource( "" );
if ( hasErrors( problems.getProblems() ) )
{
throw new ToolchainsBuildingException( problems.getProblems() );
}
return new DefaultToolchainsBuildingResult( userToolchains, problems.getProblems() );
}
private PersistedToolchains readToolchains( Source toolchainsSource, ToolchainsBuildingRequest request,
ProblemCollector problems )
{
if ( toolchainsSource == null )
{
return new PersistedToolchains();
}
PersistedToolchains toolchains;
try
{
Map<String, ?> options = Collections.singletonMap( ToolchainsReader.IS_STRICT, Boolean.TRUE );
try
{
toolchains = toolchainsReader.read( toolchainsSource.getInputStream(), options );
}
catch ( ToolchainsParseException e )
{
options = Collections.singletonMap( ToolchainsReader.IS_STRICT, Boolean.FALSE );
toolchains = toolchainsReader.read( toolchainsSource.getInputStream(), options );
problems.add( Problem.Severity.WARNING, e.getMessage(), e.getLineNumber(), e.getColumnNumber(),
e );
}
}
catch ( ToolchainsParseException e )
{
problems.add( Problem.Severity.FATAL, "Non-parseable toolchains " + toolchainsSource.getLocation()
+ ": " + e.getMessage(), e.getLineNumber(), e.getColumnNumber(), e );
return new PersistedToolchains();
}
catch ( IOException e )
{
problems.add( Problem.Severity.FATAL, "Non-readable toolchains " + toolchainsSource.getLocation()
+ ": " + e.getMessage(), -1, -1, e );
return new PersistedToolchains();
}
return toolchains;
}
private boolean hasErrors( List<Problem> problems )
{
if ( problems != null )
{
for ( Problem problem : problems )
{
if ( Problem.Severity.ERROR.compareTo( problem.getSeverity() ) >= 0 )
{
return true;
}
}
}
return false;
}
}

View File

@ -0,0 +1,63 @@
package org.apache.maven.toolchain.building;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import org.apache.maven.building.Source;
/**
* Collects toolchains that control building of effective toolchains.
*
* @author Robert Scholte
* @since 3.2.6
*/
public class DefaultToolchainsBuildingRequest
implements ToolchainsBuildingRequest
{
private Source globalToolchainsSource;
private Source userToolchainsSource;
@Override
public Source getGlobalToolchainsSource()
{
return globalToolchainsSource;
}
@Override
public ToolchainsBuildingRequest setGlobalToolchainsSource( Source globalToolchainsSource )
{
this.globalToolchainsSource = globalToolchainsSource;
return this;
}
@Override
public Source getUserToolchainsSource()
{
return userToolchainsSource;
}
@Override
public ToolchainsBuildingRequest setUserToolchainsSource( Source userToolchainsSource )
{
this.userToolchainsSource = userToolchainsSource;
return this;
}
}

View File

@ -0,0 +1,59 @@
package org.apache.maven.toolchain.building;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import java.util.ArrayList;
import java.util.List;
import org.apache.maven.building.Problem;
import org.apache.maven.toolchain.model.PersistedToolchains;
/**
*
* @author Robert Scholte
* @since 3.2.6
*/
public class DefaultToolchainsBuildingResult
implements ToolchainsBuildingResult
{
private PersistedToolchains effectiveToolchains;
private List<Problem> problems;
public DefaultToolchainsBuildingResult( PersistedToolchains effectiveToolchains, List<Problem> problems )
{
this.effectiveToolchains = effectiveToolchains;
this.problems = ( problems != null ) ? problems : new ArrayList<Problem>();
}
@Override
public PersistedToolchains getEffectiveToolchains()
{
return effectiveToolchains;
}
@Override
public List<Problem> getProblems()
{
return problems;
}
}

View File

@ -0,0 +1,41 @@
package org.apache.maven.toolchain.building;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* Builds the effective toolchains from a user toolchains file and/or a global toolchains file.
*
* @author Robert Scholte
* @since 3.2.6
*/
public interface ToolchainsBuilder
{
/**
* Builds the effective toolchains of the specified toolchains files.
*
* @param request The toolchains building request that holds the parameters, must not be {@code null}.
* @return The result of the toolchains building, never {@code null}.
* @throws ToolchainsBuildingException If the effective toolchains could not be built.
*/
ToolchainsBuildingResult build( ToolchainsBuildingRequest request )
throws ToolchainsBuildingException;
}

View File

@ -0,0 +1,88 @@
package org.apache.maven.toolchain.building;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import org.apache.maven.building.Problem;
/**
* @author Robert Scholte
* @since 3.2.6
*/
public class ToolchainsBuildingException
extends Exception
{
private final List<Problem> problems;
/**
* Creates a new exception with the specified problems.
*
* @param problems The problems that causes this exception, may be {@code null}.
*/
public ToolchainsBuildingException( List<Problem> problems )
{
super( toMessage( problems ) );
this.problems = new ArrayList<Problem>();
if ( problems != null )
{
this.problems.addAll( problems );
}
}
/**
* Gets the problems that caused this exception.
*
* @return The problems that caused this exception, never {@code null}.
*/
public List<Problem> getProblems()
{
return problems;
}
private static String toMessage( List<Problem> problems )
{
StringWriter buffer = new StringWriter( 1024 );
PrintWriter writer = new PrintWriter( buffer );
writer.print( problems.size() );
writer.print( ( problems.size() == 1 ) ? " problem was " : " problems were " );
writer.print( "encountered while building the effective toolchains" );
writer.println();
for ( Problem problem : problems )
{
writer.print( "[" );
writer.print( problem.getSeverity() );
writer.print( "] " );
writer.print( problem.getMessage() );
writer.print( " @ " );
writer.println( problem.getLocation() );
}
return buffer.toString();
}
}

View File

@ -0,0 +1,64 @@
package org.apache.maven.toolchain.building;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import org.apache.maven.building.Source;
/**
* Collects toolchains that control the building of effective toolchains.
*
* @author Robert Scholte
* @since 3.2.6
*/
public interface ToolchainsBuildingRequest
{
/**
* Gets the global toolchains source.
*
* @return The global toolchains source or {@code null} if none.
*/
Source getGlobalToolchainsSource();
/**
* Sets the global toolchains source. If both user toolchains and a global toolchains are given, the user toolchains take
* precedence.
*
* @param globalToolchainsSource The global toolchains source, may be {@code null} to disable global toolchains.
* @return This request, never {@code null}.
*/
ToolchainsBuildingRequest setGlobalToolchainsSource( Source globalToolchainsSource );
/**
* Gets the user toolchains source.
*
* @return The user toolchains source or {@code null} if none.
*/
Source getUserToolchainsSource();
/**
* Sets the user toolchains source. If both user toolchains and a global toolchains are given, the user toolchains take
* precedence.
*
* @param userToolchainsSource The user toolchains source, may be {@code null} to disable user toolchains.
* @return This request, never {@code null}.
*/
ToolchainsBuildingRequest setUserToolchainsSource( Source userToolchainsSource );
}

View File

@ -0,0 +1,50 @@
package org.apache.maven.toolchain.building;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import java.util.List;
import org.apache.maven.building.Problem;
import org.apache.maven.toolchain.model.PersistedToolchains;
/**
* Collects the output of the toolchains builder.
*
* @author Robert Scholte
* @since 3.2.6
*/
public interface ToolchainsBuildingResult
{
/**
* Gets the assembled toolchains.
*
* @return The assembled toolchains, never {@code null}.
*/
PersistedToolchains getEffectiveToolchains();
/**
* Return a list of problems, if any.
*
* @return a list of problems, never {@code null}.
*/
List<Problem> getProblems();
}

View File

@ -0,0 +1,115 @@
package org.apache.maven.toolchain.building.io;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.util.Map;
import javax.inject.Named;
import javax.inject.Singleton;
import org.apache.maven.toolchain.model.PersistedToolchains;
import org.apache.maven.toolchain.model.io.xpp3.MavenToolchainsXpp3Reader;
import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.ReaderFactory;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
/**
* Handles deserialization of toolchains from the default textual format.
*
* @author Robert Scholte
* @since 3.2.6
*/
@Named
@Singleton
public class DefaultToolchainsReader
implements ToolchainsReader
{
@Override
public PersistedToolchains read( File input, Map<String, ?> options )
throws IOException
{
if ( input == null )
{
throw new IllegalArgumentException( "input file missing" );
}
return read( ReaderFactory.newXmlReader( input ), options );
}
@Override
public PersistedToolchains read( Reader input, Map<String, ?> options )
throws IOException
{
if ( input == null )
{
throw new IllegalArgumentException( "input reader missing" );
}
try
{
MavenToolchainsXpp3Reader r = new MavenToolchainsXpp3Reader();
return r.read( input, isStrict( options ) );
}
catch ( XmlPullParserException e )
{
throw new ToolchainsParseException( e.getMessage(), e.getLineNumber(), e.getColumnNumber(), e );
}
finally
{
IOUtil.close( input );
}
}
@Override
public PersistedToolchains read( InputStream input, Map<String, ?> options )
throws IOException
{
if ( input == null )
{
throw new IllegalArgumentException( "input stream missing" );
}
try
{
MavenToolchainsXpp3Reader r = new MavenToolchainsXpp3Reader();
return r.read( input, isStrict( options ) );
}
catch ( XmlPullParserException e )
{
throw new ToolchainsParseException( e.getMessage(), e.getLineNumber(), e.getColumnNumber(), e );
}
finally
{
IOUtil.close( input );
}
}
private boolean isStrict( Map<String, ?> options )
{
Object value = ( options != null ) ? options.get( IS_STRICT ) : null;
return value == null || Boolean.parseBoolean( value.toString() );
}
}

View File

@ -0,0 +1,94 @@
package org.apache.maven.toolchain.building.io;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import java.io.IOException;
/**
* Signals a failure to parse the toolchains due to invalid syntax (e.g. non-wellformed XML or unknown elements).
*
* @author Robert Scholte
* @since 3.2.6
*/
public class ToolchainsParseException
extends IOException
{
/**
* The one-based index of the line containing the error.
*/
private final int lineNumber;
/**
* The one-based index of the column containing the error.
*/
private final int columnNumber;
/**
* Creates a new parser exception with the specified details.
*
* @param message The error message, may be {@code null}.
* @param lineNumber The one-based index of the line containing the error or {@code -1} if unknown.
* @param columnNumber The one-based index of the column containing the error or {@code -1} if unknown.
*/
public ToolchainsParseException( String message, int lineNumber, int columnNumber )
{
super( message );
this.lineNumber = lineNumber;
this.columnNumber = columnNumber;
}
/**
* Creates a new parser exception with the specified details.
*
* @param message The error message, may be {@code null}.
* @param lineNumber The one-based index of the line containing the error or {@code -1} if unknown.
* @param columnNumber The one-based index of the column containing the error or {@code -1} if unknown.
* @param cause The nested cause of this error, may be {@code null}.
*/
public ToolchainsParseException( String message, int lineNumber, int columnNumber, Throwable cause )
{
super( message );
initCause( cause );
this.lineNumber = lineNumber;
this.columnNumber = columnNumber;
}
/**
* Gets the one-based index of the line containing the error.
*
* @return The one-based index of the line containing the error or a non-positive value if unknown.
*/
public int getLineNumber()
{
return lineNumber;
}
/**
* Gets the one-based index of the column containing the error.
*
* @return The one-based index of the column containing the error or non-positive value if unknown.
*/
public int getColumnNumber()
{
return columnNumber;
}
}

View File

@ -0,0 +1,83 @@
package org.apache.maven.toolchain.building.io;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.util.Map;
import org.apache.maven.toolchain.model.PersistedToolchains;
/**
* Handles deserialization of toolchains from some kind of textual format like XML.
*
* @author Robert Scholte
* @since 3.2.6
*/
public interface ToolchainsReader
{
/**
* The key for the option to enable strict parsing. This option is of type {@link Boolean} and defaults to {@code
* true}. If {@code false}, unknown elements will be ignored instead of causing a failure.
*/
String IS_STRICT = "org.apache.maven.toolchains.io.isStrict";
/**
* Reads the toolchains from the specified file.
*
* @param input The file to deserialize the toolchains from, must not be {@code null}.
* @param options The options to use for deserialization, may be {@code null} to use the default values.
* @return The deserialized toolchains, never {@code null}.
* @throws IOException If the toolchains could not be deserialized.
* @throws ToolchainsParseException If the input format could not be parsed.
*/
PersistedToolchains read( File input, Map<String, ?> options )
throws IOException, ToolchainsParseException;
/**
* Reads the toolchains from the specified character reader. The reader will be automatically closed before the method
* returns.
*
* @param input The reader to deserialize the toolchains from, must not be {@code null}.
* @param options The options to use for deserialization, may be {@code null} to use the default values.
* @return The deserialized toolchains, never {@code null}.
* @throws IOException If the toolchains could not be deserialized.
* @throws ToolchainsParseException If the input format could not be parsed.
*/
PersistedToolchains read( Reader input, Map<String, ?> options )
throws IOException, ToolchainsParseException;
/**
* Reads the toolchains from the specified byte stream. The stream will be automatically closed before the method
* returns.
*
* @param input The stream to deserialize the toolchains from, must not be {@code null}.
* @param options The options to use for deserialization, may be {@code null} to use the default values.
* @return The deserialized toolchains, never {@code null}.
* @throws IOException If the toolchains could not be deserialized.
* @throws ToolchainsParseException If the input format could not be parsed.
*/
PersistedToolchains read( InputStream input, Map<String, ?> options )
throws IOException, ToolchainsParseException;
}

View File

@ -75,6 +75,8 @@ public class CLIManager
public static final char ALTERNATE_USER_TOOLCHAINS = 't';
public static final String ALTERNATE_GLOBAL_TOOLCHAINS = "gt";
public static final String FAIL_FAST = "ff";
public static final String FAIL_AT_END = "fae";
@ -125,6 +127,7 @@ public CLIManager()
options.addOption( OptionBuilder.withLongOpt( "settings" ).withDescription( "Alternate path for the user settings file" ).hasArg().create( ALTERNATE_USER_SETTINGS ) );
options.addOption( OptionBuilder.withLongOpt( "global-settings" ).withDescription( "Alternate path for the global settings file" ).hasArg().create( ALTERNATE_GLOBAL_SETTINGS ) );
options.addOption( OptionBuilder.withLongOpt( "toolchains" ).withDescription( "Alternate path for the user toolchains file" ).hasArg().create( ALTERNATE_USER_TOOLCHAINS ) );
options.addOption( OptionBuilder.withLongOpt( "global-toolchains" ).withDescription( "Alternate path for the global toolchains file" ).hasArg().create( ALTERNATE_GLOBAL_TOOLCHAINS ) );
options.addOption( OptionBuilder.withLongOpt( "fail-fast" ).withDescription( "Stop at first failure in reactorized builds" ).create( FAIL_FAST ) );
options.addOption( OptionBuilder.withLongOpt( "fail-at-end" ).withDescription( "Only fail the build afterwards; allow all non-impacted builds to continue" ).create( FAIL_AT_END ) );
options.addOption( OptionBuilder.withLongOpt( "fail-never" ).withDescription( "NEVER fail the build, regardless of project result" ).create( FAIL_NEVER ) );

View File

@ -37,6 +37,7 @@
import org.apache.maven.BuildAbort;
import org.apache.maven.InternalErrorException;
import org.apache.maven.Maven;
import org.apache.maven.building.Source;
import org.apache.maven.cli.event.DefaultEventSpyContext;
import org.apache.maven.cli.event.ExecutionEventLogger;
import org.apache.maven.cli.logging.Slf4jConfiguration;
@ -65,7 +66,7 @@
import org.apache.maven.settings.building.SettingsBuildingRequest;
import org.apache.maven.settings.building.SettingsBuildingResult;
import org.apache.maven.settings.building.SettingsProblem;
import org.apache.maven.settings.building.SettingsSource;
import org.apache.maven.toolchain.building.ToolchainsBuilder;
import org.codehaus.plexus.ContainerConfiguration;
import org.codehaus.plexus.DefaultContainerConfiguration;
import org.codehaus.plexus.DefaultPlexusContainer;
@ -113,6 +114,9 @@ public class MavenCli
public static final File DEFAULT_USER_TOOLCHAINS_FILE = new File( userMavenConfigurationHome, "toolchains.xml" );
public static final File DEFAULT_GLOBAL_TOOLCHAINS_FILE =
new File( System.getProperty( "maven.home", System.getProperty( "user.dir", "" ) ), "conf/toolchains.xml" );
private static final String EXT_CLASS_PATH = "maven.ext.class.path";
private ClassWorld classWorld;
@ -133,6 +137,8 @@ public class MavenCli
private SettingsBuilder settingsBuilder;
private ToolchainsBuilder toolchainsBuilder;
private DefaultSecDispatcher dispatcher;
public MavenCli()
@ -210,6 +216,7 @@ public int doMain( CliRequest cliRequest )
localContainer = container( cliRequest );
commands( cliRequest );
settings( cliRequest );
toolchains( cliRequest );
populateRequest( cliRequest );
encryption( cliRequest );
repository( cliRequest );
@ -761,10 +768,10 @@ private void settings( CliRequest cliRequest )
eventSpyDispatcher.onEvent( settingsRequest );
slf4jLogger.debug( "Reading global settings from "
+ getSettingsLocation( settingsRequest.getGlobalSettingsSource(),
+ getLocation( settingsRequest.getGlobalSettingsSource(),
settingsRequest.getGlobalSettingsFile() ) );
slf4jLogger.debug( "Reading user settings from "
+ getSettingsLocation( settingsRequest.getUserSettingsSource(), settingsRequest.getUserSettingsFile() ) );
+ getLocation( settingsRequest.getUserSettingsSource(), settingsRequest.getUserSettingsFile() ) );
SettingsBuildingResult settingsResult = settingsBuilder.build( settingsRequest );
@ -785,8 +792,57 @@ private void settings( CliRequest cliRequest )
slf4jLogger.warn( "" );
}
}
@SuppressWarnings( "checkstyle:methodlength" )
private void toolchains( CliRequest cliRequest )
throws Exception
{
File userToolchainsFile;
private Object getSettingsLocation( SettingsSource source, File file )
if ( cliRequest.commandLine.hasOption( CLIManager.ALTERNATE_USER_TOOLCHAINS ) )
{
userToolchainsFile =
new File( cliRequest.commandLine.getOptionValue( CLIManager.ALTERNATE_USER_TOOLCHAINS ) );
userToolchainsFile = resolveFile( userToolchainsFile, cliRequest.workingDirectory );
if ( !userToolchainsFile.isFile() )
{
throw new FileNotFoundException( "The specified user toolchains file does not exist: "
+ userToolchainsFile );
}
}
else
{
userToolchainsFile = DEFAULT_USER_TOOLCHAINS_FILE;
}
File globalToolchainsFile;
if ( cliRequest.commandLine.hasOption( CLIManager.ALTERNATE_GLOBAL_TOOLCHAINS ) )
{
globalToolchainsFile =
new File( cliRequest.commandLine.getOptionValue( CLIManager.ALTERNATE_GLOBAL_TOOLCHAINS ) );
globalToolchainsFile = resolveFile( globalToolchainsFile, cliRequest.workingDirectory );
if ( !globalToolchainsFile.isFile() )
{
throw new FileNotFoundException( "The specified global toolchains file does not exist: "
+ globalToolchainsFile );
}
}
else
{
globalToolchainsFile = DEFAULT_GLOBAL_TOOLCHAINS_FILE;
}
cliRequest.request.setGlobalToolchainsFile( globalToolchainsFile );
cliRequest.request.setUserToolchainsFile( userToolchainsFile );
// Unlike settings, the toolchains aren't built here.
// That's done by the maven-toolchains-plugin, by calling it from the project with the proper configuration
}
private Object getLocation( Source source, File file )
{
if ( source != null )
{
@ -974,7 +1030,7 @@ else if ( request.isInteractiveMode() && !cliRequest.commandLine.hasOption( CLIM
.setUpdateSnapshots( updateSnapshots ) // default: false
.setNoSnapshotUpdates( noSnapshotUpdates ) // default: false
.setGlobalChecksumPolicy( globalChecksumPolicy ) // default: warn
.setUserToolchainsFile( userToolchainsFile );
;
if ( alternatePomFile != null )
{