def maven_dep( coord=None, group=None, id=None, version=None, classifier=None, type=None, ): assert ( (coord is None) ^ (frozenset({group, id, version, classifier, type}) == frozenset({None}))), \ "Invalid Maven dependency." if coord is not None: return artifact.parse_artifact(coord) assert not ((group is None) or (id is None) or (version is None)), \ "Invalid Maven artifact dependency: incomplete coordinate." return artifact.Artifact( group_id=group, artifact_id=id, version=version, classifier=classifier, packaging=type, )
def list_dependencies( coordinates, scope="runtime", local_repo=None, ): """Lists the resolved dependencies. Args: coordinates: Collection of Artifact to examine. scope: Optional Maven scope to determine the classpath for. Default is runtime. local_repo: Optional explicit Maven local repository to use. Returns: An iterable of Maven artifact coordinates. """ with tempfile.NamedTemporaryFile(prefix="pom.", suffix=".xml") as pom_file, \ tempfile.NamedTemporaryFile(prefix="maven-dependency-resolved.", suffix=".txt") as tfile: with open(pom_file.name, "wt") as file: file.write( workflow_task.format_pom_file( artf=artifact.Artifact("unknown", "unknown", "unknown"), compile_deps=coordinates, )) args = [ "mvn", "--batch-mode", "--file={}".format(pom_file.name), ] if local_repo is not None: args += ["-Dmaven.repo.local={}".format(local_repo)] args += [ "dependency:list", "-DoutputFile={}".format(tfile.name), "-Dsort=true", "-DincludeScope={}".format(scope), ] cmd = command.Command(args=args) log_maven_output(cmd.output_lines) with open(tfile.name, "rt") as file: lines = file.readlines() lines = map(str.strip, lines) lines = filter(None, lines) lines = filter( lambda line: (line != "The following files have been resolved:"), lines) lines = map(artifact.parse_artifact, lines) return sorted(lines)
def get_dependency_tree( coordinates, scope=None, local_repo=None, ): """Reports the dependency tree as a text representation. Args: coordinates: Collection of Artifact to examine. scope: Optional Maven scope to determine the classpath for. local_repo: Optional explicit Maven local repository to use. Returns: A text representation of the Maven dependency tree. """ with tempfile.NamedTemporaryFile(prefix="pom.", suffix=".xml") as pom_file, \ tempfile.NamedTemporaryFile(prefix="maven-dependency-tree.", suffix=".txt") as tfile: with open(pom_file.name, "wt") as file: file.write( workflow_task.format_pom_file( artf=artifact.Artifact("root", "root", "0"), compile_deps=coordinates, )) args = [ "mvn", "--batch-mode", "--file={}".format(pom_file.name), ] if local_repo is not None: args += ["-Dmaven.repo.local={}".format(local_repo)] args += [ "dependency:tree", "-DoutputFile={}".format(tfile.name), "-Dverbose", ] if (scope is not None) and (len(scope) > 0): args.append("-Dscope={}".format(scope)) cmd = command.Command(args=args) log_maven_output(cmd.output_lines) with open(tfile.name, "rt") as file: return file.read()
def list_classpath_entries( coordinates, scope="runtime", local_repo=None, ): """Lists the classpath entries. Args: coordinates: Collection of Artifact to examine. scope: Optional Maven scope to determine the classpath for. Default is runtime. local_repo: Optional explicit Maven local repository to use. Returns: An iterable of classpath entries. """ with tempfile.NamedTemporaryFile(prefix="pom.", suffix=".xml") as pom_file, \ tempfile.NamedTemporaryFile(prefix="maven-classpath.", suffix=".txt") as tfile: with open(pom_file.name, "wt") as file: file.write( workflow_task.format_pom_file( artf=artifact.Artifact("unknown", "unknown", "unknown"), compile_deps=coordinates, )) args = [ "mvn", "--batch-mode", "--file={}".format(pom_file.name), ] if local_repo is not None: args += ["-Dmaven.repo.local={}".format(local_repo)] args += [ "dependency:build-classpath", "-DincludeScope={}".format(scope), "-Dmdep.cpFile={}".format(tfile.name), ] cmd = command.Command(args=args) log_maven_output(cmd.output_lines) with open(tfile.name, "rt") as file: return file.read().split(":")
def explain(self, artifact_name): """Explains where a dependency come from. Args: artifact_name: Name of the Maven artifact dependency to explain. """ unversioned = artifact.Artifact( group_id=artifact_name.group_id, artifact_id=artifact_name.artifact_id, version=None, ) chains = self._versions[unversioned] ruler = '-' * 100 print("Resolved dependency %s in %d ways:" % (artifact_name, len(chains))) for ichain, dep_chain in enumerate(chains): print(ruler) print("Dependency chain #%d: %s" % (ichain, "\n\tfrom ".join(map(str, dep_chain))))
def artifact_for_path(self, path): """Reverse engineer the Artifact coordinate from a repository file path. Args: path: Path of a Maven artifact in this repository. Returns: The parsed Artifact coordinate. None if the file path does not belong to this repository. """ path = "file://" + os.path.abspath(path) if not path.startswith(self.path): return None path = os.path.relpath(path, self.path) [*group_id, artifact_id, version, name] = path.split("/") group_id = ".".join(group_id) name = base.strip_prefix(name, artifact_id + "-" + version) if name.startswith("-"): (classifier, extension) = name[1:].split(".", 1) elif name.startswith("."): classifier = None extension = name[1:] else: raise Error( "Invalid file name does not match expected Maven artifact format: {!r}" .format(path)) if (classifier == "tests") and (extension == "jar"): packaging = "test-jar" else: packaging = extension return artifact.Artifact( group_id=group_id, artifact_id=artifact_id, version=version, classifier=classifier, packaging=packaging, )