#scalaenv, #sbtenv, #playenv でScala, sbt, PlayFrameworkのバージョンを管理する

## 2017.06 追記

案外使っていただけているようなのでorgを作ってtransferしました。

- [scalaenv/scalaenv](https://github.com/scalaenv/scalaenv)
- [sbtenv/sbtenv](https://github.com/sbtenv/sbtenv)

homebrewとanyenvにはPRも出しました。
(transferなので旧リポジトリを参照しても勝手にリダイレクトされると思いますが)

----

「Scalaってrbenvみたいにバージョンを切り替えて管理できるツールないの？？」と思ったところでrbenv<del>パク</del>参考にすればいいことに気づき[つくってみました](http://blog.mazgi.com/2014/02/i-made-scalaenv-sbtenv-and-playenv-based-on-rbenv/)。
しょぼいながらもautocompletionとインストール機能まで実装できたので開発メモを兼ねて現状を書いてみます。

----

## インストール

それぞれREADMEに従ってください。
といっても`git clone`して`PATH`を通すだけです。

* Scalaバージョン管理ツール： [scalaenv](https://github.com/mazgi/scalaenv)
* sbtバージョン管理ツール： [sbtenv](https://github.com/mazgi/sbtenv)
* Play Frameworkバージョン管理ツール： [playenv](https://github.com/mazgi/playenv)

## 使い方

使い方は[scalaenv](https://github.com/mazgi/scalaenv), [sbtenv](https://github.com/mazgi/sbtenv), [playenv](https://github.com/mazgi/playenv)全部一緒なのでここではscalaenvを例にとります。

### インストールされているバージョンの一覧表示

```shell-session
[mazgi@BRUICHLADDICH] $ scalaenv versions
* scala-2.10.1
* scala-2.10.2
* scala-2.10.3
* scala-2.11.0-M2
* scala-2.11.0-M3
* scala-2.11.0-M4
* scala-2.11.0-M5
* scala-2.11.0-M7
* scala-2.11.0-M8
* scala-2.9.0.1
* scala-2.9.0.final
* scala-2.9.1-1
* scala-2.9.1.final
* scala-2.9.2
* scala-2.9.3
```

### 特定のバージョンをインストールする

#### インストール可能バージョンの一覧表示

`scalaenv install`を`-l`オプション付きで実行するとインストール可能なバージョン一覧が表示されます。
というか`scalaenv install`のあとに指定された文字列をインストール対象バージョンと見なせなかったらインストール可能バージョン一覧を表示するだけだったりします。

```shell-session
[mazgi@BRUICHLADDICH] $ scalaenv install -l
All available versions:
scala-2.10.1
scala-2.10.2
scala-2.10.3
scala-2.11.0-M2
scala-2.11.0-M3
scala-2.11.0-M4
scala-2.11.0-M5
scala-2.11.0-M7
scala-2.11.0-M8
scala-2.9.0.1
scala-2.9.0.final
scala-2.9.1-1
scala-2.9.1.final
scala-2.9.2
scala-2.9.3
```

インストールといっても`$SCALAENV_ROOT/versions`内に展開してるだけなのでtarballを展開すればどんなバージョンでもインストールできます。

#### インストールする

例えば`scala-2.11.0-M8`をインストールする場合、`scalaenv install scala-2.11.0-M8`と実行するとインストールできます。
今のところインストール済みバージョンを指定すると上書きインストールします。
あとアンインストール機能はありません。`$SCALAENV_ROOT/versions`の下から手動で消してください。

単にcurlでダウンロードして展開してるだけです。SHA1SUMが提供されているバージョンであれば一応チェックサム確認します。
(Scala|sbt|PlayFramework)さん、なんでバージョンによってダウンロードURL変わったりSHA1SUMあったりなかったりするの・・・

```shell-session
[mazgi@BRUICHLADDICH] $ scalaenv install scala-2.11.0-M8
Installing scala-2.11.0-M8:
Downloading scala-2.11.0-M8 archives...
######################################################################## 100.0%
Extracting files...
scala-2.11.0-M8 installed.
```

例外処理ほとんど書いてないので途中でなんかあると簡単にコケると思います。

### バージョン切り替え方法

#### ユーザースコープ(global)のScalaバージョンを切り替える

ログインユーザー全体のScalaバージョンを切り替えるには`scalaenv global`にバージョン文字列を続けます。
`global`というサブコマンド名ですが、有効なのは同じログインユーザーのシェルのみで、他のユーザーには影響を与えません。

`scalaenv global scala-2.10.1`と実行するとScalaのバージョンが`2.10.1`になります。

```shell-session
[mazgi@BRUICHLADDICH] $ scalaenv global scala-2.10.1
[mazgi@BRUICHLADDICH] $ scala -version
Scala code runner version 2.10.1 -- Copyright 2002-2013, LAMP/EPFL
```

`scalaenv global scala-2.10.2`と実行するとScalaのバージョンが`2.10.2`に切り替わります。

```shell-session
[mazgi@BRUICHLADDICH] $ scalaenv global scala-2.10.2
[mazgi@BRUICHLADDICH] $ scala -version
Scala code runner version 2.10.2 -- Copyright 2002-2013, LAMP/EPFL
```

#### 特定のディレクトリ以下(local)のScalaバージョンを切り替える

特定のディレクトリとそのサブディレクトリのScalaバージョンを切り替えるには、対象のディレクトリ上で`scalaenv local`にバージョン文字列を続けます。
例えばこんなディレクトリツリーがあるとします。

```shell-session
[mazgi@BRUICHLADDICH] $ tree
.
├── 2.10.3
│   └── subdir
│       └── 2.11.0-M2
└── 2.11.0-M8
    └── subdir
```

ディレクトリ`2.10.3/`に移って`scalaenv local scala-2.10.3`を実行するとScalaのバージョンが`2.10.3`になります。

```shell-session
[mazgi@BRUICHLADDICH] $ cd 2.10.3
[mazgi@BRUICHLADDICH] $ scala -version
Scala code runner version 2.10.2 -- Copyright 2002-2013, LAMP/EPFL
[mazgi@BRUICHLADDICH] $ scalaenv local scala-2.10.3
[mazgi@BRUICHLADDICH] $ scala -version
Scala code runner version 2.10.3 -- Copyright 2002-2013, LAMP/EPFL
```

サブディレクトリでも有効です。

```shell-session
[mazgi@BRUICHLADDICH] $ cd subdir
[mazgi@BRUICHLADDICH] $ pwd
/tmp/scalaenv_testdrive/2.10.3/subdir
[mazgi@BRUICHLADDICH] $ scala -version
Scala code runner version 2.10.3 -- Copyright 2002-2013, LAMP/EPFL
```

さらにサブディレクトリに移って違うバージョンを指定するとそちらのScalaバージョンになります。

```shell-session
[mazgi@BRUICHLADDICH] $ cd 2.11.0-M2
[mazgi@BRUICHLADDICH] $ pwd
/tmp/scalaenv_testdrive/2.10.3/subdir/2.11.0-M2
[mazgi@BRUICHLADDICH] $ scalaenv local scala-2.11.0-M2
[mazgi@BRUICHLADDICH] $ scala -version
Scala code runner version 2.11.0-M2 -- Copyright 2002-2013, LAMP/EPFL
```

しかし親ディレクトリに戻ると元のバージョンに戻ります。

```shell-session
[mazgi@BRUICHLADDICH] $ cd ..
[mazgi@BRUICHLADDICH] $ pwd
/tmp/scalaenv_testdrive/2.10.3/subdir
[mazgi@BRUICHLADDICH] $ scala -version
Scala code runner version 2.10.3 -- Copyright 2002-2013, LAMP/EPFL
```

#### シェルセッション(shell)のScalaバージョンを切り替える

カレントシェルセッションのScalaバージョンを切り替えるには、`scalaenv shell`にバージョン文字列を続けます。

例えば`scalaenv shell scala-2.11.0-M7`が実行されたシェルセッション上でのScalaバージョンは`2.11.0-M7`ですが、そのシェルセッションを抜けると`scalaenv local`で指定されていたバージョンに切り替わります。

```shell-session
[mazgi@BRUICHLADDICH] $ pwd
/tmp/scalaenv_testdrive/2.11.0-M8
[mazgi@BRUICHLADDICH] $ scala -version
Scala code runner version 2.11.0-M8 -- Copyright 2002-2013, LAMP/EPFL
[mazgi@BRUICHLADDICH] $ zsh
[mazgi@BRUICHLADDICH] $ scalaenv shell scala-2.11.0-M7
[mazgi@BRUICHLADDICH] $ scala -version
Scala code runner version 2.11.0-M7 -- Copyright 2002-2013, LAMP/EPFL
[mazgi@BRUICHLADDICH] $ exit
[mazgi@BRUICHLADDICH] $ scala -version
Scala code runner version 2.11.0-M8 -- Copyright 2002-2013, LAMP/EPFL
```

## 感想

bashって奥深いですね