3

我正在使用eather在我的代码中重新创建相同的maven依赖结构:树。按照文档,我发现这个有用的示例正确列出了与插件相同的依赖关系,但它缺少任何“树”信息,它只是一个平面列表。

 public static void main( String[] args )
    throws Exception
{
    System.out.println( "------------------------------------------------------------" );
    System.out.println( ResolveTransitiveDependencies.class.getSimpleName() );

    RepositorySystem system = Booter.newRepositorySystem();

    RepositorySystemSession session = Booter.newRepositorySystemSession( system );

    Artifact artifact = new DefaultArtifact( "org.eclipse.aether:aether-impl:1.0.0.v20140518" );

    DependencyFilter classpathFlter = DependencyFilterUtils.classpathFilter( JavaScopes.COMPILE );

    CollectRequest collectRequest = new CollectRequest();
    collectRequest.setRoot( new Dependency( artifact, JavaScopes.COMPILE ) );
    collectRequest.setRepositories( Booter.newRepositories( system, session ) );

    DependencyRequest dependencyRequest = new DependencyRequest( collectRequest, classpathFlter );

    List<ArtifactResult> artifactResults =
        system.resolveDependencies( session, dependencyRequest ).getArtifactResults();

    for ( ArtifactResult artifactResult : artifactResults )
    {
        System.out.println( artifactResult.getArtifact() + " resolved to " + artifactResult.getArtifact().getFile() );
    }
}

然后我编写了另一段代码来检索非传递依赖关系,并递归调用它,能够获得完整的依赖关系图,但没有任何限制,所以我应该实现一些过滤/限制例程。

由于我想尽可能多地保留相同的插件逻辑,而不引入“我的”过滤,有没有办法调整第一个示例以检索层次结构信息?

4

1 回答 1

3

如果你想要exactly the same插件实现的行为,我建议在这里查看插件的源代码,这样你就不会错过任何细微差别。但基本方法是使用collectRequestto collectDependencies,如下所示:

public static void main(String[] args) throws Exception {
    System.out.println("------------------------------------------------------------");

    RepositorySystem system = Booter.newRepositorySystem();

    RepositorySystemSession session = Booter.newRepositorySystemSession(system);

    Artifact artifact = new DefaultArtifact("org.apache.maven.plugins:maven-shade-plugin:2.3");

    DependencyFilter classpathFlter = DependencyFilterUtils.classpathFilter(JavaScopes.COMPILE);

    CollectRequest collectRequest = new CollectRequest();
    collectRequest.setRoot(new Dependency(artifact, JavaScopes.COMPILE));
    collectRequest.setRepositories(Booter.newRepositories(system, session));

    DependencyRequest dependencyRequest = new DependencyRequest(collectRequest, classpathFlter);

    List<ArtifactResult> artifactResults =
            system.resolveDependencies(session, dependencyRequest).getArtifactResults();

//        for (ArtifactResult artifactResult : artifactResults) {
//            System.out.println(artifactResult.getArtifact() + " resolved to " + artifactResult.getArtifact().getFile());
//        }

    //use collectDependencies to collect
    CollectResult collectResult = system.collectDependencies(session, collectRequest);
    DependencyNode node = collectResult.getRoot();
    node.accept(new TreeDependencyVisitor(new DependencyVisitor() {
        String indent = "";
        @Override
        public boolean visitEnter(DependencyNode dependencyNode) {
            System.out.println(indent + dependencyNode.getArtifact());
            indent += "    ";
            return true;
        }

        @Override
        public boolean visitLeave(DependencyNode dependencyNode) {
            indent = indent.substring(0, indent.length() - 4);
            return true;
        }
    }));

}

[编辑:] 要包含测试依赖项,您需要自定义会话的 depSelector,如下所示:

    DependencySelector depFilter =
            new AndDependencySelector(
                    new ScopeDependencySelector( "provided" ),
                    new OptionalDependencySelector(),
                    new ExclusionDependencySelector()
            );

并将classpathFilter添加到遍历中:

DependencyFilter classpathFlter = DependencyFilterUtils.classpathFilter(JavaScopes.TEST);

node.accept(new TreeDependencyVisitor(new FilteringDependencyVisitor(new DependencyVisitor() {
    ...
}, classpathFlter)));

不过,这并不完全一样dependency:tree,因为它实际上会列出所有的 jar,这些 jar 将用于测试类路径。但是有了这个,你实际上可以进一步自定义 NodeVisitor 来过滤你想要的任何东西。

于 2016-01-31T21:29:33.560 回答