mirror of https://github.com/apache/maven.git
[MNG-7051] Optionally skip non-existing profiles and break on missing required profiles.
This commit is contained in:
parent
8df10f93be
commit
8defd16965
|
@ -19,22 +19,6 @@ package org.apache.maven;
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.LinkedHashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import javax.inject.Named;
|
|
||||||
import javax.inject.Singleton;
|
|
||||||
|
|
||||||
import org.apache.maven.artifact.ArtifactUtils;
|
import org.apache.maven.artifact.ArtifactUtils;
|
||||||
import org.apache.maven.execution.BuildResumptionAnalyzer;
|
import org.apache.maven.execution.BuildResumptionAnalyzer;
|
||||||
import org.apache.maven.execution.BuildResumptionDataRepository;
|
import org.apache.maven.execution.BuildResumptionDataRepository;
|
||||||
|
@ -44,15 +28,19 @@ import org.apache.maven.execution.ExecutionEvent;
|
||||||
import org.apache.maven.execution.MavenExecutionRequest;
|
import org.apache.maven.execution.MavenExecutionRequest;
|
||||||
import org.apache.maven.execution.MavenExecutionResult;
|
import org.apache.maven.execution.MavenExecutionResult;
|
||||||
import org.apache.maven.execution.MavenSession;
|
import org.apache.maven.execution.MavenSession;
|
||||||
|
import org.apache.maven.execution.ProfileActivation;
|
||||||
import org.apache.maven.execution.ProjectDependencyGraph;
|
import org.apache.maven.execution.ProjectDependencyGraph;
|
||||||
import org.apache.maven.graph.GraphBuilder;
|
import org.apache.maven.graph.GraphBuilder;
|
||||||
import org.apache.maven.internal.aether.DefaultRepositorySystemSessionFactory;
|
import org.apache.maven.internal.aether.DefaultRepositorySystemSessionFactory;
|
||||||
import org.apache.maven.lifecycle.LifecycleExecutionException;
|
import org.apache.maven.lifecycle.LifecycleExecutionException;
|
||||||
import org.apache.maven.lifecycle.internal.ExecutionEventCatapult;
|
import org.apache.maven.lifecycle.internal.ExecutionEventCatapult;
|
||||||
import org.apache.maven.lifecycle.internal.LifecycleStarter;
|
import org.apache.maven.lifecycle.internal.LifecycleStarter;
|
||||||
|
import org.apache.maven.model.Model;
|
||||||
import org.apache.maven.model.Prerequisites;
|
import org.apache.maven.model.Prerequisites;
|
||||||
|
import org.apache.maven.model.Profile;
|
||||||
import org.apache.maven.model.building.ModelProblem;
|
import org.apache.maven.model.building.ModelProblem;
|
||||||
import org.apache.maven.model.building.Result;
|
import org.apache.maven.model.building.Result;
|
||||||
|
import org.apache.maven.model.superpom.SuperPomProvider;
|
||||||
import org.apache.maven.plugin.LegacySupport;
|
import org.apache.maven.plugin.LegacySupport;
|
||||||
import org.apache.maven.project.MavenProject;
|
import org.apache.maven.project.MavenProject;
|
||||||
import org.apache.maven.project.ProjectBuilder;
|
import org.apache.maven.project.ProjectBuilder;
|
||||||
|
@ -66,6 +54,26 @@ import org.eclipse.aether.RepositorySystemSession;
|
||||||
import org.eclipse.aether.repository.WorkspaceReader;
|
import org.eclipse.aether.repository.WorkspaceReader;
|
||||||
import org.eclipse.aether.util.repository.ChainedWorkspaceReader;
|
import org.eclipse.aether.util.repository.ChainedWorkspaceReader;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import static java.util.stream.Collectors.toSet;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Jason van Zyl
|
* @author Jason van Zyl
|
||||||
*/
|
*/
|
||||||
|
@ -109,6 +117,9 @@ public class DefaultMaven
|
||||||
@Inject
|
@Inject
|
||||||
private BuildResumptionDataRepository buildResumptionDataRepository;
|
private BuildResumptionDataRepository buildResumptionDataRepository;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private SuperPomProvider superPomProvider;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MavenExecutionResult execute( MavenExecutionRequest request )
|
public MavenExecutionResult execute( MavenExecutionRequest request )
|
||||||
{
|
{
|
||||||
|
@ -316,11 +327,17 @@ public class DefaultMaven
|
||||||
|
|
||||||
validatePrerequisitesForNonMavenPluginProjects( session.getProjects() );
|
validatePrerequisitesForNonMavenPluginProjects( session.getProjects() );
|
||||||
|
|
||||||
validateActivatedProfiles( session.getProjects(), request.getActiveProfiles() );
|
validateRequiredProfiles( session, request.getProfileActivation() );
|
||||||
|
if ( session.getResult().hasExceptions() )
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
validateOptionalProfiles( session, request.getProfileActivation() );
|
||||||
|
|
||||||
lifecycleStarter.execute( session );
|
lifecycleStarter.execute( session );
|
||||||
|
|
||||||
validateActivatedProfiles( session.getProjects(), request.getActiveProfiles() );
|
validateOptionalProfiles( session, request.getProfileActivation() );
|
||||||
|
|
||||||
if ( session.getResult().hasExceptions() )
|
if ( session.getResult().hasExceptions() )
|
||||||
{
|
{
|
||||||
|
@ -493,22 +510,93 @@ public class DefaultMaven
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validateActivatedProfiles( List<MavenProject> projects, List<String> activeProfileIds )
|
/**
|
||||||
|
* Get all profiles that are detected in the projects, any parent of the projects, or the settings.
|
||||||
|
* @param session The Maven session
|
||||||
|
* @return A {@link Set} of profile identifiers, never {@code null}.
|
||||||
|
*/
|
||||||
|
private Set<String> getAllProfiles( MavenSession session )
|
||||||
{
|
{
|
||||||
Collection<String> notActivatedProfileIds = new LinkedHashSet<>( activeProfileIds );
|
final Model superPomModel = superPomProvider.getSuperModel( "4.0.0" );
|
||||||
|
final Set<MavenProject> projectsIncludingParents = new HashSet<>();
|
||||||
for ( MavenProject project : projects )
|
for ( MavenProject project : session.getProjects() )
|
||||||
{
|
{
|
||||||
for ( List<String> profileIds : project.getInjectedProfileIds().values() )
|
boolean isAdded = projectsIncludingParents.add( project );
|
||||||
|
MavenProject parent = project.getParent();
|
||||||
|
while ( isAdded && parent != null )
|
||||||
{
|
{
|
||||||
notActivatedProfileIds.removeAll( profileIds );
|
isAdded = projectsIncludingParents.add( parent );
|
||||||
|
parent = parent.getParent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( String notActivatedProfileId : notActivatedProfileIds )
|
final Stream<String> projectProfiles = projectsIncludingParents.stream()
|
||||||
|
.map( MavenProject::getModel )
|
||||||
|
.map( Model::getProfiles )
|
||||||
|
.flatMap( Collection::stream )
|
||||||
|
.map( Profile::getId );
|
||||||
|
final Stream<String> settingsProfiles = session.getSettings().getProfiles().stream()
|
||||||
|
.map( org.apache.maven.settings.Profile::getId );
|
||||||
|
final Stream<String> superPomProfiles = superPomModel.getProfiles().stream()
|
||||||
|
.map( Profile::getId );
|
||||||
|
|
||||||
|
return Stream.of( projectProfiles, settingsProfiles, superPomProfiles )
|
||||||
|
.flatMap( Function.identity() )
|
||||||
|
.collect( toSet() );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether the required profiles were found in any of the projects we're building or the settings.
|
||||||
|
* @param session the Maven session.
|
||||||
|
* @param profileActivation the requested optional and required profiles.
|
||||||
|
*/
|
||||||
|
private void validateRequiredProfiles( MavenSession session, ProfileActivation profileActivation )
|
||||||
|
{
|
||||||
|
final Set<String> allAvailableProfiles = getAllProfiles( session );
|
||||||
|
|
||||||
|
final Set<String> requiredProfiles = new HashSet<>( );
|
||||||
|
requiredProfiles.addAll( profileActivation.getRequiredActiveProfileIds() );
|
||||||
|
requiredProfiles.addAll( profileActivation.getRequiredInactiveProfileIds() );
|
||||||
|
|
||||||
|
// Check whether the required profiles were found in any of the projects we're building.
|
||||||
|
final Set<String> notFoundRequiredProfiles = requiredProfiles.stream()
|
||||||
|
.filter( rap -> !allAvailableProfiles.contains( rap ) )
|
||||||
|
.collect( toSet() );
|
||||||
|
|
||||||
|
if ( !notFoundRequiredProfiles.isEmpty() )
|
||||||
{
|
{
|
||||||
logger.warn( "The requested profile \"" + notActivatedProfileId
|
final String message = String.format(
|
||||||
+ "\" could not be activated because it does not exist." );
|
"The requested profiles [%s] could not be activated or deactivated because they do not exist.",
|
||||||
|
String.join( ", ", notFoundRequiredProfiles )
|
||||||
|
);
|
||||||
|
addExceptionToResult( session.getResult(), new MissingProfilesException( message ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether any of the requested optional profiles were not activated or deactivated.
|
||||||
|
* @param session the Maven session.
|
||||||
|
* @param profileActivation the requested optional and required profiles.
|
||||||
|
*/
|
||||||
|
private void validateOptionalProfiles( MavenSession session, ProfileActivation profileActivation )
|
||||||
|
{
|
||||||
|
final Set<String> allAvailableProfiles = getAllProfiles( session );
|
||||||
|
|
||||||
|
final Set<String> optionalProfiles = new HashSet<>( );
|
||||||
|
optionalProfiles.addAll( profileActivation.getOptionalActiveProfileIds() );
|
||||||
|
optionalProfiles.addAll( profileActivation.getOptionalInactiveProfileIds() );
|
||||||
|
|
||||||
|
final Set<String> notFoundOptionalProfiles = optionalProfiles.stream()
|
||||||
|
.filter( rap -> !allAvailableProfiles.contains( rap ) )
|
||||||
|
.collect( toSet() );
|
||||||
|
|
||||||
|
if ( !notFoundOptionalProfiles.isEmpty() )
|
||||||
|
{
|
||||||
|
final String message = String.format(
|
||||||
|
"The requested optional profiles [%s] could not be activated or deactivated because they "
|
||||||
|
+ "do not exist.", String.join( ", ", notFoundOptionalProfiles )
|
||||||
|
);
|
||||||
|
logger.warn( message );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
package org.apache.maven;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Signals that the user referenced one or more Maven profiles that could not be located in either the project or the
|
||||||
|
* settings.
|
||||||
|
*/
|
||||||
|
public class MissingProfilesException
|
||||||
|
extends Exception
|
||||||
|
{
|
||||||
|
public MissingProfilesException( String message )
|
||||||
|
{
|
||||||
|
super( message );
|
||||||
|
}
|
||||||
|
}
|
|
@ -76,6 +76,8 @@ public class DefaultMavenExecutionRequest
|
||||||
|
|
||||||
private List<Profile> profiles;
|
private List<Profile> profiles;
|
||||||
|
|
||||||
|
private final ProfileActivation profileActivation = new ProfileActivation();
|
||||||
|
|
||||||
private List<String> pluginGroups;
|
private List<String> pluginGroups;
|
||||||
|
|
||||||
private boolean isProjectPresent = true;
|
private boolean isProjectPresent = true;
|
||||||
|
@ -130,10 +132,6 @@ public class DefaultMavenExecutionRequest
|
||||||
|
|
||||||
private boolean showErrors = false;
|
private boolean showErrors = false;
|
||||||
|
|
||||||
private List<String> activeProfiles;
|
|
||||||
|
|
||||||
private List<String> inactiveProfiles;
|
|
||||||
|
|
||||||
private TransferListener transferListener;
|
private TransferListener transferListener;
|
||||||
|
|
||||||
private int loggingLevel = LOGGING_LEVEL_INFO;
|
private int loggingLevel = LOGGING_LEVEL_INFO;
|
||||||
|
@ -343,11 +341,7 @@ public class DefaultMavenExecutionRequest
|
||||||
{
|
{
|
||||||
if ( activeProfiles != null )
|
if ( activeProfiles != null )
|
||||||
{
|
{
|
||||||
this.activeProfiles = new ArrayList<>( activeProfiles );
|
this.profileActivation.overwriteActiveProfiles( activeProfiles );
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this.activeProfiles = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
|
@ -358,16 +352,18 @@ public class DefaultMavenExecutionRequest
|
||||||
{
|
{
|
||||||
if ( inactiveProfiles != null )
|
if ( inactiveProfiles != null )
|
||||||
{
|
{
|
||||||
this.inactiveProfiles = new ArrayList<>( inactiveProfiles );
|
this.profileActivation.overwriteInactiveProfiles( inactiveProfiles );
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this.inactiveProfiles = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ProfileActivation getProfileActivation()
|
||||||
|
{
|
||||||
|
return this.profileActivation;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MavenExecutionRequest setRemoteRepositories( List<ArtifactRepository> remoteRepositories )
|
public MavenExecutionRequest setRemoteRepositories( List<ArtifactRepository> remoteRepositories )
|
||||||
{
|
{
|
||||||
|
@ -406,21 +402,13 @@ public class DefaultMavenExecutionRequest
|
||||||
@Override
|
@Override
|
||||||
public List<String> getActiveProfiles()
|
public List<String> getActiveProfiles()
|
||||||
{
|
{
|
||||||
if ( activeProfiles == null )
|
return this.profileActivation.getActiveProfiles();
|
||||||
{
|
|
||||||
activeProfiles = new ArrayList<>();
|
|
||||||
}
|
|
||||||
return activeProfiles;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> getInactiveProfiles()
|
public List<String> getInactiveProfiles()
|
||||||
{
|
{
|
||||||
if ( inactiveProfiles == null )
|
return this.profileActivation.getInactiveProfiles();
|
||||||
{
|
|
||||||
inactiveProfiles = new ArrayList<>();
|
|
||||||
}
|
|
||||||
return inactiveProfiles;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -277,22 +277,62 @@ public interface MavenExecutionRequest
|
||||||
|
|
||||||
MavenExecutionRequest setProfiles( List<Profile> profiles );
|
MavenExecutionRequest setProfiles( List<Profile> profiles );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Use {@link #getProfileActivation()}.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
MavenExecutionRequest addActiveProfile( String profile );
|
MavenExecutionRequest addActiveProfile( String profile );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Use {@link #getProfileActivation()}.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
MavenExecutionRequest addActiveProfiles( List<String> profiles );
|
MavenExecutionRequest addActiveProfiles( List<String> profiles );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Use {@link #getProfileActivation()}.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
MavenExecutionRequest setActiveProfiles( List<String> profiles );
|
MavenExecutionRequest setActiveProfiles( List<String> profiles );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The list of profiles that the user wants to activate.
|
||||||
|
* @deprecated Use {@link #getProfileActivation()}.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
List<String> getActiveProfiles();
|
List<String> getActiveProfiles();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Use {@link #getProfileActivation()}.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
MavenExecutionRequest addInactiveProfile( String profile );
|
MavenExecutionRequest addInactiveProfile( String profile );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Use {@link #getProfileActivation()}.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
MavenExecutionRequest addInactiveProfiles( List<String> profiles );
|
MavenExecutionRequest addInactiveProfiles( List<String> profiles );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Use {@link #getProfileActivation()}.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
MavenExecutionRequest setInactiveProfiles( List<String> profiles );
|
MavenExecutionRequest setInactiveProfiles( List<String> profiles );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The list of profiles that the user wants to de-activate.
|
||||||
|
* @deprecated Use {@link #getProfileActivation()}.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
List<String> getInactiveProfiles();
|
List<String> getInactiveProfiles();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the requested activation(s) of profile(s) in this execution.
|
||||||
|
* @return requested (de-)activation(s) of profile(s) in this execution. Never {@code null}.
|
||||||
|
*/
|
||||||
|
ProfileActivation getProfileActivation();
|
||||||
|
|
||||||
// Proxies
|
// Proxies
|
||||||
List<Proxy> getProxies();
|
List<Proxy> getProxies();
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,201 @@
|
||||||
|
package org.apache.maven.execution;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
import static java.util.stream.Collectors.toSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Container for storing the request from the user to activate or de-activate certain profiles and optionally fail the
|
||||||
|
* build if those profiles do not exist.
|
||||||
|
*/
|
||||||
|
public class ProfileActivation
|
||||||
|
{
|
||||||
|
private enum ActivationSettings
|
||||||
|
{
|
||||||
|
ACTIVATION_OPTIONAL( true, true ),
|
||||||
|
ACTIVATION_REQUIRED( true, false ),
|
||||||
|
DEACTIVATION_OPTIONAL( false, true ),
|
||||||
|
DEACTIVATION_REQUIRED( false, false );
|
||||||
|
|
||||||
|
/** Should the profile be active? */
|
||||||
|
final boolean active;
|
||||||
|
/** Should the build continue if the profile is not present? */
|
||||||
|
final boolean optional;
|
||||||
|
|
||||||
|
ActivationSettings( final boolean active, final boolean optional )
|
||||||
|
{
|
||||||
|
this.active = active;
|
||||||
|
this.optional = optional;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ActivationSettings of( final boolean active, final boolean optional )
|
||||||
|
{
|
||||||
|
if ( optional )
|
||||||
|
{
|
||||||
|
return active ? ACTIVATION_OPTIONAL : DEACTIVATION_OPTIONAL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return active ? ACTIVATION_REQUIRED : DEACTIVATION_REQUIRED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final Map<String, ActivationSettings> activations = new HashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mimics the pre-Maven 4 "active profiles" list.
|
||||||
|
* @deprecated Use {@link #getRequiredActiveProfileIds()} and {@link #getOptionalActiveProfileIds()} instead.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public List<String> getActiveProfiles()
|
||||||
|
{
|
||||||
|
return new ArrayList<>( getProfileIds( pa -> pa.active ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mimics the pre-Maven 4 "inactive profiles" list.
|
||||||
|
* @deprecated Use {@link #getRequiredInactiveProfileIds()} and {@link #getOptionalInactiveProfileIds()} instead.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public List<String> getInactiveProfiles()
|
||||||
|
{
|
||||||
|
return new ArrayList<>( getProfileIds( pa -> !pa.active ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overwrites the active profiles based on a pre-Maven 4 "active profiles" list.
|
||||||
|
* @param activeProfileIds A {@link List} of profile IDs that must be activated.
|
||||||
|
* @deprecated Use {@link #activateOptionalProfile(String)} or {@link #activateRequiredProfile(String)} instead.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public void overwriteActiveProfiles( List<String> activeProfileIds )
|
||||||
|
{
|
||||||
|
getActiveProfiles().forEach( this.activations::remove );
|
||||||
|
activeProfileIds.forEach( this::activateOptionalProfile );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overwrites the inactive profiles based on a pre-Maven 4 "inactive profiles" list.
|
||||||
|
* @param inactiveProfileIds A {@link List} of profile IDs that must be deactivated.
|
||||||
|
* @deprecated Use {@link #deactivateOptionalProfile(String)} or {@link #deactivateRequiredProfile(String)} instead.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public void overwriteInactiveProfiles( List<String> inactiveProfileIds )
|
||||||
|
{
|
||||||
|
getInactiveProfiles().forEach( this.activations::remove );
|
||||||
|
inactiveProfileIds.forEach( this::deactivateOptionalProfile );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark a profile as required and activated.
|
||||||
|
* @param id The identifier of the profile.
|
||||||
|
*/
|
||||||
|
public void activateRequiredProfile( String id )
|
||||||
|
{
|
||||||
|
this.activations.put( id, ActivationSettings.ACTIVATION_REQUIRED );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark a profile as optional and activated.
|
||||||
|
* @param id The identifier of the profile.
|
||||||
|
*/
|
||||||
|
public void activateOptionalProfile( String id )
|
||||||
|
{
|
||||||
|
this.activations.put( id, ActivationSettings.ACTIVATION_OPTIONAL );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark a profile as required and deactivated.
|
||||||
|
* @param id The identifier of the profile.
|
||||||
|
*/
|
||||||
|
public void deactivateRequiredProfile( String id )
|
||||||
|
{
|
||||||
|
this.activations.put( id, ActivationSettings.DEACTIVATION_REQUIRED );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark a profile as optional and deactivated.
|
||||||
|
* @param id The identifier of the profile.
|
||||||
|
*/
|
||||||
|
public void deactivateOptionalProfile( String id )
|
||||||
|
{
|
||||||
|
this.activations.put( id, ActivationSettings.DEACTIVATION_OPTIONAL );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a profile activation to the request.
|
||||||
|
* @param id The identifier of the profile.
|
||||||
|
* @param active Should the profile be activated?
|
||||||
|
* @param optional Can the build continue if the profile does not exist?
|
||||||
|
*/
|
||||||
|
public void addProfileActivation( String id, boolean active, boolean optional )
|
||||||
|
{
|
||||||
|
final ActivationSettings settings = ActivationSettings.of( active, optional );
|
||||||
|
this.activations.put( id, settings );
|
||||||
|
}
|
||||||
|
|
||||||
|
private Set<String> getProfileIds( final Predicate<ActivationSettings> predicate )
|
||||||
|
{
|
||||||
|
return this.activations.entrySet().stream()
|
||||||
|
.filter( e -> predicate.test( e.getValue() ) )
|
||||||
|
.map( e -> e.getKey() )
|
||||||
|
.collect( toSet() );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Required active profile identifiers, never {@code null}.
|
||||||
|
*/
|
||||||
|
public Set<String> getRequiredActiveProfileIds()
|
||||||
|
{
|
||||||
|
return getProfileIds( pa -> !pa.optional && pa.active );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Optional active profile identifiers, never {@code null}.
|
||||||
|
*/
|
||||||
|
public Set<String> getOptionalActiveProfileIds()
|
||||||
|
{
|
||||||
|
return getProfileIds( pa -> pa.optional && pa.active );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Required inactive profile identifiers, never {@code null}.
|
||||||
|
*/
|
||||||
|
public Set<String> getRequiredInactiveProfileIds()
|
||||||
|
{
|
||||||
|
return getProfileIds( pa -> !pa.optional && !pa.active );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Optional inactive profile identifiers, never {@code null}.
|
||||||
|
*/
|
||||||
|
public Set<String> getOptionalInactiveProfileIds()
|
||||||
|
{
|
||||||
|
return getProfileIds( pa -> pa.optional && !pa.active );
|
||||||
|
}
|
||||||
|
}
|
|
@ -54,6 +54,7 @@ import org.apache.maven.execution.MavenExecutionRequest;
|
||||||
import org.apache.maven.execution.MavenExecutionRequestPopulationException;
|
import org.apache.maven.execution.MavenExecutionRequestPopulationException;
|
||||||
import org.apache.maven.execution.MavenExecutionRequestPopulator;
|
import org.apache.maven.execution.MavenExecutionRequestPopulator;
|
||||||
import org.apache.maven.execution.MavenExecutionResult;
|
import org.apache.maven.execution.MavenExecutionResult;
|
||||||
|
import org.apache.maven.execution.ProfileActivation;
|
||||||
import org.apache.maven.execution.scope.internal.MojoExecutionScopeModule;
|
import org.apache.maven.execution.scope.internal.MojoExecutionScopeModule;
|
||||||
import org.apache.maven.extension.internal.CoreExports;
|
import org.apache.maven.extension.internal.CoreExports;
|
||||||
import org.apache.maven.extension.internal.CoreExtensionEntry;
|
import org.apache.maven.extension.internal.CoreExtensionEntry;
|
||||||
|
@ -1379,9 +1380,7 @@ public class MavenCli
|
||||||
request.setSelectedProjects( projectActivation.activeProjects );
|
request.setSelectedProjects( projectActivation.activeProjects );
|
||||||
request.setExcludedProjects( projectActivation.inactiveProjects );
|
request.setExcludedProjects( projectActivation.inactiveProjects );
|
||||||
|
|
||||||
final ProfileActivation profileActivation = determineProfileActivation( commandLine );
|
performProfileActivation( commandLine, request.getProfileActivation() );
|
||||||
request.addActiveProfiles( profileActivation.activeProfiles );
|
|
||||||
request.addInactiveProfiles( profileActivation.inactiveProfiles );
|
|
||||||
|
|
||||||
final String localRepositoryPath = determineLocalRepositoryPath( request );
|
final String localRepositoryPath = determineLocalRepositoryPath( request );
|
||||||
if ( localRepositoryPath != null )
|
if ( localRepositoryPath != null )
|
||||||
|
@ -1507,41 +1506,41 @@ public class MavenCli
|
||||||
}
|
}
|
||||||
|
|
||||||
// Visible for testing
|
// Visible for testing
|
||||||
static ProfileActivation determineProfileActivation( final CommandLine commandLine )
|
static void performProfileActivation( final CommandLine commandLine,
|
||||||
|
final ProfileActivation profileActivation )
|
||||||
{
|
{
|
||||||
final ProfileActivation result = new ProfileActivation();
|
|
||||||
|
|
||||||
if ( commandLine.hasOption( CLIManager.ACTIVATE_PROFILES ) )
|
if ( commandLine.hasOption( CLIManager.ACTIVATE_PROFILES ) )
|
||||||
{
|
{
|
||||||
String[] profileOptionValues = commandLine.getOptionValues( CLIManager.ACTIVATE_PROFILES );
|
final String[] optionValues = commandLine.getOptionValues( CLIManager.ACTIVATE_PROFILES );
|
||||||
if ( profileOptionValues != null )
|
|
||||||
|
if ( optionValues == null || optionValues.length == 0 )
|
||||||
{
|
{
|
||||||
for ( String profileOptionValue : profileOptionValues )
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( final String optionValue : optionValues )
|
||||||
|
{
|
||||||
|
for ( String token : optionValue.split( "," ) )
|
||||||
{
|
{
|
||||||
StringTokenizer profileTokens = new StringTokenizer( profileOptionValue, "," );
|
String profileId = token.trim();
|
||||||
|
boolean active = true;
|
||||||
while ( profileTokens.hasMoreTokens() )
|
if ( profileId.charAt( 0 ) == '-' || profileId.charAt( 0 ) == '!' )
|
||||||
{
|
{
|
||||||
String profileAction = profileTokens.nextToken().trim();
|
active = false;
|
||||||
|
profileId = profileId.substring( 1 );
|
||||||
if ( profileAction.startsWith( "-" ) || profileAction.startsWith( "!" ) )
|
|
||||||
{
|
|
||||||
result.deactivate( profileAction.substring( 1 ) );
|
|
||||||
}
|
|
||||||
else if ( profileAction.startsWith( "+" ) )
|
|
||||||
{
|
|
||||||
result.activate( profileAction.substring( 1 ) );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result.activate( profileAction );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else if ( token.charAt( 0 ) == '+' )
|
||||||
|
{
|
||||||
|
profileId = profileId.substring( 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean optional = profileId.charAt( 0 ) == '?';
|
||||||
|
profileId = profileId.substring( optional ? 1 : 0 );
|
||||||
|
|
||||||
|
profileActivation.addProfileActivation( profileId, active, optional );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ExecutionListener determineExecutionListener()
|
private ExecutionListener determineExecutionListener()
|
||||||
|
@ -1796,23 +1795,6 @@ public class MavenCli
|
||||||
return container.lookup( ModelProcessor.class );
|
return container.lookup( ModelProcessor.class );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Visible for testing
|
|
||||||
static class ProfileActivation
|
|
||||||
{
|
|
||||||
final List<String> activeProfiles = new ArrayList<>();
|
|
||||||
final List<String> inactiveProfiles = new ArrayList<>();
|
|
||||||
|
|
||||||
public void deactivate( final String profile )
|
|
||||||
{
|
|
||||||
inactiveProfiles.add( profile );
|
|
||||||
}
|
|
||||||
|
|
||||||
public void activate( final String profile )
|
|
||||||
{
|
|
||||||
activeProfiles.add( profile );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Visible for testing
|
// Visible for testing
|
||||||
static class ProjectActivation
|
static class ProjectActivation
|
||||||
{
|
{
|
||||||
|
|
|
@ -20,7 +20,7 @@ package org.apache.maven.cli;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import static java.util.Arrays.asList;
|
import static java.util.Arrays.asList;
|
||||||
import static org.apache.maven.cli.MavenCli.determineProfileActivation;
|
import static org.apache.maven.cli.MavenCli.performProfileActivation;
|
||||||
import static org.apache.maven.cli.MavenCli.determineProjectActivation;
|
import static org.apache.maven.cli.MavenCli.determineProjectActivation;
|
||||||
import static org.hamcrest.CoreMatchers.is;
|
import static org.hamcrest.CoreMatchers.is;
|
||||||
import static org.hamcrest.CoreMatchers.nullValue;
|
import static org.hamcrest.CoreMatchers.nullValue;
|
||||||
|
@ -33,6 +33,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
import static org.junit.jupiter.api.Assumptions.assumeTrue;
|
import static org.junit.jupiter.api.Assumptions.assumeTrue;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.hamcrest.collection.IsIterableContainingInOrder.contains;
|
import static org.hamcrest.collection.IsIterableContainingInOrder.contains;
|
||||||
|
import static org.hamcrest.collection.IsIterableContainingInAnyOrder.containsInAnyOrder;
|
||||||
import static org.mockito.Mockito.inOrder;
|
import static org.mockito.Mockito.inOrder;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.times;
|
import static org.mockito.Mockito.times;
|
||||||
|
@ -46,9 +47,11 @@ import org.apache.commons.cli.GnuParser;
|
||||||
import org.apache.commons.cli.Option;
|
import org.apache.commons.cli.Option;
|
||||||
import org.apache.commons.cli.Options;
|
import org.apache.commons.cli.Options;
|
||||||
import org.apache.commons.cli.ParseException;
|
import org.apache.commons.cli.ParseException;
|
||||||
|
import org.apache.commons.cli.Parser;
|
||||||
import org.apache.maven.Maven;
|
import org.apache.maven.Maven;
|
||||||
import org.apache.maven.eventspy.internal.EventSpyDispatcher;
|
import org.apache.maven.eventspy.internal.EventSpyDispatcher;
|
||||||
import org.apache.maven.execution.MavenExecutionRequest;
|
import org.apache.maven.execution.MavenExecutionRequest;
|
||||||
|
import org.apache.maven.execution.ProfileActivation;
|
||||||
import org.apache.maven.project.MavenProject;
|
import org.apache.maven.project.MavenProject;
|
||||||
import org.apache.maven.shared.utils.logging.MessageUtils;
|
import org.apache.maven.shared.utils.logging.MessageUtils;
|
||||||
import org.apache.maven.toolchain.building.ToolchainsBuildingRequest;
|
import org.apache.maven.toolchain.building.ToolchainsBuildingRequest;
|
||||||
|
@ -88,25 +91,29 @@ public class MavenCliTest
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDetermineProfileActivation() throws ParseException
|
public void testPerformProfileActivation() throws ParseException
|
||||||
{
|
{
|
||||||
MavenCli.ProfileActivation result;
|
final Parser parser = new GnuParser();
|
||||||
Options options = new Options();
|
|
||||||
|
final Options options = new Options();
|
||||||
options.addOption( Option.builder( Character.toString( CLIManager.ACTIVATE_PROFILES ) ).hasArg().build() );
|
options.addOption( Option.builder( Character.toString( CLIManager.ACTIVATE_PROFILES ) ).hasArg().build() );
|
||||||
|
|
||||||
result = determineProfileActivation( new GnuParser().parse( options, new String[]{ "-P", "test1,+test2" } ) );
|
ProfileActivation activation;
|
||||||
assertThat( result.activeProfiles.size(), is( 2 ) );
|
|
||||||
assertThat( result.activeProfiles, contains( "test1", "test2" ) );
|
|
||||||
|
|
||||||
result = determineProfileActivation( new GnuParser().parse( options, new String[]{ "-P", "!test1,-test2" } ) );
|
activation = new ProfileActivation();
|
||||||
assertThat( result.inactiveProfiles.size(), is( 2 ) );
|
performProfileActivation( parser.parse( options, new String[]{ "-P", "test1,+test2,?test3,+?test4" } ), activation );
|
||||||
assertThat( result.inactiveProfiles, contains( "test1", "test2" ) );
|
assertThat( activation.getRequiredActiveProfileIds(), containsInAnyOrder( "test1", "test2" ) );
|
||||||
|
assertThat( activation.getOptionalActiveProfileIds(), containsInAnyOrder( "test3", "test4" ) );
|
||||||
|
|
||||||
result = determineProfileActivation( new GnuParser().parse( options, new String[]{ "-P", "-test1,+test2" } ) );
|
activation = new ProfileActivation();
|
||||||
assertThat( result.activeProfiles.size(), is( 1 ) );
|
performProfileActivation( parser.parse( options, new String[]{ "-P", "!test1,-test2,-?test3,!?test4" } ), activation );
|
||||||
assertThat( result.activeProfiles, contains( "test2" ) );
|
assertThat( activation.getRequiredInactiveProfileIds(), containsInAnyOrder( "test1", "test2" ) );
|
||||||
assertThat( result.inactiveProfiles.size(), is( 1 ) );
|
assertThat( activation.getOptionalInactiveProfileIds(), containsInAnyOrder( "test3", "test4" ) );
|
||||||
assertThat( result.inactiveProfiles, contains( "test1" ) );
|
|
||||||
|
activation = new ProfileActivation();
|
||||||
|
performProfileActivation( parser.parse( options, new String[]{ "-P", "-test1,+test2" } ), activation );
|
||||||
|
assertThat( activation.getRequiredActiveProfileIds(), containsInAnyOrder( "test2" ) );
|
||||||
|
assertThat( activation.getRequiredInactiveProfileIds(), containsInAnyOrder( "test1" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -51,7 +51,8 @@ public interface ModelProblem
|
||||||
V20,
|
V20,
|
||||||
V30,
|
V30,
|
||||||
V31,
|
V31,
|
||||||
V37
|
V37,
|
||||||
|
V40
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -190,6 +190,8 @@ public class DefaultModelValidator
|
||||||
{
|
{
|
||||||
String prefix = "profiles.profile[" + profile.getId() + "].";
|
String prefix = "profiles.profile[" + profile.getId() + "].";
|
||||||
|
|
||||||
|
validateId( prefix, "id", problems, Severity.ERROR, Version.V40, profile.getId(), null, m );
|
||||||
|
|
||||||
if ( !profileIds.add( profile.getId() ) )
|
if ( !profileIds.add( profile.getId() ) )
|
||||||
{
|
{
|
||||||
addViolation( problems, errOn30, Version.V20, "profiles.profile.id", null,
|
addViolation( problems, errOn30, Version.V20, "profiles.profile.id", null,
|
||||||
|
|
|
@ -403,6 +403,16 @@ public class DefaultModelValidatorTest
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
public void testInvalidProfileId()
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
SimpleProblemCollector result = validateRaw( "invalid-profile-id.xml" );
|
||||||
|
|
||||||
|
assertViolations( result, 0, 1, 0 );
|
||||||
|
|
||||||
|
assertTrue( result.getErrors().get( 0 ).contains( "?invalid-id" ) );
|
||||||
|
}
|
||||||
|
|
||||||
public void testDuplicateProfileId()
|
public void testDuplicateProfileId()
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
<!--
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<project>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<artifactId>aid</artifactId>
|
||||||
|
<groupId>gid</groupId>
|
||||||
|
<version>0.1</version>
|
||||||
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
|
<profiles>
|
||||||
|
<profile>
|
||||||
|
<id>?invalid-id</id>
|
||||||
|
</profile>
|
||||||
|
</profiles>
|
||||||
|
</project>
|
Loading…
Reference in New Issue