Import src/jekyll tree from sbt.github.com site

This commit is contained in:
Mark Harrah 2012-09-13 23:02:08 -04:00
parent 369655391f
commit 6668e9cce0
32 changed files with 2964 additions and 0 deletions

1
src/jekyll/CNAME Normal file
View File

@ -0,0 +1 @@
www.scala-sbt.org

5
src/jekyll/_config.yml Normal file
View File

@ -0,0 +1,5 @@
pygments: true
name: Simple Build Tool
description: Homepage for the Simple Build Tool
url: http://scala-sbt.org
markdown: rdiscount

View File

@ -0,0 +1,31 @@
<script type="text/javascript" src="/jquery.scrollto.min.js"></script>
<script type="text/javascript">
(function($){ $(function(){
$("#top").click(function(){ $("#intro").ScrollTo(); })
var applyH = function() {
$("#intro, .feature").each(function (i, elt) {
if ($(elt).height() < $(window).height()) {
$(elt).height($(window).height());
}
});
};
$(window).bind('resize', function() { applyH(); });
applyH();
$('#features a, .st').click(function(e){
var h = $(this).attr('href');
if(h && h[0] && h[0] == '#') {
e.preventDefault();
$(h).ScrollTo({
callback:function(){ window.location.hash = h;}
});
}
});
});})(jQuery);
</script>
</body>
</html>

View File

@ -0,0 +1,13 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en-us">
<head>
<title>{% if page.title %}{{ page.title }} - {% endif %}{{ site.title }}</title>
<link href='http://fonts.googleapis.com/css?family=Copse' rel='stylesheet' type='text/css'>
<link href='/resources/site.css' rel='stylesheet' type='text/css'>
<link href='/resources/syntax.css' rel='stylesheet' type='text/css'>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js">
</script>
</head>
<body>

View File

@ -0,0 +1,13 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en-us">
<head>
<title>{% if page.title %}{{ page.title }} - {% endif %}{{ site.title }}</title>
<link href='http://fonts.googleapis.com/css?family=Copse' rel='stylesheet' type='text/css'>
<link href='/resources/howto-site.css' rel='stylesheet' type='text/css'>
<link href='/resources/syntax.css' rel='stylesheet' type='text/css'>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js">
</script>
</head>
<body>

View File

@ -0,0 +1,15 @@
<!-- Topbar
================================================== -->
<div class="cf" id="more" >
<div id="top">
<div class="container">
<a class="brand" href="/">SBT</a>
<ul class="nav">
<li><a href="/learn.html">Learn</a>
<li><a href="/download.html">Download</a>
<li><a href="/community.html">Community</a></li>
<li><a href="#top">Top</a></li>
</ul>
</div>
</div>
</div>

View File

@ -0,0 +1,23 @@
{% include howto_header.txt %}
{% include topbar.txt %}
<div class="cf" id="container">
<div class="span2 columns container-spacer"><p>&nbsp;</p></div>
<div id="intro" class="span10 columns content">
<div id="head" class="cf">
<h2><span style="color:black;">sbt</span> {{page.title}}</h2>
</div>
<div id="pagecontent" class="cf">
{{ content }}
</div>
</div>
</div>
<div class="span6 columns"><p>&nbsp;</p></div>
</div>
</body>
</html>

View File

@ -0,0 +1,65 @@
{% include header.txt %}
{% include topbar.txt %}
<div class="cf" id="container">
<div class="span2 columns container-spacer"><p>&nbsp;</p></div>
<div id="intro" class="span10 columns content">
<div id="head" class="cf">
<div id="name" class="left">
<h1>sbt</h1>
<h2>{{page.title}}</h2>
<p id="what">{{page.tagline}}</p>
</div>
<div class="left page-description" id="vc">
{{page.description | markdownify }}
</div>
</div>
<div id="features" class="cf">
<div id="feature-list">
<ul class="left">
{% for link in page.toplinks %}
{% capture x %}{% cycle 'odd', 'even' %}{% endcapture %}
{% if x == 'odd' %}
{% if link.link %}
<li><a href="{{link.link}}">{{link.name}}</a></li>
{% else %}
<li><a href="#{{link.id}}">{{link.name}}</a></li>
{% endif %}
{% endif %}
{% endfor %}
</ul>
<ul class="left">
{% for link in page.toplinks %}
{% capture x %}{% cycle 'odd2', 'even2' %}{% endcapture %}
{% if x == 'even2' %}
{% if link.link %}
<li><a href="{{link.link}}">{{link.name}}</a></li>
{% else %}
<li><a href="#{{link.id}}">{{link.name}}</a></li>
{% endif %}
{% endif %}
{% endfor %}
</ul>
</div>
</div>
<div id="pagecontent" class="cf">
{{ content }}
</div>
</div>
<div id="extra">
<ul id="examples">
{% for link in page.toplinks %}{% if link.content %}
{% if link.content %}
<li id="{{link.id}}" class="feature contained">{{ link.content | markdownify }}</li>
{% endif %}
{% endif %}{% endfor %}
</ul>
</div>
</div>
<div class="span6 columns"><p>&nbsp;</p></div>
</div>
{% include footer.txt %}

View File

@ -0,0 +1,25 @@
{% include howto_header.txt %}
<div class="cf" id="container">
<div class="span2 columns container-spacer"><p>&nbsp;</p></div>
<div id="intro" class="span10 columns content">
<div id="head" class="cf">
<h2>{{page.title}}</h2>
</div>
<div class="cf"><div id="feature-list">
<h3> How to ...</h3>
<ul class="left" id="section-toc">
{% for section in page.sections %}
<li id="feature"><h5>... <a href="#{{section.id}}">{{section.name}}</a></h5></li>
{% endfor %}
</ul>
</div></div>
<div id="pagecontent" class="cf">
{{ content }}
</div>
</div>
</div>
</div>
{% include footer.txt %}

View File

@ -0,0 +1,66 @@
---
layout: default
title: Community Plugins
tagline: ensuring everything is possible.
description: 'The [SBT Organization](http://github.com/sbt) contains a [SBT Community Plugins](http://github.com/sbt/sbt-community-plugins) project. This project aims to unify all the SBT plugins in the community and ensure their compatibility and timely releases with new versions of SBT. There is also a [list of plugins](https://github.com/harrah/xsbt/wiki/sbt-0.10-plugins-list) that is up-to-date.'
toplinks:
- name: 'Available Plugins'
link: 'plugins.html'
- name: 'Community Ivy repository'
id: 'communityrepo'
content: |
#### Community Ivy Repository ####
[Typesafe, Inc.](http://www.typesafe.com) has provided a freely available [Ivy Repository](http://scalasbt.artifactoryonline.com/scalasbt) for SBT projects to make use of.
If you would like to publish your project to this Ivy repository, first contact [sbt-repo-admins](http://groups.google.com/group/sbt-repo-admins?hl=en) and request privileges
(we have to verify code ownership, rights to publish, etc.). After which, you can deploy your plugins using the following configuration:
publishTo := Some(Resolver.url("sbt-plugin-releases", new URL("http://scalasbt.artifactoryonline.com/scalasbt/sbt-plugin-releases/"))(Resolver.ivyStylePatterns))
publishMavenStyle := false
You'll also need to add your credentials somewhere. I use a `~/.sbt/sbtpluginpublish.sbt` file:
credentials += Credentials("Artifactory Realm", "scalasbt.artifactoryonline.com", "jsuereth", "@my encrypted password@")
Where `@my encrypted password@` is actually obtained using the following [instructions](http://wiki.jfrog.org/confluence/display/RTF/Centrally+Secure+Passwords).
*Note: Your code must abide by the [repository polices](repository-rules.html).*
To automatically deploy snapshot/release versions of your plugin use
the following configuration:
publishTo <<= (version) { version: String =>
val scalasbt = "http://scalasbt.artifactoryonline.com/scalasbt/"
val (name, url) = if (version.contains("-SNAPSHOT"))
("sbt-plugin-snapshots", scalasbt+"sbt-plugin-snapshots")
else
("sbt-plugin-releases", scalasbt+"sbt-plugin-releases")
Some(Resolver.url(name, new URL(url))(Resolver.ivyStylePatterns))
}
*Note: ivy repositories currently don't support Maven-style snapshots.*
- name: 'SBT Organization'
id: 'sbtorg'
content: |
#### SBT Organization ####
The [SBT Organization](http://github.com/sbt) is available for use by any SBT plugin.
Developers who contribute their plugins into the community organization will still retain
control over their repository and its access. The Goal of the SBT organization is to
organize SBT software into one central location.
A side benefit to using the SBT organization for projects is that you can use gh-pages to host websites in the http://scala-sbt.org domain.
- name: 'Community Plugin Build'
id: 'pluginbuild'
content: |
#### SBT Community Plugin Build ####
The [SBT Community Plugins](http://github.com/sbt/sbt-community-plugins) project aims to build *all* SBT plugins in a single build.
This should enable thorough testing of plugins and ensure that plugins work together.
---

14
src/jekyll/community.md Normal file
View File

@ -0,0 +1,14 @@
---
layout: default
title: Community
tagline: Amazing People, including you
description: |
A wonderful, highly engaged community that you can talk to and be a part of.
toplinks:
- name: 'Mailing List'
link: 'http://groups.google.com/group/simple-build-tool/topics'
- name: 'Community Plugins'
link: 'community-plugins.html'
- name: 'Source Code'
link: 'http://github.com/harrah/xsbt'
---

85
src/jekyll/download.md Normal file
View File

@ -0,0 +1,85 @@
---
layout: default
title: download
tagline: up and running in moments.
description: |
The [SBT Launcher](http://github.com/sbt/sbt-launcher-package) project contains a set of native packages for use in your operating system.
[msi](#windows) | [yum](#rpm) | [apt-get](#deb) | [homebrew](#mac) | [by hand](#manual)
toplinks:
- name: 'Windows MSI downloads'
id: 'windows'
content: |
#### Windows Releases ####
[Click here](http://scalasbt.artifactoryonline.com/scalasbt/sbt-native-packages/org/scala-sbt/sbt/0.12.0/sbt.msi) for the latest windows MSI.
*Note: please make sure to report any issues you may find [here](https://github.com/sbt/sbt-launcher-package/issues).*
- name: 'Yum Repository'
id: 'rpm'
content: |
#### Yum Repositories ####
The sbt package is available from the [Typesafe Yum Repository](http://rpm.typesafe.com).
Please install [this rpm](http://rpm.typesafe.com/typesafe-repo-2.0.0-1.noarch.rpm) to add the typesafe yum repository to your list of approved sources.
Then run:
yum install sbt
to grab the latest release of sbt.
*Note: please make sure to report any issues you may find [here](https://github.com/sbt/sbt-launcher-package/issues).*"
- name: 'Apt Repository'
id: 'deb'
content: |
#### APT Repositories ####
The sbt package is available from the [Typesafe Debian Repository](http://apt.typesafe.com).
Please install [this deb](http://apt.typesafe.com/repo-deb-build-0002.deb) to enable the typesafe repository.
Then run:
apt-get install sbt
to grab the latest release of sbt.
*Note: please make sure to report any issues you may find [here](https://github.com/sbt/sbt-launcher-package/issues).*"
- name: 'Homebrew'
id: 'mac'
content: |
#### Hombrew ####
Use HomeBrew:
$ brew install sbt
- name: 'Manual Installation'
id: 'manual'
content: |
#### Pre-Built Zip files ###
Download one of the pre-built [zip](http://scalasbt.artifactoryonline.com/scalasbt/sbt-native-packages/org/scala-sbt/sbt/0.12.0/sbt.zip)
or [tgz](http://scalasbt.artifactoryonline.com/scalasbt/sbt-native-packages/org/scala-sbt/sbt/0.12.0/sbt.tgz) and
add the bin/ to your path.
#### By Hand installation ####
First, download the [launcher jar](http://typesafe.artifactoryonline.com/typesafe/ivy-releases/org.scala-sbt/sbt-launch/0.12.0/sbt-launch.jar)
and place it somewhere useful.
THEN, create a script in that same directory.
##### Windows #####
Create a `sbt.bat` file next to the launch jar.
set SCRIPT_DIR=%~dp0
java -Xmx512M -jar "%SCRIPT_DIR%sbt-launch.jar" %*
Add the directory containing `sbt.bat` to the windows path.
##### Unix-Like #####
Create a `sbt` script (a good place is `~/bin/sbt`
java -Xmx512M -jar `dirname $0`/sbt-launch.jar "$@"
then make the script executable:
$ chmod u+x ~/bin/sbt
---
<!-- This page has no content. -->

26
src/jekyll/howto.md Normal file
View File

@ -0,0 +1,26 @@
---
layout: content
title: How to...
description: How to do common tasks.
---
{% capture table %}
{% for page in site.pages %}
{% if page.sections %}
### {{page.title}} [(details)]({{page.url}}) ###
{% for section in page.sections %}
... {{section.name}} [(details)]({{page.url | append: "#" | append: section.id}})
{% if section.short %} {{section.short | strip_newlines | markdownify}}
{% elsif section.batch %} {% highlight console %} $ sbt {{section.batch | strip_newlines}} {% endhighlight %}
{% elsif section.setting %} {% highlight scala %} {{section.setting | strip_newlines}} {% endhighlight %}
{% elsif section.command %} {% highlight console %} > {{section.command | strip_newlines}} {% endhighlight %}
{% elsif section.commands %} {% highlight console %} {{section.commands}} {% endhighlight %}
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
{% endcapture %}
{{ table | unindent | markdownify }}

View File

@ -0,0 +1,76 @@
---
layout: howto
title: Generating files
sections:
- id: sources
name: generate sources
setting: 'sourceGenerators in Compile <+= <your Task[Seq[File]] here>'
- id: resources
name: generate resources
setting: 'resourceGenerators in Compile <+= <your Task[Seq[File]] here>'
---
sbt provides standard hooks for adding source or resource generation tasks.
<h4 id="sources">Generate sources</h4>
A source generation task should generate sources in a subdirectory of `sourceManaged` and return a sequence of files generated. The key to add the task to is called `sourceGenerators`. It should be scoped according to whether the generated files are main (`Compile`) or test (`Test`) sources. This basic structure looks like:
{% highlight scala %}
sourceGenerators in Compile <+= <your Task[Seq[File]] here>
{% endhighlight %}
For example, assuming a method `def makeSomeSources(base: File): Seq[File]`,
{% highlight scala %}
sourceGenerators in Compile <+= sourceManaged in Compile map { outDir: File =>
makeSomeSources(outDir / "demo")
}
{% endhighlight %}
As a specific example, the following generates a hello world source file:
{% highlight scala %}
sourceGenerators in Compile <+= sourceManaged in Compile map { dir =>
val file = dir / "demo" / "Test.scala"
IO.write(file, """object Test extends App { println("Hi") }""")
Seq(file)
}
{% endhighlight %}
Executing 'run' will print "Hi". Change `Compile` to `Test` to make it a test source. For efficiency, you would only want to generate sources when necessary and not every run.
By default, generated sources are not included in the packaged source artifact. To do so, add them as you would other mappings. See `Adding files to a package`.
<h4 id="resources">Generate resources</h4>
A resource generation task should generate resources in a subdirectory of `resourceManaged` and return a sequence of files generated. The key to add the task to is called `resourceGenerators`. It should be scoped according to whether the generated files are main (`Compile`) or test (`Test`) resources. This basic structure looks like:
{% highlight scala %}
resourceGenerators in Compile <+= <your Task[Seq[File]] here>
{% endhighlight %}
For example, assuming a method `def makeSomeResources(base: File): Seq[File]`,
{% highlight scala %}
resourceGenerators in Compile <+= resourceManaged in Compile map { outDir: File =>
makeSomeResources(outDir / "demo")
}
{% endhighlight %}
As a specific example, the following generates a properties file containing the application name and version:
{% highlight scala %}
resourceGenerators in Compile <+=
(resourceManaged in Compile, name, version) map { (dir, n, v) =>
val file = dir / "demo" / "myapp.properties"
val contents = "name=%s\nversion=%s".format(n,v)
IO.write(file, contents)
Seq(file)
}
}
{% endhighlight %}
Change `Compile` to `Test` to make it a test resource. Normally, you would only want to generate resources when necessary and not every run.
By default, generated resources are not included in the packaged source artifact. To do so, add them as you would other mappings. See the `Adding files to a package` section.

298
src/jekyll/howto/inspect.md Normal file
View File

@ -0,0 +1,298 @@
---
layout: howto
title: Inspect the build
sections:
- id: taskhelp
name: show or search help for a command, task, or setting
command: help compile
- id: listtasks
name: list available tasks
command: tasks
- id: listsettings
name: list available settings
command: settings
- id: dependencies
name: display forward and reverse dependencies of a setting or task
command: inspect compile
- id: taskdependencytree
name: display tree of setting/task dependencies
command: inspect compile
- id: description
name: display the description and type of a setting or task
command: help compile
- id: delegates
name: display the delegation chain of a setting or task
command: inspect compile
- id: related
name: display related settings or tasks
command: inspect compile
- id: session
name: show the current session (temporary) settings
command: session list
- id: projects
name: show the list of projects and builds
command: projects
- id: about
name: show basic information about sbt and the current build
command: about
- id: value
name: show the value of a setting
command: show name
- id: result
name: show the result of executing a task
command: show update
- id: classpath
name: show the classpath used for compilation or testing
command: show compile:dependency-classpath
- id: applications
name: show the main classes detected in a project
command: show compile:discovered-main-classes
- id: tests
name: show the test classes detected in a project
command: show defined-test-names
---
[Inspecting Settings]: https://github.com/harrah/xsbt/wiki/Inspecting-Settings
<h4 id="taskhelp">Show or search help for a command, task, or setting</h4>
The `help` command is used to show available commands and search the help for commands, tasks, or settings.
If run without arguments, `help` lists the available commands.
{% highlight console %}
> help
help Displays this help message or prints detailed help on
requested commands (run 'help <command>').
about Displays basic information about sbt and the build.
reload (Re)loads the project in the current directory
...
{% endhighlight %}
{% highlight console %}
> help compile
{% endhighlight %}
If the argument passed to `help` is the name of an existing command, setting or task, the help
for that entity is displayed. Otherwise, the argument is interpreted as a regular expression that
is used to search the help of all commands, settings and tasks.
The `tasks` command is like `help`, but operates only on tasks.
Similarly, the `settings` command only operates on settings.
See also `help help`, `help tasks`, and `help settings`.
<h4 id="listtasks">List available tasks</h4>
The `tasks` command, without arguments, lists the most commonly used tasks.
It can take a regular expression to search task names and descriptions.
The verbosity can be increased to show or search less commonly used tasks.
See `help tasks` for details.
<h4 id="listsettings">List available tasks</h4>
The `settings` command, without arguments, lists the most commonly used settings.
It can take a regular expression to search setting names and descriptions.
The verbosity can be increased to show or search less commonly used settings.
See `help settings` for details.
<h4 id="dependencies">Display forward and reverse dependencies of a setting or task</h4>
The `inspect` command displays several pieces of information about a given setting or task, including
the dependencies of a task/setting as well as the tasks/settings that depend on the it. For example,
{% highlight console %}
> inspect test:compile
...
[info] Dependencies:
[info] test:compile::compile-inputs
[info] test:compile::streams
[info] Reverse dependencies:
[info] test:defined-test-names
[info] test:defined-sbt-plugins
[info] test:print-warnings
[info] test:discovered-main-classes
[info] test:defined-tests
[info] test:exported-products
[info] test:products
...
{% endhighlight %}
See the [Inspecting Settings] page for details.
<h4 id="taskdependencytree">Display tree of setting/task dependencies</h4>
In addition to displaying immediate forward and reverse dependencies as described in the previous section,
the `inspect` command can display the full dependency tree for a task or setting.
For example,
{% highlight console %}
> inspect tree clean
[info] *:clean = Task[Unit]
[info] +-*:clean-files = List(<project>/lib_managed, <project>/target)
[info] | +-{.}/*:managed-directory = lib_managed
[info] | +-*:target = target
[info] | +-*:base-directory = <project>
[info] | +-*:this-project = Project(id: demo, base: <project>, ...
[info] |
[info] +-*:clean-keep-files = List(<project>/target/.history)
[info] +-*:history = Some(<project>/target/.history)
...
{% endhighlight %}
For each task, `inspect tree` show the type of the value generated by the task.
For a setting, the `toString` of the setting is displayed.
See the [Inspecting Settings] page for details on the `inspect` command.
<h4 id="description">Display the description and type of a setting or task</h4>
While the `help`, `settings`, and `tasks` commands display a description of a task,
the `inspect` command also shows the type of a setting or task and the value of a setting.
For example:
{% highlight console %}
> inspect update
[info] Task: sbt.UpdateReport
[info] Description:
[info] Resolves and optionally retrieves dependencies, producing a report.
...
{% endhighlight %}
{% highlight console %}
> inspect scala-version
[info] Setting: java.lang.String = 2.9.2
[info] Description:
[info] The version of Scala used for building.
...
{% endhighlight %}
See the [Inspecting Settings] page for details.
<h4 id="delegates">Display the delegation chain of a setting or task</h4>
See the [Inspecting Settings] page for details.
<h4 id="related">Display related settings or tasks</h4>
The `inspect` command can help find scopes where a setting or task is defined.
The following example shows that different options may be specified to the Scala
for testing and API documentation generation.
{% highlight console %}
> inspect scalac-options
...
[info] Related:
[info] compile:doc::scalac-options
[info] test:scalac-options
[info] */*:scalac-options
[info] test:doc::scalac-options
{% endhighlight %}
See the [Inspecting Settings] page for details.
<h4 id="projects">Show the list of projects and builds</h4>
The `projects` command displays the currently loaded projects.
The projects are grouped by their enclosing build and the current project is indicated by an asterisk.
For example,
{% highlight console %}
> projects
[info] In file:/home/user/demo/
[info] * parent
[info] sub
[info] In file:/home/user/dep/
[info] sample
{% endhighlight %}
<h4 id="session">Show the current session (temporary) settings</h4>
`session list` displays the settings that have been added at the command line for the current project. For example,
{% highlight console %}
> session list
1. maxErrors := 5
2. scalacOptions += "-explaintypes"
{% endhighlight %}
`session list-all` displays the settings added for all projects.
For details, see `help session`.
<h4 id="about">Show basic information about sbt and the current build</h4>
{% highlight console %}
> about
[info] This is sbt 0.12.0
[info] The current project is {file:~/code/sbt.github.com/}default
[info] The current project is built against Scala 2.9.2
[info] Available Plugins: com.jsuereth.ghpages.GhPages, com.jsuereth.git.GitPlugin, com.jsuereth.sbtsite.SitePlugin
[info] sbt, sbt plugins, and build definitions are using Scala 2.9.2
{% endhighlight %}
<h4 id="value">Show the value of a setting</h4>
The `inspect` shows the value of a setting as part of its output, but the `show` command is dedicated to this job.
It shows the output of the setting provided as an argument.
For example,
{% highlight console %}
> show organization
[info] com.github.sbt
{% endhighlight %}
The `show` command also works for tasks, described next.
<h4 id="result">Show the result of executing a task</h4>
{% highlight console %}
> show update
... <output of update> ...
[info] Update report:
[info] Resolve time: 122 ms, Download time: 5 ms, Download size: 0 bytes
[info] compile:
[info] org.scala-lang:scala-library:2.9.2: ...
{% endhighlight %}
The `show` command will execute the task provided as an argument and then print the result.
Note that this is different from the behavior of the `inspect` command (described in other sections),
which does not execute a task and thus can only display its type and not its generated value.
<h4 id="compilecp">Show the classpath used for compilation or testing</h4>
{% highlight console %}
> show compile:dependency-classpath
...
[info] ArrayBuffer(Attributed(~/.sbt/0.12.0/boot/scala-2.9.2/lib/scala-library.jar))
{% endhighlight %}
For the test classpath,
{% highlight console %}
> show test:dependency-classpath
...
[info] ArrayBuffer(Attributed(~/code/sbt.github.com/target/scala-2.9.2/classes), Attributed(~/.sbt/0.12.0/boot/scala-2.9.2/lib/scala-library.jar), Attributed(~/.ivy2/cache/junit/junit/jars/junit-4.8.2.jar))
{% endhighlight %}
<h4 id="applications">Show the main classes detected in a project</h4>
sbt detects the classes with public, static main methods for use by the `run` method and to tab-complete the `run-main` method.
The `discovered-main-classes` task does this discovery and provides as its result the list of class names.
For example, the following shows the main classes discovered in the main sources:
{% highlight console %}
> show compile:discovered-main-classes
... <runs compile if out of date> ...
[info] List(org.example.Main)
{% endhighlight %}
<h4 id="tests">Show the test classes detected in a project</h4>
sbt detects tests according to fingerprints provided by test frameworks.
The `defined-test-names` task provides as its result the list of test names detected in this way.
For example,
{% highlight console %}
> show test:defined-test-names
... < runs test:compile if out of date > ...
[info] List(org.example.TestA, org.example.TestB)
{% endhighlight %}

View File

@ -0,0 +1,180 @@
---
layout: howto
title: Interactive mode
sections:
- id: basic_completion
name: use tab completion
command: 'test-only <TAB>'
- id: verbose_completion
name: show more tab completion suggestions
short: Press tab multiple times.
- id: show_keybindings
name: view basic JLine keybindings
commands: |
> console-quick
scala> :keybindings
- id: change_keybindings
name: modify the default JLine keybindings
- id: prompt
name: configure the prompt string
setting: 'shellPrompt := { (s: State) => System.getProperty("user.name") + "> " }'
- id: history
name: use history
command: '!'
- id: history_file
name: change the location of the interactive history file
setting: 'historyPath <<= baseDirectory(t => Some(t / ".history"))'
- id: share_history
name: share interactive history across projects
setting: 'historyPath <<= (target in LocalRootProject) { t => Some(t / ".history") }'
- id: disable_history
name: disable interactive history
setting: 'historyPath := None'
- id: pre_commands
name: start interactive mode after executing some commands first
batch: clean compile shell
---
[State]: https://github.com/harrah/xsbt/wiki/Build-State
By default, sbt's interactive mode is started when no commands are provided on the command line or when the `shell` command is invoked.
<h4 id="basic_completion">Using tab completion</h4>
As the name suggests, tab completion is invoked by hitting the tab key.
Suggestions are provided that can complete the text entered to the left of the current cursor position.
Any part of the suggestion that is unambiguous is automatically appended to the current text.
Commands typically support tab completion for most of their syntax.
As an example, entering `tes` and hitting tab:
> tes<TAB>
results in sbt appending a `t`:
> test
To get further completions, hit tab again:
> test<TAB>
test-frameworks test-listeners test-loader test-only test-options test:
Now, there is more than one possibility for the next character, so sbt prints the available options.
We will select `test-only` and get more suggestions by entering the rest of the command and hitting tab twice:
> test-only<TAB><TAB>
-- sbt.DagSpecification sbt.EmptyRelationTest sbt.KeyTest sbt.RelationTest sbt.SettingsTest
The first tab inserts an unambiguous space and the second suggests names of tests to run.
The suggestion of `--` is for the separator between test names and options provided to the test framework.
The other suggestions are names of test classes for one of sbt's modules.
Test name suggestions require tests to be compiled first.
If tests have been added, renamed, or removed since the last test compilation, the completions will be out of date until another successful compile.
<h4 id="verbose_completion">Showing more completions</h4>
Some commands have different levels of completion. Hitting tab multiple times increases the verbosity of completions. (Presently, this feature is rarely used.)
<h4 id="show_keybindings">Showing JLine keybindings</h4>
Both the Scala and sbt command prompts use JLine for interaction. The Scala REPL contains a `:keybindings` command to show many of the keybindings used for JLine. For sbt, this can be used by running one of the `console` commands (`console`, `console-quick`, or `console-project`) and then running `:keybindings`. For example:
> console-project
[info] Starting scala interpreter...
...
scala> :keybindings
Reading jline properties for default key bindings.
Accuracy not guaranteed: treat this as a guideline only.
1 CTRL-A: move to the beginning of the line
2 CTRL-B: move to the previous character
...
<h4 id="change_keybindings">Changing JLine keybindings</h4>
JLine, used by both Scala and sbt, uses a configuration file for many of its keybindings.
The location of this file can be changed with the system property `jline.keybindings`.
The default keybindings file is included in the sbt launcher and may be used as a starting point for customization.
<h4 id="prompt">Configure the prompt string</h4>
By default, sbt only displays `> ` to prompt for a command.
This can be changed through the `shellPrompt` setting, which has type `State => String`.
[State] contains all state for sbt and thus provides access to all build information for use in the prompt string.
Examples:
{% highlight scala %}
// set the prompt (for this build) to include the project id.
shellPrompt in ThisBuild := { state => Project.extract(state).currentRef.project + "> " }
// set the prompt (for the current project) to include the username
shellPrompt := { state => System.getProperty("user.name") + "> " }
{% endhighlight %}
<h4 id="history">Using history</h4>
Interactive mode remembers history even if you exit sbt and restart it.
The simplest way to access history is to press the up arrow key to cycle
through previously entered commands. Use `Ctrl+r` to incrementally
search history backwards. The following commands are supported:
* `!` Show history command help.
* `!!` Execute the previous command again.
* `!:` Show all previous commands.
* `!:n` Show the last n commands.
* `!n` Execute the command with index `n`, as shown by the `!:` command.
* `!-n` Execute the nth command before this one.
* `!string` Execute the most recent command starting with 'string'
* `!?string` Execute the most recent command containing 'string'
<h4 id="history_file">Changing the history file location</h4>
By default, interactive history is stored in the `target/` directory for the current project (but is not removed by a `clean`).
History is thus separate for each subproject.
The location can be changed with the `historyPath` setting, which has type `Option[File]`.
For example, history can be stored in the root directory for the project instead of the output directory:
{% highlight scala %}
historyPath <<= baseDirectory(t => Some(t / ".history"))
{% endhighlight %}
The history path needs to be set for each project, since sbt will use the value of `historyPath` for the current project (as selected by the `project` command).
<h4 id="share_history">Use the same history for all projects</h4>
The previous section describes how to configure the location of the history file.
This setting can be used to share the interactive history among all projects in a build instead of using a different history for each project.
The way this is done is to set `historyPath` to be the same file, such as a file in the root project's `target/` directory:
{% highlight scala %}
historyPath <<=
(target in LocalRootProject) { t =>
Some(t / ".history")
}
{% endhighlight %}
The `in LocalRootProject` part means to get the output directory for the root project for the build.
<h4 id="disable_history">Disable interactive history</h4>
If, for whatever reason, you want to disable history, set `historyPath` to `None` in each project it should be disabled in:
{% highlight scala %}
historyPath := None
{% endhighlight %}
<h4 id="pre_commands">Run commands before entering interactive mode</h4>
Interactive mode is implemented by the `shell` command.
By default, the `shell` command is run if no commands are provided to sbt on the command line.
To run commands before entering interactive mode, specify them on the command line followed by `shell`.
For example,
$ sbt clean compile shell
This runs `clean` and then `compile` before entering the interactive prompt.
If either `clean` or `compile` fails, sbt will exit without going to the prompt.
To enter the prompt whether or not these initial commands succeed, prepend `-shell`, which means to run `shell` if any command fails.
For example,
$ sbt -shell clean compile shell

254
src/jekyll/howto/logging.md Normal file
View File

@ -0,0 +1,254 @@
---
layout: howto
title: Configure and use logging
sections:
- id: last
name: view the logging output of the previously executed command
command: last
- id: tasklast
name: view the previous logging output of a specific task
command: last compile
- id: printwarnings
name: show warnings from the previous compilation
command: print-warnings
- id: level
name: change the logging level globally
command: set every logLevel := Level.Debug
- id: tasklevel
name: change the logging level for a specific task, configuration, or project
setting: logLevel in compile := Level.Debug
- id: trace
name: configure printing of stack traces
command: set every traceLevel := 5`
- id: nobuffer
name: print the output of tests immediately instead of buffering
setting: logBuffered := false
- id: custom
name: add a custom logger
- id: log
name: log messages from a task
---
[print-warnings]: #printwarnings
[previous output]: #last
[Streams]: http://harrah.github.com/xsbt/latest/api/#sbt.std.Streams
<h4 id="last">View logging output of the previously executed command</h4>
When a command is run, more detailed logging output is sent to a file than to the screen (by default).
This output can be recalled for the command just executed by running `last`.
For example, the output of `run` when the sources are uptodate is:
{% highlight console %}
> run
[info] Running A
Hi!
[success] Total time: 0 s, completed Feb 25, 2012 1:00:00 PM
{% endhighlight %}
The details of this execution can be recalled by running `last`:
{% highlight console %}
> last
[debug] Running task... Cancelable: false, max worker threads: 4, check cycles: false
[debug]
[debug] Initial source changes:
[debug] removed:Set()
[debug] added: Set()
[debug] modified: Set()
[debug] Removed products: Set()
[debug] Modified external sources: Set()
[debug] Modified binary dependencies: Set()
[debug] Initial directly invalidated sources: Set()
[debug]
[debug] Sources indirectly invalidated by:
[debug] product: Set()
[debug] binary dep: Set()
[debug] external source: Set()
[debug] Initially invalidated: Set()
[debug] Copy resource mappings:
[debug]
[info] Running A
[debug] Starting sandboxed run...
[debug] Waiting for threads to exit or System.exit to be called.
[debug] Classpath:
[debug] /tmp/e/target/scala-2.9.2/classes
[debug] /tmp/e/.sbt/0.12.0/boot/scala-2.9.2/lib/scala-library.jar
[debug] Waiting for thread run-main to exit
[debug] Thread run-main exited.
[debug] Interrupting remaining threads (should be all daemons).
[debug] Sandboxed run complete..
[debug] Exited with code 0
[success] Total time: 0 s, completed Jan 1, 2012 1:00:00 PM
{% endhighlight %}
Configuration of the logging level for the console and for the backing file are described in following sections.
<h4 id="tasklast">View the logging output of a specific task</h4>
When a task is run, more detailed logging output is sent to a file than to the screen (by default).
This output can be recalled for a specific task by running `last <task>`.
For example, the first time `compile` is run, output might look like:
{% highlight console %}
> compile
[info] Updating {file:/.../demo/}example...
[info] Resolving org.scala-lang#scala-library;2.9.2 ...
[info] Done updating.
[info] Compiling 1 Scala source to .../demo/target/scala-2.9.2/classes...
[success] Total time: 0 s, completed Jun 1, 2012 1:11:11 PM
{% endhighlight %}
The output indicates that both dependency resolution and compilation were performed.
The detailed output of each of these may be recalled individually.
For example,
{% highlight console %}
> last compile
[debug]
[debug] Initial source changes:
[debug] removed:Set()
[debug] added: Set(/home/mark/tmp/a/b/A.scala)
[debug] modified: Set()
...
{% endhighlight %}
and:
{% highlight console %}
> last update
[info] Updating {file:/.../demo/}example...
[debug] post 1.3 ivy file: using exact as default matcher
[debug] :: resolving dependencies :: example#example_2.9.2;0.1-SNAPSHOT
[debug] confs: [compile, runtime, test, provided, optional, compile-internal, runtime-internal, test-internal, plugin, sources, docs, pom]
[debug] validate = true
[debug] refresh = false
[debug] resolving dependencies for configuration 'compile'
...
{% endhighlight %}
<h4 id="printwarnings">Display warnings from the previous compilation</h4>
The Scala compiler does not print the full details of warnings by default.
Compiling code that uses the deprecated `error` method from Predef might generate the following output:
{% highlight console %}
> compile
[info] Compiling 1 Scala source to <...>/classes...
[warn] there were 1 deprecation warnings; re-run with -deprecation for details
[warn] one warning found
{% endhighlight %}
The details aren't provided, so it is necessary to add `-deprecation` to the options passed to the compiler (`scalacOptions`) and recompile.
An alternative when using Scala 2.10 and later is to run `print-warnings`.
This task will display all warnings from the previous compilation.
For example,
{% highlight console %}
> print-warnings
[warn] A.scala:2: method error in object Predef is deprecated: Use sys.error(message) instead
[warn] def x = error("Failed.")
[warn] ^
{% endhighlight %}
<h4 id="level">Change the logging level globally</h4>
The amount of logging is controlled by the `logLevel` setting, which takes values from the `Level` enumeration.
Valid values are `Error`, `Warn`, `Info`, and `Debug` in order of increasing verbosity.
To change the global logging level, set `logLevel in Global`.
For example, to set it temporarily from the sbt prompt,
{% highlight console %}
> set logLevel in Global := Level.Warn
{% endhighlight %}
<h4 id="tasklevel">Change the logging level for a specific task, configuration, or project</h4>
The amount of logging is controlled by the `logLevel` setting, which takes values from the `Level` enumeration.
Valid values are `Error`, `Warn`, `Info`, and `Debug` in order of increasing verbosity.
The logging level may be configured globally, as described in the previous section, or it may be applied to a specific project, configuration, or task.
For example, to change the logging level for compilation to only show warnings and errors:
{% highlight console %}
> set logLevel in compile := Level.Warn
{% endhighlight %}
To enable debug logging for all tasks in the current project,
{% highlight console %}
> set logLevel := Level.Warn
{% endhighlight %}
A common scenario is that after running a task, you notice that you need more information than was shown by default.
A `logLevel` based solution typically requires changing the logging level and running a task again.
However, there are two cases where this is unnecessary.
First, warnings from a previous compilation may be displayed using `print-warnings` for the main sources or `test:print-warnings` for test sources.
Second, output from the previous execution is available either for a single task or for in its entirety.
See the section on [print-warnings] and the sections on [previous output].
<h4 id="trace">Configure printing of stack traces</h4>
By default, sbt hides the stack trace of most exceptions thrown during execution.
It prints a message that indicates how to display the exception.
However, you may want to show more of stack traces by default.
The setting to configure is `traceLevel`, which is a setting with an Int value.
When `traceLevel` is set to a negative value, no stack traces are shown.
When it is zero, the stack trace is displayed up to the first sbt stack frame.
When positive, the stack trace is shown up to that many stack frames.
For example, the following configures sbt to show stack traces up to the first sbt frame:
{% highlight console %}
> set every traceLevel := 0
{% endhighlight %}
The `every` part means to override the setting in all scopes.
To change the trace printing behavior for a single project, configuration, or task, scope `traceLevel` appropriately:
{% highlight console %}
> set traceLevel in Test := 5
> set traceLevel in update := 0
> set traceLevel in ThisProject := -1
{% endhighlight %}
<h4 id="nobuffer">Print the output of tests immediately instead of buffering</h4>
By default, sbt buffers the logging output of a test until the whole class finishes.
This is so that output does not get mixed up when executing in parallel.
To disable buffering, set the `logBuffered` setting to false:
{% highlight scala %}
logBuffered := false
{% endhighlight %}
<h4 id="custom">Add a custom logger</h4>
The setting `extraLoggers` can be used to add custom loggers.
A custom logger should implement [AbstractLogger].
`extraLoggers` is a function `ScopedKey[_] => Seq[AbstractLogger]`.
This means that it can provide different logging based on the task that requests the logger.
{% highlight scala %}
extraLoggers ~= { currentFunction =>
(key: ScopedKey[_]) => {
myCustomLogger(key) +: currentFunction(key)
}
}
{% endhighlight %}
Here, we take the current function for the setting `currentFunction` and provide a new function.
The new function prepends our custom logger to the ones provided by the old function.
<h4 id="log">Log messages in a task</h4>
The special task `streams` provides per-task logging and I/O via a [Streams] instance.
To log, a task maps the `streams` task and uses its `log` member:
{% highlight scala %}
myTask <<= (..., streams) map { (..., s) =>
s.log.warn("A warning.")
}
{% endhighlight %}

View File

@ -0,0 +1,60 @@
---
layout: howto
title: Project metadata
sections:
- id: name
name: set the project name
setting: name := "demo"
- id: version
name: set the project version
setting: version := "1.0"
- id: organization
name: set the project organization
setting: organization := "org.example"
- id: other
name: set the project homepage and other metadata used in a published pom.xml
---
A project should define `name` and `version`. These will be used in various parts of the build, such as the names of generated artifacts. Projects that are published to a repository should also override `organization`.
<h4 id="name">Set the project name</h4>
{% highlight scala %}
name := "Your project name"
{% endhighlight %}
For published projects, this name is normalized to be suitable for use as an artifact name and dependency ID. This normalized name is stored in `normalizedName`.
<h4 id="version">Set the project version</h4>
{% highlight scala %}
version := "1.0"
{% endhighlight %}
<h4 id="organization">Set the project organization</h4>
{% highlight scala %}
organization := "org.example"
{% endhighlight %}
By convention, this is a reverse domain name that you own, typically one specific to your project. It is used as a namespace for projects.
A full/formal name can be defined in the `organizationName` setting. This is used in the generated pom.xml. If the organization has a web site, it may be set in the `organizationHomepage` setting. For example:
{% highlight scala %}
organization := "Example, Inc."
organizationHomepage := "org.example"
{% endhighlight %}
<h4 id="other">Set the project's homepage and other metadata</h4>
{% highlight scala %}
homepage := Some(url("http://scala-sbt.org"))
startYear := Some(2008)
description := "A build tool for Scala."
licenses += "GPLv2" -> "http://www.gnu.org/licenses/gpl-2.0.html"
{% endhighlight %}

View File

@ -0,0 +1,78 @@
---
layout: howto
title: Configure packaging
sections:
- id: export
name: use the packaged jar on classpaths instead of class directory
setting: exportJars := true
- id: manifest
name: add manifest attributes
setting: 'packageOptions in (Compile, packageBin) += Package.ManifestAttributes( Attributes.Name.SEALED -> "true" )'
- id: name
name: change the file name of a package
- id: contents
name: modify the contents of the package
setting: 'mappings in (Compile, packageBin) <+= baseDirectory { dir => ( dir / "example.txt") -> "out/example.txt" }'
---
[mapping files]: https://github.com/harrah/xsbt/wiki/Mapping-Files
[Artifacts]: https://github.com/harrah/xsbt/wiki/Artifacts
<h4 id="export">Use the packaged jar on classpaths instead of class directory</h4>
By default, a project exports a directory containing its resources and compiled class files. Set `exportJars` to true to export the packaged jar instead. For example,
{% highlight scala %}
exportJars := true
{% endhighlight %}
The jar will be used by `run`, `test`, `console`, and other tasks that use the full classpath.
<h4 id="manifest">Add attributes to the manifest</h4>
By default, sbt constructs a manifest for the binary package from settings such as `organization` and `mainClass`. Additional attributes may be added to the `packageOptions` setting scoped by the configuration and package task.
Main attributes may be added with `Package.ManifestAttributes`. There are two variants of this method, once that accepts repeated arguments that map an attribute of type `java.util.jar.Attributes.Name` to a String value and other that maps attribute names (type String) to the String value.
For example,
{% highlight scala %}
packageOptions in (Compile, packageBin) +=
Package.ManifestAttributes( java.util.jar.Attributes.Name.SEALED -> "true" )
{% endhighlight %}
Other attributes may be added with `Package.JarManifest`.
{% highlight scala %}
packageOptions in (Compile, packageBin) += {
import java.util.jar.{Attributes, Manifest}
val manifest = new Manifest
manifest.getAttributes("foo/bar/").put(Attributes.Name.SEALED, "false")
Package.JarManifest( manifest )
}
{% endhighlight %}
Or, to read the manifest from a file:
{% highlight scala %}
packageOptions in (Compile, packageBin) += {
val manifest = Using.fileInputStream( in => new java.util.jar.Manifest(in) )
Package.JarManifest( manifest )
}
{% endhighlight %}
<h4 id="name">Change the file name of a package</h4>
The `artifactName` setting controls the name of generated packages. See the [Artifacts] page for details.
<h4 id="contents">Modify the contents of the package</h4>
The contents of a package are defined by the `mappings` task, of type `Seq[(File,String)]`. The `mappings` task is a sequence of mappings from a file to include in the package to the path in the package. See the page on [mapping files] for convenience functions for generating these mappings. For example, to add the file `in/example.txt` to the main binary jar with the path "out/example.txt",
{% highlight scala %}
mappings in (Compile, packageBin) <+= baseDirectory { base =>
(base / "in" / "example.txt") -> "out/example.txt"
}
{% endhighlight %}
Note that `mappings` is scoped by the configuration and the specific package task. For example, the mappings for the test source package are defined by the `mappings in (Test, packageSrc)` task.

View File

@ -0,0 +1,70 @@
---
layout: howto
title: Running commands
sections:
- id: batch
name: pass arguments to a command or task in batch mode
batch: 'clean "test-only org.example.Test" "run-main demo.Main a b c"'
- id: multi
name: provide multiple commands to run consecutively
command: ';clean ;compile'
- id: read
name: read commands from a file
command: '< /path/to/file'
- id: alias
name: define an alias for a command or task
command: 'alias h=help'
- id: eval
name: quickly evaluate a Scala expression
command: 'eval 2+2'
---
<h4 id="batch">Pass arguments to a command in batch mode</h4>
sbt interprets each command line argument provided to it as a command together with the command's arguments.
Therefore, to run a command that takes arguments in batch mode, quote the command and its arguments.
For example,
$ sbt 'project X' clean '~ compile'
<h4 id="multi">Provide several commands to run consecutively </h4>
Multiple commands can be scheduled at once by prefixing each command with a semicolon.
This is useful for specifying multiple commands where a single command string is accepted.
For example, the syntax for triggered execution is `~ <command>`.
To have more than one command run for each triggering, use semicolons.
For example, the following runs `clean` and then `compile` each time a source file changes:
> ~ ;clean;compile
<h4 id="read">Read commands from a file</h4>
The `<` command reads commands from the files provided to it as arguments. Run `help <` at the sbt prompt for details.
<h4 id="alias">Set, unset, and show aliases for commands</h4>
The `alias` command defines, removes, and displays aliases for commands. Run `help alias` at the sbt prompt for details.
Example usage:
> alias a=about
> alias
a = about
> a
[info] This is sbt ...
> alias a=
> alias
> a
[error] Not a valid command: a ...
<h4 id="eval">Quickly evaluate a Scala expression</h4>
The `eval` command compiles and runs the Scala expression passed to it as an argument.
The result is printed along with its type.
For example,
> eval 2+2
4: Int
Variables defined by an `eval` are not visible to subsequent `eval`s, although changes to system properties persist and affect the JVM that is running sbt.
Use the Scala REPL (`console` and related commands) for full support for evaluating Scala code interactively.

136
src/jekyll/howto/scala.md Normal file
View File

@ -0,0 +1,136 @@
---
layout: howto
title: Configure and use Scala
sections:
- id: version
name: set the Scala version used for building the project
setting: version := "1.0"
- id: noauto
name: disable the automatic dependency on the Scala library
setting: autoScalaLibrary := false
- id: temporary
name: temporarily switch to a different Scala version
command: ++ 2.8.2
- id: local
name: use a local Scala installation for building a project
setting: scalaHome := Some(file("/path/to/scala/home/"))
- id: cross
name: build a project against multiple Scala versions
- id: console-quick
name: enter the Scala REPL with a project's dependencies on the classpath, but not the compiled project classes
command: console-quick
- id: console
name: enter the Scala REPL with a project's dependencies and compiled code on the classpath
command: console
- id: console-project
name: enter the Scala REPL with plugins and the build definition on the classpath
command: console-project
- id: initial
name: define the initial commands evaluated when entering the Scala REPL
setting: initialCommands in console := """println("Hi!")"""
- id: embed
name: use the Scala REPL from project code
---
[console-project]: https://github.com/harrah/xsbt/wiki/Console-Project
[cross building]: https://github.com/harrah/xsbt/wiki/Cross-Build
[original proposal]: https://gist.github.com/404272
By default, sbt's interactive mode is started when no commands are provided on the command line or when the `shell` command is invoked.
<h4 id="version">Set the Scala version used for building the project</h4>
The `scalaVersion` configures the version of Scala used for compilation. By default, sbt also adds a dependency on the Scala library with this version. See the next section for how to disable this automatic dependency. If the Scala version is not specified, the version sbt was built against is used. It is recommended to explicitly specify the version of Scala.
For example, to set the Scala version to "2.9.2",
{% highlight scala %}
scalaVersion := "2.9.2"
{% endhighlight %}
<h4 id="noauto">Disable the automatic dependency on the Scala library</h4>
sbt adds a dependency on the Scala standard library by default. To disable this behavior, set the `autoScalaLibrary` setting to false.
{% highlight scala %}
autoScalaLibrary := false
{% endhighlight %}
<h4 id="temporary">Temporarily switch to a different Scala version</h4>
To set the Scala version in all scopes to a specific value, use the `++` command. For example, to temporarily use Scala 2.8.2, run:
> ++ 2.8.2
<h4 id="local">Use a local Scala version</h4>
Defining the `scalaHome` setting with the path to the Scala home directory will use that Scala installation. sbt still requires `scalaVersion` to be set when a local Scala version is used. For example,
{% highlight scala %}
scalaVersion := "2.10.0-local"
scalaHome := Some(file("/path/to/scala/home/"))
{% endhighlight %}
<h4 id="cross">Build a project against multiple Scala versions</h4>
See [cross building].
<h4 id="console-quick">Enter the Scala REPL with a project's dependencies on the classpath, but not the compiled project classes</h4>
The `console-quick` action retrieves dependencies and puts them on the classpath of the Scala REPL. The project's sources are not compiled, but sources of any source dependencies are compiled. To enter the REPL with test dependencies on the classpath but without compiling test sources, run `test:console-quick`. This will force compilation of main sources.
<h4 id="console">Enter the Scala REPL with a project's dependencies and compiled classes on the classpath</h4>
The `console` action retrieves dependencies and compiles sources and puts them on the classpath of the Scala REPL. To enter the REPL with test dependencies and compiled test sources on the classpath, run `test:console`.
<h4 id="console-project">Enter the Scala REPL with plugins and the build definition on the classpath</h4>
> console-project
For details, see the [console-project] page.
<h4 id="initial">Define the initial commands evaluated when entering the Scala REPL</h4>
Set `initialCommands in console` to set the initial statements to evaluate when `console` and `console-quick` are run. To configure `console-quick` separately, use `initialCommands in consoleQuick`.
For example,
{% highlight scala %}
initialCommands in console := """println("Hello from console")"""
initialCommands in consoleQuick := """println("Hello from console-quick")"""
{% endhighlight %}
The `console-project` command is configured separately by `initialCommands in consoleProject`. It does not use the value from `initialCommands in console` by default. For example,
{% highlight scala %}
initialCommands in consoleProject := """println("Hello from console-project")"""
{% endhighlight %}
<h4 id="embed">Use the Scala REPL from project code</h4>
sbt runs tests in the same JVM as sbt itself and Scala classes are not in the same class loader as the application classes. This is also the case in `console` and when `run` is not forked. Therefore, when using the Scala interpreter, it is important to set it up properly to avoid an error message like:
Failed to initialize compiler: class scala.runtime.VolatileBooleanRef not found.
** Note that as of 2.8 scala does not assume use of the java classpath.
** For the old behavior pass -usejavacp to scala, or if using a Settings
** object programmatically, settings.usejavacp.value = true.
The key is to initialize the Settings for the interpreter using _embeddedDefaults_. For example:
{% highlight scala %}
val settings = new Settings
settings.embeddedDefaults[MyType]
val interpreter = new Interpreter(settings, ...)
{% endhighlight %}
Here, MyType is a representative class that should be included on the interpreter's classpath and in its application class loader. For more background, see the [original proposal] that resulted in _embeddedDefaults_ being added.
Similarly, use a representative class as the type argument when using the _break_ and _breakIf_ methods of _ILoop_, as in the following example:
{% highlight scala %}
def x(a: Int, b: Int) = {
import scala.tools.nsc.interpreter.ILoop
ILoop.breakIf[MyType](a != b, "a" -> a, "b" -> b )
}
{% endhighlight %}

View File

@ -0,0 +1,64 @@
---
layout: howto
title: Triggered execution
sections:
- id: basic
name: run a command when sources change
command: '~ test'
- id: multi
name: run multiple commands when sources change
command: '~ ;a ;b'
- id: sources
name: configure the sources that are checked for changes
setting: 'watchSources <+= baseDirectory { _ / "examples.txt" }'
- id: interval
name: set the time interval between checks for changes to sources
setting: 'pollInterval := 1000 // in ms'
---
<h4 id="basic">Run a command when sources change</h4>
You can make a command run when certain files change by prefixing the command with `~`. Monitoring is terminated when `enter` is pressed. This triggered execution is configured by the `watch` setting, but typically the basic settings `watch-sources` and `poll-interval` are modified as described in later sections.
The original use-case for triggered execution was continuous compilation:
{% highlight scala %}
> ~ test:compile
> ~ compile
{% endhighlight %}
You can use the triggered execution feature to run any command or task, however. The following will poll for changes to your source code (main or test) and run `test-only` for the specified test.
{% highlight scala %}
> ~ test-only example.TestA
{% endhighlight %}
<h4 id="multi">Run multiple commands when sources change</h4>
The command passed to `~` may be any command string, so multiple commands may be run by separating them with a semicolon. For example,
{% highlight scala %}
> ~ ;a ;b
{% endhighlight %}
This runs `a` and then `b` when sources change.
<h4 id="sources">Configure the sources checked for changes</h4>
* `watchSources` defines the files for a single project that are monitored for changes. By default, a project watches resources and Scala and Java sources.
* `watchTransitiveSources` then combines the `watchSources` for the current project and all execution and classpath dependencies (see [Full Configuration] for details on inter-project dependencies).
To add the file `demo/example.txt` to the files to watch,
{% highlight scala %}
watchSources <+= baseDirectory { _ / "demo" / "examples.txt" }
{% endhighlight %}
<h4 id="interval">Configure the polling time</h4>
`pollInterval` selects the interval between polling for changes in milliseconds. The default value is `500 ms`. To change it to `1 s`,
{% highlight scala %}
pollInterval := 1000 // in ms
{% endhighlight %}

374
src/jekyll/index.html Normal file
View File

@ -0,0 +1,374 @@
---
layout: none
title: simple build tool
tagline: is a minimally intrusive<br/> build tool for <a href="http://www.scala-lang.org/" class="scala" target="_blank">Scala</a> projects
description: ''
---
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html"; charset="utf-8">
<title>simple build tool</title>
<link href='http://fonts.googleapis.com/css?family=Copse' rel='stylesheet' type='text/css'>
<link href='/resources/site.css' rel='stylesheet' type='text/css'> <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js">
</script>
</head>
<body class="cf">
{% include topbar.txt %}
<div id="container" class="cf">
<div id="intro">
<div id="head" class="contained cf">
<div id="name" class="left">
<h1>sbt</h1>
<h2>simple build tool</h2>
<p id="what">
is a minimally intrusive<br/> build tool for <a href="http://www.scala-lang.org/" class="scala" target="_blank">Scala</a> projects
</p>
</div>
<div class="left" id="vc">
<div id="start">Start <em>Building</em></div>
<div id="install-primary">
<button class="btn download" data-jar="download.html" id="get-launcher-primary"><span></span> Download</button> the latest version
</div>
<div id="install-extra">Click <a id="install-info-toggle" href="#">here</a> for install instructions</div>
</div>
</div>
<div id="install-info">
<div id="install-info-content">
Are you a <a href="#" id="show-nix">unix/osx</a> or a <a href="#" id="show-win">Windows</a> user?
<div id="nix">
<p>
If you are running an unix-based operating system, open your terminal shell and enable execute permisions on the <a href="https://raw.github.com/sbt/sbt-launcher-package/full-packaging/sbt">sbt script</a>
</p>
<pre><code>$ chmod u+x sbt</code></pre>
<p>
Then run the install command to get the latest
</P>
<pre><code>$ sbt</code></pre>
<p>
Afterwards you can run the sbt command in any directory to create a new project.
</p>
</div>
<div id="win">
If you're feeling adventurous, try our <a href="http://typesafe.artifactoryonline.com/typesafe/windows-releases/org/scalasbt/sbt/0.11.2/sbt.msi">MSI installer</a>.
</div>
<div class="controls"><button id="hide-install-info" class="btn">Hide this</button></div>
</div>
</div>
<div id="features" class="cf">
<div id="feature-list" class="contained">
<ul class="left">
<li>
<a href="#repl">Fast, transparent REPL workflow</a>
</li>
<li>
<a href="#scripted">Scala-scripted configuration</a>
</li>
<li>
<a href="#plugins">Flexible plugin architecture</a>
</li>
<li>
<a href="#compilation">Continuous incremental compilation</a>
</li>
<li>
<a href="#trigger">Triggered task execution</a>
</li>
</ul>
<ul class="left">
<li>
<a href="#cross-compile">Cross-Scala version compilation</a>
</li>
<li>
<a href="#testing">Out of the box testing with ScalaCheck, Specs, and ScalaTest</a>
</li>
<li>
<a href="#multi-project">Multi-module and external project support</a>
</li>
<li>
<a href="#parallel">Parallel task and test execution</a>
</li>
<li>
<a href="#dependency-man">Concise dependency management DSL</a>
</li>
</ul>
</div>
</div>
</div>
<div id="extra">
<ul id="examples">
<li id="repl" class="feature">
<h3>Say hi to the REPL.</h3>
<div class="more">
<div class="line">
<pre><code>$ sbt
> hello_</code></pre>
</div>
<div class="line">
<p>
From the REPL you can execute project tasks and inspect settings
</p>
</div>
<div class="line">
<pre><code>> compile
[info] Compiling 1 Scala source to ...
[success] Total time: 1 s, completed Aug 21, 2011 7:34:52 PM</code></pre>
</div>
<div class="line">
<p>
All settings and commands are tab-completable for fast, easy access
</p>
</div>
<div class="line">
<pre><code>> show &lt;tab&gt;
Display all 153 possibilities? (y or n) </code></pre>
</div>
</div>
<div class="ita">
<a href="#scripted" class="st">Is that all?</a>
</div>
</li>
<li id="scripted" class="feature">
<h3>Typesafety is a given.</h3>
<div class="more">
<div class="line">
<p>
All project configuration is scripted in Scala providing out of the box modularity and all of the flexibility of the Scala programming language.
</p>
</div>
<div class="line">
<pre><code>override lazy val settings = super.settings :+
(shellPrompt := { s => Project.extract(s).cid + "> " })</code></pre>
</div>
<div class="line">
<p>
Simple projects will only require a simple configuration in <code>.sbt</code> format.
</p>
</div>
<div class="line">
<pre><code>organization := "com.your.domain"
name := "your-module"
version := "0.1.3"
libraryDependencies += "com.other.domain" %% "other-module" % "1.0"
</code></pre>
</div>
</div>
<div class="ita">
<a href="#plugins" class="st">Is that all?</a>
</div>
</li>
<li id="plugins" class="feature">
<h3>Simple Extensibility.</h3>
<div class="more">
<div class="line">
<p>
Plugins provide a means of injecting and augmenting settings and commands. Since plugins are just Scala code, you can package and share plugins between projects.
</p>
</div>
<div class="line">
<pre><code>object MyPlugin extends Plugin {
val MyConf = config("my")
override def settings: Seq[Setting[_]] = inConfig(MyConf)(Seq(
// ...
))
}</code></pre>
</div>
</div>
<div class="ita">
<a href="#compilation" class="st">Is that all?</a>
</div>
</li>
<li id="compilation" class="feature">
<h3>Only what you need.</h3>
<div class="more">
<div class="line">
<p>
Sbt will only compile source code that has changed and when necessary. Why wait around for something to be recompiled when you can be doing more productive work?
</p>
</div>
<div class="line">
<pre><code>> compile
[info] Compiling 1 Scala source to ...
[success] Total time: 1 s, completed Aug 21, 2011 7:34:52 PM
> compile
[success] Total time: 1 s, completed Aug 21, 2011 7:34:54 PM
</code></pre>
</div>
</div>
<div class="ita">
<a href="#trigger" class="st">Is that all?</a>
</div>
</li>
<li id="trigger" class="feature">
<h3>Do repeat yourself.</h3>
<div class="more">
<div class="line">
<p>
All build tasks and commands can be re-triggered when dependent source code changes by prepending the <code>~</code> modifier, leaving you free to focus on your craft and not on life-wasting repetition.
</p>
</div>
<div class="line">
<pre><code>> ~ test</code></pre>
</div>
</div>
<div class="ita">
<a href="#cross-compile" class="st">Is that all?</a>
</div>
</li>
<li id="cross-compile" class="feature">
<h3>Fluency in many dialects.</h3>
<div class="more">
<div class="line">
<p>
Scala is a fast evolving and forward thinking language which, in the past, has led to binary incompatibility between versions. Sbt makes it simple to switch between and execute commands against your Scala source code over many versions of Scala with ease.
</p>
</div>
<div class="line">
<pre><code>> + compile</code></pre>
</div>
</div>
<div class="ita">
<a href="#testing" class="st">Is that all?</a>
</div<
</li>
<li id="testing" class="feature">
<h3>Many frameworks. One test interface.</h3>
<div class="more">
<div class="line">
<p>
For some, testing is an afterthought. Sbt makes testing part of your normal workflow by providing a generic interface to validate your code against any supporting testing library.
</p>
</div>
<div class="line">
<pre><code>> test-only your.EasySpec</code></pre>
</div>
</div>
<div class="ita">
<a href="#multi-project" class="st">Is that all?</a>
</div>
</li>
<li id="multi-project" class="feature">
<h3>There's room for more in here.</h3>
<div class="more">
<div class="line">
<p>
When it's time to make the split, Sbt makes it easy to coordinate multiple projects in one simple build file.
</p>
</div>
<div class="line">
<pre><code>object YourBuild extends Build {
lazy val root = Project(".", file("."), settings = Seq(..)) aggregate(a, b)
lazy val b = Project("b", file("b"))
lazy val c = Project("c", file("c")) dependsOn(b)
}</code></pre>
</div>
</div>
<div class="ita">
<a href="#parallel" class="st">Is that all?</a>
</div>
</li>
<li id="parallel" class="feature">
<h3>Why wait?</h3>
<div class="more">
<div class="line">
<p>
By default, build tasks that do not depend on one another execute in parallel. This also applies to your tests. Instead of sequentially executing your tests, Sbt will run them in parallel.
...something about parallel task execution...
</p>
</div>
<div class="line">
<pre><code>/* fill me in */</code></pre>
</div>
</div>
<div class="ita">
<a href="#dependency-man" class="st">Is that all?</a>
</div>
</li>
<li id="dependency-man" class="feature">
<h3>Simply dependable.</h3>
<div class="more">
<div class="line">
<p>
Close your eyes. Now open them. You no longer have to manage your dependencies in XML. Use a simple declarative DSL to add dependencies and sbt takes care of the rest.
</p>
</div>
<div class="line">
<pre><code>libraryDependencies ++= Seq(
"com.scalaproject" %% "module-a" % "1.4.7",
"com.javaproject" % "module-b" % "2.1.0"
)</code></pre>
</div>
</div>
<div class="ita">
<a href="#intro" class="st">Is that all?</a>
</div>
</li>
</ul>
<div id="foot">
<div class="content"/>
</div>
</div>
</div>
<script type="text/javascript" src="jquery.scrollto.min.js"></script>
<script type="text/javascript">
(function($){ $(function(){
$('#more-hand').click(function() {
var self = $(this);
$('#info').slideToggle('fast', function() {
self.text('↬ ' + (/more/.test(self.text()) ? "less":"more"));
});
});
$("#top").click(function(){ $("#intro").ScrollTo(); })
var applyH = function() {
$("#intro, .feature").height($(window).height());
};
$(window).bind('resize', function() { applyH(); });
applyH();
$("#get-launcher-primary").bind('click', function(e) {
window.location.href= $(this).data()['jar'];
})
$('#features a, .st').click(function(e){
e.preventDefault();
var h = $(this).attr('href');
$(h).ScrollTo({
callback:function(){ window.location.hash = h;}
});
});
$("#install-info-toggle, #hide-install-info").bind('click', function(){
$('#install-info-content').slideToggle('fast', function() {
$('#nix, #win').hide();
});
});
$('#show-nix').bind('click', function(){
$('#win').hide();
$('#nix').show();
});
$('#show-win').bind('click', function(){
$('#nix').hide();
$('#win').show();
});
});})(jQuery);
</script>
</body>
</html>

6
src/jekyll/jquery.scrollto.min.js vendored Normal file
View File

@ -0,0 +1,6 @@
/*
GNU Affero General Public License version 3 {@link http://www.gnu.org/licenses/agpl-3.0.html}
*/
(function(b){if(b.ScrollTo)window.console.warn("$.ScrollTo has already been defined...");else{b.ScrollTo={config:{duration:400,easing:"swing",callback:undefined,durationMode:"each"},configure:function(c){b.extend(b.ScrollTo.config,c||{});return this},scroll:function(c,d){var f=b.ScrollTo,a=c.pop(),e=a.$container,g=a.$target;a=b("<span/>").css({position:"absolute",top:"0px",left:"0px"});var h=e.css("position");e.css("position","relative");a.appendTo(e);var i=a.offset().top;g=g.offset().top-i;a.remove();
e.css("position",h);e.animate({scrollTop:g+"px"},d.duration,d.easing,function(j){if(c.length===0)typeof d.callback==="function"&&d.callback.apply(this,[j]);else f.scroll(c,d);return true});return true},fn:function(c){var d=b.ScrollTo,f=b(this);if(f.length===0)return this;var a=f.parent(),e=[];for(config=b.extend({},d.config,c);a.length===1&&!a.is("body")&&a.get(0)!==document;){c=a.get(0);if(a.css("overflow-y")!=="visible"&&c.scrollHeight!==c.clientHeight){e.push({$container:a,$target:f});f=a}a=a.parent()}e.push({$container:b(b.browser.msie?
"html":"body"),$target:f});if(config.durationMode==="all")config.duration/=e.length;d.scroll(e,config);return this},construct:function(c){var d=b.ScrollTo;b.fn.ScrollTo=d.fn;d.config=b.extend(d.config,c);return this}};b.ScrollTo.construct()}})(jQuery);

21
src/jekyll/learn.md Normal file
View File

@ -0,0 +1,21 @@
---
layout: default
title: Learning SBT
tagline: From Basics to Wizardry
description: |
We highly recommend trying the [Getting Started Guide](https://github.com/harrah/xsbt/wiki/Getting-Started-Welcome)
before diving into sbt. There are also a lot of great introductory [talks](talks.html) available for your viewing pleasure.
toplinks:
- name: 'Getting Started Guide'
link: 'https://github.com/harrah/xsbt/wiki/Getting-Started-Welcome'
- name: 'How to ...'
link: 'howto.html'
- name: 'Talks'
link: 'talks.html'
- name: 'Wiki'
link: 'https://github.com/harrah/xsbt/wiki'
- name: 'Plugins'
link: 'plugins.html'
- name: 'FAQ'
link: 'https://github.com/harrah/xsbt/wiki/FAQ'
---

109
src/jekyll/plugins.html Normal file
View File

@ -0,0 +1,109 @@
---
layout: default
title: Plugins
tagline: There's a plugin for that.
description: |
SBT has a rich community of plugins contributed by a set of very amazing people.
toplinks:
- name: 'IDEs'
id: 'ides'
content: |
* IntelliJ IDEA
* [SBT Plugin to generate IDEA project configuration](https://github.com/mpeltonen/sbt-idea)
* [IDEA Plugin to embed an SBT Console into the IDE](https://github.com/orfjackal/idea-sbt-plugin)
* [Netbeans](https://github.com/remeniuk/sbt-netbeans-plugin)
* [Eclipse](https://github.com/typesafehub/sbteclipse)
- name: 'Web'
id: 'web'
content: |
* [xsbt-web-plugin](https://github.com/siasia/xsbt-web-plugin)
* [xsbt-webstart](https://github.com/ritschwumm/xsbt-webstart)
* [sbt-appengine](https://github.com/sbt/sbt-appengine)
* [sbt-gwt-plugin](https://github.com/thunderklaus/sbt-gwt-plugin)
* [sbt-cloudbees-plugin](https://github.com/timperrett/sbt-cloudbees-plugin)
* [coffeescripted-sbt](https://github.com/softprops/coffeescripted-sbt)
* [less-sbt](https://github.com/softprops/less-sbt)
* [sbt-emberjs](https://github.com/stefri/sbt-emberjs)
* [sbt-closure](https://github.com/eltimn/sbt-closure)
- name: 'Testing'
id: 'test'
content: |
* [junit_xml_listener](https://github.com/ijuma/junit_xml_listener)
* [sbt-growl-plugin](https://github.com/softprops/sbt-growl-plugin)
* [sbt-teamcity-test-reporting-plugin](https://github.com/guardian/sbt-teamcity-test-reporting-plugin)
* [xsbt-cucumber-plugin](https://github.com/skipoleschris/xsbt-cucumber-plugin)
* [sbt-scct](https://github.com/dvc94ch/sbt-scct)
* [jacoco4sbt](https://bitbucket.org/jmhofer/jacoco4sbt)
- name: 'Static Code Analysis'
id: 'staticcode'
content: |
* [cpd4sbt](https://bitbucket.org/jmhofer/cpd4sbt) (copy/paste detection, works for Scala, too)
* [findbugs4sbt](https://bitbucket.org/jmhofer/findbugs4sbt) (FindBugs only supports Java projects atm)
- name: 'One Jar'
id: 'onejar'
content: |
* [sbt-assembly](https://github.com/sbt/sbt-assembly)
* [xsbt-proguard-plugin](https://github.com/siasia/xsbt-proguard-plugin)
* [sbt-deploy](https://github.com/reaktor/sbt-deploy)
* [sbt-appbundle](https://github.com/sbt/sbt-appbundle)
- name: 'Graphics'
id: 'lwjgl'
content: |
* [sbt-lwjgl-plugin](https://github.com/philcali/sbt-lwjgl-plugin) - LWJGL (LightWeight Java Game Library)
- name: 'Release'
id: 'release'
content: |
* [posterous-sbt](https://github.com/n8han/posterous-sbt)
* [sbt-signer-plugin](https://github.com/rossabaker/sbt-signer-plugin)
* [sbt-izpack](http://software.clapper.org/sbt-izpack/) (generates IzPack an installer)
* [sbt-pgp-plugin](https://github.com/sbt/xsbt-gpg-plugin) (PGP signing plugin, can generate keys too)
* [sbt-release](https://github.com/gseitz/sbt-release) (customizable release process)
- name: 'System'
id: 'system'
content: |
* [sbt-sh](https://github.com/steppenwells/sbt-sh) (executes shell commands)
* [cronish-sbt](https://github.com/philcali/cronish-sbt) (interval sbt / shell command execution)
* [git](https://github.com/sbt/sbt-git-plugin) (executes git commands)
- name: 'Code Generator'
id: 'codegen'
content: |
* [sbt-scalaxb](https://github.com/eed3si9n/scalaxb) (XSD and WSDL binding)
* [sbt-protobuf](https://github.com/gseitz/sbt-protobuf) (Google Protocol Buffers)
* [sbt-avro](https://github.com/cavorite/sbt-avro) (Apache Avro)
* [sbt-xjc](https://github.com/retronym/sbt-xjc) (XSD binding, using [JAXB XJC](http://download.oracle.com/javase/6/docs/technotes/tools/share/xjc.html))
* [xsbt-scalate-generate](https://github.com/mojolly/xsbt-scalate-generate) (Generate/Precompile Scalate Templates)
* [sbt-antlr](https://github.com/stefri/sbt-antlr) (Generate Java source code based on ANTLR3 grammars)
* [xsbt-reflect](https://github.com/ritschwumm/xsbt-reflect) (Generate Scala source code for project name and version)
* [lifty](https://github.com/lifty/lifty) (Brings scaffolding to SBT)
* [sbt-thrift](https://github.com/bigtoast/sbt-thrift) (Thrift Code Generation)
* [xsbt-hginfo](https://bitbucket.org/lukas_pustina/xsbt-hginfo) (Generate Scala source code for Mercurial repository information)
- name: 'Database'
id: 'db'
content: |
* [sbt-liquibase](https://github.com/bigtoast/sbt-liquibase) (Liquibase RDBMS database migrations)
- name: 'Documentation'
id: 'docs'
content: |
* [sbt-ghpages-plugin](https://github.com/jsuereth/xsbt-ghpages-plugin) (publishes generated site and api)
* [sbt-lwm](http://software.clapper.org/sbt-lwm/) (Convert lightweight markup files, e.g., Markdown and Textile, to HTML)
- name: 'Utility'
id: 'utility'
content: |
* [jot](https://github.com/softprops/jot) (Write down your ideas lest you forget them)
* [ls-sbt](https://github.com/softprops/ls) (An sbt interface for ls.implicit.ly)
* [np](https://github.com/softprops/np) (Dead simple new project directory generation)
* [sbt-editsource](http://software.clapper.org/sbt-editsource/) (A poor man's *sed*(1), for SBT)
* [sbt-dirty-money](https://github.com/sbt/sbt-dirty-money) (Cleans Ivy2 cache)
* [sbt-dependency-graph](https://github.com/jrudolph/sbt-dependency-graph) (Creates a graphml file of the dependency tree)
* [sbt-inspectr](https://github.com/eed3si9n/sbt-inspectr) (Displays settings dependency tree)
* [sbt-revolver](https://github.com/spray/sbt-revolver) (Triggered restart, hot reloading)
* [sbt-scalaedit](https://github.com/kjellwinblad/sbt-scalaedit-plugin) (Open and upgrade ScalaEdit (text editor))
* [sbt-dropbox-plugin](https://github.com/jberkel/sbt-dropbox-plugin/) (Transfer files to Dropbox)
- name: 'Android'
id: 'android'
content: |
* [android-plugin](https://github.com/jberkel/android-plugin)
---

View File

@ -0,0 +1,15 @@
---
layout: content
title: Community Repository Policy
---
The community repository has the following guideline for artifacts published to it:
1. All pubished artifacts are the authors own work or have an appropriate license which grants distribution rights.
2. All published artifacts come from open source projects, that have an open patch acceptance policy.
3. All published artifacts are placed under an organization in a DNS domain for which you have the permission to use or are an owner (scala-sbt.org is available for SBT plugins).
4. All published artifacts are signed by a committer of the project (coming soon).

View File

@ -0,0 +1,284 @@
html,body,div,span,applet,object,iframe,h1,h2,h3,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video{margin:0;padding:0;border:0;font-size:100%;font:inherit;vertical-align:baseline}
ul {margin:0;border:0;font-size:100%;font:inherit;vertical-align:baseline}
code {padding:0;border:0;font-size:100%;vertical-align:baseline}
article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}
blockquote,q{quotes:none}
blockquote:before,blockquote:after,q:before,q:after{content:'';content:none}
table{border-collapse:collapse;border-spacing:0}
.cf:before,.cf:after{content:"";display:table}
.cf:after{clear:both}
.cf{zoom:1}
body, html {
font-family: sans-serif;
height:100%;
}
a:link, a:visited {
color:#2EABFF;/*15f*/
padding-left:4px;
text-decoration:none;
}
a.scala:link, a.scala:visited {
color:#FF0000;
}
p {
margin-bottom:.5em;
}
h1 { font-size:130px; line-height:1em; }
h2 { color:#bbb; font-size:2.5em; }
h3 { font-size:1.75em; line-height:1.5em; }
h4 { font:inherit; }
h4 { font-size:1.5em;margin:1.3em 0em 0.7em 0em;padding:0;border:0;vertical-align:baseline }
li { margin:0.5em 0; }
#more {
background:#576369; position:fixed;
left:0; right:0; top:0; z-index:9999;
padding:0 0 .25em 0;
font-family: 'Lucida Grande', 'Helvetica', sans-serif; /* for consistency with rest of site */
font-size:24px;
text-shadow:0 1px #333;
-moz-box-shadow:0px 2px 2px #ccc;
-webkit-box-shadow:0px 2px 2px #ccc;
box-shadow:0px 2px 2px #ccc;
filter: progid:DXImageTransform.Microsoft.Shadow(strength=2, direction=180, color='#cccccc');
-ms-filter: "progid:DXImageTransform.Microsoft.Shadow(strength=2, Direction=180, Color='#cccccc')";
}
#more-hand, #top { color:#eee; margin:.25em .5em 0 .5em; }
a#get-launcher:link, a#get-launcher:visited {
border-left:0;
-moz-box-shadow:0px 0px 4px #333333;
-webkit-box-shadow:0px 0px 4px #333333;
box-shadow:0px 0px 4px #333333;
}
#head, #feature-list, .feature h3, .feature .line, #foot .content, .ita, #install-info-content, .contained {
width:940px; margin:0 auto;
}
ul#section-toc {
list-style:none;
margin-bottom:2em;
}
#intro { padding:1em 0 0 0; text-align:left; height:100%; }
#head { border-bottom:1px solid #eee; }
#name { width:50%; }
#vc { }
.page-description { margin-top:100px; width: 50%;}
#start { font-size:50px; margin-top:100px; }
#start em { font-weight:bold; font-size:55px; }
#install-primary { margin-top:.75em;}
#install-extra { font-size: 70%; color:#bbb; margin-top:.5em; }
#install-info {
background:#576369
}
#install-info-content {
color:#eee;
display:none;
font-size:70%;
line-height:1.5em;
padding:1em 0;
text-shadow:0 1px #000;
}
#nix, #win {
display:none;
margin-top:1em;
}
#what { font-size:120%; line-height:1.4em; margin:0 0 1em 0; }
#features ul { list-style:none; }
#pagecontent { margin: 0 auto; width: 940px; }
#subscribe, #wiki, #src, #list { margin:0 0 .5em 0;}
#install {
float:right;
margin:.25em .5em 0 0;
}
.container-spacer { line-height: 40px; }
.download.btn span {
color:#fff;
text-shadow:0 1px #bbb;
}
.download.btn {
background:#83F537;
filter: progid:DXImageTransform.Microsoft.gradient(
startColorstr='#12E3FF', endColorstr='#28D7FA');
background: -webkit-gradient(linear, left top, left bottom,
from(#12E3FF), to(#28D7FA));
background: -moz-linear-gradient(top, #12E3FF, #28D7FA);
border:1px solid #28D7FA;
color:#333;
text-shadow:0 1px #eee;
}
.download.btn:hover {
background:#83F537;
filter: progid:DXImageTransform.Microsoft.gradient(
startColorstr='#4CD6F1', endColorstr='#00D4FF');
background: -webkit-gradient(linear, left top, left bottom,
from(#4CD6F1), to(#00D4FF));
background: -moz-linear-gradient(top, #4CD6F1, #00D4FF);
border:1px solid #28D7FA;
}
#more-hand { float:left; clear:both; }
#top { width:700px; margin:.25em auto; }
#top h3 a, #top .brand {
float: left;
display: block;
padding: 8px 20px 12px;
color: white;
font-size: 19px;
font-weight: 200;
line-height: 1;
}
#top a {
color: #BFBFBF;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
}
#top a:hover {
color:#fff;
}
#topbar div > ul a, .nav a {
display: block;
float: none;
padding: 6px 6px 7px;
line-height: 19px;
text-decoration: none;
margin-top:.2em;
}
#top div > ul > li, .nav > li {
display: block;
float: left;
}
#top div > ul, .nav {
padding: 0;
display: block;
float: left;
margin: 0 10px 0 0;
position: relative;
left: 0;
list-style: disc;
}
.nav li {
margin: 0;
}
#top li {
font-size: 14px;
}
#info { display:none; }
#info a { padding-left: .25em; }
#extra { height: 100%; }
#examples {
font-size:.9em;
margin:.5em 0 0 0;
line-height:1.5em;
}
.ita {
text-align:right;
}
#foot {
background: #576369;
color:#eee;
font-size:smaller;
padding:1em 0;
}
.line {
margin:.5em 0 0 0;
padding:.25em 0;
}
.line p {
border-left:10px solid #eee;
padding-left:.5em;
}
.feature {
padding:1.5em .25em;
margin:1em auto;
}
.feature .more {
padding:.25em .25em 0 .25em;
}
#info-left { margin-right:1em; }
#info-left, #info-right { float: left; }
input[type="text"] {
font-family: 'Copse', serif;
font-size:22px; padding:.25em;
color:#bbb;
margin-left:5px;
}
.left {
float:left;
}
.btn {
border:1px solid #bbb;
background:#eee;
padding:.25em .5em;
font-size:18px;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
background: #eee;
text-shadow:0 1px #fff;
filter: progid:DXImageTransform.Microsoft.gradient(
startColorstr='#eeeeee', endColorstr='#D1D1D1');
background: -webkit-gradient(linear, left top,
left bottom, from(#eeeeee),
to(#D1D1D1));
background: -moz-linear-gradient(top, #eeeeee, #D1D1D1);
margin:5px 0;
}
pre {
white-space:pre-wrap;
font-size: 16px;
font-weight: normal;
margin:.7em 0;
padding: 6px 10px;
border:1px solid #bbb;
-webkit-border-radius: 4x;
-moz-border-radius: 4px;
border-radius: 4px;
color:rgb(48,48,48);
background-color:rgb(248, 248, 248);
}

View File

@ -0,0 +1,279 @@
html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video{margin:0;padding:0;border:0;font-size:100%;font:inherit;vertical-align:baseline}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:before,blockquote:after,q:before,q:after{content:'';content:none}table{border-collapse:collapse;border-spacing:0}
.cf:before,.cf:after{content:"";display:table}.cf:after{clear:both}.cf{zoom:1}
body, html {
font-family: 'Lucida Grande', 'Helvetica', sans-serif;
font-size:24px;
height:100%;
}
a:link, a:visited {
color:#2EABFF;/*15f*/
padding-left:4px;
text-decoration:none;
}
a.scala:link, a.scala:visited {
color:#FF0000;
}
p {
margin-bottom:.5em;
}
h1, h2, h3, h4, h5, #name, #vc { font-family: 'Copse', serif; }
h1 { font-size:130px; line-height:1em; }
h2 { color:#bbb; font-size:2.5em; }
h3 { font-size:2em; line-height:1.5em; }
h4 { font-size:1.75em; line-height:1.5em; }
li { margin:1em 0; }
#more {
background:#576369; position:fixed;
left:0; right:0; top:0; z-index:9999;
padding:0 0 .25em 0;
text-shadow:0 1px #333;
-moz-box-shadow:0px 2px 2px #ccc;
-webkit-box-shadow:0px 2px 2px #ccc;
box-shadow:0px 2px 2px #ccc;
filter: progid:DXImageTransform.Microsoft.Shadow(strength=2, direction=180, color='#cccccc');
-ms-filter: "progid:DXImageTransform.Microsoft.Shadow(strength=2, Direction=180, Color='#cccccc')";
}
#more-hand, #top { color:#eee; margin:.25em .5em 0 .5em; }
a#get-launcher:link, a#get-launcher:visited {
border-left:0;
-moz-box-shadow:0px 0px 4px #333333;
-webkit-box-shadow:0px 0px 4px #333333;
box-shadow:0px 0px 4px #333333;
}
#head, #feature-list, .feature h3, .feature .line, #foot .content, .ita, #install-info-content, .contained {
width:940px; margin:0 auto;
}
#features {
font-size: 80%;
margin:1em 0;
}
#intro { padding:2em 0 0 0; text-align:left; height:100%; }
#intro p { line-height:1.5em; }
#head { border-bottom:1px solid #eee; }
#name { width:50%; }
#vc { }
.page-description { margin-top:100px; width: 50%;}
#start { font-size:50px; margin-top:100px; }
#start em { font-weight:bold; font-size:55px; }
#install-primary { margin-top:.75em;}
#install-extra { font-size: 70%; color:#bbb; margin-top:.5em; }
#install-info {
background:#576369
}
#install-info-content {
color:#eee;
display:none;
font-size:70%;
line-height:1.5em;
padding:1em 0;
text-shadow:0 1px #000;
}
#nix, #win {
display:none;
margin-top:1em;
}
#what { font-size:120%; line-height:1.4em; margin:0 0 1em 0; }
#features ul { list-style:none; width:50%; }
#pagecontent { margin: 0 auto; width: 940px; }
#subscribe, #wiki, #src, #list { margin:0 0 .5em 0;}
#install {
float:right;
margin:.25em .5em 0 0;
}
.container-spacer { line-height: 40px; }
.download.btn span {
color:#fff;
text-shadow:0 1px #bbb;
}
.download.btn {
background:#83F537;
filter: progid:DXImageTransform.Microsoft.gradient(
startColorstr='#12E3FF', endColorstr='#28D7FA');
background: -webkit-gradient(linear, left top, left bottom,
from(#12E3FF), to(#28D7FA));
background: -moz-linear-gradient(top, #12E3FF, #28D7FA);
border:1px solid #28D7FA;
color:#333;
text-shadow:0 1px #eee;
}
.download.btn:hover {
background:#83F537;
filter: progid:DXImageTransform.Microsoft.gradient(
startColorstr='#4CD6F1', endColorstr='#00D4FF');
background: -webkit-gradient(linear, left top, left bottom,
from(#4CD6F1), to(#00D4FF));
background: -moz-linear-gradient(top, #4CD6F1, #00D4FF);
border:1px solid #28D7FA;
}
#more-hand { float:left; clear:both; }
#top { width:700px; margin:.25em auto; }
#top h3 a, #top .brand {
float: left;
display: block;
padding: 8px 20px 12px;
color: white;
font-size: 19px;
font-weight: 200;
line-height: 1;
}
#top a {
color: #BFBFBF;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
}
#top a:hover {
color:#fff;
}
#topbar div > ul a, .nav a {
display: block;
float: none;
padding: 6px 6px 7px;
line-height: 19px;
text-decoration: none;
margin-top:.2em;
}
#top div > ul > li, .nav > li {
display: block;
float: left;
}
#top div > ul, .nav {
display: block;
float: left;
margin: 0 10px 0 0;
position: relative;
left: 0;
list-style: disc;
}
.nav li {
margin: 0;
}
#top li {
font-size: 14px;
}
#info { display:none; }
#info a { padding-left: .25em; }
#extra { height: 100%; }
#examples {
font-size:.9em;
margin:.5em 0 0 0;
line-height:1.5em;
}
.ita {
text-align:right;
}
#foot {
background: #576369;
color:#eee;
font-size:smaller;
padding:1em 0;
}
.line {
margin:.5em 0 0 0;
padding:.25em 0;
}
.line p {
border-left:10px solid #eee;
padding-left:.5em;
}
.feature {
padding:1.5em .25em;
margin:1em auto;
}
.feature .more {
padding:.25em .25em 0 .25em;
}
#info-left { margin-right:1em; }
#info-left, #info-right { float: left; }
input[type="text"] {
font-family: 'Copse', serif;
font-size:22px; padding:.25em;
color:#bbb;
margin-left:5px;
}
.left {
float:left;
}
.btn {
border:1px solid #bbb;
background:#eee;
padding:.25em .5em;
font-size:18px;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
background: #eee;
text-shadow:0 1px #fff;
filter: progid:DXImageTransform.Microsoft.gradient(
startColorstr='#eeeeee', endColorstr='#D1D1D1');
background: -webkit-gradient(linear, left top,
left bottom, from(#eeeeee),
to(#D1D1D1));
background: -moz-linear-gradient(top, #eeeeee, #D1D1D1);
margin:5px 0;
}
pre {
white-space:pre-wrap;
text-shadow:0 1px 1px rgba(0, 0, 0, 0.5);
font-family:'Copse', serif;
font-size: 16px;
font-weight: normal;
margin:.5em 0;
padding:.25em;
border:1px solid #bbb;
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
border-radius: 10px;
background-image:linear-gradient(rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));
color:#fff;
background-color:rgba(0, 0, 0, 0.5);
-webkit-box-shadow:inset 0 1px 3px rgba(0, 0, 0, 0.5), 0 1px 0 rgba(255, 255, 255, 0.5);
box-shadow:inset 0 1px 3px rgba(0, 0, 0, 0.5), 0 1px 0 rgba(255, 255, 255, 0.5);
}

View File

@ -0,0 +1,63 @@
/* manni style for pygmentize with .go darkened */
.hll { background-color: #ffffcc }
.c { color: #0099FF; font-style: italic } /* Comment */
.err { color: #AA0000; background-color: #FFAAAA } /* Error */
.k { color: #006699; font-weight: bold } /* Keyword */
.o { color: #555555 } /* Operator */
.cm { color: #0099FF; font-style: italic } /* Comment.Multiline */
.cp { color: #009999 } /* Comment.Preproc */
.c1 { color: #0099FF; font-style: italic } /* Comment.Single */
.cs { color: #0099FF; font-weight: bold; font-style: italic } /* Comment.Special */
.gd { background-color: #FFCCCC; border: 1px solid #CC0000 } /* Generic.Deleted */
.ge { font-style: italic } /* Generic.Emph */
.gr { color: #FF0000 } /* Generic.Error */
.gh { color: #003300; font-weight: bold } /* Generic.Heading */
.gi { background-color: #CCFFCC; border: 1px solid #00CC00 } /* Generic.Inserted */
.go { color: #333333; } /* Generic.Output */
.gp { color: #000099; font-weight: bold } /* Generic.Prompt */
.gs { font-weight: bold } /* Generic.Strong */
.gu { color: #003300; font-weight: bold } /* Generic.Subheading */
.gt { color: #99CC66 } /* Generic.Traceback */
.kc { color: #006699; font-weight: bold } /* Keyword.Constant */
.kd { color: #006699; font-weight: bold } /* Keyword.Declaration */
.kn { color: #006699; font-weight: bold } /* Keyword.Namespace */
.kp { color: #006699 } /* Keyword.Pseudo */
.kr { color: #006699; font-weight: bold } /* Keyword.Reserved */
.kt { color: #007788; font-weight: bold } /* Keyword.Type */
.m { color: #FF6600 } /* Literal.Number */
.s { color: #CC3300 } /* Literal.String */
.na { color: #330099 } /* Name.Attribute */
.nb { color: #336666 } /* Name.Builtin */
.nc { color: #00AA88; font-weight: bold } /* Name.Class */
.no { color: #336600 } /* Name.Constant */
.nd { color: #9999FF } /* Name.Decorator */
.ni { color: #999999; font-weight: bold } /* Name.Entity */
.ne { color: #CC0000; font-weight: bold } /* Name.Exception */
.nf { color: #CC00FF } /* Name.Function */
.nl { color: #9999FF } /* Name.Label */
.nn { color: #00CCFF; font-weight: bold } /* Name.Namespace */
.nt { color: #330099; font-weight: bold } /* Name.Tag */
.nv { color: #003333 } /* Name.Variable */
.ow { color: #000000; font-weight: bold } /* Operator.Word */
.w { color: #bbbbbb } /* Text.Whitespace */
.mf { color: #FF6600 } /* Literal.Number.Float */
.mh { color: #FF6600 } /* Literal.Number.Hex */
.mi { color: #FF6600 } /* Literal.Number.Integer */
.mo { color: #FF6600 } /* Literal.Number.Oct */
.sb { color: #CC3300 } /* Literal.String.Backtick */
.sc { color: #CC3300 } /* Literal.String.Char */
.sd { color: #CC3300; font-style: italic } /* Literal.String.Doc */
.s2 { color: #CC3300 } /* Literal.String.Double */
.se { color: #CC3300; font-weight: bold } /* Literal.String.Escape */
.sh { color: #CC3300 } /* Literal.String.Heredoc */
.si { color: #AA0000 } /* Literal.String.Interpol */
.sx { color: #CC3300 } /* Literal.String.Other */
.sr { color: #33AAAA } /* Literal.String.Regex */
.s1 { color: #CC3300 } /* Literal.String.Single */
.ss { color: #FFCC33 } /* Literal.String.Symbol */
.bp { color: #336666 } /* Name.Builtin.Pseudo */
.vc { color: #003333 } /* Name.Variable.Class */
.vg { color: #003333 } /* Name.Variable.Global */
.vi { color: #003333 } /* Name.Variable.Instance */
.il { color: #FF6600 } /* Literal.Number.Integer.Long */

24
src/jekyll/talks.md Normal file
View File

@ -0,0 +1,24 @@
---
layout: default
title: Talks
tagline: People presenting SBT topics
description: "This page contains a list of presentations about SBT. If you know about a presentation that isn't on the list please open an issue [https://github.com/sbt/sbt.github.com](https://github.com/sbt/sbt.github.com)."
toplinks: #Links at the top.
- name: 'Building SBT Plugins'
id: 'buildingsbtplugins'
content: |
#### Building SBT Plugins ####
Presentation showing how to build SBT plugins. The source code and presentation pdf
can be found [here](https://github.com/mads379/sbt-plugin-examples "here").
- name: 'SBT Cookbook'
id: 'sbtcookbook'
content: |
#### SBT Cookbook ####
A [talk](http://youtu.be/V2rl62CZPVc) on the basics of SBT as well as some cookbook examples.
---

View File

@ -0,0 +1,191 @@
---
layout: content
title: Deploying to Sonatype
---
Deploying to sonatype is easy! Just follow these simple steps:
## First - PGP Signatures ##
You'll need to PGP sign your artifacts for the Sonatype repository. Don't worry, there's a [plugin for that](http://scala-sbt.org/xsbt-gpg-plugin). Follow the instructions for the plugin and you'll have PGP signed artifacts in no time.
*Note: The plugin is a jvm-only solution to generate PGP keys and sign artifacts. It can work with the GPG command line tool, but the command line is not needed.*
## Second - Maven Publishing Settings ##
To publish to a maven repository, you'll need to configure a few settings so that the correct metadata is generated.
publishMavenStyle := true
is used to ensure POMs are generated and pushed. Next, you have to set up the repositories you wish to push too. Luckily, Sonatype's OSSRH uses the same URLs for everyone:
publishTo <<= version { (v: String) =>
val nexus = "https://oss.sonatype.org/"
if (v.trim.endsWith("SNAPSHOT"))
Some("snapshots" at nexus + "content/repositories/snapshots")
else
Some("releases" at nexus + "service/local/staging/deploy/maven2")
}
Another good idea is to not publish your test artifacts:
publishArtifact in Test := false
## Third - POM Metadata ##
Now, we want to control what's available in the `pom.xml` file. This file describes our project in the maven repository and is used by indexing services for search and discover. This means it's important that `pom.xml` should have all information we wish to advertise as well as required info!
First, let's make sure no repositories show up in the POM file. To publish on maven-central, all *required* artifacts must also be hosted on maven central. However, sometimes we have optional dependencies for special features. If that's the case, let's remove the repositories for optional dependencies in our artifact:
pomIncludeRepository := { _ => false }
Next, the POM metadata that isn't generated by SBT must be added. This is done through the `pomExtra` configuration option:
pomExtra := (
<url>http://jsuereth.com/scala-arm</url>
<licenses>
<license>
<name>BSD-style</name>
<url>http://www.opensource.org/licenses/bsd-license.php</url>
<distribution>repo</distribution>
</license>
</licenses>
<scm>
<url>git@github.com:jsuereth/scala-arm.git</url>
<connection>scm:git:git@github.com:jsuereth/scala-arm.git</connection>
</scm>
<developers>
<developer>
<id>jsuereth</id>
<name>Josh Suereth</name>
<url>http://jsuereth.com</url>
</developer>
</developers>)
Specifically, the `url`, `license`, `scm.url`, `scm.connection` and `developer` sections are required. The above is an example from the [scala-arm](http://jsuereth.com/scala-arm) project.
*Note* that sbt will automatically inject `licenses` and `url` nodes if they are already present in your build file. Thus an alternative to the above `pomExtra` is to include the following entries:
licenses := Seq("BSD-style" -> url("http://www.opensource.org/licenses/bsd-license.php"))
homepage := Some(url("http://jsuereth.com/scala-arm"))
This might be advantageous if those keys are used also by other plugins (e.g. `ls`). You **cannot use both** the sbt `licenses` key and the `licenses` section in `pomExtra` at the same time, as this will produce duplicate entries in the final POM file, leading to a rejection in Sonatype's staging process.
*The full format of a pom.xml file is [outlined here](http://maven.apache.org/pom.html).*
## Fourth - Adding credentials ##
The credentials for your Sonatype OSSRH account need to be added somewhere. Common convention is a `~/.sbt/sonatype.sbt` file with the following:
credentials += Credentials("Sonatype Nexus Repository Manager",
"oss.sonatype.org",
"<your username>",
"<your password>")
*Note: The first two strings must be `"Sonatype Nexus Repository Manager"` and `"oss.sonatype.org"` for Ivy to use the credentials.*
## Finally - Publish ##
In SBT, run `publish` and you should see something like the following:
> publish
Please enter your PGP passphrase> ***********
[info] Packaging /home/josh/projects/typesafe/scala-arm/target/scala-2.9.1/scala-arm_2.9.1-1.2.jar ...
[info] Wrote /home/josh/projects/typesafe/scala-arm/target/scala-2.9.1/scala-arm_2.9.1-1.2.pom
[info] Packaging /home/josh/projects/typesafe/scala-arm/target/scala-2.9.1/scala-arm_2.9.1-1.2-javadoc.jar ...
[info] Packaging /home/josh/projects/typesafe/scala-arm/target/scala-2.9.1/scala-arm_2.9.1-1.2-sources.jar ...
[info] :: delivering :: com.jsuereth#scala-arm_2.9.1;1.2 :: 1.2 :: release :: Mon Jan 23 13:16:57 EST 2012
[info] Done packaging.
[info] Done packaging.
[info] Done packaging.
[info] delivering ivy file to /home/josh/projects/typesafe/scala-arm/target/scala-2.9.1/ivy-1.2.xml
[info] published scala-arm_2.9.1 to https://oss.sonatype.org/service/local/staging/deploy/maven2/com/jsuereth/scala-arm_2.9.1/1.2/scala-arm_2.9.1-1.2-sources.jar
[info] published scala-arm_2.9.1 to https://oss.sonatype.org/service/local/staging/deploy/maven2/com/jsuereth/scala-arm_2.9.1/1.2/scala-arm_2.9.1-1.2-javadoc.jar.asc
[info] published scala-arm_2.9.1 to https://oss.sonatype.org/service/local/staging/deploy/maven2/com/jsuereth/scala-arm_2.9.1/1.2/scala-arm_2.9.1-1.2-sources.jar.asc
[info] published scala-arm_2.9.1 to https://oss.sonatype.org/service/local/staging/deploy/maven2/com/jsuereth/scala-arm_2.9.1/1.2/scala-arm_2.9.1-1.2.jar
[info] published scala-arm_2.9.1 to https://oss.sonatype.org/service/local/staging/deploy/maven2/com/jsuereth/scala-arm_2.9.1/1.2/scala-arm_2.9.1-1.2.jar.asc
[info] published scala-arm_2.9.1 to https://oss.sonatype.org/service/local/staging/deploy/maven2/com/jsuereth/scala-arm_2.9.1/1.2/scala-arm_2.9.1-1.2.pom.asc
[info] published scala-arm_2.9.1 to https://oss.sonatype.org/service/local/staging/deploy/maven2/com/jsuereth/scala-arm_2.9.1/1.2/scala-arm_2.9.1-1.2.pom
[info] published scala-arm_2.9.1 to https://oss.sonatype.org/service/local/staging/deploy/maven2/com/jsuereth/scala-arm_2.9.1/1.2/scala-arm_2.9.1-1.2-javadoc.jar
[success] Total time: 9 s, completed Jan 23, 2012 1:17:03 PM
After publishing you have to follow the [Release workflow of nexus](https://docs.sonatype.org/display/Repository/Sonatype+OSS+Maven+Repository+Usage+Guide#SonatypeOSSMavenRepositoryUsageGuide-8.ReleaseIt). In the future, we hope to provide a Nexus SBT plugin that allows the release workflow procedures to be performed directly from SBT.
*Note: Staged releases allow testing across large projects of independent releases before pushing the full project.*
<sub>*Note:* An error message of `PGPException: checksum mismatch at 0 of 20` indicates that you got the passphrase wrong. We have found at least on OS X that there may be issues with characters outside the 7-bit ASCII range (e.g. Umlauts). If you are absolutely sure that you typed the right phrase and the error doesn't disappear, try changing the passphrase.</sub>
## Summary ##
To get your project hosted on Sonatype (and Maven Central), you will need to:
* Have GPG key pair, with published public key,
* A SBT file with your Sonatype credentials *that is not pushed to the VCS*,
* Modify `project/plugins.sbt` to include the `xsbt-gpg-plugin` to sign the artefacts,
* Modify `build.sbt` with the required elements in the generated POM.
Starting with a project that is not being published, you'll need to install GPG, generate and publish your key. Swtiching to SBT,
you'll then need to:
#### ~/.sbt/sonatype.sbt
This file (kept *outside the VCS*) contains the Sonatype credentials settings:
credentials += Credentials("Sonatype Nexus Repository Manager",
"oss.sonatype.org",
"your-sonatype-username",
"your-sonatype-password")
#### project/plugins.sbt
This file specifies the plugins for your project. If you intend to sign the artefacts, you'll need to include @jsuereth's `xsbt-gpg-plugin`:
resolvers += Resolver.url("sbt-plugin-releases", /* no new line */
new URL("http://scalasbt.artifactoryonline.com/scalasbt/sbt-plugin-releases")) /* no new line */
(Resolver.ivyStylePatterns)
addSbtPlugin("com.jsuereth" % "xsbt-gpg-plugin" % "0.5")
#### build.sbt
Finally, you'll need to tweak the generated POM in your `build.sbt`. The tweaks include specifying the project's authors, URL, SCM and many others:
publishTo <<= version { v: String =>
val nexus = "https://oss.sonatype.org/"
if (v.trim.endsWith("SNAPSHOT")) Some("snapshots" at nexus + "content/repositories/snapshots")
else Some("releases" at nexus + "service/local/staging/deploy/maven2")
}
publishMavenStyle := true
publishArtifact in Test := false
pomIncludeRepository := { _ => false }
pomExtra := (
<url>http://your.project.url</url>
<licenses>
<license>
<name>BSD-style</name>
<url>http://www.opensource.org/licenses/bsd-license.php</url>
<distribution>repo</distribution>
</license>
</licenses>
<scm>
<url>git@github.com:your-account/your-project.git</url>
<connection>scm:git:git@github.com:your-account/your-project.git</connection>
</scm>
<developers>
<developer>
<id>you</id>
<name>Your Name</name>
<url>http://your.url</url>
</developer>
</developers>
)