получение журналов из Mercurial с помощью API - PullRequest
5 голосов
/ 17 декабря 2009

Я хотел бы получить журналы из хранилища Mercurial, используя команды API Mercurial. К сожалению, mercurial.commands.log печатает сообщения на стандартный вывод вместо того, чтобы возвращать какой-то хороший список ревизий, например, например. писвн делает. Можно ли достичь легко? Я хотел бы добавить поддержку Mercurial в свою программу и хотел бы сделать это настолько легко, насколько это возможно.

Ответы [ 3 ]

8 голосов
/ 18 декабря 2009

Вы должны сделать что-то вроде этого:

from mercurial import ui, hg
u = ui.ui()
repo = hg.repo()
for rev in repo:
    print repo[rev]

подписанный объект является объектом контекста. У него есть полезные методы, такие как description(), branch() и user(). Для полного списка того, что он может сделать, см. источник (или выполните dir() на нем).

2 голосов
/ 08 января 2010

да, у меня была та же проблема .. похоже, что она предназначена для запрета удаленного получения журналов. Веб-интерфейс дает небольшую RSS-ленту, но мне не хватило истории. Итак, мы создали наш собственный канал RSS ...

это не самая сложная вещь и настроена по нашему вкусу, вы можете смешать поля вокруг в print_item (), чтобы изменить внешний вид канала. Вы также можете изменить его так, чтобы он возвращал информацию журнала для определенных наборов изменений, если это необходимо.

Вам нужно будет добавить псевдоним скрипта в apache, что-то вроде (см. http://httpd.apache.org/docs/2.0/howto/cgi.html для получения дополнительной информации):

ScriptAlias /feed.cgi /usr/local/systems/hg/script/feed.cgi

Содержимое файла feed.cgi:

#!/usr/bin/env python2.5
# -*- python -*-

"""
Creates a rss feed from commit log messages in a repository/branch.
Can be filtered on commit logs from a set date eg date=2009-12-12
or by a number of days previous eg. days=7

Usage: 
 * retrieve all logs: http://hg.server/feed.cgi?repository=MyRepo
 * retrieve logs from set date: http://hg.server/feed.cgi?repository=DMyRepo&date=2009-11-11
 * retrieve logs from last 77 days: http://hg.server/feed.cgi?repository=DMyRepo&days=77
 * retrieve all logs from a branch: http://hg.server/feed.cgi?repository=MyRepo&branch=myBranch

Script Location on server: /usr/local/systems/hg/script/feed.cgi
"""

defaultdateformats = (
'%Y-%m-%d %H:%M:%S',
'%Y-%m-%d %I:%M:%S%p',
'%Y-%m-%d %H:%M',
'%Y-%m-%d %I:%M%p',
'%Y-%m-%d',
'%m-%d',
'%m/%d',
'%m/%d/%y',
'%m/%d/%Y',
'%a %b %d %H:%M:%S %Y',
'%a %b %d %I:%M:%S%p %Y',
'%a, %d %b %Y %H:%M:%S', # GNU coreutils "/bin/date --rfc-2822"
'%b %d %H:%M:%S %Y',
'%b %d %I:%M:%S%p %Y',
'%b %d %H:%M:%S',
'%b %d %I:%M:%S%p',
'%b %d %H:%M',
'%b %d %I:%M%p',
'%b %d %Y',
'%b %d',
'%H:%M:%S',
'%I:%M:%S%p',
'%H:%M',
'%I:%M%p',
)

import os, sys, cgi, cgitb, datetime, time
cgitb.enable()

from mercurial import ui, hg, util
from mercurial.node import short

def find_repository(name):
    base = '/usr/local/systems/hg/repos/'
    path = os.path.join(base, name)

    repos = hg.repository(None, path)
    return repos

def find_changes(repos, branch, date):

    # returns true if d2 is newer than d1
    def newerDate(d1, d2):
         d1 = datetime.datetime.fromtimestamp(d1)
         d2 = datetime.datetime.fromtimestamp(d2)
         return d1 < d2

    #for ctx in repos.changelog:
    #    print ctx

    changes = repos.changelog

    out = []
    # filter on branch
    if branch != '':
        changes = [change for change in changes if repos.changectx(change).branch() == branch ]

    # filter on date
    if date != '':
        changes = [change for change in changes if newerDate(date, repos.changectx(change).date()[0]) ]

    return changes

def print_item(change, link_template):
    def _element(name, content):
        content = cgi.escape(content)

        print "      <%(name)s>%(content)s</%(name)s>" % {
            'name': name,
            'content': content
            }

    link = link_template % {'node': short(change.node())}
    print "    <item>"
    _element('title', str(change.rev()))
    _element('description', change.description())
    _element('guid', str(change.rev()))
    _element('author', change.user())
    _element('link', link)
    _element('pubdate', str(datetime.datetime.fromtimestamp(change.date()[0])))
    print "    </item>"

def print_rss(changes, repos, template):
    print """<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <link>N/A</link>
    <language>en-us</language>

    <title>Changelog</title>
    <description>Changelog</description>
"""
    for change in changes:
        ctx = repos.changectx(change)
        print_item(ctx, template)

    print """
  </channel>
</rss>
"""

if __name__=="__main__":

    # -*- python -*-
    print "Content-Type: application/rss+xml; charset=UTF-8"
    print

    f = cgi.FieldStorage()

    if not f.has_key("repository"):
        print "Need to specify repository."
        sys.exit()

    repository = f['repository'].value
    branch = ''
    if f.has_key('branch'):
        branch = f['branch'].value

    date = ''
    if f.has_key('date') and not f.has_key('days'):
        try:
            #date = datetime.datetime.strptime(f['date'].value, '%Y-%m-%d')
            date = util.parsedate(f['date'].value)[0]
        except:
            print 'Error in date format, use one of the following formats:', defaultdateformats
            sys.exit()
    elif f.has_key('days') and not f.has_key('date'):
        days = int(f['days'].value)
        try:
            date = datetime.datetime.now() - datetime.timedelta(days=days)
            date = time.mktime(date.timetuple())
        except:
            print 'Error in days, please use a standard number eg. days=7'
            sys.exit()
    elif f.has_key('days') and f.has_key('date'):
        print 'Error, please only supply a dayrange OR a date, not both'
        sys.exit()

    repos = find_repository(repository)
    changes = find_changes(repos, branch, date)
    rev_link_template = 'http://hg.server/hg/%(repos)s/rev/%%(node)s' % {
        'repos': repository
        }
    print_rss(changes, repos, rev_link_template)
2 голосов
/ 17 декабря 2009

Простой ответ - использовать ui.pushbuffer() непосредственно перед вызовом команды log и log_output = ui.popbuffer() сразу после ее вызова. Таким образом, log_output будет содержать выходные данные команды log.

Вы действительно ищете прямой вывод журнала или вам действительно нужны различия или другие данные? Если мы знаем, что именно вы пытаетесь получить (например: «сообщения о фиксации каждого набора изменений между X и Y»), мы сможем показать вам лучший способ.

РЕДАКТИРОВАТЬ: Взгляните на вики-страницу Mercurial API , чтобы узнать, как получить большую часть общей информации от repo и ctx объектов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...