【问题标题】:Ammonite: how to use another script from an Ivy dependency?Ammonite:如何使用 Ivy 依赖项中的另一个脚本?
【发布时间】:2019-12-24 17:34:52
【问题描述】:

我有一个 Ammonite 脚本,我想在 JAR 中交付。

在另一个项目中我想使用这个脚本 - 但到目前为止没有成功。

我按照文档(sol_local_build.sc)试过了:

import $ivy.`mycompany:myproject_2.12:2.1.0-SNAPSHOT`, local_build

@main
def doit():Unit =
  println(local_build.curl("http://localhost:8080"))

local_build.sc 在我要使用的脚本中。

这是我得到的例外:

sol_local_build.sc:2: '.' expected but eof found.

^

【问题讨论】:

    标签: scala ammonite scala-script


    【解决方案1】:

    脚本必须即时编译。

    将您的脚本放入标准的 sbt 项目中

    在一个目录内,示例目录名:“test1”

    放置您的外部脚本(示例名称:“script.sc”)

    // script.sc

    println("Hello world!")

    进入test1项目的资源目录(“test1\src\main\resources\script.sc”)

    在本地发布项目,即 sbt publishLocal

    发布到“.ivy2\local\default\test1_2.12\0.1-SNAPSHOT\ ...”目录。

    现在您可以使用以下菊石脚本“test.sc”。

    它从本地 ivy 存储库中的 jar 中读取“script.sc”

    并将其写入本地目录(必须具有读/写权限),然后执行外部进程,

    调用scala“解释器”并执行脚本。

    // test.sc
    
    import $ivy.`default:test1_2.12:0.1-SNAPSHOT`
    
    
    val scriptCode = scala.util.Try {scala.io.Source.fromResource("script.sc").mkString} getOrElse """Println("Script-file not found!")"""
    
    println("*" * 30)
    println(scriptCode)
    println("*" * 30)
    println()
    
    
    java.nio.file.Files.write(java.nio.file.Paths.get("script.sc"), scriptCode.getBytes(java.nio.charset.StandardCharsets.UTF_8))
    
    val cmd = Seq("cmd.exe", "/c", "scala", "script.sc")
    
    val output = sys.process.Process(cmd).!! 
    
    println(output)
    

    执行 Ammonite REPL 脚本,你会得到:

    ******************************
    // script.sc
    
    println("Hello world!")
    ******************************
    
    Hello world!
    
    

    脚本没有错误处理并将文件留在运行目录中。 您可以使用“-savecompiled”编译器开关加快执行速度,即

    val cmd = Seq("cmd.exe", "/c", "scala", "-savecompiled", "script.sc")
    

    然后在运行目录中创建一个额外的 .jar 文件。

    【讨论】:

    • 谢谢,但我怎样才能重用库文件的功能,比如我的问题中的doit 使用了我的库中的curl
    • 在最后尝试 import $ivy.mycompany:myproject_2.12:2.1.0-SNAPSHOT, local_build._ ._!
    • 在 import-$ivy 语句的末尾添加 ._。检查你的文件编码!
    • 这里没有成功。对于import $ivy.mycompany:devops_2.13:2.4.0-SNAPSHOT, local_build._ 我收到以下错误:project_build.sc:1: not found: value local_build import $ivy.$ , local_build._
    • 你的脚本是用:scala project_build.sc 开始的吗?
    【解决方案2】:

    Scala 脚本不是真正解释的,而是“在后台”编译的 就像每个普通的 Scala 程序一样。 因此,所有代码必须在编译期间可访问 并且您不能从 jar 文件中调用其他脚本中的函数!

    但是 Ammonite 具有内置的多阶段功能。 它编译一个部分,执行它,然后编译下一部分!

    小改进的菊石脚本。 它不是没有错误的,但可以运行。

    也许有更好的方法可以将脚本从 jar 中取出。 你应该问问李浩毅!

    // test_ammo.sc 
    // using ammonite ops
    
    // in subdirectoy /test1
    
    // Ammonite REPL:
    // import $exec.test1.test_ammo
    // @ Ammonite-multi-stage
    
    import $ivy.`default::test1:0.1-SNAPSHOT`
    
    //import scala.util.Properties
    import scala.sys.process.Process
    
    val scriptFileName = "script.sc"
    
    write.over(pwd/"test1"/scriptFileName, read(resource(getClass.getClassLoader)/scriptFileName))
    
    val cmd = Seq("cmd.exe", "/c", "scala", scriptFileName)
    val output = Process(cmd).!! 
    println(output)
    
    @
    
    import $exec.script // no .sc suffix
    
    ppp() // is a function inside script.sc
    
    

    项目资源文件夹中的script.sc 使用“sbt publishLocal”在本地发布:

    // script.sc
    
    println("Hello world!")
    
    def ppp() = println("Hello world from ppp!")
    

    【讨论】:

    • 再次感谢;)。我是 Mac 用户,所以我做了:val cmd = Seq("bash", "scala", scriptFileName),但它无法编译它,它甚至无法解析菊石导入 local_build.sc:4: error: not found: value ammonite import ammonite.main.Router.main
    【解决方案3】:

    为了完整起见,我可以按如下方式解决我的问题:

    • 只需在此项目中创建一个 Scala 文件即可。
    • 将脚本内容复制到 一个东西。
      package mycompany.myproject
      
      object LocalBuild {
         def curl(..)...
      }
      
    • 将依赖项添加到您的 sbt 文件中(例如 ammonite.ops
    • 像这样使用它:
      $ivy.`mycompany:myproject_2.12:2.1.0-SNAPSHOT`, mycompany.myproject.LocalBuild
      
         @main
         def doit():Unit =
            println(LocalBuild.curl("http://localhost:8080"))
      
      

    【讨论】:

      猜你喜欢
      • 2019-08-11
      • 2014-12-13
      • 1970-01-01
      • 2015-11-05
      • 2015-11-18
      • 2021-12-30
      • 2020-07-24
      • 1970-01-01
      • 2011-02-06
      相关资源
      最近更新 更多