<commit_before># xsbt-web-plugin

*Version 2.0*

xsbt-web-plugin is an [sbt](http://www.scala-sbt.org/) extension for building [J2EE](http://en.wikipedia.org/wiki/Java_Servlet) Web applications in Scala and Java.

## Requirements

* sbt 0.13.6+

## Quick reference

Add xsbt-web-plugin to *project/plugins.sbt*:

```scala
addSbtPlugin("com.earldouglas" % "xsbt-web-plugin" % "2.0.2")
```

Enable the Jetty plugin:

*build.sbt*:

```scala
enablePlugins(JettyPlugin)
```

From the sbt console:

* Start (or restart) the container with `jetty:start`
* Stop the container with `jetty:stop`
* Build a *.war* file with `package`

To use Tomcat instead of Jetty:

* Substitute `TomcatPlugin` for `JettyPlugin`
* Substitute `tomcat:start` for `jetty:start`
* Substitute `tomcat:stop` for `jetty:stop`

## Starting from scratch

Create a new empty project:

```
mkdir myproject
cd myproject
```

Set up the project structure:

```
mkdir project
mkdir -p src/main/scala
mkdir -p src/main/webapp/WEB-INF
```

Configure sbt:

*project/build.properties:*

```
sbt.version=0.13.8
```

*project/plugins.sbt:*

```scala
addSbtPlugin("com.earldouglas" % "xsbt-web-plugin" % "2.0.2")
```

*build.sbt:*

```scala
scalaVersion := "2.11.6"

libraryDependencies += "javax.servlet" % "javax.servlet-api" % "3.0.1" % "provided"

enablePlugins(JettyPlugin)
```

Add a servlet:

*src/main/scala/servlets.scala*:

```scala
package servlets

import javax.servlet.http._

class MyServlet extends HttpServlet {

  override def doGet(request: HttpServletRequest, response: HttpServletResponse) {
    response.setContentType("text/html")
    response.setCharacterEncoding("UTF-8")
    response.getWriter.write("""<h1>Hello, world!</h1>""")
  }

}
```

*src/main/webapp/WEB-INF/web.xml*:

```xml
<web-app>

  <servlet>
    <servlet-name>my servlet</servlet-name>
    <servlet-class>servlets.MyServlet</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>my servlet</servlet-name>
    <url-pattern>/*</url-pattern>
  </servlet-mapping>

</web-app>
```

## Configuration and use

### Triggered execution

xsbt-web-plugin supports sbt's [triggered execution](http://www.scala-sbt.org/0.13/docs/Triggered-Execution.html) by prefixing commands with `~`.

*sbt console:*

```
> ~jetty:start
```

This starts the Jetty container, then monitors the sources, resources, and webapp directories for changes, which triggers a container restart.

### Custom container

To use a custom J2EE container, e.g. a main class named `runner.Run`, enable `ContainerPlugin` and set `containerLibs` and `containerLaunchCmd`:

```scala
enablePlugins(ContainerPlugin)

containerLibs in Container := Seq(
    "org.eclipse.jetty" %  "jetty-webapp" % "9.1.0.v20131115"
  , "org.eclipse.jetty" %  "jetty-plus"   % "9.1.0.v20131115"
  , "test"              %% "runner"       % "0.1.0-SNAPSHOT"
)

containerLaunchCmd in Container := Seq("runner.Run", "8080", (target in webappPrepare).value.absolutePath)
```

*sbt:*

```
> container:start
> container:stop
```

*Example: [container/custom-runner](https://github.com/earldouglas/xsbt-web-plugin/tree/master/src/sbt-test/container/custom-runner)*

### Forked JVM options

To set environment properties for the forked container JVM, set `containerForkOptions`:

```scala
containerForkOptions := new ForkOptions(runJVMOptions = Seq("-Dh2g2=42"))
```

*Example: [container/fork-options](https://github.com/earldouglas/xsbt-web-plugin/tree/master/src/sbt-test/container/fork-options)*

Alternatively, set `javaOptions` in the `Jetty` (or `Tomcat`) configuration:

```scala
javaOptions in Jetty += "-Dh2g2=42"
```

To attach an Eclipse debugger, set `-Xdebug` and `-Xrunjdwp`:

*build.sbt:*

```scala
javaOptions in container ++= Seq(
  "-Xdebug",
  "-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000"
)
```

In Eclipse, create and run a new *Remote Java Application* launch configuration with a *Connection Type* of *Scala debugger (Socket Attach)*, set to connect to *localhost* on port *8000*.

*Example: [container/java-options](https://github.com/earldouglas/xsbt-web-plugin/tree/master/src/sbt-test/container/java-options)*

### Jetty version

By default, Jetty 9.2.1 is used.  To use a different version, set `containerLibs`:

```scala
containerLibs := Seq("org.mortbay.jetty" % "jetty-runner" % "7.0.0.v20091005" intransitive())
```

Depending on the version, it may also be necessary to specify the name of Jetty's runner:

```scala
containerMain := "org.mortbay.jetty.runner.Runner"
```

*Examples:*

* *[container/jetty-7](https://github.com/earldouglas/xsbt-web-plugin/tree/master/src/sbt-test/container/jetty-7)*
* *[container/jetty-8](https://github.com/earldouglas/xsbt-web-plugin/tree/master/src/sbt-test/container/jetty-8)*
* *[container/jetty-9](https://github.com/earldouglas/xsbt-web-plugin/tree/master/src/sbt-test/container/jetty-9)*

### Container port

By default, the container runs on port *8080*.  To use a different port, set `containerPort`:

```scala
containerPort := 9090
```

*Examples:*

* *[container/jetty-port-9090](https://github.com/earldouglas/xsbt-web-plugin/tree/master/src/sbt-test/container/jetty-port-9090)*
* *[container/tomcat-port-9090](https://github.com/earldouglas/xsbt-web-plugin/tree/master/src/sbt-test/container/tomcat-port-9090)*

### *jetty.xml*

To use a *jetty.xml* configuration file, set `containerConfigFile`:

```scala
containerConfigFile := Some(file("etc/jetty.xml"))
```

This option can be used to enable SSL and HTTPS.

*Examples:*

* *[container/jetty-xml-http](https://github.com/earldouglas/xsbt-web-plugin/tree/master/src/sbt-test/container/jetty-xml-http)*
* *[container/jetty-xml-https](https://github.com/earldouglas/xsbt-web-plugin/tree/master/src/sbt-test/container/jetty-xml-https)*

### Multi-project applications

*Examples:*

* *[container/multi-module-single-webapp](https://github.com/earldouglas/xsbt-web-plugin/tree/master/src/sbt-test/container/multi-module-single-webapp)*
* *[container/multi-module-multi-webapp](https://github.com/earldouglas/xsbt-web-plugin/tree/master/src/sbt-test/container/multi-module-multi-webapp)*

### Tomcat version

By default, Tomcat 192.168.3.11 is used.  To use a different version, set `containerLibs`:

```scala
containerLibs := Seq("com.github.jsimone" % "webapp-runner" % "192.168.3.11" intransitive())
```

Depending on the version, it may also be necessary to specify the name of Tomcat's runner:

```scala
containerMain := "webapp.runner.launch.Main"
```

### Massaging the *.war* file

After the *<project>/target/webapp* directory is prepared, it can be modified with an arbitrary `File => Unit` function.

To manipulate the contents of this directory before it is packaged as a *.war* file, set `webappPostProcess`:

```scala
webappPostProcess := {
  webappDir =>
    def listFiles(level: Int)(f: File): Unit = {
      val indent = ((1 until level) map { _ => "  " }).mkString
      if (f.isDirectory) {
        streams.value.log.info(indent + f.getName + "/")
        f.listFiles foreach { listFiles(level + 1) }
      } else streams.value.log.info(indent + f.getName)
    }
    listFiles(1)(webappDir)
}
```

*Examples:*

* *[war/simple](https://github.com/earldouglas/xsbt-web-plugin/tree/master/src/sbt-test/war/simple)*
* *[webapp/yuicompressor](https://github.com/earldouglas/xsbt-web-plugin/tree/master/src/sbt-test/webapp/yuicompressor)*

### Custom resources directory

Files in the extra resource directory are not compiled, and are bundled directly in the project artifact *.jar* file.

To add a custom resources directory, set `unmanagedResourceDirectories`:

```scala
unmanagedResourceDirectories in Compile <+= (sourceDirectory in Compile)(_ / "extra")
```

*Example: [webapp/unmanaged-resources](https://github.com/earldouglas/xsbt-web-plugin/tree/master/src/sbt-test/webapp/unmanaged-resources)*

### Custom sources directory

Scala files in the extra source directory are compiled, and bundled in the project artifact *.jar* file.

To add a custom sources directory, set `unmanagedSourceDirectories`:

```scala
unmanagedSourceDirectories in Compile <+= (sourceDirectory in Compile)(_ / "extra")
```

*Example: [webapp/unmanaged-sources](https://github.com/earldouglas/xsbt-web-plugin/tree/master/src/sbt-test/webapp/unmanaged-sources)*

### Utilizing *WEB-INF/classes*

By default, project classes are packaged into a *.jar* file, shipped in the *WEB-INF/lib* directory of the *.war* file.  To instead keep them extracted in *WEB-INF/classes*, set `webappWebInfClasses`:

```scala
webappWebInfClasses := true
```

*Examples:*

* *[webapp/web-inf-classes](https://github.com/earldouglas/xsbt-web-plugin/tree/master/src/sbt-test/webapp/web-inf-classes)*
* *[webapp/web-inf-lib](https://github.com/earldouglas/xsbt-web-plugin/tree/master/src/sbt-test/webapp/web-inf-lib)*

### Web application destination

The Web application destination directory is where the static Web content, compiled Scala classes, library *.jar* files, etc. are placed.  By default, they go to *<project>/target/webapp*.

To specify a different directory, set `target` in the `webappPrepare` configuration:

```scala
target in webappPrepare := target.value / "WebContent"
```

*Example: [webapp/webapp-dest](https://github.com/earldouglas/xsbt-web-plugin/tree/master/src/sbt-test/webapp/webapp-dest)*

### Web application resources

The Web application resources directory is where static Web content (including *.html*, *.css*, and *.js* files, the *web.xml* container configuration file, etc.  By default, this is kept in *<project>/src/main/webapp*.

To specify a different directory, set `sourceDirectory` in the `webappPrepare` configuration:

```scala
sourceDirectory in webappPrepare := (sourceDirectory in Compile).value / "WebContent"
```

*Example: [webapp/webapp-src](https://github.com/earldouglas/xsbt-web-plugin/tree/master/src/sbt-test/webapp/webapp-src)*

### Prepare the Web application for execution and deployment

For situations when the prepared *<project>/target/webapp* directory is needed, but the packaged *.war* file isn't.

*sbt console:*

```
webapp:prepare
```

### Add manifest attributes

By default, the *.war* file includes the same manifest attributes as the project's artifact:

* Implementation-Vendor
* Implementation-Title
* Implementation-Version
* Implementation-Vendor-Id
* Specification-Vendor
* Specification-Title
* Specification-Version

These can be changed in both artifacts:

*build.sbt:*

```scala
packageOptions in (Compile, packageBin) +=
    Package.ManifestAttributes( java.util.jar.Attributes.Name.SEALED -> "true" )
```

Or in just the *.war* file:

*build.sbt:*

```scala
packageOptions in packageWar +=
  Package.ManifestAttributes( java.util.jar.Attributes.Name.SEALED -> "true" )
```

### Using JRebel

Add the JRebel sbt plugin (which generates *jrebel.xml*) to *project/plugins.sbt*:

```scala
addSbtPlugin("fi.gekkio.sbtplugins" % "sbt-jrebel-plugin" % "0.10.0")
```

Add the following lines to *build.sbt*, making sure to specify the correct path to JRebel:

```scala
seq(jrebelSettings: _*)

jrebel.webLinks += (sourceDirectory in Compile).value / "webapp"

jrebel.enabled := true

javaOptions in Jetty ++= Seq(
    "-javaagent:/path/to/jrebel/jrebel.jar",
    "-noverify",
    "-XX:+UseConcMarkSweepGC",
    "-XX:+CMSClassUnloadingEnabled"
)
```

Start the container, and trigger `~compile`, and your changes should be picked up automatically:

```scala
> jetty:start
> ~compile
```

### Container shutdown and sbt

By default, sbt will shutdown the running container when exiting sbt.

To allow the container to continue running after sbt exits, set `containerShutdownOnExit`:

```scala
containerShutdownOnExit := false
```
<commit_msg>Fix error in example<commit_after># xsbt-web-plugin

*Version 2.0*

xsbt-web-plugin is an [sbt](http://www.scala-sbt.org/) extension for building [J2EE](http://en.wikipedia.org/wiki/Java_Servlet) Web applications in Scala and Java.

## Requirements

* sbt 0.13.6+

## Quick reference

Add xsbt-web-plugin to *project/plugins.sbt*:

```scala
addSbtPlugin("com.earldouglas" % "xsbt-web-plugin" % "2.0.2")
```

Enable the Jetty plugin:

*build.sbt*:

```scala
enablePlugins(JettyPlugin)
```

From the sbt console:

* Start (or restart) the container with `jetty:start`
* Stop the container with `jetty:stop`
* Build a *.war* file with `package`

To use Tomcat instead of Jetty:

* Substitute `TomcatPlugin` for `JettyPlugin`
* Substitute `tomcat:start` for `jetty:start`
* Substitute `tomcat:stop` for `jetty:stop`

## Starting from scratch

Create a new empty project:

```
mkdir myproject
cd myproject
```

Set up the project structure:

```
mkdir project
mkdir -p src/main/scala
mkdir -p src/main/webapp/WEB-INF
```

Configure sbt:

*project/build.properties:*

```
sbt.version=0.13.8
```

*project/plugins.sbt:*

```scala
addSbtPlugin("com.earldouglas" % "xsbt-web-plugin" % "2.0.2")
```

*build.sbt:*

```scala
scalaVersion := "2.11.6"

libraryDependencies += "javax.servlet" % "javax.servlet-api" % "3.0.1" % "provided"

enablePlugins(JettyPlugin)
```

Add a servlet:

*src/main/scala/servlets.scala*:

```scala
package servlets

import javax.servlet.http._

class MyServlet extends HttpServlet {

  override def doGet(request: HttpServletRequest, response: HttpServletResponse) {
    response.setContentType("text/html")
    response.setCharacterEncoding("UTF-8")
    response.getWriter.write("""<h1>Hello, world!</h1>""")
  }

}
```

*src/main/webapp/WEB-INF/web.xml*:

```xml
<web-app>

  <servlet>
    <servlet-name>my servlet</servlet-name>
    <servlet-class>servlets.MyServlet</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>my servlet</servlet-name>
    <url-pattern>/*</url-pattern>
  </servlet-mapping>

</web-app>
```

## Configuration and use

### Triggered execution

xsbt-web-plugin supports sbt's [triggered execution](http://www.scala-sbt.org/0.13/docs/Triggered-Execution.html) by prefixing commands with `~`.

*sbt console:*

```
> ~jetty:start
```

This starts the Jetty container, then monitors the sources, resources, and webapp directories for changes, which triggers a container restart.

### Custom container

To use a custom J2EE container, e.g. a main class named `runner.Run`, enable `ContainerPlugin` and set `containerLibs` and `containerLaunchCmd`:

```scala
enablePlugins(ContainerPlugin)

containerLibs in Container := Seq(
    "org.eclipse.jetty" %  "jetty-webapp" % "9.1.0.v20131115"
  , "org.eclipse.jetty" %  "jetty-plus"   % "9.1.0.v20131115"
  , "test"              %% "runner"       % "0.1.0-SNAPSHOT"
)

containerLaunchCmd in Container := Seq("runner.Run", "8080", (target in webappPrepare).value.absolutePath)
```

*sbt:*

```
> container:start
> container:stop
```

*Example: [container/custom-runner](https://github.com/earldouglas/xsbt-web-plugin/tree/master/src/sbt-test/container/custom-runner)*

### Forked JVM options

To set environment properties for the forked container JVM, set `containerForkOptions`:

```scala
containerForkOptions := new ForkOptions(runJVMOptions = Seq("-Dh2g2=42"))
```

*Example: [container/fork-options](https://github.com/earldouglas/xsbt-web-plugin/tree/master/src/sbt-test/container/fork-options)*

Alternatively, set `javaOptions` in the `Jetty` (or `Tomcat`) configuration:

```scala
javaOptions in Jetty += "-Dh2g2=42"
```

To attach an Eclipse debugger, set `-Xdebug` and `-Xrunjdwp`:

*build.sbt:*

```scala
javaOptions in Jetty ++= Seq(
  "-Xdebug",
  "-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000"
)
```

In Eclipse, create and run a new *Remote Java Application* launch configuration with a *Connection Type* of *Scala debugger (Socket Attach)*, set to connect to *localhost* on port *8000*.

*Example: [container/java-options](https://github.com/earldouglas/xsbt-web-plugin/tree/master/src/sbt-test/container/java-options)*

### Jetty version

By default, Jetty 9.2.1 is used.  To use a different version, set `containerLibs`:

```scala
containerLibs := Seq("org.mortbay.jetty" % "jetty-runner" % "7.0.0.v20091005" intransitive())
```

Depending on the version, it may also be necessary to specify the name of Jetty's runner:

```scala
containerMain := "org.mortbay.jetty.runner.Runner"
```

*Examples:*

* *[container/jetty-7](https://github.com/earldouglas/xsbt-web-plugin/tree/master/src/sbt-test/container/jetty-7)*
* *[container/jetty-8](https://github.com/earldouglas/xsbt-web-plugin/tree/master/src/sbt-test/container/jetty-8)*
* *[container/jetty-9](https://github.com/earldouglas/xsbt-web-plugin/tree/master/src/sbt-test/container/jetty-9)*

### Container port

By default, the container runs on port *8080*.  To use a different port, set `containerPort`:

```scala
containerPort := 9090
```

*Examples:*

* *[container/jetty-port-9090](https://github.com/earldouglas/xsbt-web-plugin/tree/master/src/sbt-test/container/jetty-port-9090)*
* *[container/tomcat-port-9090](https://github.com/earldouglas/xsbt-web-plugin/tree/master/src/sbt-test/container/tomcat-port-9090)*

### *jetty.xml*

To use a *jetty.xml* configuration file, set `containerConfigFile`:

```scala
containerConfigFile := Some(file("etc/jetty.xml"))
```

This option can be used to enable SSL and HTTPS.

*Examples:*

* *[container/jetty-xml-http](https://github.com/earldouglas/xsbt-web-plugin/tree/master/src/sbt-test/container/jetty-xml-http)*
* *[container/jetty-xml-https](https://github.com/earldouglas/xsbt-web-plugin/tree/master/src/sbt-test/container/jetty-xml-https)*

### Multi-project applications

*Examples:*

* *[container/multi-module-single-webapp](https://github.com/earldouglas/xsbt-web-plugin/tree/master/src/sbt-test/container/multi-module-single-webapp)*
* *[container/multi-module-multi-webapp](https://github.com/earldouglas/xsbt-web-plugin/tree/master/src/sbt-test/container/multi-module-multi-webapp)*

### Tomcat version

By default, Tomcat 192.168.3.11 is used.  To use a different version, set `containerLibs`:

```scala
containerLibs := Seq("com.github.jsimone" % "webapp-runner" % "192.168.3.11" intransitive())
```

Depending on the version, it may also be necessary to specify the name of Tomcat's runner:

```scala
containerMain := "webapp.runner.launch.Main"
```

### Massaging the *.war* file

After the *<project>/target/webapp* directory is prepared, it can be modified with an arbitrary `File => Unit` function.

To manipulate the contents of this directory before it is packaged as a *.war* file, set `webappPostProcess`:

```scala
webappPostProcess := {
  webappDir =>
    def listFiles(level: Int)(f: File): Unit = {
      val indent = ((1 until level) map { _ => "  " }).mkString
      if (f.isDirectory) {
        streams.value.log.info(indent + f.getName + "/")
        f.listFiles foreach { listFiles(level + 1) }
      } else streams.value.log.info(indent + f.getName)
    }
    listFiles(1)(webappDir)
}
```

*Examples:*

* *[war/simple](https://github.com/earldouglas/xsbt-web-plugin/tree/master/src/sbt-test/war/simple)*
* *[webapp/yuicompressor](https://github.com/earldouglas/xsbt-web-plugin/tree/master/src/sbt-test/webapp/yuicompressor)*

### Custom resources directory

Files in the extra resource directory are not compiled, and are bundled directly in the project artifact *.jar* file.

To add a custom resources directory, set `unmanagedResourceDirectories`:

```scala
unmanagedResourceDirectories in Compile <+= (sourceDirectory in Compile)(_ / "extra")
```

*Example: [webapp/unmanaged-resources](https://github.com/earldouglas/xsbt-web-plugin/tree/master/src/sbt-test/webapp/unmanaged-resources)*

### Custom sources directory

Scala files in the extra source directory are compiled, and bundled in the project artifact *.jar* file.

To add a custom sources directory, set `unmanagedSourceDirectories`:

```scala
unmanagedSourceDirectories in Compile <+= (sourceDirectory in Compile)(_ / "extra")
```

*Example: [webapp/unmanaged-sources](https://github.com/earldouglas/xsbt-web-plugin/tree/master/src/sbt-test/webapp/unmanaged-sources)*

### Utilizing *WEB-INF/classes*

By default, project classes are packaged into a *.jar* file, shipped in the *WEB-INF/lib* directory of the *.war* file.  To instead keep them extracted in *WEB-INF/classes*, set `webappWebInfClasses`:

```scala
webappWebInfClasses := true
```

*Examples:*

* *[webapp/web-inf-classes](https://github.com/earldouglas/xsbt-web-plugin/tree/master/src/sbt-test/webapp/web-inf-classes)*
* *[webapp/web-inf-lib](https://github.com/earldouglas/xsbt-web-plugin/tree/master/src/sbt-test/webapp/web-inf-lib)*

### Web application destination

The Web application destination directory is where the static Web content, compiled Scala classes, library *.jar* files, etc. are placed.  By default, they go to *<project>/target/webapp*.

To specify a different directory, set `target` in the `webappPrepare` configuration:

```scala
target in webappPrepare := target.value / "WebContent"
```

*Example: [webapp/webapp-dest](https://github.com/earldouglas/xsbt-web-plugin/tree/master/src/sbt-test/webapp/webapp-dest)*

### Web application resources

The Web application resources directory is where static Web content (including *.html*, *.css*, and *.js* files, the *web.xml* container configuration file, etc.  By default, this is kept in *<project>/src/main/webapp*.

To specify a different directory, set `sourceDirectory` in the `webappPrepare` configuration:

```scala
sourceDirectory in webappPrepare := (sourceDirectory in Compile).value / "WebContent"
```

*Example: [webapp/webapp-src](https://github.com/earldouglas/xsbt-web-plugin/tree/master/src/sbt-test/webapp/webapp-src)*

### Prepare the Web application for execution and deployment

For situations when the prepared *<project>/target/webapp* directory is needed, but the packaged *.war* file isn't.

*sbt console:*

```
webapp:prepare
```

### Add manifest attributes

By default, the *.war* file includes the same manifest attributes as the project's artifact:

* Implementation-Vendor
* Implementation-Title
* Implementation-Version
* Implementation-Vendor-Id
* Specification-Vendor
* Specification-Title
* Specification-Version

These can be changed in both artifacts:

*build.sbt:*

```scala
packageOptions in (Compile, packageBin) +=
    Package.ManifestAttributes( java.util.jar.Attributes.Name.SEALED -> "true" )
```

Or in just the *.war* file:

*build.sbt:*

```scala
packageOptions in packageWar +=
  Package.ManifestAttributes( java.util.jar.Attributes.Name.SEALED -> "true" )
```

### Using JRebel

Add the JRebel sbt plugin (which generates *jrebel.xml*) to *project/plugins.sbt*:

```scala
addSbtPlugin("fi.gekkio.sbtplugins" % "sbt-jrebel-plugin" % "0.10.0")
```

Add the following lines to *build.sbt*, making sure to specify the correct path to JRebel:

```scala
seq(jrebelSettings: _*)

jrebel.webLinks += (sourceDirectory in Compile).value / "webapp"

jrebel.enabled := true

javaOptions in Jetty ++= Seq(
    "-javaagent:/path/to/jrebel/jrebel.jar",
    "-noverify",
    "-XX:+UseConcMarkSweepGC",
    "-XX:+CMSClassUnloadingEnabled"
)
```

Start the container, and trigger `~compile`, and your changes should be picked up automatically:

```scala
> jetty:start
> ~compile
```

### Container shutdown and sbt

By default, sbt will shutdown the running container when exiting sbt.

To allow the container to continue running after sbt exits, set `containerShutdownOnExit`:

```scala
containerShutdownOnExit := false
```

{'fraction_non_alphanumeric': 0.15189117734851393, 'fraction_numerical': 0.012366210396145154, 'mean_word_length': 4.736790606653621, 'pattern_counts': {'":': 0, '<': 47, '<?xml version=': 0, '>': 63, 'https://': 40, 'lorem ipsum': 0, 'www.': 4, 'xml': 22}, 'pii_count': 4, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6106833', 'n_tokens_mistral': 8365, 'n_tokens_neox': 7836, 'n_words': 1847}