Skip to content

Commit

Permalink
Fix dependency generation
Browse files Browse the repository at this point in the history
Support for different namespaces requires more complicated
delf-dependency resolution mechanism.  Basically, if there is
dependency some self-provided artifacts then generated require should
have the same version and namespace as provided artifact.
  • Loading branch information
mizdebsk committed Oct 14, 2013
1 parent cd18f52 commit 849f5b4
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;
import java.util.zip.ZipEntry;
Expand Down Expand Up @@ -100,6 +102,18 @@ public class DefaultInstaller

private Map<Package, Package> packages;

/** map package => installed devel artifacts (no aliases) */
private Map<Package, Set<Artifact>> packageDevelArtifacts;

/** map package => installed user artifacts (no aliases) */
private Map<Package, Set<Artifact>> packageUserArtifacts;

/** map package => provided artifacts and aliases */
private Map<Package, Set<Artifact>> packagedArtifacts;

/** map generic artifact => provided artifact */
private Map<Artifact, Artifact> providedArtifacts;

private Set<Artifact> skippedArtifacts;

private PackagingRule ruleForArtifact( Artifact artifact )
Expand Down Expand Up @@ -244,20 +258,52 @@ private void installArtifact( Package pkg, Artifact artifact, List<Artifact> ali
pkg.addSymlink( symlink, primaryJppArtifact.getFile().toPath() );
}

Set<Artifact> packaged = packagedArtifacts.get( pkg );
if ( packaged == null )
{
packaged = new HashSet<>();
packagedArtifacts.put( pkg, packaged );
}

for ( Artifact jppArtifact : jppArtifacts )
{
String namespace = ArtifactUtils.getScope( jppArtifact );
packaged.add( artifact.setVersion( jppArtifact.getVersion() ) );
providedArtifacts.put( artifact.setVersion( jppArtifact.getVersion() ),
ArtifactUtils.setScope( artifact.setVersion( jppArtifact.getVersion() ), namespace ) );
pkg.getMetadata().addMapping( ArtifactUtils.setScope( artifact, namespace ), jppArtifact );
for ( Artifact alias : aliases )
{
packaged.add( alias.setVersion( jppArtifact.getVersion() ) );
providedArtifacts.put( alias.setVersion( jppArtifact.getVersion() ),
ArtifactUtils.setScope( alias.setVersion( jppArtifact.getVersion() ), namespace ) );
pkg.getMetadata().addMapping( ArtifactUtils.setScope( alias, namespace ), jppArtifact );
}
}
}

private Artifact resolveDependencyArtifact( Artifact artifact )
private Artifact resolveDependencyArtifact( Package pkg, Artifact artifact )
{
Artifact versionlessArtifact = artifact.setVersion( ArtifactUtils.DEFAULT_VERSION );
Set<Artifact> packaged = packagedArtifacts.get( pkg );
if ( packaged.contains( artifact ) || packaged.contains( versionlessArtifact ) )
return null;

Artifact providedArtifact = providedArtifacts.get( artifact );
if ( providedArtifact == null )
providedArtifact = providedArtifacts.get( versionlessArtifact );
if ( providedArtifact != null )
return providedArtifact;

ResolutionRequest request = new ResolutionRequest( artifact );
ResolutionResult result = resolver.resolve( request );

if ( result.getArtifactFile() == null )
{
logger.warn( "Unable to resolve dependency artifact " + artifact
+ ", generating dependencies with version " + ArtifactUtils.DEFAULT_VERSION + " and no namespace." );
}

String version = result.getCompatVersion() != null ? result.getCompatVersion() : ArtifactUtils.DEFAULT_VERSION;
artifact = artifact.setVersion( version );

Expand All @@ -284,7 +330,9 @@ private void generateDevelRequires( Package pkg, Artifact artifact )

for ( Artifact dependencyArtifact : result.getDependencyArtifacts() )
{
metadata.addBuildDependency( resolveDependencyArtifact( dependencyArtifact ) );
Artifact resolvedDependencyArtifact = resolveDependencyArtifact( pkg, dependencyArtifact );
if ( resolvedDependencyArtifact != null )
metadata.addBuildDependency( resolvedDependencyArtifact );
}

if ( result.getJavaVersion() != null )
Expand All @@ -308,7 +356,9 @@ private void generateUserRequires( Package pkg, Artifact artifact )

for ( Artifact dependencyArtifact : result.getDependencyArtifacts() )
{
metadata.addRuntimeDependency( resolveDependencyArtifact( dependencyArtifact ) );
Artifact resolvedDependencyArtifact = resolveDependencyArtifact( pkg, dependencyArtifact );
if ( resolvedDependencyArtifact != null )
metadata.addRuntimeDependency( resolvedDependencyArtifact );
}

if ( result.getJavaVersion() != null )
Expand Down Expand Up @@ -384,7 +434,7 @@ private boolean containsNativeCode( Artifact artifact )
}

private void installArtifact( Artifact artifact, String packageName )
throws IOException, ModelFormatException
throws IOException
{
Path rawModelPath = ArtifactUtils.getRawModelPath( artifact );
boolean isAttachedArtifact = rawModelPath == null;
Expand Down Expand Up @@ -425,13 +475,46 @@ private void installArtifact( Artifact artifact, String packageName )

if ( isPomArtifact )
{
generateDevelRequires( pkg, artifact );
Set<Artifact> develArtifacts = packageDevelArtifacts.get( pkg );
if ( develArtifacts == null )
{
develArtifacts = new HashSet<>();
packageDevelArtifacts.put( pkg, develArtifacts );
}

develArtifacts.add( artifact );
}
else if ( !isAttachedArtifact )
{
pkg.setPureDevelPackage( false );
installPomFiles( pkg, artifact, jppArtifacts );
generateUserRequires( pkg, artifact );

Set<Artifact> userArtifacts = packageUserArtifacts.get( pkg );
if ( userArtifacts == null )
{
userArtifacts = new HashSet<>();
packageUserArtifacts.put( pkg, userArtifacts );
}

userArtifacts.add( artifact );
}
}

private void generateRequires()
throws IOException, ModelFormatException
{
for ( Entry<Package, Set<Artifact>> entry : packageDevelArtifacts.entrySet() )
{
Package pkg = entry.getKey();
for ( Artifact artifact : entry.getValue() )
generateDevelRequires( pkg, artifact );
}

for ( Entry<Package, Set<Artifact>> entry : packageUserArtifacts.entrySet() )
{
Package pkg = entry.getKey();
for ( Artifact artifact : entry.getValue() )
generateUserRequires( pkg, artifact );
}
}

Expand Down Expand Up @@ -480,6 +563,10 @@ public InstallationResult install( InstallationRequest request )
LoggingUtils.setLoggerThreshold( logger, settings.isDebug() );

packages = new TreeMap<>();
packageDevelArtifacts = new HashMap<>();
packageUserArtifacts = new HashMap<>();
packagedArtifacts = new HashMap<>();
providedArtifacts = new HashMap<>();
skippedArtifacts = new HashSet<>();

Package mainPackage = new Package( Package.MAIN, settings, logger );
Expand All @@ -499,6 +586,8 @@ public InstallationResult install( InstallationRequest request )

Path root = request.getInstallRoot();

generateRequires();

if ( Files.exists( root ) && !Files.isDirectory( root ) )
throw new IOException( root + " is not a directory" );

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,7 @@
import java.nio.file.Path;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.codehaus.plexus.logging.Logger;
Expand Down Expand Up @@ -114,32 +112,6 @@ public void addSkippedArtifacts( Set<Artifact> skippedArtifacts )
this.skippedArtifacts.addAll( skippedArtifacts );
}

/**
* Optimize fragment file by removing self-satisfiable dependencies (dependencies on artifacts provided by the same
* package).
*/
public void optimize()
{
Set<Artifact> providedArtifacts = new HashSet<>();
for ( Entry<Artifact, Set<Artifact>> entry : mapping.entrySet() )
{
Artifact mavenArtifact = entry.getKey();
for ( Artifact jppArtifact : entry.getValue() )
{
Artifact providedArtifact = mavenArtifact.setVersion( jppArtifact.getVersion() );
providedArtifacts.add( providedArtifact );
}
}

for ( Iterator<Artifact> iter = dependencies.iterator(); iter.hasNext(); )
if ( providedArtifacts.contains( iter.next() ) )
iter.remove();

for ( Iterator<Artifact> iter = develDependencies.iterator(); iter.hasNext(); )
if ( providedArtifacts.contains( iter.next() ) )
iter.remove();
}

public void write( Path path, boolean writeDevel, InstallerSettings settings )
throws IOException
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,6 @@ public void createDepmaps( String groupId, String artifactId, String version, Pa
private void installMetadata( String packageName )
throws IOException
{
getMetadata().optimize();

if ( !getMetadata().isEmpty() )
{
Path file = Files.createTempFile( "xmvn", ".xml" );
Expand Down

0 comments on commit 849f5b4

Please sign in to comment.