ScoopでWindowsにおける開発環境構築を最適化しよう

1. はじめに

Windowsには他のOSには無い致命的な問題が一つあった。そう、OS標準のパッケージマネージャが無いことだ。

Windows10ではPackageManagementという大変素晴らしいOS標準のパッケージマネージャが搭載された。

これでコマンドラインだけで開発環境をガンガン作れるに違いない。そう考える人がいてもおかしくはない。正直、僕だってそう思いたい。

2. PackageManagementの問題点

僕はPackageManagementのアーキテクチャが難しすぎる事は大きな問題だと考えている。このエントリを是非読んで欲しい。

もうね、何でこんなに大変なことになってるのかと。

いや、歴史的経緯を鑑みつつ、OSに標準搭載されるパッケージマネージャが持つべき仕組みをキチンと備えた妥当な設計になっているじゃないか、と強い調子で言われれば説得力があるようにも思える。

じゃあ、この素晴らしい抽象度で実装されたPackageManagement様におかれましては、それはそれは様々なバリエーションの動作をするんですよね?というと、実態はそうじゃない。

現在のPackageManagementは、雑に言えばChocolateyの何かややこしいラッパーでしかない。確かに、PowerShell Galleryには、沢山のモジュールがあるよ。あれ、便利なモジュールどんだけあんの?

僕としては、直接Chocolatey使えば良いと思うんだよね。ジッサイ。

「OSに標準搭載されたボキャブラリでアプリケーションをインストールし、アンインストールできることは大変すばらしい事だ!」

アア、ハイ、ソノトオリデスネ。

3. Chocolateyの問題点

Chocolatey使ってて、まずダルいなって思うのは、UACのポップアップ。コマンドラインで作業してるのに突然現れてマウスでクリックしないと先にすすめなくなるアレ。マジでイライラする。

Windows10はマルチユーザOSだけど、ユーザの切り替えなんてやってねぇよ。というか、複数の環境が必要ならDockerなり、Hyper-Vなり使ってる。だからね、現在のユーザローカルにだけコマンドのパスが通れば良いんだよ。

次にダルいなって思うのは、結構な頻度でアンインストールが失敗すること。インストールが綺麗にできる以上に、大事なのはアンインストールが綺麗にできることだ。

いやいや、MSI形式のインストーラの問題だろ、それって言われれば、確かにちゃんと切り分けてないから、これは言いがかりかもしれないけどね。

ある程度の規模感でChocolatey使おうと思うと、ローカルリポジトリ的なものが欲しくなると思うんだけど、それを用意するのがとんでもなく面倒なのも辛い。確かに、How To Host Feed辺りをちゃんと読めば出来るよ。

面倒すぎるんで、僕としてはあんまやりたくない感じの手順だけどね。

というわけで、僕の個人的な趣向としてはChocolateyが嫌いだ。避けようが無くて使う事があるのは否定しないが、出来る限り使いたくないとさえ思っている。

4. Scoopについて

というわけで、今週のおススメはScoopだ。

4.1. Scoopを使うべきか?

まず、最初に言っておく。Scoopは真っ当なパッケージマネージャではない。そして、linux文化圏にいるけど、色々理由があって今はWindowsを使ってるって人間に向けて開発されている。

Scoopがどういう思想で作られているかみたいな話は、公式のWikiに書いてある。

これを読めば、自分がScoopを使うべきなのかは、ある程度ハッキリと理解できるだろう。

Windowsしか使わないし、linux文化圏のやり方をWindows上でやることに意義を感じないなら、Scoopを使う必要はない。

そして、Scoopは開発環境を構築するためのツールだ。開発環境構築を楽にすることに強くフォーカスしているおかげで、色んなことがシンプルで簡単になっている。細かいことは、あまり考慮していない。

4.2. Scoopの何が素晴らしいか

ユーザのローカルディレクトリに何でもインストールするので、あのうざったいUACポップアップが出ない。

C:\Users\taichi\scoop\shims

みたいなディレクトリにコマンドをガンガン投げ込むスタイルだ。Scoopをインストールした時にこのディレクトリがPATHに追加される。

次に、ローカルディレクトリにファイルを展開していくスタイルなので、アンインストールが安定して動作する。特に難しい事をやってないので、それほど失敗する余地が無いってことなんだろう。

そして、Scoopでインストール可能なアプリケーションのメタデータはgitリポジトリで管理している。だから、Scoop標準のメタデータストア内に、欲しいものが無いなら比較的簡単にオレオレScoopリポジトリを作れる。

4.3. Scoopのダメなところ

4.3.1. Windowsインストーラ文脈にのっていないこと

一番ダメなところであり、素晴らしいところは、Windowsのインストーラに関する文脈に全く乗っていないところだ。つまり、Scoopを使ってインストールしたアプリケーションは、Windows標準のアプリと機能から参照できない。ただし、これはmainバケットからインストールしたものに限る。

例えば、openjdkmainバケットにあるが、oraclejdkextrasバケットという少し隔離された場所にある。mainバケットは、scoopがデフォルトで参照するアプリケーションリポジトリで、extrasバケットは、追加のコマンドを実行することで参照できるリポジトリだ。

中身をきちんと確認していないがphpというバケットもある。流石のPHPだ。

extrasバケットには、exeやmsiといったWindowsのインストーラに関する文脈に乗っているものが含まれている。例えば、oraclejdkをインストールするなら、あの忌々しいUACポップアップが普通にポロリーンだ。

4.3.2. 最新版しか使えないこと

アプリケーションは基本的に最新版しか使えないし、細かくリビジョンを切り替えることは出来ない。みんなが大好きなpyenvだのnvmだのといった仕組みとは違うってことだ。

Scoopではメジャーバージョンが違うものは、違うアプリケーションとして管理している。例えば、

scoop install ruby

とすると、今なら 2.4.1-2 が入るし

scoop install ruby19

とすれば、今なら 1.9.3-p551 が入る。

両方入れた時に、rubyコマンドで実行されるバイナリを切り替えるには、 scoop resetというサブコマンドが用意されているので、それを使って切り替えればいい。詳細は公式マニュアルを見て欲しい。

細かいバージョンの差異に伴う再現テストなんて、ローカルでやらずにCIサーバでマトリックステストすれば良くない?僕としては、そういう気持ちです。

ちなみに、scoopを使えば、みんなが大好きなanacondaもコマンド一発でインストールできるよ。僕は使わんけど。

5. さぁ、Scoopを使おう

5.1. Scoopのインストール

こんな所まで長文を読んだって事は、Scoopを使おうって気になったってことだろうから、Scoopをインストールしてみよう。

Powershell3以上の環境で、こういうコマンドを実行する。Chocolateyのインストールと大体一緒だよね。

iex (new-object net.webclient).downloadstring('https://get.scoop.sh')

エラーが出てインストールできないなら、こういうコマンドで、ExecutionPolicy を少し緩めて欲しい。

Set-ExecutionPolicy RemoteSigned -scope CurrentUser

これで、scoop コマンドが実行できるようになった。

5.2. Scoopでアプリケーションをインストール

じゃあ、試しにnodeでもインストールしてみようか。その前に、Scoopのバケットを検索してみよう。

scoop search node

今の時点では、こういう感じの出力がなされる。

'main' bucket:
    eventstore (4.0.2) --> includes 'EventStore.ClusterNode.exe'
    nodejs-lts (6.11.3)
    nodejs (8.5.0)
    sliksvn (1.9.7) --> includes 'svn-populate-node-origins-index.exe'

あなたは最新のnodeをガンガン使って行くNodeジャンキーだろうか?それとも、しっかりと動作するLTS版を好むタイプだろうか?

僕は、もちろんNodeジャンキーなので、最新版のnodejsを使いたい。こういうコマンドを入力しよう。

scoop install nodejs

こういう感じの出力がなされて、最新版のnodejsがインストールされた。

Installing 'nodejs' (8.5.0).
node-v8.5.0-win-x64.7z (8.7 MB) [=============================================================================] 100%
Checking hash of node-v8.5.0-win-x64.7z... ok.
Extracting... done.
Linking ~\scoop\apps\nodejs\current => ~\scoop\apps\nodejs\8.5.0
Persisting bin
Persisting cache
Running post-install script...
'nodejs' (8.5.0) was installed successfully!

素晴らしい。

5.3. Scoopでアプリケーションをアンインストール

次は、アンインストールだ。今入れたばかりのアプリケーションを何でアンインストールするのかって?

それは、僕がインストールジャンキーだから、というのは冗談で単に説明のためだ。

予想できると思うけど、こういうコマンドでアンインストールできる。

scoop uninstall nodejs

こういう感じの出力がなされて、さっきインストールしたばかりのnodejsがきれいさっぱりいなくなった。

Uninstalling 'nodejs' (8.4.0).
Unlinking ~\scoop\apps\nodejs\current
Removing ~\scoop\apps\nodejs\current from your path.
Removing ~\scoop\apps\nodejs\current\bin from your path.
'nodejs' was uninstalled.

キマるぜぇ!!

5.4. Scoopで複数バージョンをインストールしたい

どうしてもローカルに複数バージョンのアプリケーションをインストールしたいって呪われた性癖を持つ人はいると思う。

そういうあなたには、versionsバケットというものが用意されている。こういうコマンドを実行すると、最新版ではないアプリケーションの情報を検索できるようになる。

scoop bucket add versions

これで、もう一度nodeを検索してみよう。

scoop search node

ようこそ、バージョニング地獄へ。

'main' bucket:
    eventstore (4.0.2) --> includes 'EventStore.ClusterNode.exe'
    nodejs-lts (6.11.3)
    nodejs (8.5.0)
    sliksvn (1.9.7) --> includes 'svn-populate-node-origins-index.exe'

'versions' bucket:
    nodejs010 (0.10.48)
    nodejs012 (0.12.18)
    nodejs4 (4.8.4)
    nodejs6 (6.11.3)
    nodejs7 (7.10.1)
    nodejs8 (8.5.0)

安心してくれ。どのメジャーバージョンでもコマンド一発で最新版が入れ放題だ!

5.5. もっとScoopを知りたい!

公式のWikiを見てほしい。すごく丁寧にドキュメントが書かれていて、知りたい事はなんでも分かるようになっている。

6. まとめ

僕は、かなりLinux文化に染まっているとは言え、GNU信者ではないのでゲームができないLinuxデスクトップを使ったりはしない。普通のWindowsユーザだ。

なので、Bash on Windowsに喜んだりする一方で、ある程度はPowerShellを使って作業したい。

とはいえ、いくら設計に優れていても、ややこしいだけのものを我慢して使いたくはない。

こういう気持ちに同調してくれるWindowsユーザは多い筈だ。コマンドラインベースで、開発環境のセットアップを自動化したいが、どうもしっくりこないって人は多いんじゃないかな。

そういうあなたは、是非Scoopを試してみて欲しい。