ppic 機能追加しました。

昨日作っていたppicに機能を追加しました。現在の最新は0.2.5です。追加された機能は以下です。

  • --stable-onlyオプションを追加しました。
  • --allオプションはdeprecatedになり--installedオプションになりました
  • 一定時間(deaultは10分)各packageの情報のjsonをcacheしておくことにしました
  • --dependencyオプションを付けました

--stable-onlyオプションを追加しました

昨日の記事のコメントには書いたのですが、--stable-onlyオプションを追加 しました。これは、packageの更新を確認したかった際に、alpha版を取ってく るのではなくstable版を取得したい、という希望を叶えようとしてのことです。

現在、ちょうどdjangoがalpha版のリリースしていて1.8a1を出すのですが。 stable版の1.7.4との更新を見たいというような状況です。

オプション無しで実行した結果は以下の様になります。(1.8a)

(django)$ ppic django
collecting information .. takes at least 0.0 sec
{
  "packages": [
    {
      "name": "Django",
      "_previous_version": "1.7.1",
      "version": "1.8a1",
      "last_modified": "2015-01-16T22:25:13"
    }
  ],
  "update_candidates": [
    "Django: '1.7.1' -> '1.8a1'"
  ],
  "new_install_candidates": []
}

一方 --stable-only を付けた場合は以下の様になります(1.7.4)

(django)$ ppic django --stable-only
collecting information .. takes at least 0.0 sec
{
  "packages": [
    {
      "name": "Django",
      "_previous_version": "1.7.1",
      "version": "1.7.4",
      "last_modified": "2015-01-27T17:22:19"
    }
  ],
  "update_candidates": [
    "Django: '1.7.1' -> '1.7.4'"
  ],
  "new_install_candidates": []
}

--allオプションはdeprecatedになり--installedオプションになりました

これはそのままです。 --all というオプション名は分かりにくいかなと 思い止めました。一応現在のversion(0.2.5)でも有効では有ります。ただ deprecatedです。

一定時間(deaultは10分)各packageの情報のjsonをcacheしておくことにしました

--installed オプションを付けて結果を眺めていると結構楽しかったりす るのですが。環境中にインストールされているパッケージの数が多いとそれな りに時間が掛かります。基本的には、情報を取得するために、インストールさ れているパッケージ毎にpypiにアクセスする必要があるので遅くなるのはしょ うが無いところがあります。ただ、遊んでいる最中に待たされても気分も良く ないだろうということで結果をcacheすることにしました。

cache先は --logging=debug オプションを付加すると調べる事ができます。

(django)$ ppic pyramid --logging=debug 2>&1 | head
distribution[name=pyramid] is not found
collecting information .. takes at least 0.0 sec
load: cachepath=/var/folders/b7/2rk7xp2d0hb2r21zbzjwxb_m0000gn/T/ppic.json
save: cachepath=/var/folders/b7/2rk7xp2d0hb2r21zbzjwxb_m0000gn/T/ppic.json
{
  "packages": [
    {
      "name": "pyramid",
      "version": "1.5.2",
      "last_modified": "2014-11-10T05:06:15"

今回の場合だと「/var/folders/b7/2rk7xp2d0hb2r21zbzjwxb_m0000gn/T/ppic.json」ですね。

cache timeoutの指定

--cache-timeout を使うとcacheを利用する時間を引き伸ばすことができます。例えば、現状取得したデータで十分。最新の情報を知りたい訳ではなくなるべく待ちたくない。という時には以下の様にすると長時間キャッシュを使います。

(django)$ ppic --cache-timeout=100000000000000 pyramid

また、cacheを一時的に無効にしたいという場合には --no-cache というオプションがあります。

dependencyオプションを付けました

これは完全に遊びなのですが。パッケージの依存関係を考慮して取得するようにしてみました。--dependencyを付けると有効になります。 例えば、pyramidに対して使うと以下のような出力になります。

(django)$ ppic --dependency pyramid
  {
    "packages": [
      {
        "name": "pyramid", 
        "version": "1.5.2", 
        "last_modified": "2014-11-10T05:06:15"
      }
    ], 
    "update_candidates": [], 
    "new_install_candidates": [
      "pyramid: '' -> '1.5.2'"
    ], 
    "dependencies": [
      {
        "pyramid": "UNKNOWN"
      }
    ]
  }

依存先のパッケージが表示されていないですね。。これは環境にpyramidがイ ンストールされていないためです(new_install_candidatesのところにpyramid が有りますね)。

残念ながらpythonではパッケージのインストールないしはダウンロードを抜き に依存先のパッケージの情報を知ることができません。pypiにアクセスして得 られるjsonも依存ライブラリを表すオプションであるinstall_requiresに 関する情報を持っていません。(この辺りnpm showにdependenciesのあるnode の方が羨ましいと思いますね)

環境に該当パッケージがインストールされている場合

環境に該当パッケージがインストールされている場合はもちろん、依存関係を見てくれます。

(pyramid)$ ppic --dependency pyramid
{
  "packages": [
    {
      "name": "PasteDeploy", 
      "_previous_version": "1.5.2", 
      "version": "1.5.2", 
      "last_modified": "2013-12-27T17:41:02"
    }, 
    {
      "name": "WebOb", 
      "_previous_version": "1.4", 
      "version": "1.4", 
      "last_modified": "2014-05-15T01:30:57"
    }, 
    {
      "name": "pyramid", 
      "_previous_version": "1.5.1", 
      "version": "1.5.2", 
      "last_modified": "2014-11-10T05:06:15"
    }, 
    {
      "name": "repoze.lru", 
      "_previous_version": "0.6", 
      "version": "0.6", 
      "last_modified": "2012-07-12T20:48:40"
    }, 
    {
      "name": "setuptools", 
      "_previous_version": "3.6", 
      "version": "12.1", 
      "last_modified": "2015-02-11T01:16:43"
    }, 
    {
      "name": "translationstring", 
      "_previous_version": "1.1", 
      "version": "1.3", 
      "last_modified": "2014-11-05T20:19:35"
    }, 
    {
      "name": "venusian", 
      "_previous_version": "1.0", 
      "version": "1.0", 
      "last_modified": "2014-06-30T17:27:36"
    }, 
    {
      "name": "zope.deprecation", 
      "_previous_version": "4.1.1", 
      "version": "4.1.2", 
      "last_modified": "2015-01-13T15:28:52"
    }, 
    {
      "name": "zope.interface", 
      "_previous_version": "4.1.1", 
      "version": "4.1.2", 
      "last_modified": "2014-12-28T01:05:28"
    }
  ], 
  "update_candidates": [
    "pyramid: '1.5.1' -> '1.5.2'", 
    "setuptools: '3.6' -> '12.1'", 
    "translationstring: '1.1' -> '1.3'", 
    "zope.deprecation: '4.1.1' -> '4.1.2'", 
    "zope.interface: '4.1.1' -> '4.1.2'"
  ], 
  "new_install_candidates": [], 
  "dependencies": [
    {
      "pyramid": [
        "setuptools", 
        "WebOb", 
        "repoze.lru", 
        {
          "zope.interface": [
            "setuptools"
          ]
        }, 
        {
          "zope.deprecation": [
            "setuptools"
          ]
        }, 
        "venusian", 
        "translationstring", 
        "PasteDeploy"
      ]
    }, 
    {
      "zope.deprecation": [
        "setuptools"
      ]
    }, 
    {
      "zope.interface": [
        "setuptools"
      ]
    }
  ]
}

dependencies部分は完全にお遊びです。少し特殊な表記になっているのですが 各パッケージの依存関係をjsonで表しています。この表記では、子を持ってい るパッケージ(依存先パッケージを持つパッケージ)はobjectとして表示され、 子を持たないパッケージは単なる文字列として表記されます。このようなアド ホックな表記にした理由は子を持たないパッケージをオブジェクトの表記にし た場合に現状のjson出力のフォーマットの場合だと縦に間延びして依存関係が どのようになっているのか追いづらくなってしまっていたからです。