Merge lp:~henninge/launchpad/devel-update-copyright into lp:launchpad

Proposed by Henning Eggers
Status: Merged
Approved by: Curtis Hovey
Approved revision: no longer in the source branch.
Merged at revision: 11645
Proposed branch: lp:~henninge/launchpad/devel-update-copyright
Merge into: lp:launchpad
Diff against target: 203 lines (+135/-41)
3 files modified
buildout-templates/bin/lint.sh.in (+3/-41)
utilities/find-changed-files.sh (+45/-0)
utilities/update-copyright (+87/-0)
To merge this branch: bzr merge lp:~henninge/launchpad/devel-update-copyright
Reviewer Review Type Date Requested Status
Curtis Hovey (community) code Approve
Review via email: mp+36701@code.launchpad.net

Commit message

New utility scripts: find-changed-files.sh and update-copyright.

Description of the change

Adds a little script that updates the year information in the copyright header of all changed files. This should make it easy to keep them up to date.

I extracted the code that finds changed files using bzr from lint.sh, which is used by 'make lint'.

No test, this is just a little helper script. Use "bzr diff" after a run to see that it worked.

To post a comment you must log in.
Revision history for this message
Curtis Hovey (sinzui) wrote :

Thank you so much for this.

review: Approve (code)
Revision history for this message
Robert Collins (lifeless) wrote :

There is a bzr plugin that can do this without it being in the LP
source tree. It would be nicer to use that.

Revision history for this message
Brad Crittenden (bac) wrote :

I'm glad to learn of bzr-update-copyright.

Unfortunately when we first put the copyright notice in the files we started with 2009. Using the bzr plugin will change that to use the actual years the file was touched. IANACL so I don't know which is correct but I'd like that to be a decision we make rather than whatever the tool currently writes, so I'd discourage use of the bzr plugin until we can agree.

Note the two tools do not coexist well now as Henning's uses collapsed year ranges, which we prefer, (e.g. "2009-2010") while the plugin produces a comma-separated list. Once the latter is put in the code then this tool is broken.

Perhaps the best effort would be towards improving the plugin.

I'd like for us to get one or the other b/c we spend a lot of time fixing silly copyright notices or leaving them wrong.

Revision history for this message
Robert Collins (lifeless) wrote :

I'd like to see the bzr plugin improved if its insufficient. Perhaps a
file in the bzr extensions namespace in the tree, with a config file
to say (use -, and start in 2009).

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'buildout-templates/bin/lint.sh.in'
--- buildout-templates/bin/lint.sh.in 2010-07-17 21:42:06 +0000
+++ buildout-templates/bin/lint.sh.in 2010-09-28 07:58:44 +0000
@@ -1,6 +1,6 @@
1#!/bin/bash1#!/bin/bash
2#2#
3# Copyright 2009 Canonical Ltd. This software is licensed under the3# Copyright 2009-2010 Canonical Ltd. This software is licensed under the
4# GNU Affero General Public License version 3 (see the file LICENSE).4# GNU Affero General Public License version 3 (see the file LICENSE).
5#5#
6# Runs pocketlint on files changed from parent branch.6# Runs pocketlint on files changed from parent branch.
@@ -12,47 +12,9 @@
12[ -z "$utilitiesdir" ] && utilitiesdir=.12[ -z "$utilitiesdir" ] && utilitiesdir=.
1313
1414
15bzr() {
16 # For pylint to operate properly, PYTHONPATH must point to the ./lib
17 # directory in the launchpad tree. This directory includes a bzrlib. When
18 # this script calls bzr, we want it to use the system bzrlib, not the one
19 # in the launchpad tree.
20 PYTHONPATH='' `which bzr` "$@"
21}
22
23
24if [ -z "$1" ]; then15if [ -z "$1" ]; then
25 # No command line argument provided, use the default logic.16 # No command line argument provided, lint all changed files.
26 bzr diff > /dev/null17 files=$($utilitiesdir/find-changed-files.sh)
27 diff_status=$?
28 if [ $diff_status -eq 0 ] ; then
29 # No uncommitted changes in the tree.
30 bzr status | grep "^Current thread:" > /dev/null
31 if [ $? -eq 0 ] ; then
32 # This is a loom, lint changes relative to the lower thread.
33 rev_option="-r thread:"
34 else
35 if test "$(bzr pipes | sed -n -e "/^\\*/q;p" | wc -l)" -gt 0; then
36 # This is a pipeline with at least one pipe before the
37 # current, lint changes relative to the previous pipe
38 rev_option="-r ancestor::prev"
39 else
40 # Lint changes relative to the parent.
41 rev=`bzr info | sed \
42 '/parent branch:/!d; s/ *parent branch: /ancestor:/'`
43 rev_option="-r $rev"
44 fi
45 fi
46 elif [ $diff_status -eq 1 ] ; then
47 # Uncommitted changes in the tree, lint those changes.
48 rev_option=""
49 else
50 # bzr diff failed
51 exit 1
52 fi
53 # Extract filename from status line. Strip the @ that mark symlinks.
54 files=`bzr st --short $rev_option |
55 sed -e '/^.[MN]/!d; s/.* //' -e 's/@$//'`
56else18else
57 # Add newlines so grep filters out pyfiles correctly later.19 # Add newlines so grep filters out pyfiles correctly later.
58 files=`echo $* | tr " " "\n"`20 files=`echo $* | tr " " "\n"`
5921
=== added file 'utilities/find-changed-files.sh'
--- utilities/find-changed-files.sh 1970-01-01 00:00:00 +0000
+++ utilities/find-changed-files.sh 2010-09-28 07:58:44 +0000
@@ -0,0 +1,45 @@
1#!/bin/bash
2#
3# Copyright 2009-2010 Canonical Ltd. This software is licensed under the
4# GNU Affero General Public License version 3 (see the file LICENSE).
5#
6# Determine the changed files in Bazaar piplines, looms and plain branches.
7
8bzr() {
9 # PYTHONPATH may point to the ./lib directory in the launchpad tree. This
10 # directory includes a bzrlib. When this script calls bzr, we want it to
11 # use the system bzrlib, not the one in the launchpad tree.
12 PYTHONPATH='' `which bzr` "$@"
13}
14
15bzr diff > /dev/null
16diff_status=$?
17if [ $diff_status -eq 0 ] ; then
18 # No uncommitted changes in the tree.
19 bzr status | grep "^Current thread:" > /dev/null
20 if [ $? -eq 0 ] ; then
21 # This is a loom, lint changes relative to the lower thread.
22 rev_option="-r thread:"
23 elif [ "$(bzr pipes | sed -n -e "/^\\*/q;p" | wc -l)" -gt 0 ]; then
24 # This is a pipeline with at least one pipe before the
25 # current, lint changes relative to the previous pipe
26 rev_option="-r ancestor::prev"
27 else
28 # Lint changes relative to the parent.
29 rev=`bzr info | sed \
30 '/parent branch:/!d; s/ *parent branch: /ancestor:/'`
31 rev_option="-r $rev"
32 fi
33elif [ $diff_status -eq 1 ] ; then
34 # Uncommitted changes in the tree, return those files.
35 rev_option=""
36else
37 # bzr diff failed
38 exit 1
39fi
40# Extract filename from status line. Strip the @ that mark symlinks.
41files=`bzr st --short $rev_option |
42 sed -e '/^.[MN]/!d; s/.* //' -e 's/@$//'`
43
44echo $files
45
046
=== added file 'utilities/update-copyright'
--- utilities/update-copyright 1970-01-01 00:00:00 +0000
+++ utilities/update-copyright 2010-09-28 07:58:44 +0000
@@ -0,0 +1,87 @@
1#!/usr/bin/python
2#
3# Copyright 2010 Canonical Ltd. This software is licensed under the
4# GNU Affero General Public License version 3 (see the file LICENSE).
5
6"""Update the year in copyright notices.
7
8This simple script determines the changed files and updates the copyright
9notice to reflect the current year. Looks for the notice in the first three
10lines of the file and leaves the file unchanged if it finds none.
11"""
12
13from datetime import date
14import os
15import re
16from subprocess import (
17 PIPE,
18 Popen,
19 )
20import sys
21
22
23# This script lives in the 'utilites' directory.
24UTILITIES_DIR = os.path.dirname(__file__)
25CURRENT_YEAR = date.today().year
26copyright_pattern = re.compile(
27 "Copyright (?P<years>(?P<yearfrom>[0-9]{4})(-[0-9]{4})?) Canonical Ltd.")
28
29def years_string(yearfrom):
30 """Build the new years string."""
31 if int(yearfrom) >= CURRENT_YEAR:
32 return yearfrom
33 return "%s-%d" % (yearfrom, CURRENT_YEAR)
34
35def update_copyright(lines):
36 """Update the copyright notice in the given file lines."""
37 for line in range(min(len(lines), 3)):
38 match = copyright_pattern.search(lines[line])
39 if match is not None:
40 old_years = match.group('years')
41 new_years = years_string(match.group('yearfrom'))
42 if old_years != new_years:
43 lines[line] = lines[line].replace(old_years, new_years)
44 return True
45 return False
46 return False
47
48
49def update_files(filenames):
50 """Open the files with the given file names and update them."""
51 for filename in filenames:
52 if not os.path.isfile(filename):
53 print "Skipped: %s does not exist or is not a regular file." %(
54 filename)
55 continue
56 if not os.access(filename, os.W_OK):
57 print "Skipped: %s is not writeable." % filename
58 continue
59 lines = file(filename).readlines()
60 changed = update_copyright(lines)
61 if changed:
62 newfile = open(filename, 'w')
63 newfile.write(''.join(lines))
64 newfile.close()
65 print "Updated: %s" % filename
66 else:
67 print "Unchanged: %s" % filename
68
69def find_changed_files():
70 """Use the find-changed-files.sh script."""
71 find_changed_files_cmd = [
72 os.path.join(UTILITIES_DIR, 'find-changed-files.sh')]
73 filenames = Popen(find_changed_files_cmd, stdout=PIPE).communicate()[0]
74 return filenames.strip()
75
76def find_and_update():
77 """Put it all together."""
78 filenames = find_changed_files()
79 if filenames != '':
80 update_files(filenames.split(' '))
81
82if __name__ == "__main__":
83 if len(sys.argv) < 2:
84 find_and_update()
85 else:
86 update_files(sys.argv[1:])
87