Merge lp:~james-w/pkgme/careful-tar-exclude into lp:pkgme

Proposed by James Westby
Status: Merged
Approved by: James Westby
Approved revision: 151
Merged at revision: 149
Proposed branch: lp:~james-w/pkgme/careful-tar-exclude
Merge into: lp:pkgme
Diff against target: 156 lines (+58/-13)
3 files modified
pkgme/debuild.py (+12/-11)
pkgme/tests/__init__.py (+1/-0)
pkgme/tests/test_debuild.py (+45/-2)
To merge this branch: bzr merge lp:~james-w/pkgme/careful-tar-exclude
Reviewer Review Type Date Requested Status
Michael Vogt (community) Approve
Review via email: mp+126327@code.launchpad.net

Commit message

Be more careful in excluding/transforming when making a tarfile.

Only exclude ./debian in case the application contains a 'something/debian'
dir.

Don't transform symlink targets. If they are absolute they shouldn't be
changed. If they are relative and contain the current dir name then they
are broken anyway.

Description of the change

Hi,

This fixes the two (I think) causes of the "unrepresentable changes to source"
errors we are seeing. Both are mistakes in the tar command we use to create
the tarball that change the contents.

Thanks,

James

To post a comment you must log in.
Revision history for this message
Michael Vogt (mvo) wrote :

This is a drive-by review. The fix and the tests look fine!

The only remark is that it took me some seconds to figure out what:

  def get_all_paths(path):
    """Get all the paths that are needed for `path`.

is doing. Maybe something like:
"""Get all the paths that are needed to build/mkdir `path`.
"

review: Approve
Revision history for this message
Jonathan Lange (jml) wrote :

On 26 September 2012 07:53, Michael Vogt <email address hidden> wrote:
> Review: Approve
>
> This is a drive-by review. The fix and the tests look fine!
>
>
> The only remark is that it took me some seconds to figure out what:
>
> def get_all_paths(path):
> """Get all the paths that are needed for `path`.
>
> is doing. Maybe something like:

Renaming to get_all_parents would probably clarify.

Other than that, wonderful, thanks!

jml

151. By James Westby

Rename get_all_paths to try and make the intent clearer.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'pkgme/debuild.py'
2--- pkgme/debuild.py 2012-07-27 07:49:18 +0000
3+++ pkgme/debuild.py 2012-09-26 14:45:26 +0000
4@@ -24,7 +24,7 @@
5 bin_files = []
6 for dirpath, dirnames, filenames in os.walk(directory):
7 for filename in filenames:
8- # test if its a binary file,
9+ # test if its a binary file,
10 # this is what grep is doing to identify binary files
11 if "\0" in open(os.path.join(dirpath, filename)).read(4*1024):
12 bin_files.append(
13@@ -40,7 +40,7 @@
14 to include binary data like icons.
15 """
16 debian_dir = os.path.join(directory, "debian")
17- bin_files = [os.path.join("debian", p)
18+ bin_files = [os.path.join("debian", p)
19 for p in _find_binary_files_in_dir(debian_dir)]
20 with open(os.path.join(
21 directory, "debian/source/include-binaries"), "w") as f:
22@@ -49,13 +49,13 @@
23
24 def build_source_package(directory, sign=True):
25 """Build a source package using debuild"""
26- # prepare the debian/dir by adding binary files to
27+ # prepare the debian/dir by adding binary files to
28 # debian/source/include-binaries
29- #
30+ #
31 # this is essentially what the following is doing:
32- # "debuild --source-option=--include-binaries"
33+ # "debuild --source-option=--include-binaries"
34 # but that option is only available on natty and later (not lucid)
35- #
36+ #
37 # once we do no longer support lucid this can go
38 build_debian_source_include_binaries_content(directory)
39 # now build the orig.tar.gz
40@@ -71,7 +71,7 @@
41
42 def build_orig_tar_gz(target_dir):
43 """Build a pkgname_version.orig.tar.gz from the target_dir.
44-
45+
46 This is usually run as part of build_source_package and does
47 rarely need to be run on its own.
48
49@@ -85,11 +85,12 @@
50 version = changelog.get_version()
51 target_file = os.path.join(
52 target_dir, "..", "%s_%s.orig.tar.gz" % (pkgname, version))
53- cmd = ["tar",
54- "-c",
55+ cmd = ["tar",
56+ "-c",
57 "-z",
58- "--exclude", "debian",
59- "--transform", "s,.,%s-%s," % (pkgname, version),
60+ "--exclude", "./debian",
61+ # "S" flag means "don't transform symlink targets"
62+ "--transform", "s,.,%s-%s,S" % (pkgname, version),
63 "-f", target_file,
64 ".",
65 ]
66
67=== modified file 'pkgme/tests/__init__.py'
68--- pkgme/tests/__init__.py 2012-08-31 10:13:33 +0000
69+++ pkgme/tests/__init__.py 2012-09-26 14:45:26 +0000
70@@ -8,6 +8,7 @@
71 module_names = [
72 'pkgme.tests.test_api',
73 'pkgme.tests.test_backend',
74+ 'pkgme.tests.test_debuild',
75 'pkgme.tests.test_distutils_command',
76 'pkgme.tests.test_info_elements',
77 'pkgme.tests.test_main',
78
79=== modified file 'pkgme/tests/test_debuild.py'
80--- pkgme/tests/test_debuild.py 2012-09-03 15:13:23 +0000
81+++ pkgme/tests/test_debuild.py 2012-09-26 14:45:26 +0000
82@@ -11,6 +11,21 @@
83 )
84
85
86+def expand_path_components(path):
87+ """Get all the path components that are needed to mkdir `path`.
88+
89+ get_all_paths('foo') == ['foo']
90+ get_all_paths('foo/bar') == ['foo', 'foo/bar']
91+ get_all_paths('foo/bar/baz') == ['foo', 'foo/bar', 'foo/bar/baz']
92+ get_all_paths('') == []
93+ """
94+ parts = []
95+ while path != '':
96+ parts.insert(0, path)
97+ path = os.path.dirname(path)
98+ return parts
99+
100+
101 def DebianTempDirFixture():
102 return FileTree(
103 {'debian/icons/': {},
104@@ -19,7 +34,7 @@
105
106 class BuildTarTestCase(TestCase):
107
108- def test_build_orig_tar_gz(self):
109+ def make_debian_tempdir(self):
110 tempdir = self.useFixture(DebianTempDirFixture())
111 changelog_path = tempdir.join("debian", "changelog")
112 with open(changelog_path, "w") as f:
113@@ -30,8 +45,12 @@
114
115 -- Some Guy <foo@example.com> Thu, 19 Apr 2012 10:53:30 +0200
116 """)
117+ return tempdir
118+
119+ def test_build_orig_tar_gz(self):
120+ tempdir = self.make_debian_tempdir()
121 with open(tempdir.join("canary"), "w") as f:
122- f.write("pieep")
123+ f.write("peep")
124 # build it
125 result_path = build_orig_tar_gz(tempdir.path)
126 # verify
127@@ -42,6 +61,30 @@
128 ["testpkg-0.1", "testpkg-0.1/canary"],
129 [m.name for m in f.getmembers()])
130
131+ def test_build_orig_tar_gz_not_exclude_other_debian(self):
132+ tempdir = self.make_debian_tempdir()
133+ canary_filename = "something/debian/canary"
134+ os.makedirs(tempdir.join(os.path.dirname(canary_filename)))
135+ with open(tempdir.join(canary_filename), "w") as f:
136+ f.write("pieep")
137+ result_path = build_orig_tar_gz(tempdir.path)
138+ canary_paths = expand_path_components(canary_filename)
139+ expected_paths = ["testpkg-0.1"]
140+ expected_paths += ["testpkg-0.1/" + path for path in canary_paths]
141+ with tarfile.open(result_path) as f:
142+ self.assertEqual(expected_paths,
143+ [m.name for m in f.getmembers()])
144+
145+ def test_build_orig_tar_gz_preserves_absolute_symlinks(self):
146+ tempdir = self.make_debian_tempdir()
147+ source = 'source'
148+ target = '/a/path'
149+ os.symlink(target, tempdir.join(source))
150+ result_path = build_orig_tar_gz(tempdir.path)
151+ with tarfile.open(result_path) as f:
152+ info = f.getmember("testpkg-0.1/" + source)
153+ self.assertEqual(target, info.linkname)
154+
155
156 class BuildIncludeBinariesTestCase(TestCase):
157

Subscribers

People subscribed via source and target branches

to all changes: