tl;dr
- パッケージマネージャ マジ便利
-
Scoop と PackageManagement は Windows で使えるパッケージマネージャ
-
PackageManagement
- Microsoft製のパッケージマネージャ
- 後ろで動いてるのは、NuGet や Chocolatey
-
Scoop
- 主にCLI環境を整えるのにフォーカスしているパッケージマネージャ
- 未登録パッケージでも、独自にBucketというリポジトリを登録すれば管理できる
-
PackageManagement
- この2つがあれば、大概のことは何とかなる
パッケージマネージャって何?
そもそも、Windows だけを使っていると、パッケージマネージャと言うものにあまり馴染みが無いかも知れない。
例えば、Firefox をインストールしようと思った時、従来の Windows ユーザであれば、
- ブラウザを開く ( 当然Firefoxではない )
- Google で Firefox と検索
- 公式サイトを表示
- ダウンロードリンクを探す
- ダウンロード
- ダウンロードフォルダを開く
- インストーラを実行
- インストーラーの指示に従い、進める
- 完了
という手順を踏んでいると思う。
また、アンインストールをする場合には、
- コントロールパネル or 設定画面 を開く
- プログラムと機能 or アプリと機能 を開く
- アプリを選択し、アプリをアンインストール
という手順が必要となる。
これが、パッケージマネージャを利用すると、
ターミナルを起動し、
# インストール
brew cask install firefox
# アンインストール
brew cask uninstall firefox
でサクッとできてしまう。これだけで、もう魅力的なのは分かる。
それ以外にも、
- バージョンアップもコマンドから簡単
- 依存関係も上手いこと解決してくれる
- A 動かすには B が必要で、B 動かすには C が必要で... だから全部入れちゃえ!
- え、C 消すの? A が使ってる B が使ってる C を、ホントに消しちゃうの?
- コマンドで全てが完了できる
- すなわち、手順の共有 が容易
- すなわち、自動化 も容易
といった利点がある。
Windows で使えるパッケージマネージャ
これまでも、Windows で使えるパッケージマネージャは存在していた。
- NuGet
- Chocolatey
- [Microsoft Web Platform Installer] (https://www.microsoft.com/web/downloads/platform.aspx)
特に、Chocolatey は登録パッケージも豊富で、私の周りでは一番利用者が多かった。
PackageManagement (OneGet)
PackageManagement は、Windows 8 の頃に生まれた OneGet というパッケージマネージャの後継で、Windows 10 で正式に採用された比較的新しいパッケージマネージャである。
これ、「また新しいエコシステム作りやがって ... 」 という話ではなく、各パッケージマネージャの操作を抽象化し、共通のコマンドで扱えるようにしただけのもので、裏で動いてるのは NuGet や Chocolatey リポジトリから取得したスクリプト。
特徴
- 何と言っても、Microsoft 公式
- Windows10ではデフォルトで使える
- Chocolatey が後ろにいる事もあり、最初からパッケージが充実している
導入
以下記事でコンパクトにまとまっている。
課題点
しかし、PackageManagement にはいくつか 使いづらいなぁ と思う点がある
- コマンド体系が分かりづらい
- サブコマンドではないので、何ができるのか、どうすればできるのかがぱっと分からない
- 慣れの問題ではあるが …
- サブコマンドではないので、何ができるのか、どうすればできるのかがぱっと分からない
- Chocolatey の問題点を継承している
- アンインストールを結構な確率で失敗する
- パッケージが古いままのものも多い
- これからエコシステムが発展していけば、あるいは
- UAC がインストールの邪魔をする
- 解決しているとの情報もあるが、未検証
今の所、PackageManagement はほぼ Chocolatey のラッパーとしてしか使っておらず、PowerShell Gallery や Web PI も対象に入れれば、また印象が変わるかも。
Scoop
Scoop は、主に CLI コマンドに特化したパッケージマネージャである。
Linuxに慣れ親しんだユーザが、Windows でもその使い心地を再現したいといったニーズに答えている。
特徴
- 公式リポジトリ ( Scoop では、Bucket という ) で、使いそうな CLI コマンドをほとんど網羅している
- sudo curl grep sed less coreutils wget which jq git hub win32-openssh rsync netcat gcc make...
- 無いものは、独自 Bucket を Github に置けば扱える
- インストール先が
~/scoop
以下に集められて環境を汚さない (一部例外あり) - インストール / アンインストール / アップデートに失敗しない
- コマンド体系も分かりやすい
- インストール定義が JSON でできているが、これ自体がとても分かりやすい
Github の wiki が良くまとめられているので、そちらも参照するとよい
導入
以下記事では、導入の他、Chocolatey との比較もあって参考になる
ScoopでWindowsにおける開発環境構築を最適化しよう
課題点
Scoop にも、使っていてあれ?と思う点がある
2018/2/23 追記
下記の PATH が壊される件、経過観察してみたところ、どうやら Dashlane によるものだった可能性が濃厚。
Scoop 、犯人扱いしてごめんよ。
-
[未確定] PATH が壊される現在、導入した数名に発生している。再現性もない。調査中。念のため、PATH をバックアップして使用中。最近は起きていないので直ったかな?
- 常に最新版
- 開発環境等で使う場合は慎重に
どう使い分けるのか
現在、これら2つを使い分けながら Windows 環境を作っていて、それなりに満足している。
以下、思考フロー。
( Linux 環境で何かしたいなぁ ) ○。
⇒ Windows Subsystem for Linux (WSL) を使う。
( Linux のあのコマンド使いたいなぁ )○。
⇒ Scoop で探す or なければ独自 Bucket に追加。
( GUI のあるアプリ使いたいなぁ )○。
⇒ PackageManagement で探す。
( あのプログラム言語の環境つくりたいなぁ )○。
-
Case 1. ローカルで便利スクリプトを実行する、またはツールの実行環境・ビルド環境として必要
⇒ まずは Scoop で探す。Python, Go, Nodejs, Ruby 等はサクッと入れられる。 -
Case 2. チームで開発環境・バージョンを合わせる
⇒ Docker を利用。 -
Case 3. エディタの開発支援機能を使うための環境を用意する
⇒ 悩み中。いまは Scoop で雑に入れた環境を利用することで凌ぐ。
未解決問題
GUI アプリケーションのバージョンアップ問題
最近の GUI アプリケーションは、独自にアップデート機能を有している物が多く、パッケージマネージャはほぼインストール / アンインストールを自動化しているだけな感じ。まぁ、それでも十分だけど。
インストーラの設定デフォルト問題
Chocolatey の場合、内部でインストーラを Silent モードで起動しているだけのものも多いが、設定値がデフォルトになるのが、時々イラッとする。
管理対象多い問題
マシン移行を考えた時、PackageManagement, Scoop, WSL 側の apt と移行しないといけない環境が多い。
家 Mac では Ansible + ちょっと手作業 で移行できるようできているので、それと比べると煩雑。
Tips
Alias の上書き
Powershell には、デフォルトでいくつかの Alias が存在している。
PS> Get-Alias ls
CommandType Name Version Source
----------- ---- ------- ------
Alias ls -> Get-ChildItem
多分、PowerShell の使い勝手を Linux ユーザにも馴染むようにとの心遣いであると思うのだが、オプションも違ったりとイマイチ心遣いが足りず、Scoop で入れた方のコマンドが使いたいという時がある。
PS> ls -la
Get-ChildItem : パラメーター名 'la' に一致するパラメーターが見つかりません。
発生場所 行:1 文字:4
+ ls -la
+ ~~~
+ CategoryInfo : InvalidArgument: (:) [Get-ChildItem]、ParameterBindingException
+ FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand
そんな時は、PowerShell の Profile で Alias を無効化すると良い。
PS> notepad $profile
上記コマンドでメモ帳が立ち上がるので、その中に
...
del alias:ls -Force
と無効にしたい Alias を記述する。
これで、Alias にヒットせずに、Scoop で入れたコマンドの方が呼ばれる。
PS> ls -la
drwxr-xr-x 9 Hoge Administrators 4096 Apr 25 2017 .
drwxr-xr-x 11 Hoge Administrators 4096 Nov 13 15:31 ..
-rw-r--r-- 1 Hoge Administrators 7 Sep 23 2016 .gitignore
-rw-r--r-- 1 Hoge Administrators 686 Oct 4 2016 README.md
Powershell 版が呼びたければ、直接 Alias の参照先コマンドを打てば良い
PS> Get-ChildItem
環境変数の設定
Powershell からシステム環境変数を変更するのは、結構手間がかかったりする。
そこで、Profile に関数を設定しておくと良い。
最新版は、gist に置いてある
...
function setenv($key, $value, $target) {
if (! $target) {
$target = "User"
}
if (($target -eq "Process") -Or ($target -eq "User") -Or ($target -eq "Machine")) {
$now = [environment]::getEnvironmentVariable($key, $target)
if ($now) {
$tChoiceDescription = "System.Management.Automation.Host.ChoiceDescription"
$result = $host.ui.PromptForChoice("", "Already Exists. Overwrite ?", @(
New-Object $tChoiceDescription ("&Yes")
New-Object $tChoiceDescription ("&No")
), 1)
switch ($result) {
0 {break}
1 {
Write-Host "`r`nAborted." -ForegroundColor DarkRed
return
}
}
}
[environment]::setEnvironmentVariable($key, $value, $target)
[environment]::setEnvironmentVariable($key, $value, "Process")
} else {
Write-Host "Failure ! - Invalid Target" -ForegroundColor DarkYellow
}
}
function setpath($value, $target) {
if (! $target) {
$target = "User"
}
if (($target -eq "Process") -Or ($target -eq "User") -Or ($target -eq "Machine")) {
$item = Convert-Path $value
$path = [environment]::getEnvironmentVariable("PATH", $target)
$list = $path -split ";"
if (! $list.Contains($item)) {
$_path = $path + ";" + $item + ";"
$newpath = $_path -replace ";;", ";"
[environment]::setEnvironmentVariable("PATH", $newpath, $target)
$_path = [environment]::getEnvironmentVariable("PATH", "Process") + ";" + $item + ";"
$newpath = $_path -replace ";;", ";"
[environment]::setEnvironmentVariable("PATH", $newpath, "Process")
} else {
Write-Host "Already Exists." -ForegroundColor DarkYellow
}
} else {
Write-Host "Failure ! - Invalid Target" -ForegroundColor DarkRed
}
}
PS1> setenv foo bar # Add foo=bar as User Environment Variables
PS1> setenv foo bar Machine # Add foo=bar as Machine Environment Variables
PS1> setpath C:\hoge\huga # Add 'C:\hoge\huga' to path as User Environment Variables
PS1> setpath C:/hoge/piyo # '/' is convertible to '\'
ConEmu 等から $profile
が読み込めない
ConEmu や、 Cmder は、独自の Profile を持っているため、$profile
を読み込んでくれない。そんな時は、独自 Profile の方で $profile
を読み込むように指示すると良い。
...
.$profile # ← この一行を追加する