Aether,如何获得与层次结构的依赖关系
Aether, how to get dependencies with hierarchy
我正在使用 eather 在我的代码中重新创建与 maven dependency:tree 相同的结构。
根据文档,我发现这个有用的 example 它正确地列出了与插件相同的依赖关系,但它缺少任何 "tree" 信息,它只是一个简单的列表。
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() );
}
}
然后我编写了另一段代码来检索非传递依赖项,并递归调用它,能够获得完整的依赖关系图,但没有任何限制,所以我应该实现一些 filtering/limit 例程。
由于我想尽可能保持相同的插件逻辑,而不引入 "my" 过滤,是否有任何方法可以修改第一个示例以检索层次结构信息?
如果你想要 exactly the same
行为,作为插件实现,我建议查看插件的源代码 here,这样你就不会错过任何细微差别。但是基本的做法是使用collectRequest
到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,它们将用于测试类路径。但是有了这个你实际上可以进一步自定义 NodeVisitor 来过滤你想要的任何东西。
我正在使用 eather 在我的代码中重新创建与 maven dependency:tree 相同的结构。 根据文档,我发现这个有用的 example 它正确地列出了与插件相同的依赖关系,但它缺少任何 "tree" 信息,它只是一个简单的列表。
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() );
}
}
然后我编写了另一段代码来检索非传递依赖项,并递归调用它,能够获得完整的依赖关系图,但没有任何限制,所以我应该实现一些 filtering/limit 例程。
由于我想尽可能保持相同的插件逻辑,而不引入 "my" 过滤,是否有任何方法可以修改第一个示例以检索层次结构信息?
如果你想要 exactly the same
行为,作为插件实现,我建议查看插件的源代码 here,这样你就不会错过任何细微差别。但是基本的做法是使用collectRequest
到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,它们将用于测试类路径。但是有了这个你实际上可以进一步自定义 NodeVisitor 来过滤你想要的任何东西。