rcmdnk's blog

We Get Requests

MacでHomebrewを使ってパッケージを管理していると インストールした覚えの無いパッケージも大量に入っている事がありますが、 それはインストールしようとしたパッケージが必要とするモジュールなどを含むパッケージを自動でインストールしてくれているからです。

パッケージのリストを管理したい時にこういった依存先のパッケージも全て記録していくと 後々元のパッケージが要らなくなっても残ってしまったりします。

Homebrewでは最近パッケージのインストール時に直接インストールされたのか、 依存関係によってインストールされたのか確認出来る様なフラッグが導入されました。

installed_on_request/installed_as_dependency

Homebrewでインストールされたパッケージを確認するには通常 brew listとしますが、これだと全てのインストールされたパッケージが表示されます。

直接インストールされたのか、依存関係によってインストールされたのか を確認するには

$ brew info --json=v1 <package>

を使います。

$ brew info --json=v1 brew-file|jq .
[
  {
    "name": "brew-file",
    "full_name": "rcmdnk/file/brew-file",
    "desc": "Brewfile manager for Homebrew.",
    "homepage": "https://github.com/rcmdnk/homebrew-file/",
    "oldname": null,
    "aliases": [],
    "versions": {
      "stable": "4.2.0",
      "bottle": false,
      "devel": null,
      "head": "HEAD"
    },
    "revision": 0,
    "version_scheme": 0,
    "installed": [
      {
        "version": "4.2.0",
        "used_options": [],
        "built_as_bottle": false,
        "poured_from_bottle": false,
        "runtime_dependencies": [],
        "installed_as_dependency": false,
        "installed_on_request": true
      }
    ],
    "linked_keg": "4.2.0",
    "pinned": false,
    "outdated": false,
    "keg_only": false,
    "dependencies": [],
    "recommended_dependencies": [],
    "optional_dependencies": [],
    "build_dependencies": [],
    "conflicts_with": [],
    "caveats": null,
    "requirements": [],
    "options": [
      {
        "option": "--without-completions",
        "description": "Disable bash/zsh completions"
      }
    ],
    "bottle": {}
  }
]

こんな感じでJSON形式でパッケージの情報がとってこれます1

この中のinstalledの項目にある installed_as_dependency/installed_on_requestというのが 最近導入された値です。

installed_as_dependencytrueなら他のパッケージが依存するものとしてインストールされたものになります。 installed_on_requesttrueなら直接brew install <package>でインストールされたものになります。

通常はこれらはどちらかがtrueでどちらかがfalseと反対になっているはずですが、 一部、両方trueだったりするものもあってちょっと良く分かりません。 (ただのバグか、導入の段階でちょっと混乱が起きてるのか。。。?)

また、この値が導入されたのは最近(6月中旬頃2)なので それ以前にインストールされたパッケージについては これらの値はnullになっています。

これらの値を更新するにはreinstallなどする必要があります。

brew-fileでの取扱

そもそもこの情報はbrew-fileのIssuesでこれ使えないか、と教えてもらったもので 実際にこれらの情報を使える様にしてみました。

Use new installed_on_request and installed_as_dependency flags · Issue #75 · rcmdnk/homebrew-file

brew file initに新しく--on_requestというオプションを追加して

$ brew file init --on_request

とすると、installed_on_requesttrueのものだけをBrewfileに書き出す様になります。

もしくは環境変数で

export HOMEBREW_BREWFILE_ON_REQUEST=1

と設定しておくと常に--on_requestを付加している状態になります。

ただし、まだこの値がnullのものもあるのでそういったものに関してはそのまま書き出す様にしています。

なので今現在--on_requestをしてもほとんどのパッケージが書き出されてしまう可能性がありますが 今後徐々に値が入っているパッケージが増えていくので徐々に使える様になるはずです。

leavesとの違い

以前、これに近いことをbrew leavesの出力を使ってやっていました。 brew leavesはどのパッケージからも依存されていないパッケージだけを表示するコマンドです。

$ brew file init --leaves

もしくは環境変数で

export HOMEBREW_BREWFILE_LEAVES=1

としておくとこのbrew leavesの結果だけを書き出す様になります。

このleavesを使う問題点としては、 例えばgoを必要として最初にインストールした場合、 他のgoに依存したパッケージを後からインストールすると gobrew leavesに残らなくなります。

これだと困るのでとりあえずの処置として

export HOMEBREW_BREWFILE_TOP_PACKAGES=go,coreutils

の様に環境変数で設定しておくとこれらのパッケージは常に書き出すことが出来る様にしています。

ただし、逆に何かの依存関係でインストールされたものも その親のパッケージがアンインストールされると今度はそれがleavesとして残る様になってしまいます。 これらは正直いらないパッケージなのですがこれまでだと自分でそのパッケージを判断する以外に確認のしようがありませんでした。

これらを解決してくれるのが上のinstalled_on_requestなどの値で、 実際にインストール時に値が振られるので その後親のパッケージの削除などに左右される事無く値を見ることが出来ます。

今の自分の環境で調べてみると

  • 全てのパッケージ: 223
  • leaves: 127
  • on_request (null含む): 210

となっています。 nullなものが多いのでほとんどのパッケージが書き出されている状態ですが、 全ての値が埋まれば大体同じ数になるはずで、 違いは

  • on_requestだけど後から入れたパッケージが依存している場合(on_requestのみに載る)、
  • as_dependencyだけど親のパッケージがアンインストールされた場合(leavesのみに載る)

になります。

必要のないパッケージの削除

その様な確認が出来る様になったので、何かのパッケージの依存パッケージとしてインストールされたものの、 親のパッケージがアンインストールされて最早不要になったパッケージを削除する事も出来ます。

brew-fileを使えば

$ brew file clean_non_request
brew uninstall unixodbc

###########################################
# This is dry run.
# If you want to enforce cleanup, use '-C':
#     $ brew-file clean_non_request -C
###########################################

とすることでその様なパッケージを探すことが出来ます。

$ brew file clean_non_request -C

とするとそれらのパッケージを実際に削除します。

まとめ

Homebrewは未だにかなりアクティブに更新があって 細かな情報確認も出来る様になってきています。

なかなか全部追うのは大変ですが、まだ気付いてない機能もありそうなので 暇があったらちょっとずつ見ていきたいと思います。

Sponsored Links
  1. 出力は一行で書かれてるのでjqで整形してあります。jqbrew install jqでインストールできます。

  2. tab: store installed_{as_dependency,on_request}. · Homebrew/brew@b99fb56

Sponsored Links

« HomebrewでインストールされるPython(2)の変更について werckerで鍵認証に失敗してdeploy出来なかった件 »

}