Search in sources :

Example 1 with IvyNodeElement

use of org.apache.lucene.validation.ivyde.IvyNodeElement in project lucene-solr by apache.

the class LibVersionsCheckTask method emitConflict.

private boolean emitConflict(StringBuilder builder, String conflictCoordinate, IvyNodeElement parent, int depth) {
    for (IvyNodeElement child : parent.getDependencies()) {
        String indirectCoordinate = "/" + child.getOrganization() + "/" + child.getName();
        if (conflictCoordinate.equals(indirectCoordinate)) {
            Dependency dependency = directDependencies.get(conflictCoordinate);
            String directVersion = dependency.directVersion;
            if (isConflict(conflictCoordinate, directVersion, child.getRevision())) {
                for (int i = 0; i < depth - 1; ++i) {
                    builder.append("    ");
                }
                builder.append("+-- ");
                builder.append(indirectCoordinate).append("=").append(child.getRevision());
                builder.append(" <<< Conflict (direct=").append(directVersion);
                builder.append(", latest=").append(dependency.latestVersion).append(")\n");
                return true;
            }
        } else if (hasConflicts(conflictCoordinate, child)) {
            for (int i = 0; i < depth - 1; ++i) {
                builder.append("    ");
            }
            builder.append("+-- ");
            builder.append(indirectCoordinate).append("=").append(child.getRevision()).append("\n");
            if (emitConflict(builder, conflictCoordinate, child, depth + 1)) {
                return true;
            }
        }
    }
    return false;
}
Also used : IvyNodeElement(org.apache.lucene.validation.ivyde.IvyNodeElement)

Example 2 with IvyNodeElement

use of org.apache.lucene.validation.ivyde.IvyNodeElement in project lucene-solr by apache.

the class LibVersionsCheckTask method collectConflicts.

/**
   * Recursively finds indirect dependencies that have a version conflict with a direct dependency.
   * Returns true if one or more conflicts are found, false otherwise
   */
private boolean collectConflicts(IvyNodeElement root, IvyNodeElement parent, String moduleName) {
    boolean conflicts = false;
    for (IvyNodeElement child : parent.getDependencies()) {
        String coordinate = "/" + child.getOrganization() + "/" + child.getName();
        Dependency dependency = directDependencies.get(coordinate);
        if (null != dependency) {
            // Ignore this indirect dependency if it's not also a direct dependency
            String indirectVersion = child.getRevision();
            if (isConflict(coordinate, dependency.directVersion, indirectVersion)) {
                conflicts = true;
                Set<String> moduleNames = dependency.conflictLocations.get(root);
                if (null == moduleNames) {
                    moduleNames = new HashSet<>();
                    dependency.conflictLocations.put(root, moduleNames);
                }
                moduleNames.add(moduleName);
            }
            conflicts |= collectConflicts(root, child, moduleName);
        }
    }
    return conflicts;
}
Also used : IvyNodeElement(org.apache.lucene.validation.ivyde.IvyNodeElement)

Example 3 with IvyNodeElement

use of org.apache.lucene.validation.ivyde.IvyNodeElement in project lucene-solr by apache.

the class LibVersionsCheckTask method findLatestConflictVersions.

private boolean findLatestConflictVersions() {
    boolean success = true;
    StringBuilder latestIvyXml = new StringBuilder();
    latestIvyXml.append("<ivy-module version=\"2.0\">\n");
    latestIvyXml.append("  <info organisation=\"org.apache.lucene\" module=\"core-tools-find-latest-revision\"/>\n");
    latestIvyXml.append("  <configurations>\n");
    latestIvyXml.append("    <conf name=\"default\" transitive=\"false\"/>\n");
    latestIvyXml.append("  </configurations>\n");
    latestIvyXml.append("  <dependencies>\n");
    for (Map.Entry<String, Dependency> directDependency : directDependencies.entrySet()) {
        Dependency dependency = directDependency.getValue();
        if (dependency.conflictLocations.entrySet().isEmpty()) {
            continue;
        }
        latestIvyXml.append("    <dependency org=\"");
        latestIvyXml.append(dependency.org);
        latestIvyXml.append("\" name=\"");
        latestIvyXml.append(dependency.name);
        latestIvyXml.append("\" rev=\"latest.release\" conf=\"default->*\"/>\n");
    }
    latestIvyXml.append("  </dependencies>\n");
    latestIvyXml.append("</ivy-module>\n");
    File buildDir = new File(commonBuildDir, "ivy-transitive-resolve");
    if (!buildDir.exists() && !buildDir.mkdirs()) {
        throw new BuildException("Could not create temp directory " + buildDir.getPath());
    }
    File findLatestIvyXmlFile = new File(buildDir, "find.latest.conflicts.ivy.xml");
    try {
        try (Writer writer = new OutputStreamWriter(new FileOutputStream(findLatestIvyXmlFile), StandardCharsets.UTF_8)) {
            writer.write(latestIvyXml.toString());
        }
        ResolveOptions options = new ResolveOptions();
        // Download only module descriptors, not artifacts
        options.setDownload(false);
        // Resolve only direct dependencies
        options.setTransitive(false);
        // Download the internet!
        options.setUseCacheOnly(false);
        // Don't print to the console
        options.setOutputReport(false);
        // Don't log to the console
        options.setLog(LogOptions.LOG_QUIET);
        // Resolve all configurations
        options.setConfs(new String[] { "*" });
        ResolveReport resolveReport = ivy.resolve(findLatestIvyXmlFile.toURI().toURL(), options);
        IvyNodeElement root = IvyNodeElementAdapter.adapt(resolveReport);
        for (IvyNodeElement element : root.getDependencies()) {
            String coordinate = "/" + element.getOrganization() + "/" + element.getName();
            Dependency dependency = directDependencies.get(coordinate);
            if (null == dependency) {
                log("ERROR: the following coordinate key does not appear in " + centralizedVersionsFile.getName() + ": " + coordinate, Project.MSG_ERR);
                success = false;
            } else {
                dependency.latestVersion = element.getRevision();
            }
        }
    } catch (IOException e) {
        log("Exception writing to " + findLatestIvyXmlFile.getPath() + ": " + e.toString(), Project.MSG_ERR);
        success = false;
    } catch (ParseException e) {
        log("Exception parsing filename " + findLatestIvyXmlFile.getPath() + ": " + e.toString(), Project.MSG_ERR);
        success = false;
    }
    return success;
}
Also used : IvyNodeElement(org.apache.lucene.validation.ivyde.IvyNodeElement) IOException(java.io.IOException) ResolveReport(org.apache.ivy.core.report.ResolveReport) FileOutputStream(java.io.FileOutputStream) OutputStreamWriter(java.io.OutputStreamWriter) BuildException(org.apache.tools.ant.BuildException) ParseException(java.text.ParseException) Map(java.util.Map) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) File(java.io.File) ResolveOptions(org.apache.ivy.core.resolve.ResolveOptions) Writer(java.io.Writer) OutputStreamWriter(java.io.OutputStreamWriter) StringWriter(java.io.StringWriter)

Example 4 with IvyNodeElement

use of org.apache.lucene.validation.ivyde.IvyNodeElement in project lucene-solr by apache.

the class LibVersionsCheckTask method resolveTransitively.

/**
   * Transitively resolves all dependencies in the given ivy.xml file,
   * looking for indirect dependencies with versions that conflict
   * with those of direct dependencies.  Dependency conflict when a
   * direct dependency's version is older than that of an indirect
   * dependency with the same /org/name.
   * 
   * Returns true if no version conflicts are found and no resolution
   * errors occurred, false otherwise.
   */
private boolean resolveTransitively(File ivyXmlFile) {
    boolean success = true;
    ResolveOptions options = new ResolveOptions();
    // Download only module descriptors, not artifacts
    options.setDownload(false);
    // Resolve transitively, if not already specified in the ivy.xml file
    options.setTransitive(true);
    // Download the internet!
    options.setUseCacheOnly(false);
    // Don't print to the console
    options.setOutputReport(false);
    // Don't log to the console
    options.setLog(LogOptions.LOG_QUIET);
    // Resolve all configurations
    options.setConfs(new String[] { "*" });
    // Rewrite the ivy.xml, replacing all 'transitive="false"' with 'transitive="true"'
    // The Ivy API is file-based, so we have to write the result to the filesystem.
    String moduleName = "unknown";
    String ivyXmlContent = xmlToString(ivyXmlFile);
    Matcher matcher = MODULE_NAME_PATTERN.matcher(ivyXmlContent);
    if (matcher.find()) {
        moduleName = matcher.group(1);
    }
    ivyXmlContent = ivyXmlContent.replaceAll("\\btransitive\\s*=\\s*[\"']false[\"']", "transitive=\"true\"");
    File transitiveIvyXmlFile = null;
    try {
        File buildDir = new File(commonBuildDir, "ivy-transitive-resolve");
        if (!buildDir.exists() && !buildDir.mkdirs()) {
            throw new BuildException("Could not create temp directory " + buildDir.getPath());
        }
        matcher = MODULE_DIRECTORY_PATTERN.matcher(ivyXmlFile.getCanonicalPath());
        if (!matcher.matches()) {
            throw new BuildException("Unknown ivy.xml module directory: " + ivyXmlFile.getCanonicalPath());
        }
        String moduleDirPrefix = matcher.group(1).replaceAll("[/\\\\]", ".");
        transitiveIvyXmlFile = new File(buildDir, "transitive." + moduleDirPrefix + ".ivy.xml");
        try (Writer writer = new OutputStreamWriter(new FileOutputStream(transitiveIvyXmlFile), StandardCharsets.UTF_8)) {
            writer.write(ivyXmlContent);
        }
        ResolveReport resolveReport = ivy.resolve(transitiveIvyXmlFile.toURI().toURL(), options);
        IvyNodeElement root = IvyNodeElementAdapter.adapt(resolveReport);
        for (IvyNodeElement directDependency : root.getDependencies()) {
            String coordinate = "/" + directDependency.getOrganization() + "/" + directDependency.getName();
            Dependency dependency = directDependencies.get(coordinate);
            if (null == dependency) {
                log("ERROR: the following coordinate key does not appear in " + centralizedVersionsFile.getName() + ": " + coordinate);
                success = false;
            } else {
                dependency.directlyReferenced = true;
                if (collectConflicts(directDependency, directDependency, moduleName)) {
                    success = false;
                }
            }
        }
    } catch (ParseException | IOException e) {
        if (null != transitiveIvyXmlFile) {
            log("Exception reading " + transitiveIvyXmlFile.getPath() + ": " + e.toString());
        }
        success = false;
    }
    return success;
}
Also used : IvyNodeElement(org.apache.lucene.validation.ivyde.IvyNodeElement) Matcher(java.util.regex.Matcher) IOException(java.io.IOException) ResolveReport(org.apache.ivy.core.report.ResolveReport) FileOutputStream(java.io.FileOutputStream) OutputStreamWriter(java.io.OutputStreamWriter) BuildException(org.apache.tools.ant.BuildException) ParseException(java.text.ParseException) ResolveOptions(org.apache.ivy.core.resolve.ResolveOptions) File(java.io.File) Writer(java.io.Writer) OutputStreamWriter(java.io.OutputStreamWriter) StringWriter(java.io.StringWriter)

Example 5 with IvyNodeElement

use of org.apache.lucene.validation.ivyde.IvyNodeElement in project lucene-solr by apache.

the class LibVersionsCheckTask method emitConflicts.

/**
   * Returns the number of direct dependencies in conflict with indirect
   * dependencies.
   */
private int emitConflicts() {
    int conflicts = 0;
    StringBuilder builder = new StringBuilder();
    for (Map.Entry<String, Dependency> directDependency : directDependencies.entrySet()) {
        String coordinate = directDependency.getKey();
        Set<Map.Entry<IvyNodeElement, Set<String>>> entrySet = directDependency.getValue().conflictLocations.entrySet();
        if (entrySet.isEmpty()) {
            continue;
        }
        ++conflicts;
        Map.Entry<IvyNodeElement, Set<String>> first = entrySet.iterator().next();
        int notPrinted = entrySet.size() - 1;
        builder.append("VERSION CONFLICT: transitive dependency in module(s) ");
        boolean isFirst = true;
        for (String moduleName : first.getValue()) {
            if (isFirst) {
                isFirst = false;
            } else {
                builder.append(", ");
            }
            builder.append(moduleName);
        }
        builder.append(":\n");
        IvyNodeElement element = first.getKey();
        builder.append('/').append(element.getOrganization()).append('/').append(element.getName()).append('=').append(element.getRevision()).append('\n');
        emitConflict(builder, coordinate, first.getKey(), 1);
        if (notPrinted > 0) {
            builder.append("... and ").append(notPrinted).append(" more\n");
        }
        builder.append("\n");
    }
    if (builder.length() > 0) {
        log(builder.toString());
    }
    return conflicts;
}
Also used : IvyNodeElement(org.apache.lucene.validation.ivyde.IvyNodeElement) Set(java.util.Set) HashSet(java.util.HashSet) Map(java.util.Map) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap)

Aggregations

IvyNodeElement (org.apache.lucene.validation.ivyde.IvyNodeElement)5 File (java.io.File)2 FileOutputStream (java.io.FileOutputStream)2 IOException (java.io.IOException)2 OutputStreamWriter (java.io.OutputStreamWriter)2 StringWriter (java.io.StringWriter)2 Writer (java.io.Writer)2 ParseException (java.text.ParseException)2 HashMap (java.util.HashMap)2 LinkedHashMap (java.util.LinkedHashMap)2 Map (java.util.Map)2 ResolveReport (org.apache.ivy.core.report.ResolveReport)2 ResolveOptions (org.apache.ivy.core.resolve.ResolveOptions)2 BuildException (org.apache.tools.ant.BuildException)2 HashSet (java.util.HashSet)1 Set (java.util.Set)1 Matcher (java.util.regex.Matcher)1