Question

Je suis en train d'obtenir le numéro de révision mercurial / id (c'est un hachage pas un nombre) par programme en python.

La raison en est que je veux l'ajouter aux fichiers css / js sur notre site comme ceci:

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

Alors que chaque fois qu'une modification est apportée à la feuille de style, il obtiendra une nouvelle URL et ne plus utiliser l'ancienne version en cache.

ou si vous savez où trouver une bonne documentation pour le module mercurial python , qui serait également utile. Je ne peux pas sembler trouver partout.

Ma solution

J'ai fini à l'aide de sous-processus pour exécuter juste une commande qui obtient le nœud hg. J'ai choisi cette solution parce que le api n'est pas garanti de rester le même, mais l'interface bash sera probablement:

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

Exemple d'utilisation:

> path_to_file = "/home/jim/workspace/lgr/pinax/projects/lgr/site_media/base.css"
> get_hg_rev(path_to_file)
'0ed525cf38a7b7f4f1321763d964a39327db97c4'
Était-ce utile?

La solution

Il est vrai qu'il n'y a pas API officielle, mais vous pouvez avoir une idée sur les meilleures pratiques en lisant d'autres extensions, en particulier ceux livrés avec hg. Pour ce problème particulier, je voudrais faire quelque chose comme ceci:

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

Mise à jour À un moment donné l'ordre des paramètres changé, maintenant il est comme ceci:

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

Autres conseils

Voulez-vous dire cette documentation
Notez que, comme indiqué dans cette page, il n'y a pas officiel API , parce qu'ils se réservent toujours le droit de modifier à tout moment. Mais vous pouvez voir la liste des changements dans les dernières versions, il est pas très vaste.

Une mise à jour, la version propre subprocess (utilise .check_output(), ajouté en Python 2.7 / 3.1) que j'utilise dans mes paramètres Django fichier pour une vérification de déploiement de bout en bout brut (je vide dans un commentaire HTML):

import subprocess

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

Vous pouvez envelopper dans un try si vous ne voulez pas un accident de parcours étrange pour éviter tout démarrage:

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

donner un essai à l'extension mot-clé

Si vous utilisez Python 2, vous souhaitez utiliser hglib .

Je ne sais pas quoi utiliser si vous utilisez Python 3, désolé. Probablement hgapi .

Contenu de cette réponse

  • API de Mercurial
  • Comment utiliser hglib
  • Pourquoi hglib est le meilleur choix pour les utilisateurs Python 2
  • Si vous écrivez un crochet, qui a découragé l'interface interne est terriblement pratique

API de Mercurial

Mercurial a deux API officielles.

  1. Le serveur de commande Mercurial. Vous pouvez lui parler de Python 2 en utilisant le hglib ( wiki , PyPI ), qui est maintenu par l'équipe Mercurial.
  2. l'interface de ligne de commande de Mercurial. Vous pouvez parler via subprocess ou hgapi ou somesuch.

Comment utiliser hglib

Installation:

pip install python-hglib

Utilisation:

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

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

Plus d'informations sur l'utilisation sur le hglib page wiki .

Pourquoi hglib est le meilleur choix pour les utilisateurs Python 2

Parce qu'il est maintenu par l'équipe Mercurial, et il est ce que l'équipe Mercurial recommande pour l'interfaçage avec Mercurial.

De wiki de Mercurial, la déclaration suivante sur l'interface avec Mercurial:

  

Pour la grande majorité des code tiers, la meilleure approche est d'utiliser publiée Mercurial, documenté et API stable: l'interface de ligne de commande. Vous pouvez également utiliser le CommandServer ou les bibliothèques qui sont basées sur pour obtenir un rapide, stable, langue Interface -neutre.

A partir de la page du serveur de commande:

  

[Le serveur de commande permet] des applications tierces et les bibliothèques de communiquer avec Mercurial sur un tuyau qui élimine le surcoût de démarrage par-commande. Les bibliothèques peuvent alors résumer la génération de commande et l'analyse syntaxique de présenter une API de langage approprié à ces commandes.

L'interface python pour la commande serveur mercuriel, comme dit, est hglib.

Le per-commande au-dessus de l'interface de ligne de commande est pas une blague, en passant. Une fois, je construit une suite de tests très faible (seulement environ 5 essais) qui a utilisé hg via subprocess pour créer, COMMIT par une poignée de prises en pension avec par exemple fusionner des situations. Tout au long du projet, le moteur d'exécution de la suite resté entre 5 à 30 secondes, avec presque tout le temps passé dans les appels hg.

Si vous écrivez un crochet, qui a découragé l'interface interne est terriblement pratique

La signature d'une fonction de crochet de python est comme ceci:

# 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 et repo font partie du API interne . Le fait qu'ils sont là, dans votre fonction args les rend d'utiliser terriblement pratique, comme dans cet exemple d'un crochet preupdate qui interdit entre certaines branches se confond.

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.

Si votre code crochet est pas si important, et vous n'êtes pas le publier, vous pouvez choisir d'utiliser l'API interne découragée non officielle. Si votre crochet est part d'une extension que vous publiez, mieux hglib d'utilisation.

FWIW pour éviter la récupération de cette valeur sur chaque page / vue de rendre, je viens de me mettre Deploy dans le fichier settings.py. Ensuite, je peux faire référence à settings.REVISION sans tous les frais généraux d'accès à Mercurial et / ou un autre processus. Avez-vous jamais ce changement de valeur w / o rechargeant votre serveur?

Je voulais faire la même chose l'OP voulait faire, obtenir hg id -i à partir d'un script (obtenir la révision de la pointe de l'ensemble REFERENTIEL pas d'un seul fichier dans ce repo) mais je ne voulais pas utiliser popen, et le code de brendan m'a lancé, mais n'a pas été ce que je voulais.

J'ai donc écrit ceci ... Commentaires / accueil critique. Cela devient la pointe rev dans l'hexagone comme une chaîne.

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")
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top