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;
}
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;
}
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;
}
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;
}
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;
}
Aggregations