Search in sources :

Example 26 with DependencyPath

use of com.google.cloud.tools.opensource.dependencies.DependencyPath in project cloud-opensource-java by GoogleCloudPlatform.

the class LinkageProblemCauseAnnotator method annotateProblem.

private static void annotateProblem(ClassPathBuilder classPathBuilder, ClassPathResult rootResult, Map<Artifact, ClassPathResult> artifactResolutionCache, LinkageProblem linkageProblem) throws IOException {
    ClassFile sourceClass = linkageProblem.getSourceClass();
    ClassPathEntry sourceEntry = sourceClass.getClassPathEntry();
    Artifact sourceArtifact = sourceEntry.getArtifact();
    ClassPathResult subtreeResult = artifactResolutionCache.get(sourceArtifact);
    if (subtreeResult == null) {
        // Resolves the dependency graph with the source artifact at the root.
        subtreeResult = classPathBuilder.resolveWithMaven(sourceArtifact);
        artifactResolutionCache.put(sourceArtifact, subtreeResult);
    }
    Symbol symbol = linkageProblem.getSymbol();
    ClassPathEntry entryInSubtree = subtreeResult.findEntryBySymbol(symbol);
    if (entryInSubtree == null) {
        linkageProblem.setCause(UnknownCause.getInstance());
        return;
    }
    Artifact artifactInSubtree = entryInSubtree.getArtifact();
    ImmutableList<DependencyPath> dependencyPathsToSource = rootResult.getDependencyPaths(sourceEntry);
    if (dependencyPathsToSource.isEmpty()) {
        // When an artifact is excluded, it's possible to have no dependency path to sourceEntry.
        linkageProblem.setCause(UnknownCause.getInstance());
        return;
    }
    DependencyPath pathToSourceEntry = dependencyPathsToSource.get(0);
    DependencyPath pathFromSourceEntryToUnselectedEntry = subtreeResult.getDependencyPaths(entryInSubtree).get(0);
    DependencyPath pathToUnselectedEntry = pathToSourceEntry.concat(pathFromSourceEntryToUnselectedEntry);
    ClassPathEntry selectedEntry = rootResult.findEntryById(artifactInSubtree.getGroupId(), artifactInSubtree.getArtifactId());
    if (selectedEntry != null) {
        Artifact selectedArtifact = selectedEntry.getArtifact();
        if (!selectedArtifact.getVersion().equals(artifactInSubtree.getVersion())) {
            // Different version of that artifact is selected in rootResult
            ImmutableList<DependencyPath> pathToSelectedArtifact = rootResult.getDependencyPaths(selectedEntry);
            if (pathToSelectedArtifact.isEmpty()) {
                linkageProblem.setCause(UnknownCause.getInstance());
                return;
            }
            linkageProblem.setCause(new DependencyConflict(linkageProblem, pathToSelectedArtifact.get(0), pathToUnselectedEntry));
        } else {
            // A linkage error was already there when sourceArtifact was built.
            linkageProblem.setCause(UnknownCause.getInstance());
        }
    } else {
        // No artifact that matches groupId and artifactId in rootResult.
        // Checking exclusion elements in the dependency path
        Artifact excludingArtifact = pathToSourceEntry.findExclusion(artifactInSubtree.getGroupId(), artifactInSubtree.getArtifactId());
        if (excludingArtifact != null) {
            linkageProblem.setCause(new ExcludedDependency(pathToUnselectedEntry, excludingArtifact));
        } else {
            linkageProblem.setCause(new MissingDependency(pathToUnselectedEntry));
        }
    }
}
Also used : DependencyPath(com.google.cloud.tools.opensource.dependencies.DependencyPath) Artifact(org.eclipse.aether.artifact.Artifact)

Example 27 with DependencyPath

use of com.google.cloud.tools.opensource.dependencies.DependencyPath in project java-cloud-bom by googleapis.

the class BomContentTest method findNoDowngradeViolation.

/**
 * Returns messages describing the violation of the no-downgrade rule by {@code artifact} against
 * the BOM containing {@code bomArtifacts}. An empty list if there is no violations.
 */
private static ImmutableList<String> findNoDowngradeViolation(Map<String, Artifact> bomArtifacts, Artifact artifact) throws InvalidVersionSpecificationException {
    ImmutableList.Builder<String> violations = ImmutableList.builder();
    ClassPathBuilder classPathBuilder = new ClassPathBuilder();
    ClassPathResult result = classPathBuilder.resolve(ImmutableList.of(artifact), false, DependencyMediation.MAVEN);
    for (ClassPathEntry entry : result.getClassPath()) {
        Artifact transitiveDependency = entry.getArtifact();
        String key = Artifacts.makeKey(transitiveDependency);
        Artifact bomArtifact = bomArtifacts.get(key);
        if (bomArtifact == null) {
            // transitiveDependency is not part of the BOM
            continue;
        }
        Version versionInBom = versionScheme.parseVersion(bomArtifact.getVersion());
        Version versionInTransitiveDependency = versionScheme.parseVersion(transitiveDependency.getVersion());
        if (versionInTransitiveDependency.compareTo(versionInBom) <= 0) {
            // the no-downgrade rule.
            continue;
        }
        // Filter by scopes that are invisible to library users
        ImmutableList<DependencyPath> dependencyPaths = result.getDependencyPaths(entry);
        Verify.verify(!dependencyPaths.isEmpty(), "The class path entry should have at least one dependency path from the root");
        boolean dependencyVisibleToUsers = false;
        for (DependencyPath dependencyPath : dependencyPaths) {
            int length = dependencyPath.size();
            // As the root element is an empty node, the last element is at "length - 2".
            Dependency dependency = dependencyPath.getDependency(length - 2);
            if (dependencyScopesVisibleToUsers.contains(dependency.getScope())) {
                dependencyVisibleToUsers = true;
                break;
            }
        }
        if (!dependencyVisibleToUsers) {
            // provided scope.
            continue;
        }
        // A violation of the no-downgrade rule is found.
        violations.add(artifact + " has a transitive dependency " + transitiveDependency + ". This is higher version than " + bomArtifact + " in the BOM. Example dependency path: " + dependencyPaths.get(0));
    }
    return violations.build();
}
Also used : ImmutableList(com.google.common.collect.ImmutableList) DependencyPath(com.google.cloud.tools.opensource.dependencies.DependencyPath) ClassPathBuilder(com.google.cloud.tools.opensource.classpath.ClassPathBuilder) ClassPathResult(com.google.cloud.tools.opensource.classpath.ClassPathResult) Dependency(org.eclipse.aether.graph.Dependency) ClassPathEntry(com.google.cloud.tools.opensource.classpath.ClassPathEntry) Artifact(org.eclipse.aether.artifact.Artifact) Version(org.eclipse.aether.version.Version)

Aggregations

DependencyPath (com.google.cloud.tools.opensource.dependencies.DependencyPath)27 Artifact (org.eclipse.aether.artifact.Artifact)17 Dependency (org.eclipse.aether.graph.Dependency)15 Test (org.junit.Test)15 DefaultArtifact (org.eclipse.aether.artifact.DefaultArtifact)12 DependencyGraph (com.google.cloud.tools.opensource.dependencies.DependencyGraph)9 ImmutableList (com.google.common.collect.ImmutableList)5 ClassPathEntry (com.google.cloud.tools.opensource.classpath.ClassPathEntry)4 ClassPathResult (com.google.cloud.tools.opensource.classpath.ClassPathResult)4 AnnotatedClassPath (com.google.cloud.tools.opensource.classpath.AnnotatedClassPath)2 Artifacts (com.google.cloud.tools.opensource.dependencies.Artifacts)2 DependencyGraphBuilder (com.google.cloud.tools.opensource.dependencies.DependencyGraphBuilder)2 RepositoryUtility (com.google.cloud.tools.opensource.dependencies.RepositoryUtility)2 ImmutableList.toImmutableList (com.google.common.collect.ImmutableList.toImmutableList)2 ImmutableSet (com.google.common.collect.ImmutableSet)2 File (java.io.File)2 IOException (java.io.IOException)2 HashSet (java.util.HashSet)2 Optional (java.util.Optional)2 RepositoryException (org.eclipse.aether.RepositoryException)2