Аммонит: как использовать другой скрипт из зависимости Айви?

У меня есть Ammonite Script, который я хочу доставить в 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.

^

3 ответа

Скрипт необходимо компилировать на лету.

Поместите свой скрипт в стандартный проект sbt

внутри каталога, пример имени каталога: "test1"

Поместите свой внешний скрипт (пример имени: "script.sc")

// script.sc

println("Hello world!")

в каталог ресурсов ("test1\src\main\resources\script.sc") проекта test1

Опубликуйте проект локально, т.е. sbt publishLocal

Он публикуется в каталоге ".ivy2\local\default\test1_2.12\0.1-SNAPSHOT\ ... ".

Теперь вы можете использовать следующий скрипт аммонита "test.sc".

Читает "script.sc" из jar в локальном репозитории ivy.

и записывает его в локальный каталог (должен иметь доступ для чтения / записи), а затем выполняет внешний процесс,

который вызывает "интерпретатор" 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.

Для полноты я мог бы решить свою проблему следующим образом:

  • Просто создайте файл 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"))
    
    

Сценарии Scala на самом деле не интерпретируются, но компилируются "под капотом", как и любая обычная программа Scala. Поэтому весь код должен быть доступен во время компиляции, и вы не можете вызывать функцию внутри другого скрипта из jar-файла!

Но у Ammonite есть встроенная многоступенчатая функция. Он компилирует одну часть, выполняет ее, а затем компилирует следующую часть!

Немного улучшенный аммонит-скрипт. Это не безошибочно, но работает.

Может, есть способ лучше вытащить скрипт из банки. Спросите Ли Хаойи!

// 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!")
Другие вопросы по тегам