Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 290001 Details for
Bug 337853
repoman commit should auto-update ChangeLog
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
echangelog functionality in repoman v2
repoman-changelog-v2.patch (text/plain), 10.21 KB, created by
Fabian Groffen
on 2011-10-16 20:30:06 UTC
(
hide
)
Description:
echangelog functionality in repoman v2
Filename:
MIME Type:
Creator:
Fabian Groffen
Created:
2011-10-16 20:30:06 UTC
Size:
10.21 KB
patch
obsolete
># HG changeset patch ># User Fabian Groffen <grobian@gentoo.org> ># Date 1318796644 -7200 ># Node ID 16cdfb19e2c8f2c24fd9e7bc2616952a2536362d ># Parent bf2b85d81512bd4a3fa7ec31be77507d5b9dba13 >changelog: implemented echangelog functionality > >Instead of calling echangelog, which on its turn has to query the VCS >again, use the existing information on changes made to the current >directory, and update the ChangeLog from Python itself. >This avoids a call to echangelog, and avoids again retrieving the same >VCS information as repoman already did. It makes repoman independent >from external tools it didn't install itself, and should be faster in >general. > >diff -r bf2b85d81512 -r 16cdfb19e2c8 bin/repoman >--- a/bin/repoman Sun Oct 16 15:59:20 2011 +0200 >+++ b/bin/repoman Sun Oct 16 22:24:04 2011 +0200 >@@ -652,19 +652,15 @@ > if vcs is None: > options.echangelog = 'n' > >-if 'commit' == options.mode and \ >- options.echangelog == 'y' and \ >- find_binary('echangelog') is None: >- logging.error("echangelog not found, and --echangelog is enabled") >- sys.exit(1) >- > # The --echangelog option causes automatic ChangeLog generation, > # which invalidates changelog.ebuildadded and changelog.missing > # checks. >-# Note: We don't use ChangeLogs in distributed SCMs. >+# Note: Some don't use ChangeLogs in distributed SCMs. > # It will be generated on server side from scm log, > # before package moves to the rsync server. >-# This is needed because we try to avoid merge collisions. >+# This is needed because they try to avoid merge collisions. >+# Gentoo's Council decided to always use the ChangeLog file. >+# TODO: shouldn't this just be switched on the repo, iso the VCS? > check_changelog = options.echangelog != 'y' and vcs in ('cvs', 'svn') > > # Generate an appropriate PORTDIR_OVERLAY value for passing into the >@@ -2291,36 +2287,6 @@ > myautoadd+=[myunadded[x]] > del myunadded[x] > >- if myautoadd: >- print(">>> Auto-Adding missing Manifest(s)...") >- if options.pretend: >- if vcs == "cvs": >- print("(cvs add "+" ".join(myautoadd)+")") >- elif vcs == "svn": >- print("(svn add "+" ".join(myautoadd)+")") >- elif vcs == "git": >- print("(git add "+" ".join(myautoadd)+")") >- elif vcs == "bzr": >- print("(bzr add "+" ".join(myautoadd)+")") >- elif vcs == "hg": >- print("(hg add "+" ".join(myautoadd)+")") >- retval=0 >- else: >- if vcs == "cvs": >- retval=os.system("cvs add "+" ".join(myautoadd)) >- elif vcs == "svn": >- retval=os.system("svn add "+" ".join(myautoadd)) >- elif vcs == "git": >- retval=os.system("git add "+" ".join(myautoadd)) >- elif vcs == "bzr": >- retval=os.system("bzr add "+" ".join(myautoadd)) >- elif vcs == "hg": >- retval=os.system("hg add "+" ".join(myautoadd)) >- if retval: >- writemsg_level("!!! Exiting on %s (shell) error code: %s\n" % \ >- (vcs, retval), level=logging.ERROR, noiselevel=-1) >- sys.exit(retval) >- > if myunadded: > print(red("!!! The following files are in your local tree but are not added to the master")) > print(red("!!! tree. Please remove them from the local tree or add them to the master tree.")) >@@ -2409,8 +2375,6 @@ > myheaders = [] > mydirty = [] > >- print("* %s files being committed..." % green(str(len(myupdates))), end=' ') >- > commitmessage = options.commitmsg > if options.commitmsgfile: > try: >@@ -2480,22 +2444,60 @@ > if changelog_modified: > continue > >- myupdates.append(changelog_path) >- logging.info("calling echangelog for package %s" % x) >- # --no-strict is required if only manifest(s) have changed >- echangelog_args = ["echangelog", "--no-strict", >- "--vcs", vcs, changelog_msg] >- if options.pretend: >- writemsg_stdout("(%s)\n" % (" ".join(echangelog_args),), >- noiselevel=-1) >- continue >- echangelog_args = [_unicode_encode(arg) for arg in echangelog_args] >- echangelog_cwd = _unicode_encode(checkdir, >- encoding=_encodings['fs'], errors='strict') >- retcode = subprocess.call(echangelog_args, cwd=echangelog_cwd) >- if retcode != os.EX_OK: >- logging.error("echangelog exited with '%s' status" % retcode) >- sys.exit(retcode) >+ # get changes for this package >+ cdrlen = len(checkdir_relative) >+ clnew = [elem[cdrlen:] for elem in mynew if elem.startswith(checkdir_relative)] >+ clremoved = [elem[cdrlen:] for elem in myremoved if elem.startswith(checkdir_relative)] >+ clchanged = [elem[cdrlen:] for elem in mychanged if elem.startswith(checkdir_relative)] >+ new_changelog = utilities.UpdateChangeLog(checkdir_relative, \ >+ catdir, pkgdir, \ >+ clnew, clremoved, clchanged, \ >+ changelog_msg, options.pretend) >+ if new_changelog is None: >+ writemsg_level("!!! Updating the ChangeLog failed\n", \ >+ level=logging.ERROR, noiselevel=-1) >+ sys.exit(1) >+ >+ # if the ChangeLog was just created, add it to vcs >+ if new_changelog: >+ myautoadd+=[changelog_path] >+ # myautoadd is appended to myupdates below >+ else: >+ myupdates.append(changelog_path) >+ >+ if myautoadd: >+ print(">>> Auto-Adding missing Manifest/ChangeLog file(s)...") >+ if options.pretend: >+ if vcs == "cvs": >+ print("(cvs add "+" ".join(myautoadd)+")") >+ elif vcs == "svn": >+ print("(svn add "+" ".join(myautoadd)+")") >+ elif vcs == "git": >+ print("(git add "+" ".join(myautoadd)+")") >+ elif vcs == "bzr": >+ print("(bzr add "+" ".join(myautoadd)+")") >+ elif vcs == "hg": >+ print("(hg add "+" ".join(myautoadd)+")") >+ retval=0 >+ else: >+ if vcs == "cvs": >+ retval=os.system("cvs add "+" ".join(myautoadd)) >+ elif vcs == "svn": >+ retval=os.system("svn add "+" ".join(myautoadd)) >+ elif vcs == "git": >+ retval=os.system("git add "+" ".join(myautoadd)) >+ elif vcs == "bzr": >+ retval=os.system("bzr add "+" ".join(myautoadd)) >+ elif vcs == "hg": >+ retval=os.system("hg add "+" ".join(myautoadd)) >+ if retval: >+ writemsg_level("!!! Exiting on %s (shell) error code: %s\n" % \ >+ (vcs, retval), level=logging.ERROR, noiselevel=-1) >+ sys.exit(retval) >+ >+ myupdates+=myautoadd >+ >+ print("* %s files being committed..." % green(str(len(myupdates))), end=' ') > > if vcs not in ('cvs', 'svn'): > # With git, bzr and hg, there's never any keyword expansion, so >diff -r bf2b85d81512 -r 16cdfb19e2c8 pym/repoman/utilities.py >--- a/pym/repoman/utilities.py Sun Oct 16 15:59:20 2011 +0200 >+++ b/pym/repoman/utilities.py Sun Oct 16 22:24:04 2011 +0200 >@@ -17,7 +17,8 @@ > "have_profile_dir", > "parse_metadata_use", > "UnknownHerdsError", >- "check_metadata" >+ "check_metadata", >+ "UpdateChangeLog" > ] > > import errno >@@ -35,6 +36,12 @@ > from portage.process import find_binary > from portage import exception > from portage import util >+import time >+import textwrap >+import difflib >+import shutil >+from tempfile import mkstemp >+from itertools import chain > normalize_path = util.normalize_path > util.initialize_logger() > >@@ -308,7 +315,6 @@ > @rtype: string or None > @returns: A string on success or None if an error occurs. > """ >- from tempfile import mkstemp > fd, filename = mkstemp() > try: > os.write(fd, _unicode_encode(_( >@@ -511,3 +517,111 @@ > outvcs = seek() > > return outvcs >+ >+def UpdateChangeLog(pkgdir, category, package, new, removed, changed, msg, pretend): >+ """ Write an entry to an existing ChangeLog, or create a new one. """ >+ >+ # figure out who to write as >+ if 'GENTOO_COMMITTER_NAME' in os.environ and \ >+ 'GENTOO_COMMITTER_EMAIL' in os.environ: >+ user = '%s <%s>' % (os.getenv('GENTOO_COMMITTER_NAME'), \ >+ os.getenv('GENTOO_COMMITTER_EMAIL')) >+ elif 'GENTOO_AUTHOR_NAME' in os.environ and \ >+ 'GENTOO_AUTHOR_EMAIL' in os.environ: >+ user = '%s <%s>' % (os.getenv('GENTOO_AUTHOR_NAME'), \ >+ os.getenv('GENTOO_AUTHOR_EMAIL')) >+ elif 'ECHANGELOG_USER' in os.environ: >+ user = os.getenv('ECHANGELOG_USER') >+ else: >+ (login, _, _, _, gecos, _, _) = pwd.getpwuid(os.getuid()) >+ gecos = gecos.split(',')[0] # bug #80011 >+ user = '%s <%s@gentoo.org>' % (gecos, login) >+ >+ if '<root@' in user: >+ err = 'Please set ECHANGELOG_USER or run as non-root' >+ logging.critical(err) >+ return None >+ >+ cl_path = os.path.join(pkgdir, 'ChangeLog') >+ f, clnew_path = mkstemp(); >+ >+ # create an empty ChangeLog.new with correct header first >+ try: >+ f = os.fdopen(f, 'w+') >+ f.write('# ChangeLog for %s/%s\n' % (category, package)) >+ year = time.strftime('%Y') >+ f.write('# Copyright 1999-%s Gentoo Foundation; Distributed under the GPL v2\n' % year) >+ f.write('# $Header: $\n') >+ f.write('\n') >+ >+ # write new ChangeLog entry >+ date = time.strftime('%d %b %Y') >+ newebuild = False >+ for fn in new: >+ if not fn.endswith('.ebuild'): >+ continue >+ ebuild = fn.split(os.sep)[-1][0:-7] >+ f.write('*%s (%s)\n' % (ebuild, date)) >+ newebuild = True >+ if newebuild: >+ f.write('\n') >+ new = ['+' + elem for elem in new if elem not in ['ChangeLog', 'Manifest']] >+ removed = ['-' + elem for elem in removed] >+ changed = [elem for elem in changed if elem not in ['ChangeLog', 'Manifest']] >+ mesg = '%s; %s %s:' % (date, user, \ >+ ', '.join(chain(new,removed,changed))) >+ for line in textwrap.wrap(mesg, 80, \ >+ initial_indent=' ', subsequent_indent=' ', \ >+ break_on_hyphens=False): >+ f.write('%s\n' % line) >+ for line in textwrap.wrap(msg, 80, \ >+ initial_indent=' ', subsequent_indent=' '): >+ f.write('%s\n' % line) >+ >+ # append stuff from old ChangeLog >+ cl_lines = [] >+ if os.path.exists(cl_path): >+ c = open(cl_path, 'r') >+ cl_lines = c.readlines() >+ for index, line in enumerate(cl_lines): >+ # skip the headers >+ if line.startswith('#'): >+ # normalise to $Header: $ to avoid pointless diff line >+ if line.startswith('# $Header:'): >+ cl_lines[index] = '# $Header: $\n' >+ continue >+ f.write(line) >+ c.close() >+ >+ # show diff (do we want to keep on doing this, or only when >+ # pretend?) >+ f.seek(0) >+ clnew_lines = f.readlines() >+ for line in difflib.unified_diff(cl_lines, clnew_lines, \ >+ fromfile=cl_path, tofile=cl_path + '.new', n=0): >+ print(line.rstrip()) >+ print >+ >+ f.close() >+ >+ if pretend: >+ # remove what we've done >+ os.remove(clnew_path) >+ else: >+ # rename ChangeLog.new to ChangeLog >+ shutil.move(clnew_path, cl_path) >+ >+ if cl_lines == []: >+ return True >+ else: >+ return False >+ except IOError as e: >+ err = 'Repoman is unable to create/write to Changelog.new file' >+ logging.critical(err) >+ # try to remove if possible >+ try: >+ os.remove(clnew_path) >+ except: >+ pass >+ return None >+
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 337853
:
289939
| 290001