Example #1
0
    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,
        )
Example #2
0
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)
Example #3
0
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()
Example #4
0
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(":")
Example #5
0
    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))))
Example #6
0
    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,
        )