كيف يمكنني تنفيذ Post Commit Hook مع Trac & SVN في بيئة Windows؟

StackOverflow https://stackoverflow.com/questions/84178

  •  01-07-2019
  •  | 
  •  

سؤال

أنا أعمل في بيئة Windows باستخدام Trac / SVN وأريد أن يتم دمج الالتزامات في المستودع مع Trac وإغلاق الأخطاء التي تمت ملاحظتها في تعليق SVN.

أعلم أن هناك بعض أدوات ربط النشر للقيام بذلك، ولكن لا يوجد الكثير من المعلومات حول كيفية القيام بذلك على نظام التشغيل Windows.

هل قام أحد بذلك بنجاح؟وما هي الخطوات التي اتبعتها لتحقيق ذلك؟

هذا هو الخطاف الذي أحتاج إلى وضعه في SVN، لكنني لست متأكدًا تمامًا من كيفية القيام بذلك في بيئة Windows.

تراك بوست ارتكاب هوك

هل كانت مفيدة؟

المحلول 2

حسنًا، الآن بعد أن أصبح لدي بعض الوقت لنشر تجربتي بعد اكتشاف كل ذلك، شكرًا لكريج لأنه وضعني على المسار الصحيح.إليك ما عليك القيام به (على الأقل مع SVN v1.4 وTrac v0.10.3):

  1. حدد موقع مستودع SVN الخاص بك الذي تريد تمكين Post Commit Hook له.
  2. يوجد داخل مستودع SVN دليل يسمى الخطافات، وهذا هو المكان الذي ستضع فيه خطاف التزام النشر.
  3. قم بإنشاء ملف post-commit.bat (هذا هو الملف الدفعي الذي يتم استدعاؤه تلقائيًا بواسطة التزام نشر SVN).
  4. ضع التعليمة البرمجية التالية داخل ملف post-commit.bat (سيؤدي هذا إلى استدعاء ملف cmd لالتزام النشر الخاص بك ويمرر المعلمات التي يمررها SVN تلقائيًا، %1 هو المستودع، و%2 هو المراجعة التي تم الالتزام بها.

%~dp0 rac-post-commit-hook.cmd %1 %2

  1. الآن قم بإنشاء ملف trac-post-commit-hook.cmd كما يلي:

@صدى خارج
::
::نص TRAC Post-Commit-Hook لنظام التشغيل Windows
::
::ساهمت من قبل ماركوس ، معدلة من قبل CBOOS.

::الاستخدام:
::
::1) أدخل السطر التالي في البرنامج النصي بعد الالتزام
::
::استدعاء ٪ ~ dp0 trac-post-commit-hook.cmd ٪ 1 ٪ 2
::
::2) تحقق من قسم "تعديل المسارات" أدناه ، تأكد من تعيين trac_env على الأقل


:: ----------------------------------------------------------
::تعديل المسارات هنا:

::-- هذا يجب يتم تعيينها
تعيين trac_env = c: trac mySpecialProject

::- تعيين إذا لم يكن Python في مسار النظام
::تعيين Python_Path =

::-ضبط على المجلد الذي يحتوي على trac/ إذا تم تثبيته في موقع غير قياسي
::تعيين trac_path =
:: ----------------------------------------------------------

::لا تنفذ الخطاف إذا لم تكن بيئة Trac موجودة
إذا لم تكن موجودة ٪ trac_env ٪ goto: eof

اضبط PATH=%PYTHON_PATH%;%PATH%
تعيين pythonpath = ٪ trac_path ٪ ؛ ٪ pythonpath ٪

تعيين REV=%2

::احصل على المؤلف ورسالة السجل
لـ /f ٪٪ A in ('svnlook effect -r ٪ rev ٪ 1')
لـ /f "delims ==" ٪٪ B في ('svnlook log -r ٪ rev ٪ 1')

::اتصل بنص بايثون
Python "٪ ~ dp0 trac -post -commit -hook" -p "٪ trac_env ٪" -r "٪ rev ٪" -u "٪ ٪" -M "log ٪"

الأجزاء الأكثر أهمية هنا هي تعيين TRAC_ENV الخاص بك وهو المسار إلى جذر المستودع (SET TRAC_ENV=C: rac\MySpecialProject)

الشيء المهم التالي في هذا البرنامج النصي هو القيام بما يلي:

::احصل على المؤلف ورسالة السجل
لـ /f ٪٪ A in ('svnlook effect -r ٪ rev ٪ 1')
لـ /f "delims ==" ٪٪ B في ('svnlook log -r ٪ rev ٪ 1')

إذا رأيت في ملف البرنامج النصي أعلاه أنني أستخدم svnlook (وهي أداة مساعدة لسطر الأوامر مع SVN) للحصول على رسالة السجل والمؤلف الذي قام بالالتزام بالمستودع.

بعد ذلك، يقوم السطر التالي من البرنامج النصي باستدعاء كود Python لإجراء إغلاق التذاكر وتحليل رسالة السجل.اضطررت إلى تعديل هذا لتمرير رسالة السجل والمؤلف (حيث تتطابق أسماء المستخدمين التي أستخدمها في Trac مع أسماء المستخدمين في SVN لذا كان ذلك سهلاً).

اتصل بنص بايثون
Python "٪ ~ dp0 trac -post -commit -hook" -p "٪ trac_env ٪" -r "٪ rev ٪" -u "٪ ٪" -M "log ٪"

سوف يمرر السطر أعلاه في البرنامج النصي إلى برنامج python بيئة Trac والمراجعة والشخص الذي قام بالالتزام وتعليقه.

هذا هو نص بايثون الذي استخدمته.أحد الأشياء التي قمت بها بالإضافة إلى البرنامج النصي العادي هو أننا نستخدم حقلًا مخصصًا (fixed_in_ver) يستخدمه فريق ضمان الجودة لدينا لمعرفة ما إذا كان الإصلاح الذي يقومون بالتحقق من صحته موجودًا في إصدار الكود الذي يختبرونه في ضمان الجودة.لذا، قمت بتعديل الكود الموجود في نص بايثون لتحديث هذا الحقل على التذكرة.يمكنك إزالة هذا الرمز لأنك لن تحتاج إليه، ولكنه مثال جيد لما يمكنك القيام به لتحديث الحقول المخصصة في Trac إذا كنت تريد أيضًا القيام بذلك.

لقد فعلت ذلك من خلال جعل المستخدمين يدرجون اختياريًا في تعليقاتهم شيئًا مثل:

(الإصدار 2.1.2223.0)

أستخدم بعد ذلك نفس الأسلوب الذي يستخدمه برنامج بايثون النصي مع التعبيرات العادية للحصول على المعلومات.لم يكن سيئا للغاية.

على أي حال، هذا هو نص بايثون الذي استخدمته، ونأمل أن يكون هذا برنامجًا تعليميًا جيدًا حول ما فعلته بالضبط لجعله يعمل في عالم windows حتى تتمكنوا جميعًا من الاستفادة من هذا في متجركم الخاص...

إذا كنت لا ترغب في التعامل مع الكود الإضافي الخاص بي لتحديث الحقل المخصص، فاحصل على البرنامج النصي الأساسي من هذا الموقع كما ذكر Craig أعلاه (البرنامج النصي من Edgewall)

#!/usr/bin/env python

# trac-post-commit-hook
# ----------------------------------------------------------------------------
# Copyright (c) 2004 Stephen Hansen 
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
#   The above copyright notice and this permission notice shall be included in
#   all copies or substantial portions of the Software. 
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
# ----------------------------------------------------------------------------

# This Subversion post-commit hook script is meant to interface to the
# Trac (http://www.edgewall.com/products/trac/) issue tracking/wiki/etc 
# system.
# 
# It should be called from the 'post-commit' script in Subversion, such as
# via:
#
# REPOS="$1"
# REV="$2"
# LOG=`/usr/bin/svnlook log -r $REV $REPOS`
# AUTHOR=`/usr/bin/svnlook author -r $REV $REPOS`
# TRAC_ENV='/somewhere/trac/project/'
# TRAC_URL='http://trac.mysite.com/project/'
#
# /usr/bin/python /usr/local/src/trac/contrib/trac-post-commit-hook \
#  -p "$TRAC_ENV"  \
#  -r "$REV"       \
#  -u "$AUTHOR"    \
#  -m "$LOG"       \
#  -s "$TRAC_URL"
#
# It searches commit messages for text in the form of:
#   command #1
#   command #1, #2
#   command #1 & #2 
#   command #1 and #2
#
# You can have more then one command in a message. The following commands
# are supported. There is more then one spelling for each command, to make
# this as user-friendly as possible.
#
#   closes, fixes
#     The specified issue numbers are closed with the contents of this
#     commit message being added to it. 
#   references, refs, addresses, re 
#     The specified issue numbers are left in their current status, but 
#     the contents of this commit message are added to their notes. 
#
# A fairly complicated example of what you can do is with a commit message
# of:
#
#    Changed blah and foo to do this or that. Fixes #10 and #12, and refs #12.
#
# This will close #10 and #12, and add a note to #12.

import re
import os
import sys
import time 

from trac.env import open_environment
from trac.ticket.notification import TicketNotifyEmail
from trac.ticket import Ticket
from trac.ticket.web_ui import TicketModule
# TODO: move grouped_changelog_entries to model.py
from trac.util.text import to_unicode
from trac.web.href import Href

try:
    from optparse import OptionParser
except ImportError:
    try:
        from optik import OptionParser
    except ImportError:
        raise ImportError, 'Requires Python 2.3 or the Optik option parsing library.'

parser = OptionParser()
parser.add_option('-e', '--require-envelope', dest='env', default='',
                  help='Require commands to be enclosed in an envelope. If -e[], '
                       'then commands must be in the form of [closes #4]. Must '
                       'be two characters.')
parser.add_option('-p', '--project', dest='project',
                  help='Path to the Trac project.')
parser.add_option('-r', '--revision', dest='rev',
                  help='Repository revision number.')
parser.add_option('-u', '--user', dest='user',
                  help='The user who is responsible for this action')
parser.add_option('-m', '--msg', dest='msg',
                  help='The log message to search.')
parser.add_option('-c', '--encoding', dest='encoding',
                  help='The encoding used by the log message.')
parser.add_option('-s', '--siteurl', dest='url',
                  help='The base URL to the project\'s trac website (to which '
                       '/ticket/## is appended).  If this is not specified, '
                       'the project URL from trac.ini will be used.')

(options, args) = parser.parse_args(sys.argv[1:])

if options.env:
    leftEnv = '\\' + options.env[0]
    rghtEnv = '\\' + options.env[1]
else:
    leftEnv = ''
    rghtEnv = ''

commandPattern = re.compile(leftEnv + r'(?P<action>[A-Za-z]*).?(?P<ticket>#[0-9]+(?:(?:[, &]*|[ ]?and[ ]?)#[0-9]+)*)' + rghtEnv)
ticketPattern = re.compile(r'#([0-9]*)')
versionPattern = re.compile(r"\(version[ ]+(?P<version>([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+))\)")

class CommitHook:
    _supported_cmds = {'close':      '_cmdClose',
                       'closed':     '_cmdClose',
                       'closes':     '_cmdClose',
                       'fix':        '_cmdClose',
                       'fixed':      '_cmdClose',
                       'fixes':      '_cmdClose',
                       'addresses':  '_cmdRefs',
                       're':         '_cmdRefs',
                       'references': '_cmdRefs',
                       'refs':       '_cmdRefs',
                       'see':        '_cmdRefs'}

    def __init__(self, project=options.project, author=options.user,
                 rev=options.rev, msg=options.msg, url=options.url,
                 encoding=options.encoding):
        msg = to_unicode(msg, encoding)
        self.author = author
        self.rev = rev
        self.msg = "(In [%s]) %s" % (rev, msg)
        self.now = int(time.time()) 
        self.env = open_environment(project)
        if url is None:
            url = self.env.config.get('project', 'url')
        self.env.href = Href(url)
        self.env.abs_href = Href(url)

        cmdGroups = commandPattern.findall(msg)


        tickets = {}

        for cmd, tkts in cmdGroups:
            funcname = CommitHook._supported_cmds.get(cmd.lower(), '')

            if funcname:

                for tkt_id in ticketPattern.findall(tkts):
                    func = getattr(self, funcname)
                    tickets.setdefault(tkt_id, []).append(func)

        for tkt_id, cmds in tickets.iteritems():
            try:
                db = self.env.get_db_cnx()

                ticket = Ticket(self.env, int(tkt_id), db)
                for cmd in cmds:
                    cmd(ticket)

                # determine sequence number... 
                cnum = 0
                tm = TicketModule(self.env)
                for change in tm.grouped_changelog_entries(ticket, db):
                    if change['permanent']:
                        cnum += 1

                # get the version number from the checkin... and update the ticket with it.
                version = versionPattern.search(msg)
                if version != None and version.group("version") != None:
                    ticket['fixed_in_ver'] = version.group("version")

                ticket.save_changes(self.author, self.msg, self.now, db, cnum+1)
                db.commit()

                tn = TicketNotifyEmail(self.env)
                tn.notify(ticket, newticket=0, modtime=self.now)
            except Exception, e:
                # import traceback
                # traceback.print_exc(file=sys.stderr)
                print>>sys.stderr, 'Unexpected error while processing ticket ' \
                                   'ID %s: %s' % (tkt_id, e)


    def _cmdClose(self, ticket):
        ticket['status'] = 'closed'
        ticket['resolution'] = 'fixed'

    def _cmdRefs(self, ticket):
        pass


if __name__ == "__main__":
    if len(sys.argv) < 5:
        print "For usage: %s --help" % (sys.argv[0])
    else:
        CommitHook()

نصائح أخرى

إجابة بنيامين قريبة، ولكن في نظام التشغيل Windows، تحتاج إلى منح ملفات البرنامج النصي للربط امتدادًا قابلاً للتنفيذ، مثل .bat أو .cmd.أنا أستخدم .cmd.يمكنك أخذ البرامج النصية للقالب، وهي نصوص برمجية لـ Unix Shell ونصوص Shell وتحويلها إلى بناء جملة .bat/.cmd.

لكن للإجابة على سؤال التكامل مع تراك اتبع الخطوات التالية.

  1. تأكد من وجود Python.exe على مسار النظام.وهذا سيجعل حياتك أسهل.

  2. قم بإنشاء post-commit.cmd في مجلد \hooks.هذا هو البرنامج النصي للربط الفعلي الذي سينفذه Subversion في حدث ما بعد الالتزام.

    @ECHO OFF
    
    :: POST-COMMIT HOOK
    ::
    :: The post-commit hook is invoked after a commit.  Subversion runs
    :: this hook by invoking a program (script, executable, binary, etc.)
    :: named 'post-commit' (for which this file is a template) with the 
    :: following ordered arguments:
    ::
    ::   [1] REPOS-PATH   (the path to this repository)
    ::   [2] REV          (the number of the revision just committed)
    ::
    :: The default working directory for the invocation is undefined, so
    :: the program should set one explicitly if it cares.
    ::
    :: Because the commit has already completed and cannot be undone,
    :: the exit code of the hook program is ignored.  The hook program
    :: can use the 'svnlook' utility to help it examine the
    :: newly-committed tree.
    ::
    :: On a Unix system, the normal procedure is to have 'post-commit'
    :: invoke other programs to do the real work, though it may do the
    :: work itself too.
    ::
    :: Note that 'post-commit' must be executable by the user(s) who will
    :: invoke it (typically the user httpd runs as), and that user must
    :: have filesystem-level permission to access the repository.
    ::
    :: On a Windows system, you should name the hook program
    :: 'post-commit.bat' or 'post-commit.exe',
    :: but the basic idea is the same.
    :: 
    :: The hook program typically does not inherit the environment of
    :: its parent process.  For example, a common problem is for the
    :: PATH environment variable to not be set to its usual value, so
    :: that subprograms fail to launch unless invoked via absolute path.
    :: If you're having unexpected problems with a hook program, the
    :: culprit may be unusual (or missing) environment variables.
    :: 
    :: Here is an example hook script, for a Unix /bin/sh interpreter.
    :: For more examples and pre-written hooks, see those in
    :: the Subversion repository at
    :: http://svn.collab.net/repos/svn/trunk/tools/hook-scripts/ and
    :: http://svn.collab.net/repos/svn/trunk/contrib/hook-scripts/
    
    setlocal
    
    :: Debugging setup
    :: 1. Make a copy of this file.
    :: 2. Enable the command below to call the copied file.
    :: 3. Remove all other commands
    ::call %~dp0post-commit-run.cmd %* > %1/hooks/post-commit.log 2>&1
    
    :: Call Trac post-commit hook
    call %~dp0trac-post-commit.cmd %* || exit 1
    
    endlocal
    
  3. قم بإنشاء trac-post-commit.cmd في مجلد \hooks:

    @ECHO OFF
    ::
    :: Trac post-commit-hook script for Windows
    ::
    :: Contributed by markus, modified by cboos.
    
    :: Usage:
    ::
    :: 1) Insert the following line in your post-commit.bat script
    ::
    :: call %~dp0\trac-post-commit-hook.cmd %1 %2
    ::
    :: 2) Check the 'Modify paths' section below, be sure to set at least TRAC_ENV
    
    setlocal
    
    :: ----------------------------------------------------------
    :: Modify paths here:
    
    :: -- this one *must* be set
    SET TRAC_ENV=D:\projects\trac\membershipdnn
    
    :: -- set if Python is not in the system path
    SET PYTHON_PATH=
    
    :: -- set to the folder containing trac/ if installed in a non-standard location
    SET TRAC_PATH=
    :: ----------------------------------------------------------
    
    :: Do not execute hook if trac environment does not exist
    IF NOT EXIST %TRAC_ENV% GOTO :EOF
    
    set PATH=%PYTHON_PATH%;%PATH%
    set PYTHONPATH=%TRAC_PATH%;%PYTHONPATH%
    
    SET REV=%2
    
    :: Resolve ticket references (fixes, closes, refs, etc.)
    Python "%~dp0trac-post-commit-resolve-ticket-ref.py" -p "%TRAC_ENV%" -r "%REV%"
    
    endlocal
    
  4. قم بإنشاء trac-post-commit-resolve-ticket-ref.py في مجلد \hooks.إستعملت نفس البرنامج النصي من EdgeWall, ، فقط قمت بإعادة تسميته لتوضيح الغرض منه بشكل أفضل.

يتم نشر خطافات الالتزام مباشرة في دليل "الخطافات" حيث يوجد المستودع على جانب الخادم.لا أعرف أين توجد هذه العناصر في بيئتك، لذلك هذا مجرد مثال

على سبيل المثال(شبابيك):

C:\Subversion\repositories\repo1\hooks\post-commit

على سبيل المثال(لينكس/يونكس):

/usr/local/subversion/repositories/repo1/hooks/post-commit

شيء واحد سأضيفه "إجابة Code Monkey مثالية" - هو أن أكون حذرًا من هذا (خطأي)

:: Modify paths here:

:: -- this one must be set
SET TRAC_ENV=d:\trac\MySpecialProject

:: -- set if Python is not in the system path
:: SET PYTHON_PATH=**d:\python**

:: -- set to the folder containing trac/ if installed in a non-standard location 
:: SET TRAC_PATH=**d:\python\Lib\site-packages\trac**

لم أقم بتعيين المسارات غير المتعلقة بالنظام واستغرقت بعض الوقت لأرى ما هو واضح:D

فقط تطابق وتأكد من أن لا أحد يرتكب نفس الخطأ!شكرا رمز القرد!1000000000 نقطة :د

أولًا شكرًا جزيلًا لـ Code Monkey!

ومع ذلك، من المهم الحصول على نص بايثون الصحيح اعتمادًا على إصدار التتبع لديك.للحصول على الإصدار المناسب، قم بفحص المجلد SVN:

http://svn.edgewall.com/repos/trac/branches/xxx-مستقر/مساهمة

أين xxx يتوافق مع إصدار التتبع الذي تستخدمه، على سبيل المثال:0.11

وإلا فسوف تحصل على خطأ ما بعد الالتزام يبدو كما يلي:

فشل الالتزام (تابع التفاصيل):دمج '/svn/project/trunk/web/directory/':200 موافق

لجميع مستخدمي Windows الذين يريدون تثبيت أحدث إصدار (0.11.5):اتبع الإرشادات الموجودة على موقع Trac المسمى TracOnWindows.

قم بتنزيل الإصدار 32 بت 1.5 Python حتى لو كان لديك نظام التشغيل Windows 64 بت.ملحوظة:رأيت في مكان ما تعليمات حول كيفية تجميع المسار للعمل أصلاً على نظام 64 بت.

عند تثبيت كل ما هو مطلوب، انتقل إلى مجلد المستودع.هناك السنانير المجلد.بداخله، ضع الملفات التي ذكرها Code Monkey، ولكن لا تقم بإنشاء "trac-post-commit-resolve-ticket-ref.py" كما فعل.خذ نصيحة Quant Analyst وافعل كما قال:

"ومع ذلك، من المهم الحصول على نص بايثون الصحيح اعتمادًا على إصدار التتبع لديك.للحصول على الإصدار المناسب، قم بفحص المجلد SVN:http://svn.edgewall.com/repos/trac/branches/XXX STIPLE/CORTRIB حيث يتوافق XXX مع إصدار TRAC الذي تستخدمه ، على سبيل المثال:0.11"

ومن هناك قم بتحميل الملف "trac-post-commit-hook" ووضعه في مجلد الخطافات.

قم بتحرير هذه السطور في trac-post-commit.cmd

SET PYTHON_PATH = "المسار إلى مجلد تثبيت بايثون"

قم بتعيين trac_env = "Path to Folder حيث قمت بـ Tracd initenv"

تذكر لا آخر \ !!!

لقد قمت بإزالة علامات الاقتباس من السطر الأخير -r "%REV%" لتكون -r %REV% ولكني لا أعرف ما إذا كان هذا مطلوبًا.لن ينجح هذا الآن (على الأقل على خادم win 2008 الخاص بي)، لأن الخطاف سيفشل (سيكون الالتزام جيدًا).هذا له علاقة بالأذونات.بشكل افتراضي، تكون الأذونات مقيدة ونحتاج إلى السماح لـ python أو svn أو trac (أيًا كان ما لا أعرفه) بتغيير معلومات التتبع.لذا انتقل إلى مجلد trac، ومجلد المشروع، ومجلد db، وانقر بزر الماوس الأيمن فوق trac.db واختر خصائص.انتقل إلى علامة تبويب الأمان وقم بتحرير الأذونات للسماح للجميع بالتحكم الكامل.هذا ليس آمنًا جدًا ولكني أهدرت كل يوم في هذه المسألة الأمنية ولا أريد أن أضيع يومًا آخر فقط للعثور على المستخدم الذي يجب عليك تمكين الأذونات له.

أتمنى أن يساعدك هذا....

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top