Python을 사용한 Mercurial 스크립팅
문제
Python에서 프로그래밍 방식으로 수은 개정 번호/ID(숫자가 아닌 해시임)를 얻으려고 합니다.
그 이유는 웹사이트의 CSS/js 파일에 다음과 같이 추가하고 싶기 때문입니다.
<link rel="stylesheet" href="example.css?{% mercurial_revision "example.css" %}" />
따라서 스타일시트가 변경될 때마다 새 URL을 얻게 되며 더 이상 이전에 캐시된 버전을 사용하지 않게 됩니다.
또는 수은에 대한 좋은 문서를 어디서 찾을 수 있는지 알고 있다면 파이썬 모듈, 그것도 도움이 될 것입니다.어디서도 찾을 수 없는 것 같아요.
내 솔루션
결국 하위 프로세스를 사용하여 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'
해결책
공식 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' )
다른 팁
당신은 의미합니까? 이 문서?
해당 페이지에 명시된 대로 공식적인 API는 언제든지 변경할 수 있는 권리를 보유하고 있기 때문입니다.그러나 지난 몇 버전의 변경 사항 목록을 볼 수 있지만 그다지 광범위하지는 않습니다.
업데이트 된 클리너 하위 프로세스 버전 (용도 .check_output()
, Python 2.7/3.1)에 추가하여 Django 설정 파일에서 원유 최종-투-엔드 배포 검사를 위해 사용합니다 (HTML 주석에 덤프) :
import subprocess
HG_REV = subprocess.check_output(['hg', 'id', '--id']).strip()
당신은 그것을 a로 감을 수 있습니다 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 = "???"
시도해보십시오 키워드 확장
Python 2를 사용하는 경우 사용하고 싶습니다. hglib
.
Python 3을 사용하고 있다면 무엇을 사용할지 모르겠습니다. 죄송합니다. 아마 hgapi
.
이 답변의 내용
- Mercurial의 API
- hglib를 사용하는 방법
- hglib가 Python 2 사용자를위한 최상의 선택 인 이유
- 후크를 쓰고 있다면 낙담 한 내부 인터페이스는 끔찍하게 편리합니다.
Mercurial의 API
Mercurial에는 두 개의 공식 API가 있습니다.
- Mercurial Command Server. Python 2를 사용하여 이야기 할 수 있습니다.
hglib
(위키, pypi) 패키지, 수은 팀이 관리합니다. - Mercurial의 명령 줄 인터페이스. 당신은 그것을 통해 이야기 할 수 있습니다
subprocess
, 또는hgapi
, 또는 somesuch.
hglib를 사용하는 방법
설치:
pip install python-hglib
용법:
import hglib
client = hglib.open("/path/to/repo")
commit = client.log("tip")
print commit.author
더 많은 사용법 정보 hglib 위키 페이지.
hglib가 Python 2 사용자를위한 최상의 선택 인 이유
수은 팀에 의해 유지되기 때문에 수은 팀이 수은과의 인터페이스를 추천하는 것입니다.
머큐리리의 위키에서, Mercurial과의 인터페이스에 대한 다음 진술 :
대다수의 타사 코드의 경우 가장 좋은 방법은 Mercurial의 게시, 문서화 및 안정적인 API : 명령 줄 인터페이스를 사용하는 것입니다. 또는 사용하십시오 사령관 또는 빠르고 안정적인 언어 중립 인터페이스를 얻기 위해 그것을 기반으로하는 라이브러리.
명령 서버 페이지에서 :
Command Server] 타사 응용 프로그램 및 라이브러리는 명령 당 시작 오버 헤드를 제거하는 파이프를 통해 Mercurial과 통신 할 수 있습니다. 그런 다음 라이브러리는 명령 생성 및 구문 분석을 캡슐화하여 언어에 적합한 API를 이러한 명령에 제시 할 수 있습니다.
Mercurial Command-Server의 Python 인터페이스는 hglib
.
그건 그렇고 명령 줄 인터페이스의 명령 당 간접비는 농담이 아닙니다. 한때 사용한 매우 작은 테스트 스위트 (약 5 개의 테스트)를 구축했습니다. hg
~을 통해 subprocess
EG 병합 상황과 함께 소수의 저장소를 만들고 Commit의 Commit을 만들려면. 프로젝트 전체에서 스위트 타임은 5 ~ 30 초 사이에 있었고 거의 모든 시간이 hg
전화.
후크를 쓰고 있다면 낙담 한 내부 인터페이스는 끔찍하게 편리합니다.
파이썬 후크 함수의 시그니처는 다음과 같습니다.
# 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)
ui
그리고 repo
앞서 언급 한 낙담 비공식의 일부입니다 내부 API. 그들이 당신의 기능에 바로 거기에 있다는 사실은이 예에서와 같이 사용하기 편리하게 사용합니다. 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
.
FWIW 모든 페이지/보기 렌더링에서 해당 값을 가져 오지 않기 위해 내 배포를 settings.py
파일. 그런 다음 참조 할 수 있습니다 settings.REVISION
수은 및/또는 다른 프로세스에 액세스하는 모든 오버 헤드없이. 서버를 다시로드 하면서이 값 변경이 있습니까?
나는 OP가하고 싶었던 것과 똑같은 일을하고 싶었습니다. hg id -i
스크립트에서 (해당 저장소의 단일 파일이 아닌 전체 저장소의 팁 개정판 가져 오기) 그러나 나는 Popen과 코드를 사용하고 싶지 않았습니다. brendan
나를 시작했지만 내가 원하는 것이 아니 었습니다.
그래서 나는 이것을 썼다 ... 댓글/비판을 환영합니다. 이것은 팁 Rev를 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")