web-dev-qa-db-ja.com

python)を使用したMercurialスクリプト

私はPythonでMercurialリビジョン番号/ ID(番号ではなくハッシュです)をプログラムで取得しようとしています。

その理由は、次のようにWebサイトのcss/jsファイルに追加したいからです。

<link rel="stylesheet" href="example.css?{% Mercurial_revision "example.css" %}" />

そのため、スタイルシートに変更が加えられるたびに、新しいURLが取得され、古いキャッシュバージョンは使用されなくなります。

[〜#〜]または[〜#〜] Mercurialの適切なドキュメントがどこにあるか知っている場合python module、それも役に立ちます。どこにも見つからないようです。

私の解決策

サブプロセスを使用して、hgノードを取得するコマンドを実行することになりました。 APIが同じままであることが保証されていないため、このソリューションを選択しましたが、bashインターフェイスはおそらく次のようになります。

import subprocess

def get_hg_rev(file_path):
    pipe = subprocess.Popen(
        ["hg", "log", "-l", "1", "--template", "{node}", file_path],
        stdout=subprocess.PIPE
        )
    return pipe.stdout.read()

使用例:

> path_to_file = "/home/jim/workspace/lgr/pinax/projects/lgr/site_media/base.css"
> get_hg_rev(path_to_file)
'0ed525cf38a7b7f4f1321763d964a39327db97c4'
29
Jiaaro

確かに公式のAPIはありませんが、他の拡張機能、特にhgにバンドルされている拡張機能を読むことで、ベストプラクティスについてのアイデアを得ることができます。この特定の問題に対して、私は次のようなことをします:

from Mercurial import ui, hg
from Mercurial.node import hex

repo = hg.repository('/path/to/repo/root', ui.ui())
fctx = repo.filectx('/path/to/file', 'tip')
hexnode = hex(fctx.node())

更新ある時点でパラメータの順序が変更され、次のようになりました。

   repo = hg.repository(ui.ui(), '/path/to/repo/root' )
15
brendan

このドキュメント という意味ですか?
そのページに記載されているように、officialAPIはありません。これは、いつでも変更する権利を留保しているためです。 。しかし、最後のいくつかのバージョンでの変更のリストを見ることができます、それはそれほど広範囲ではありません。

8
rob

更新された、よりクリーンなサブプロセスバージョン(.check_output()を使用、Python 2.7/3.1)で追加、Djangoの設定ファイルで使用)大まかなエンドツーエンドのデプロイメントチェック(HTMLコメントにダンプします):

import subprocess

HG_REV = subprocess.check_output(['hg', 'id', '--id']).strip()

起動を妨げるような奇妙な問題が発生したくない場合は、tryでラップできます。

try:
    HG_REV = subprocess.check_output(['hg', 'id', '--id']).strip()
except OSError:
    HG_REV = "? (Couldn't find hg)"
except subprocess.CalledProcessError as e:
    HG_REV = "? (Error {})".format(e.returncode)
except Exception:  # don't use bare 'except', mis-catches Ctrl-C and more
    # should never have to deal with a hangup 
    HG_REV = "???"
6
Nick T

Python 2を使用している場合は、 hglib

Python 3、申し訳ありません。おそらく hgapi を使用している場合は何を使用すればよいかわかりません。

この回答の内容

  • MercurialのAPI
  • Hglibの使い方
  • Python 2人のユーザーにとってhglibが最良の選択である理由
  • あなたがフックを書いているなら、その落胆した内部インターフェースはひどく便利です

MercurialのAPI

Mercurialには2つの公式APIがあります。

  1. Mercurialコマンドサーバー。 Python 2から、hglibwikiPyPI )パッケージを使用して通信できます。 Mercurialチーム。
  2. Mercurialのコマンドラインインターフェイス。 subprocesshgapi などで話しかけることができます。

Hglibの使い方

インストール:

pip install python-hglib

使用法:

import hglib
client = hglib.open("/path/to/repo")

commit = client.log("tip")
print commit.author

hglib wikiページ のその他の使用法情報。

Python 2人のユーザーにとってhglibが最良の選択である理由

それはMercurialチームによって維持されており、MercurialチームがMercurialとのインターフェースに推奨するものだからです。

Mercurialのwikiから 、Mercurialとのインターフェースに関する次のステートメント:

サードパーティのコードの大部分では、Mercurialの公開され、文書化された、安定したAPIであるコマンドラインインターフェイスを使用するのが最善の方法です。または、 CommandServer またはそれに基づくライブラリを使用して、高速で安定した言語に依存しないインターフェイスを取得します。

コマンドサーバーページから:

[コマンドサーバーにより]サードパーティのアプリケーションとライブラリがパイプを介してMercurialと通信できるため、コマンドごとの起動のオーバーヘッドがなくなります。次に、ライブラリはコマンドの生成と解析をカプセル化して、これらのコマンドに言語に適したAPIを提示できます。

前述のように、MercurialコマンドサーバーへのPythonインターフェイスはhglibです。

ちなみに、コマンドラインインターフェイスのコマンドごとのオーバーヘッドは冗談ではありません。私はかつて、hgを介してsubprocessを使用して、たとえば、状況をマージします。プロジェクト全体を通して、スイートのランタイムは5〜30秒の間に留まり、ほぼすべての時間がhg呼び出しに費やされました。

あなたがフックを書いているなら、その落胆した内部インターフェースはひどく便利です

Pythonフック関数のシグネチャは次のようになります:

# In the hgrc:
# [hooks]
# preupdate.my_hook = python:/path/to/file.py:my_hook

def my_hook(
    ui, repo, hooktype, 
    ... hook-specific args, find them in `hg help config` ..., 
    **kwargs)

uirepoは、前述の非公式の非公式の一部です 内部API 。それらが関数argsにあるという事実は、特定のブランチ間のマージを禁止するpreupdateフックのこの例のように、それらを使用するのに非常に便利です。

def check_if_merge_is_allowed(ui, repo, hooktype, parent1, parent2, **kwargs):
    from_ = repo[parent2].branch()
    to_ = repo[parent1].branch()
    ...
    # return True if the hook fails and the merge should not proceed.

フックコードがそれほど重要ではなく、公開していない場合は、推奨されていない非公式の内部APIを使用することを選択できます。フックが公開している拡張機能の一部である場合は、hglibを使用することをお勧めします。

3
Esteis

試してみてください キーワード拡張

3
dfa

FWIWは、すべてのページ/ビューレンダリングでその値をフェッチしないようにするために、デプロイでそれをsettings.pyファイルに配置するだけです。そうすれば、Mercurialや別のプロセスにアクセスするオーバーヘッドなしにsettings.REVISIONを参照できます。サーバーをリロードせずにこの値を変更したことはありますか?

1
Ry4an Brase

OPがやりたかったのと同じことをしたかったので、hg id -iスクリプトから(そのリポジトリ内の単一のファイルではなく、リポジトリ全体のヒントリビジョンを取得します)、popenを使用したくなかったので、brendanのコードで開始しましたが、そうではありませんでした私が欲しかったもの。

だから私はこれを書いた...コメント/批評を歓迎します。これにより、16進数のチップ回転が文字列として取得されます。

from Mercurial import ui, hg, revlog
# from Mercurial.node import hex  # should I have used this?

def getrepohex(reporoot):
    repo = hg.repository(ui.ui(), reporoot)
    revs = repo.revs('tip')
    if len(revs)==1:
      return str(repo.changectx(revs[0]))
    else:
      raise Exception("Internal failure in getrepohex")
0
Warren P