如何在scala脚本中获得自动依赖项解析?

时间:2011-09-29 16:06:17

标签: scala

我正在学习scala来自groovy / java世界。我的第一个脚本需要第三方库TagSoup进行XML / HTML解析,我不得不用旧学校的方式添加它:即从开发者网站下载TagSoup,然后将其添加到类路径中。 / p>

有没有办法在我的scala脚本中解析第三方库?我在想常春藤,我在想Grape。

想法?


对我来说最有效的答案是安装n8:

curl https://raw.github.com/n8han/conscript/master/setup.sh | sh
cs harrah/xsbt --branch v0.11.0

然后我可以很容易地导入tagsoup example.scala

  /***
      libraryDependencies ++= Seq(
          "org.ccil.cowan.tagsoup" % "tagsoup" % "1.2.1"
      )
  */

  def getLocation(address:String) = {
      ...
  }

使用scalas运行:

  scalas example.scala

感谢您的帮助!

7 个答案:

答案 0 :(得分:12)

虽然答案是SBT,但在考虑脚本的情况下可能会更有帮助。请参阅,SBT对脚本有一个特殊之处,如here所述。安装scalas之后,安装conscript然后运行cs harrah/xsbt --branch v0.11.0,或者只是自己编写或多或少这样:

#!/bin/sh
java -Dsbt.main.class=sbt.ScriptMain \
     -Dsbt.boot.directory=/home/user/.sbt/boot \
     -jar sbt-launch.jar "$@"

然后你可以这样编写你的脚本:

#!/usr/bin/env scalas
!#

/***
scalaVersion := "2.9.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
import json.{ Js, JsObject }

def process(param: JsObject) = {
  val Search.text(txt)        = param
  val Search.from_user(usr)   = param
  val Search.created_at(time) = param

  "(" + time + ")" + usr + ": " + txt
}

Http.x((Search("#scala") lang "en") ~> (_ map process foreach println))

您可能也对paulp的xsbtscript感兴趣,它会创建一个与xsbtscript具有相同内容的scalas shell(我猜后者基于前者),优点是没有安装或安装sbt ,你可以用它来做好准备:

curl https://raw.github.com/paulp/xsbtscript/master/setup.sh | sh

请注意,它会安装sbt和conscript。

还有paulp的sbt-extras,它是另一种“sbt”命令行,有更多选项。请注意,它仍然是sbt,只是启动它的shell脚本更加智能。

答案 1 :(得分:8)

SBT(简单构建工具)似乎是Scala世界中的首选构建工具。它支持许多不同的依赖关系解析机制:https://github.com/harrah/xsbt/wiki/Library-Management

答案 2 :(得分:7)

作为答案放置,因为它不适合评论长度约束

除了@Chris的回答,我想向你推荐一些公共场所(我个人认为这绝对是一流的)。虽然sbt表示简单构建工具,但有时候第一次使用sbt设置项目并不容易(所有这些都有布局,配置等)。

使用giter(g8)创建具有预定义模板的新项目(g8从github.com获取)。有Android appunfilteredmore的模板。有时它们默认包含一些依赖项。 要创建布局,只需键入:

g8 gseitz/android-sbt-project

(Android应用的一个示例)

或者,为sbt使用np插件,它提供交互式输入方式来创建新项目和基本布局。

答案 3 :(得分:2)

当前主要答案的更正和简化版本:使用scalas

你必须编写3个部分的脚本。一个是sbt,另一个是围绕SBT的一个非常简单的包装器scalas,最后一个是你的自定义脚本。请注意,前两个脚本可以全局安装(/ usr / bin /,〜/ bin /)或本地安装(在同一目录中)。

  • 第一部分是sbt。如果你已经安装好了那就好了。如果没有,你可以安装它,或者使用paulp的一个非常酷的脚本:https://github.com/paulp/sbt-extras/blob/master/sbt顺便说一下,这个东西是在Unix上使用sbt的迷人方式。虽然在Windows上不可用。反正...

  • 第二部分是scalas。它只是SBT的入口点。

#!/bin/sh
exec /path/to/sbt -Dsbt.main.class=sbt.ScriptMain -sbt-create \
    -Dsbt.boot.directory=$HOME/.sbt/boot \
    "$@"
  • 最后一部分是您的自定义脚本。例如:
#!/usr/bin/env scalas
/***
scalaVersion := "2.11.0"

libraryDependencies ++= Seq(
    "org.joda"            %   "joda-convert"      % "1.5",
    "joda-time"           %   "joda-time"         % "2.3"
)
*/

import org.joda.time._

println(DateTime.now())
//println(DateTime.now().minusHours(12).dayOfMonth())

答案 4 :(得分:0)

丹尼尔说的话。虽然值得一提的是sbt docs仔细标记了这个功能" experimental"。

实际上,如果您尝试使用scalaVersion:=" 2.10.3"来运行嵌入式脚本,那么您将获得

not found: value !#

幸运的是,这里不需要!#script header-closer,所以你可以把它留下来。

在scalaVersion:=" 2.10.3"下,脚本需要具有文件扩展名" .scala&#34 ;;使用bash shell脚本文件扩展名" .sh",无法工作。

此外,我不清楚最新版本的Dispatch(0.11.0)是否支持dispatch-twitter,该示例中使用了这一点。

有关此上下文中的标题关闭器的更多信息,请参阅Alvin Alexander关于Scala脚本的blog post或其Scala Cookbook的第14.10节。

答案 5 :(得分:0)

我有一个build.gradle文件,其中包含以下任务:

task classpath(dependsOn: jar) << {
    println "CLASSPATH=${tasks.jar.archivePath}:${configurations.runtime.asPath}"
}

然后,在我的Scala脚本中:

#!
script_dir=$(cd $(dirname "$0") >/dev/null; pwd -P)

classpath=$(cd ${script_dir} && ./gradlew classpath | grep '^CLASSPATH=' | sed -e 's|^CLASSPATH=||')

PATH=${SCALA_HOME}/bin:${PATH}

JAVA_OPTS="-Xmx4g -XX:MaxPermSize=1g" exec scala -classpath ${classpath} "$0" "$0" "$@"
!#

答案 6 :(得分:0)

请注意,我们不需要在 scalas需要一个单独的 PATH 可执行文件,因为我们可以使用 self-executing shell script 技巧。

这是一个示例脚本,它读取自己的内容(通过 $0 变量),在任意标记 (__BEGIN_SCRIPT__) 之前切掉所有内容,并对结果运行 sbt。我们使用进程替换来假装这个计算出的内容是一个真实的文件。这种方法的一个问题是 sbt 将在给定文件中查找,即它不会按顺序读取它。这会停止它使用 <(foo) 形式的进程替换,如 bash; 中所示。但是 zsh 有一个 =(foo) 形式,可查找的。

#!/usr/bin/env zsh
set -e

# Find the line # in this file ($0) after the line beginning __BEGIN_SCRIPT__
LINENUM=$(awk '/^__BEGIN_SCRIPT__/ {print NR + 1; exit 0; }' "$0")

sbtRun() {
    # Run the sbt command, such that it will fetch dependencies and execute a
    # script
    sbt -Dsbt.main.class=sbt.ScriptMain \
        -sbt-create \
        -Dsbt.boot.directory="$HOME/.sbt/boot" \
        "$@"
}

# Run SBT on the contents of this file, starting at LINENUM
sbtRun =(tail -n+"$LINENUM" "$0")

exit 0

__BEGIN_SCRIPT__
/***
scalaVersion := "2.11.0"

libraryDependencies ++= Seq(
    "org.joda"            %   "joda-convert"      % "1.5",
    "joda-time"           %   "joda-time"         % "2.3"
)
*/

import org.joda.time._

println(DateTime.now())