我正在开发一个 Maven 插件。
插件需要列出其运行的项目的依赖项,并确定依赖项来自何处(哪个远程 Maven 存储库)。如果我只获得一个远程存储库,不需要是原始存储库(即,如果它来自镜像,那么我获得镜像 URL 就可以了)。
我已经运行了 Maven API,但找不到任何会公开此信息的内容。 同样明显的是,Maven 确实知道这一点,因为 (a) 它确实从(远程)存储库下载了它,并且 (b) 本地存储库中的工件旁边有一个
_remote.repositories
文件,该文件指向该工件来自的存储库.
除了使用正确的 API 调用之外,我还有其他我不喜欢的选项:
获取依赖项的
pom.xml
,查看其 <distributionManagement>/<repository>
标签,并推断存储库。标签可能会丢失,并且分发存储库不一定与从中获取工件的存储库相同。
从本地下载的工件的相邻位置读取
_remote.repositories
,并解释它们。这是一种黑客攻击,文件明确指出不要这样做,因为它可能会发生变化。
鉴于该项目已知的所有存储库,将它们全部打开,直到我找到具有该工件的存储库。
如果有人能指出我可以用来做到这一点的 Maven API,那就太好了。
附注确定存储库 URL 的原因是为了生成一份报告,规定依赖项实际来自何处(特定要求);接收报告的一方应该能够下载依赖项并检查它是否与声明的哈希值(也出现在报告中)匹配。
您可以使用 Maven Resolve API。
RepositorySystem#collectDependency(...)
在致电
RepositorySystem#collectDependencies(...)
之前,我们需要准备自己的RepositoryListener
,例如:
RepositoryListener myListener = new AbstractRepositoryListener() {
@Override
public void artifactResolved(RepositoryEvent event) {
getLog().info("artifact=" + event.getArtifact() + " repo=" + event.getRepository());
}
};
// copy of repository session
DefaultRepositorySystemSession mySystemSession =
new DefaultRepositorySystemSession(session.getRepositorySession());
// new ChainedRepositoryListener with our own listener
ChainedRepositoryListener repositoryListener =
new ChainedRepositoryListener(mySystemSession.getRepositoryListener(), myListener);
mySystemSession.setRepositoryListener(repositoryListener);
// ...
CollectResult collectResult = repositorySystem.collectDependencies(mySystemSession, request);
// ....
RepositoryEvent#getRepository
将包含一个用于解析工件的存储库。
在某些情况下,如果 Maven 早期未解析工件或在本地安装工件,则它可以是本地存储库。
您可以检查
maven-dependency-plugin:list-repositories
的代码作为使用 Resolve API 的示例