Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 337853 | Differences between
and this patch

Collapse All | Expand All

(-)a/bin/repoman (-56 / +58 lines)
Lines 652-670 Link Here
652
if vcs is None:
652
if vcs is None:
653
	options.echangelog = 'n'
653
	options.echangelog = 'n'
654
654
655
if 'commit' == options.mode and \
656
	options.echangelog == 'y' and \
657
	find_binary('echangelog') is None:
658
	logging.error("echangelog not found, and --echangelog is enabled")
659
	sys.exit(1)
660
661
# The --echangelog option causes automatic ChangeLog generation,
655
# The --echangelog option causes automatic ChangeLog generation,
662
# which invalidates changelog.ebuildadded and changelog.missing
656
# which invalidates changelog.ebuildadded and changelog.missing
663
# checks.
657
# checks.
664
# Note: We don't use ChangeLogs in distributed SCMs.
658
# Note: Some don't use ChangeLogs in distributed SCMs.
665
# It will be generated on server side from scm log,
659
# It will be generated on server side from scm log,
666
# before package moves to the rsync server.
660
# before package moves to the rsync server.
667
# This is needed because we try to avoid merge collisions.
661
# This is needed because they try to avoid merge collisions.
662
# Gentoo's Council decided to always use the ChangeLog file.
663
# TODO: shouldn't this just be switched on the repo, iso the VCS?
668
check_changelog = options.echangelog != 'y' and vcs in ('cvs', 'svn')
664
check_changelog = options.echangelog != 'y' and vcs in ('cvs', 'svn')
669
665
670
# Generate an appropriate PORTDIR_OVERLAY value for passing into the
666
# Generate an appropriate PORTDIR_OVERLAY value for passing into the
Lines 2291-2326 Link Here
2291
				myautoadd+=[myunadded[x]]
2287
				myautoadd+=[myunadded[x]]
2292
				del myunadded[x]
2288
				del myunadded[x]
2293
2289
2294
	if myautoadd:
2295
		print(">>> Auto-Adding missing Manifest(s)...")
2296
		if options.pretend:
2297
			if vcs == "cvs":
2298
				print("(cvs add "+" ".join(myautoadd)+")")
2299
			elif vcs == "svn":
2300
				print("(svn add "+" ".join(myautoadd)+")")
2301
			elif vcs == "git":
2302
				print("(git add "+" ".join(myautoadd)+")")
2303
			elif vcs == "bzr":
2304
				print("(bzr add "+" ".join(myautoadd)+")")
2305
			elif vcs == "hg":
2306
				print("(hg add "+" ".join(myautoadd)+")")
2307
			retval=0
2308
		else:
2309
			if vcs == "cvs":
2310
				retval=os.system("cvs add "+" ".join(myautoadd))
2311
			elif vcs == "svn":
2312
				retval=os.system("svn add "+" ".join(myautoadd))
2313
			elif vcs == "git":
2314
				retval=os.system("git add "+" ".join(myautoadd))
2315
			elif vcs == "bzr":
2316
				retval=os.system("bzr add "+" ".join(myautoadd))
2317
			elif vcs == "hg":
2318
				retval=os.system("hg add "+" ".join(myautoadd))
2319
		if retval:
2320
			writemsg_level("!!! Exiting on %s (shell) error code: %s\n" % \
2321
				(vcs, retval), level=logging.ERROR, noiselevel=-1)
2322
			sys.exit(retval)
2323
2324
	if myunadded:
2290
	if myunadded:
2325
		print(red("!!! The following files are in your local tree but are not added to the master"))
2291
		print(red("!!! The following files are in your local tree but are not added to the master"))
2326
		print(red("!!! tree. Please remove them from the local tree or add them to the master tree."))
2292
		print(red("!!! tree. Please remove them from the local tree or add them to the master tree."))
Lines 2409-2416 Link Here
2409
	myheaders = []
2375
	myheaders = []
2410
	mydirty = []
2376
	mydirty = []
2411
2377
2412
	print("* %s files being committed..." % green(str(len(myupdates))), end=' ')
2413
2414
	commitmessage = options.commitmsg
2378
	commitmessage = options.commitmsg
2415
	if options.commitmsgfile:
2379
	if options.commitmsgfile:
2416
		try:
2380
		try:
Lines 2480-2501 Link Here
2480
			if changelog_modified:
2444
			if changelog_modified:
2481
				continue
2445
				continue
2482
2446
2483
			myupdates.append(changelog_path)
2447
			# get changes for this package
2484
			logging.info("calling echangelog for package %s" % x)
2448
			cdrlen = len(checkdir_relative)
2485
			# --no-strict is required if only manifest(s) have changed
2449
			clnew = [elem[cdrlen:] for elem in mynew if elem.startswith(checkdir_relative)]
2486
			echangelog_args = ["echangelog", "--no-strict",
2450
			clremoved = [elem[cdrlen:] for elem in myremoved if elem.startswith(checkdir_relative)]
2487
				"--vcs", vcs, changelog_msg]
2451
			clchanged = [elem[cdrlen:] for elem in mychanged if elem.startswith(checkdir_relative)]
2488
			if options.pretend:
2452
			new_changelog = utilities.UpdateChangeLog(checkdir_relative, \
2489
				writemsg_stdout("(%s)\n" % (" ".join(echangelog_args),),
2453
				catdir, pkgdir, \
2490
					noiselevel=-1)
2454
				clnew, clremoved, clchanged, \
2491
				continue
2455
				changelog_msg, options.pretend)
2492
			echangelog_args = [_unicode_encode(arg) for arg in echangelog_args]
2456
			if new_changelog is None:
2493
			echangelog_cwd = _unicode_encode(checkdir,
2457
				writemsg_level("!!! Updating the ChangeLog failed\n", \
2494
				encoding=_encodings['fs'], errors='strict')
2458
					level=logging.ERROR, noiselevel=-1)
2495
			retcode = subprocess.call(echangelog_args, cwd=echangelog_cwd)
2459
				sys.exit(1)
2496
			if retcode != os.EX_OK:
2460
2497
				logging.error("echangelog exited with '%s' status" % retcode)
2461
			# if the ChangeLog was just created, add it to vcs
2498
				sys.exit(retcode)
2462
			if new_changelog:
2463
				myautoadd+=[changelog_path]
2464
				# myautoadd is appended to myupdates below
2465
			else:
2466
				myupdates.append(changelog_path)
2467
2468
	if myautoadd:
2469
		print(">>> Auto-Adding missing Manifest/ChangeLog file(s)...")
2470
		if options.pretend:
2471
			if vcs == "cvs":
2472
				print("(cvs add "+" ".join(myautoadd)+")")
2473
			elif vcs == "svn":
2474
				print("(svn add "+" ".join(myautoadd)+")")
2475
			elif vcs == "git":
2476
				print("(git add "+" ".join(myautoadd)+")")
2477
			elif vcs == "bzr":
2478
				print("(bzr add "+" ".join(myautoadd)+")")
2479
			elif vcs == "hg":
2480
				print("(hg add "+" ".join(myautoadd)+")")
2481
			retval=0
2482
		else:
2483
			if vcs == "cvs":
2484
				retval=os.system("cvs add "+" ".join(myautoadd))
2485
			elif vcs == "svn":
2486
				retval=os.system("svn add "+" ".join(myautoadd))
2487
			elif vcs == "git":
2488
				retval=os.system("git add "+" ".join(myautoadd))
2489
			elif vcs == "bzr":
2490
				retval=os.system("bzr add "+" ".join(myautoadd))
2491
			elif vcs == "hg":
2492
				retval=os.system("hg add "+" ".join(myautoadd))
2493
		if retval:
2494
			writemsg_level("!!! Exiting on %s (shell) error code: %s\n" % \
2495
				(vcs, retval), level=logging.ERROR, noiselevel=-1)
2496
			sys.exit(retval)
2497
2498
		myupdates+=myautoadd
2499
2500
	print("* %s files being committed..." % green(str(len(myupdates))), end=' ')
2499
2501
2500
	if vcs not in ('cvs', 'svn'):
2502
	if vcs not in ('cvs', 'svn'):
2501
		# With git, bzr and hg, there's never any keyword expansion, so
2503
		# With git, bzr and hg, there's never any keyword expansion, so
(-)a/pym/repoman/utilities.py (-2 / +116 lines)
Lines 17-23 Link Here
17
	"have_profile_dir",
17
	"have_profile_dir",
18
	"parse_metadata_use",
18
	"parse_metadata_use",
19
	"UnknownHerdsError",
19
	"UnknownHerdsError",
20
	"check_metadata"
20
	"check_metadata",
21
	"UpdateChangeLog"
21
]
22
]
22
23
23
import errno
24
import errno
Lines 35-40 Link Here
35
from portage.process import find_binary
36
from portage.process import find_binary
36
from portage import exception
37
from portage import exception
37
from portage import util
38
from portage import util
39
import time
40
import textwrap
41
import difflib
42
import shutil
43
from tempfile import mkstemp
44
from itertools import chain
38
normalize_path = util.normalize_path
45
normalize_path = util.normalize_path
39
util.initialize_logger()
46
util.initialize_logger()
40
47
Lines 308-314 Link Here
308
	@rtype: string or None
315
	@rtype: string or None
309
	@returns: A string on success or None if an error occurs.
316
	@returns: A string on success or None if an error occurs.
310
	"""
317
	"""
311
	from tempfile import mkstemp
312
	fd, filename = mkstemp()
318
	fd, filename = mkstemp()
313
	try:
319
	try:
314
		os.write(fd, _unicode_encode(_(
320
		os.write(fd, _unicode_encode(_(
Lines 511-513 Link Here
511
		outvcs = seek()
517
		outvcs = seek()
512
518
513
	return outvcs
519
	return outvcs
520
521
def UpdateChangeLog(pkgdir, category, package, new, removed, changed, msg, pretend):
522
	""" Write an entry to an existing ChangeLog, or create a new one. """
523
524
	# figure out who to write as
525
	if 'GENTOO_COMMITTER_NAME' in os.environ and \
526
			'GENTOO_COMMITTER_EMAIL' in os.environ:
527
		user = '%s <%s>' % (os.getenv('GENTOO_COMMITTER_NAME'), \
528
				os.getenv('GENTOO_COMMITTER_EMAIL'))
529
	elif 'GENTOO_AUTHOR_NAME' in os.environ and \
530
			'GENTOO_AUTHOR_EMAIL' in os.environ:
531
		user = '%s <%s>' % (os.getenv('GENTOO_AUTHOR_NAME'), \
532
				os.getenv('GENTOO_AUTHOR_EMAIL'))
533
	elif 'ECHANGELOG_USER' in os.environ:
534
		user = os.getenv('ECHANGELOG_USER')
535
	else:
536
		(login, _, _, _, gecos, _, _) = pwd.getpwuid(os.getuid())
537
		gecos = gecos.split(',')[0]  # bug #80011
538
		user = '%s <%s@gentoo.org>' % (gecos, login)
539
	
540
	if '<root@' in user:
541
		err = 'Please set ECHANGELOG_USER or run as non-root'
542
		logging.critical(err)
543
		return None
544
545
	cl_path = os.path.join(pkgdir, 'ChangeLog')
546
	f, clnew_path = mkstemp();
547
548
	# create an empty ChangeLog.new with correct header first
549
	try:
550
		f = os.fdopen(f, 'w+')
551
		f.write('# ChangeLog for %s/%s\n' % (category, package))
552
		year = time.strftime('%Y')
553
		f.write('# Copyright 1999-%s Gentoo Foundation; Distributed under the GPL v2\n' % year)
554
		f.write('# $Header: $\n')
555
		f.write('\n')
556
557
		# write new ChangeLog entry
558
		date = time.strftime('%d %b %Y')
559
		newebuild = False
560
		for fn in new:
561
			if not fn.endswith('.ebuild'):
562
				continue
563
			ebuild = fn.split(os.sep)[-1][0:-7] 
564
			f.write('*%s (%s)\n' % (ebuild, date))
565
			newebuild = True
566
		if newebuild:
567
			f.write('\n')
568
		new = ['+' + elem for elem in new if elem not in ['ChangeLog', 'Manifest']]
569
		removed = ['-' + elem for elem in removed]
570
		changed = [elem for elem in changed if elem not in ['ChangeLog', 'Manifest']]
571
		mesg = '%s; %s %s:' % (date, user, \
572
				', '.join(chain(new,removed,changed)))
573
		for line in textwrap.wrap(mesg, 80, \
574
				initial_indent='  ', subsequent_indent='  ', \
575
				break_on_hyphens=False):
576
			f.write('%s\n' % line)
577
		for line in textwrap.wrap(msg, 80, \
578
				initial_indent='  ', subsequent_indent='  '):
579
			f.write('%s\n' % line)
580
581
		# append stuff from old ChangeLog
582
		cl_lines = []
583
		if os.path.exists(cl_path):
584
			c = open(cl_path, 'r')
585
			cl_lines = c.readlines()
586
			for index, line in enumerate(cl_lines):
587
				# skip the headers
588
				if line.startswith('#'):
589
					# normalise to $Header: $ to avoid pointless diff line
590
					if line.startswith('# $Header:'):
591
						cl_lines[index] = '# $Header: $\n'
592
					continue
593
				f.write(line)
594
			c.close()
595
596
		# show diff (do we want to keep on doing this, or only when
597
		# pretend?)
598
		f.seek(0)
599
		clnew_lines = f.readlines()
600
		for line in difflib.unified_diff(cl_lines, clnew_lines, \
601
				fromfile=cl_path, tofile=cl_path + '.new', n=0):
602
			print(line.rstrip())
603
		print
604
605
		f.close()
606
607
		if pretend:
608
			# remove what we've done
609
			os.remove(clnew_path)
610
		else:
611
			# rename ChangeLog.new to ChangeLog
612
			shutil.move(clnew_path, cl_path)
613
614
		if cl_lines == []:
615
			return True
616
		else:
617
			return False
618
	except IOError as e:
619
		err = 'Repoman is unable to create/write to Changelog.new file'
620
		logging.critical(err)
621
		# try to remove if possible
622
		try:
623
			os.remove(clnew_path)
624
		except:
625
			pass
626
		return None
627

Return to bug 337853