Pergunta

Eu estou tentando obter o mercurial número de revisão / id (é um hash não um número) de programação em python.

A razão é que eu quero adicioná-lo à css / js arquivos em nosso site assim:

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

Assim que sempre que uma alteração é feita para a folha de estilo, ele vai ter uma nova URL e não mais usar a versão antiga em cache.

ou se você sabe onde encontrar boa documentação para o mercurial python módulo , que também seria útil. Eu não consigo encontrá-lo em qualquer lugar.

My Solution

Acabei usando subprocesso apenas para executar um comando que recebe o nó hg. Eu escolhi esta solução porque a API não é garantido para permanecer o mesmo, mas a interface do bash provavelmente irá:

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()

exemplo de uso:

> path_to_file = "/home/jim/workspace/lgr/pinax/projects/lgr/site_media/base.css"
> get_hg_rev(path_to_file)
'0ed525cf38a7b7f4f1321763d964a39327db97c4'
Foi útil?

Solução

É verdade que não há API oficial, mas você pode ter uma idéia sobre as melhores práticas através da leitura de outras extensões, particularmente aqueles empacotado com hg. Para este problema particular, eu faria algo assim:

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())

Atualizar Em algum ponto da ordem parâmetro mudou, agora é assim:

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

Outras dicas

Você quer dizer esta documentação
Note-se que, como indicado na página, não há nenhuma funcionário API, porque eles ainda reserva o direito de alterá-lo a qualquer momento. Mas você pode ver a lista de mudanças nos últimos versões, não é muito extensa.

Um atualizado, limpo versão subprocess (usos .check_output(), acrescentou, em Python 2.7 / 3.1) que eu uso no arquivo meu Django configurações para um check bruto end-to-end de implantação (I despejá-lo em um comentário HTML):

import subprocess

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

Você poderia envolvê-la em um try se você não quiser algum soluço estranha para evitar o arranque:

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 = "???"

dar uma chance para a palavra-chave extensão

Se você estiver usando Python 2, que pretende utilizar hglib .

Eu não sei o que usar se você estiver usando Python 3, desculpe. Provavelmente hgapi .

O conteúdo desta resposta
  • APIs do Mercurial
  • Como usar hglib
  • Por hglib é a melhor escolha para Python 2 usuários
  • Se você estiver escrevendo um gancho, que desencorajava interface interna é muito conveniente

APIs do Mercurial

Mercurial tem duas APIs oficiais.

  1. O servidor de comando Mercurial. Você pode falar a ele de Python 2, utilizando o hglib ( wiki , PyPI ) pacote nofollow, que é mantido pela equipe Mercurial.
  2. interface de linha de comando do Mercurial. Você pode falar com ele através subprocess , ou hgapi , ou algo assim.

Como usar hglib

Instalação:

pip install python-hglib

Uso:

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

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

Mais informações sobre o uso do hglib wiki página .

Por hglib é a melhor escolha para Python 2 usuários

Porque é mantido pela equipe Mercurial, e é o que a equipe Mercurial recomendar para interface com Mercurial.

De wiki do Mercurial, a seguinte declaração sobre a interface com Mercurial:

Para a grande maioria de código de terceiros, a melhor abordagem é a utilização do Mercurial publicada, documentado e estável API: a interface de linha de comando. Como alternativa, use o CommandServer ou as bibliotecas que são baseados sobre ele para obter um rápido, estável, língua Interface -neutral.

A partir da página do servidor de comando:

[O servidor de comando permite] aplicações de terceiros e bibliotecas para se comunicar com Mercurial ao longo de um tubo que elimina a per-comando start-up em cima. As bibliotecas podem, em seguida, encapsular a geração de comando e análise de apresentar uma API linguagem apropriada a esses comandos.

A interface Python para o servidor de comando Mercurial, como disse, é hglib.

A sobrecarga por comando da interface de linha de comando não é brincadeira, a propósito. uma vez que construído um conjunto de testes muito pequenas (apenas cerca de 5 testes) que hg usados ??através subprocess para criar, por cometer cometer, um punhado de reporte com e.g. situações mesclagem. Ao longo do projeto, o tempo de execução da suíte ficou entre 5 a 30 segundos, com quase todo o tempo gasto nas chamadas hg.

Se você estiver escrevendo um gancho, que desencorajava interface interna é muito conveniente

A assinatura de uma função de gancho Python é assim:

# 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 e repo fazem parte do referido desanimado não oficial API interna. O fato de que eles estão ali em seus argumentos de função torna terrivelmente conveniente para uso, como neste exemplo de um gancho preupdate que proíbe fusões entre certos ramos.

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.

Se o seu código de gancho não é tão importante, e você não publicá-lo, você pode optar por usar a API interna não oficial desanimado. Se o seu gancho é part de uma extensão que você está publicando, melhor aproveitamento hglib.

FWIW para evitar buscar esse valor em todas as páginas / visualizar render, eu só tenho a minha implantar colocá-lo para o arquivo settings.py. Em seguida, pode fazer referência settings.REVISION sem toda a sobrecarga de acesso mercurial e / ou outro processo. Você já teve essa mudança valor w / o recarregar seu servidor?

Eu queria fazer a mesma coisa que o OP queria fazer, obter hg id -i partir de um script (obter revisão ponta de todo o repositório, não de um único arquivo em que repo), mas eu não queria usar popen, eo código de brendan me iniciou, mas não era o que eu queria.

Então eu escrevi essa ... Comentários / welcome críticas. Este recebe o rev ponta em hexadecimal como uma string.

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")
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top