def testCopyrightUpdate(self): test_cases = ( ( '2011', '# Copyright 1999-2008 Gentoo Foundation; Distributed under the GPL v2', '# Copyright 1999-2011 Gentoo Authors; Distributed under the GPL v2', ), ( '2011', '# Copyright 1999 Gentoo Foundation; Distributed under the GPL v2', '# Copyright 1999-2011 Gentoo Authors; Distributed under the GPL v2', ), ( '1999', '# Copyright 1999 Gentoo Foundation; Distributed under the GPL v2', '# Copyright 1999 Gentoo Foundation; Distributed under the GPL v2', ), ( '2018', '# Copyright 1999-2008 Gentoo Authors; Distributed under the GPL v2', '# Copyright 1999-2018 Gentoo Authors; Distributed under the GPL v2', ), ( '2018', '# Copyright 2017 Gentoo Authors; Distributed under the GPL v2', '# Copyright 2017-2018 Gentoo Authors; Distributed under the GPL v2', ), ) for year, before, after in test_cases: self.assertEqual(update_copyright_year(year, before), after)
def testCopyrightUpdate(self): test_cases = ( ( "2011", "# Copyright 1999-2008 Gentoo Foundation; Distributed under the GPL v2", "# Copyright 1999-2011 Gentoo Foundation; Distributed under the GPL v2", ), ( "2011", "# Copyright 1999 Gentoo Foundation; Distributed under the GPL v2", "# Copyright 1999-2011 Gentoo Foundation; Distributed under the GPL v2", ), ( "1999", "# Copyright 1999 Gentoo Foundation; Distributed under the GPL v2", "# Copyright 1999 Gentoo Foundation; Distributed under the GPL v2", ), ) for year, before, after in test_cases: self.assertEqual(update_copyright_year(year, before), after)
def UpdateChangeLog( pkgdir, user, msg, skel_path, category, package, new=(), removed=(), changed=(), pretend=False, quiet=False): """ Write an entry to an existing ChangeLog, or create a new one. Updates copyright year on changed files, and updates the header of ChangeLog with the contents of skel.ChangeLog. """ if '<root@' in user: if not quiet: logging.critical('Please set ECHANGELOG_USER or run as non-root') return None # ChangeLog times are in UTC gmtime = time.gmtime() year = time.strftime('%Y', gmtime) date = time.strftime('%d %b %Y', gmtime) # check modified files and the ChangeLog for copyright updates # patches and diffs (identified by .patch and .diff) are excluded for fn in chain(new, changed): if fn.endswith('.diff') or fn.endswith('.patch'): continue update_copyright(os.path.join(pkgdir, fn), year, pretend=pretend) cl_path = os.path.join(pkgdir, 'ChangeLog') clold_lines = [] clnew_lines = [] old_header_lines = [] header_lines = [] clold_file = None try: clold_file = io.open(_unicode_encode( cl_path, encoding=_encodings['fs'], errors='strict'), mode='r', encoding=_encodings['repo.content'], errors='replace') except EnvironmentError: pass f, clnew_path = mkstemp() # construct correct header first try: if clold_file is not None: # retain header from old ChangeLog first_line = True for line in clold_file: line_strip = line.strip() if line_strip and line[:1] != "#": clold_lines.append(line) break # always make sure cat/pkg is up-to-date in case we are # moving packages around, or copied from another pkg, or ... if first_line: if line.startswith('# ChangeLog for'): line = '# ChangeLog for %s/%s\n' % (category, package) first_line = False old_header_lines.append(line) header_lines.append(update_copyright_year(year, line)) if not line_strip: break clskel_file = None if not header_lines: # delay opening this until we find we need a header try: clskel_file = io.open(_unicode_encode( skel_path, encoding=_encodings['fs'], errors='strict'), mode='r', encoding=_encodings['repo.content'], errors='replace') except EnvironmentError: pass if clskel_file is not None: # read skel.ChangeLog up to first empty line for line in clskel_file: line_strip = line.strip() if not line_strip: break line = line.replace('<CATEGORY>', category) line = line.replace('<PACKAGE_NAME>', package) line = update_copyright_year(year, line) header_lines.append(line) header_lines.append('\n') clskel_file.close() # write new ChangeLog entry clnew_lines.extend(header_lines) newebuild = False for fn in new: if not fn.endswith('.ebuild'): continue ebuild = fn.split(os.sep)[-1][0:-7] clnew_lines.append('*%s (%s)\n' % (ebuild, date)) newebuild = True if newebuild: clnew_lines.append('\n') trivial_files = ('ChangeLog', 'Manifest') display_new = [ '+' + elem for elem in new if elem not in trivial_files] display_removed = [ '-' + elem for elem in removed] display_changed = [ elem for elem in changed if elem not in trivial_files] if not (display_new or display_removed or display_changed): # If there's nothing else to display, show one of the # trivial files. for fn in trivial_files: if fn in new: display_new = ['+' + fn] break elif fn in changed: display_changed = [fn] break display_new.sort() display_removed.sort() display_changed.sort() mesg = '%s; %s %s:' % (date, user, ', '.join(chain( display_new, display_removed, display_changed))) for line in textwrap.wrap( mesg, 80, initial_indent=' ', subsequent_indent=' ', break_on_hyphens=False): clnew_lines.append('%s\n' % line) for line in textwrap.wrap( msg, 80, initial_indent=' ', subsequent_indent=' '): clnew_lines.append('%s\n' % line) # Don't append a trailing newline if the file is new. if clold_file is not None: clnew_lines.append('\n') f = io.open( f, mode='w', encoding=_encodings['repo.content'], errors='backslashreplace') for line in clnew_lines: f.write(line) # append stuff from old ChangeLog if clold_file is not None: if clold_lines: # clold_lines may contain a saved non-header line # that we want to write first. # Also, append this line to clnew_lines so that the # unified_diff call doesn't show it as removed. for line in clold_lines: f.write(line) clnew_lines.append(line) else: # ensure that there is no more than one blank # line after our new entry for line in clold_file: if line.strip(): f.write(line) break # Now prepend old_header_lines to clold_lines, for use # in the unified_diff call below. clold_lines = old_header_lines + clold_lines # Trim any trailing newlines. lines = clold_file.readlines() clold_file.close() while lines and lines[-1] == '\n': del lines[-1] f.writelines(lines) f.close() # show diff if not quiet: for line in difflib.unified_diff( clold_lines, clnew_lines, fromfile=cl_path, tofile=cl_path, n=0): util.writemsg_stdout(line, noiselevel=-1) util.writemsg_stdout("\n", noiselevel=-1) if pretend: # remove what we've done os.remove(clnew_path) else: # rename to ChangeLog, and set permissions try: clold_stat = os.stat(cl_path) except OSError: clold_stat = None shutil.move(clnew_path, cl_path) if clold_stat is None: util.apply_permissions(cl_path, mode=0o644) else: util.apply_stat_permissions(cl_path, clold_stat) if clold_file is None: return True else: return False except IOError as e: err = 'Repoman is unable to create/write to Changelog.new file: %s' % (e,) logging.critical(err) # try to remove if possible try: os.remove(clnew_path) except OSError: pass return None