【问题标题】:Resolve artifact with sbt programmatically以编程方式使用 sbt 解决工件
【发布时间】:2013-12-23 06:46:05
【问题描述】:

以下博客建议如何使用 ivy (http://developers-blog.org/blog/default/2010/11/08/Embed-Ivy-How-to-use-Ivy-with-Java) 直接从 java 中获取工件。

public class IvyArtifactResolver {
    public File resolveArtifact(String groupId, String artifactId, String version) throws Exception {
        //creates clear ivy settings
        IvySettings ivySettings = new IvySettings();
        //url resolver for configuration of maven repo
        URLResolver resolver = new URLResolver();
        resolver.setM2compatible(true);
        resolver.setName("central");
        //you can specify the url resolution pattern strategy
        resolver.addArtifactPattern(
                "http://repo1.maven.org/maven2/"
                + "[organisation]/[module]/[revision]/[artifact](-[revision]).[ext]");
        //adding maven repo resolver
        ivySettings.addResolver(resolver);
        //set to the default resolver
        ivySettings.setDefaultResolver(resolver.getName());
        //creates an Ivy instance with settings
        Ivy ivy = Ivy.newInstance(ivySettings);

        File ivyfile = File.createTempFile("ivy", ".xml");
        ivyfile.deleteOnExit();

        String[] dep = null;
        dep = new String[]{groupId, artifactId, version};

        DefaultModuleDescriptor md =
                DefaultModuleDescriptor.newDefaultInstance(ModuleRevisionId.newInstance(dep[0],
                dep[1] + "-caller", "working"));

        DefaultDependencyDescriptor dd = new DefaultDependencyDescriptor(md,
                ModuleRevisionId.newInstance(dep[0], dep[1], dep[2]), false, false, true);
        md.addDependency(dd);

        //creates an ivy configuration file
        XmlModuleDescriptorWriter.write(md, ivyfile);

        String[] confs = new String[]{"default"};
        ResolveOptions resolveOptions = new ResolveOptions().setConfs(confs);

        //init resolve report
        ResolveReport report = ivy.resolve(ivyfile.toURL(), resolveOptions);

        //so you can get the jar library
        File jarArtifactFile = report.getAllArtifactsReports()[0].getLocalFile();

        return jarArtifactFile;
    }
}

我想知道 sbt 是否公开了这种接口,因为它使用了 ivy。

解析 :: ModuleId -> 文件

【问题讨论】:

    标签: sbt


    【解决方案1】:

    脚本、REPL 和依赖项

    您可能会对一个名为 Scripts, REPL, and Dependencies 的文档感兴趣。例如,脚本运行程序可以让您编写如下内容:

    #!/usr/bin/env scalas
    !#
    
    /***
    scalaVersion := "2.9.0-1"
    
    libraryDependencies ++= Seq(
      "net.databinder" %% "dispatch-twitter" % "0.8.3",
      "net.databinder" %% "dispatch-http" % "0.8.3"
    )
    */
    
    import dispatch.{ json, Http, Request }
    import dispatch.twitter.Search
    

    以编程方式驱动 sbt

    您还可以将 sbt 的任何子部分用作库并自己驱动它。由于插件生态系统,在点版本之间保持二进制兼容性非常好。抓取罐子的关键任务是update,因此def updateTask (Defaults.scala#L1113) 可能是一个不错的起点。但是,如果您从客户端代码驱动 sbt,您最终不会重新实现 sbt shell 或包含所有 sbt 的依赖项吗?你还不如有一个单独的 sbt shell 窗口或 sbt 脚本部分。

    自定义解析器

    sbt 附带了各种可定制的解析器,所以首先要检查的地方应该是:Resolvers:

    sbt 为 Ivy 中可用的存储库类型提供了一个接口:文件、URL、SSH 和 SFTP。 Ivy 中存储库的一个关键特性是使用模式来配置存储库。

    使用sbt.Resolver 中的工厂为所需类型构造存储库定义。这个工厂创建了一个可以进一步配置的Repository 对象。下表包含指向存储库类型的 Ivy 文档以及工厂和存储库类的 API 文档的链接。除了工厂名称外,SSH 和 SFTP 存储库的配置相同。 SSH 使用Resolver.ssh,SFTP 使用Resolver.sftp

    例如你可以这样做:

    resolvers += Resolver.file("my-test-repo", file("test")) transactional()
    

    原始存储库

    但如果你真的想要一个可编程的解析器,有RawRepository

    final class RawRepository(val resolver: DependencyResolver) extends Resolver
    {
        def name = resolver.getName
        override def toString = "Raw(" + resolver.toString + ")"
    }
    

    这是一个围绕org.apache.ivy.plugins.resolver.DependencyResolver 的薄包装,您应该可以通过扩展他们拥有的一个解析器来编写它。 (我自己没试过。)

    【讨论】:

    • 我想在运行时解析客户端代码中的工件。由 codebrew.io 指定自定义依赖项。
    猜你喜欢
    • 1970-01-01
    • 2020-02-19
    • 2017-11-26
    • 2012-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多