Merge ~nacc/git-ubuntu:source_builder-file_contents into git-ubuntu:master

Proposed by Nish Aravamudan
Status: Merged
Merged at revision: 38b2ef207dfe18552d5a51f52ed55edf0dc3e5eb
Proposed branch: ~nacc/git-ubuntu:source_builder-file_contents
Merge into: git-ubuntu:master
Diff against target: 214 lines (+120/-10)
2 files modified
gitubuntu/source_builder.py (+51/-0)
gitubuntu/source_builder_test.py (+69/-10)
Reviewer Review Type Date Requested Status
Server Team CI bot continuous-integration Approve
Andreas Hasenack Approve
Review via email: mp+342899@code.launchpad.net

Commit message

Make jenkins happy

To post a comment you must log in.
Revision history for this message
Server Team CI bot (server-team-bot) wrote :

FAILED: Continuous integration, rev:d138fb8ee58d7d8c3025a67fe2a33b5dd0c532f5
https://jenkins.ubuntu.com/server/job/git-ubuntu-ci/386/
Executed test runs:
    SUCCESS: VM Setup
    FAILED: Build

Click here to trigger a rebuild:
https://jenkins.ubuntu.com/server/job/git-ubuntu-ci/386/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Server Team CI bot (server-team-bot) wrote :

PASSED: Continuous integration, rev:d138fb8ee58d7d8c3025a67fe2a33b5dd0c532f5
https://jenkins.ubuntu.com/server/job/git-ubuntu-ci/387/
Executed test runs:
    SUCCESS: VM Setup
    SUCCESS: Build
    SUCCESS: Unit Tests
    SUCCESS: Integration Tests
    IN_PROGRESS: Declarative: Post Actions

Click here to trigger a rebuild:
https://jenkins.ubuntu.com/server/job/git-ubuntu-ci/387/rebuild

review: Approve (continuous-integration)
Revision history for this message
Andreas Hasenack (ahasenack) wrote :

Comments inline. Some questions, suggestions, test improvements.

review: Needs Fixing
Revision history for this message
Nish Aravamudan (nacc) wrote :
Download full text (5.9 KiB)

On 10.04.2018 [13:26:29 -0000], Andreas Hasenack wrote:
> Review: Needs Fixing
>
> Comments inline. Some questions, suggestions, test improvements.
>
> Diff comments:
>
> > diff --git a/gitubuntu/source_builder.py b/gitubuntu/source_builder.py
> > index f991be3..dc0ca43 100644
> > --- a/gitubuntu/source_builder.py
> > +++ b/gitubuntu/source_builder.py
> > @@ -77,6 +78,10 @@ class SourceSpec:
> > and the changelog is generated with this list of versions instead.
> > changelog_versions[0] is taken to be the version string of the
> > package itself.
> > + :param dict(str -> str) file_contents: a dictionary of file
> > + names to string contents. The source package should contain the
>
> Suggest to clarify that "file names" may have paths. i.e., "a
> dictionary of file names (with relative to the root of the source
> package) to string contents.". phew, that got long and ugly. Would be
> better to find another phrase for it, or just leave it alone really.
> It's just that whenever I see variables like "filename" or "path" I
> wonder if the former can include a path, an if the latter includes the
> file.

Fixed.

>
> > + specified file names with the specified contents. This is used
> > + to control the tree hashes of generated source packages.
> >
> > Keyword arguments to the constructor map directly to class instances
> > properties. Properties may be manipulated after construction.
> > @@ -141,6 +154,27 @@ class SourceFiles:
> > )
> >
> > @property
> > + def spec_files(self):
> > + """The contents of any files explicitly specified in self.spec
> > +
> > + :returns: a mapping of filename to content
> > + :rtype: dict(str, str)
> > + """
> > + if self.spec.file_contents:
> > + reserved_files_specified = [
> > + f for f in self.spec.file_contents
> > + if f in self.reserved_files
> > + ]
> > + if any(reserved_files_specified):
>
> This might be simpler: "if reserved_files_specified:", since bool([])
> is false and the list comprehension will either return [] or a list
> with one or more elements.

Fixed

> > + raise RuntimeError(
> > + "The file names %s are reserved" %
> > + ", ".join(reserved_files_specified)
>
> Shouldn't we run this check at class instantiation time? Why only now,
> when the attribute that was set a "long time ago" in a different class
> even (SourceSpec)? We check the version in SourceSpec, for example
> (see the two ValueErrors there). Also, shouldn't this exception be of
> the ValueError type as well?

Fixed

> > + )
> > + return self.spec.file_contents
> > + else:
> > + return {}
> > +
> > + @property
> > def source_format(self):
> > """The contents of debian/source/format
> >
> > @@ -231,6 +265,12 @@ class Source:
> > encoding='utf-8',
> > ensure=True,
> > )
> > + for (filename, contents) in self.files.spec_files.items():
> > + tree.joi...

Read more...

Revision history for this message
Server Team CI bot (server-team-bot) wrote :

FAILED: Continuous integration, rev:03bdb46078e2a45f28f51e45ab6c427c2aa5a202
https://jenkins.ubuntu.com/server/job/git-ubuntu-ci/388/
Executed test runs:
    SUCCESS: VM Setup
    FAILED: Build

Click here to trigger a rebuild:
https://jenkins.ubuntu.com/server/job/git-ubuntu-ci/388/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Andreas Hasenack (ahasenack) wrote :

Thanks! +1, as soon as CI approves it.

review: Approve
Revision history for this message
Server Team CI bot (server-team-bot) wrote :

PASSED: Continuous integration, rev:03bdb46078e2a45f28f51e45ab6c427c2aa5a202
https://jenkins.ubuntu.com/server/job/git-ubuntu-ci/389/
Executed test runs:
    SUCCESS: VM Setup
    SUCCESS: Build
    SUCCESS: Unit Tests
    SUCCESS: Integration Tests
    IN_PROGRESS: Declarative: Post Actions

Click here to trigger a rebuild:
https://jenkins.ubuntu.com/server/job/git-ubuntu-ci/389/rebuild

review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/gitubuntu/source_builder.py b/gitubuntu/source_builder.py
2index f991be3..22e8885 100644
3--- a/gitubuntu/source_builder.py
4+++ b/gitubuntu/source_builder.py
5@@ -66,6 +66,12 @@ class SourceSpec:
6 native = True
7 has_patches = False
8 changelog_versions = None
9+ file_contents = None
10+ reserved_files = [
11+ 'debian/changelog',
12+ 'debian/control',
13+ 'debian/rules',
14+ ]
15
16 def __init__(self, **kwargs):
17 """Instantiate a new SourceSpec class instance
18@@ -77,6 +83,11 @@ class SourceSpec:
19 and the changelog is generated with this list of versions instead.
20 changelog_versions[0] is taken to be the version string of the
21 package itself.
22+ :param dict(str -> str) file_contents: a dictionary of string
23+ relative file path names to string contents. The source
24+ package should contain the specified file names with the
25+ specified contents. This is used to control the tree hashes
26+ of generated source packages.
27
28 Keyword arguments to the constructor map directly to class instances
29 properties. Properties may be manipulated after construction.
30@@ -89,9 +100,34 @@ class SourceSpec:
31 if 'version' not in kwargs and not self.native:
32 self.version = '1-1'
33
34+ if self.native and '-' in self.version:
35+ raise ValueError("Version must not have a '-' in a native package")
36+
37 if not self.native and '-' not in self.version:
38 raise ValueError("Version must have a '-' in a non-native package")
39
40+ if self.file_contents is None:
41+ self.file_contents = {}
42+
43+ reserved_files_specified = [
44+ f for f in self.file_contents
45+ if f in self.reserved_files
46+ ]
47+ if reserved_files_specified:
48+ raise ValueError(
49+ "The file names %s are reserved" %
50+ ", ".join(reserved_files_specified)
51+ )
52+
53+ absolute_path_files_specified = [
54+ f for f in self.file_contents
55+ if f.startswith('/')
56+ ]
57+ if absolute_path_files_specified:
58+ raise ValueError(
59+ "File names %s must be relative" %
60+ ", ".join(absolute_path_files_specified)
61+ )
62
63 class SourceFiles:
64 """Representation of a Debian source package in terms of its files
65@@ -141,6 +177,15 @@ class SourceFiles:
66 )
67
68 @property
69+ def spec_files(self):
70+ """The contents of any files explicitly specified in self.spec
71+
72+ :returns: a mapping of filename to content
73+ :rtype: dict(str, str)
74+ """
75+ return self.spec.file_contents
76+
77+ @property
78 def source_format(self):
79 """The contents of debian/source/format
80
81@@ -231,6 +276,12 @@ class Source:
82 encoding='utf-8',
83 ensure=True,
84 )
85+ for (filename, contents) in self.files.spec_files.items():
86+ tree.join(filename).write_text(
87+ contents,
88+ encoding='utf-8',
89+ ensure=True,
90+ )
91 debian.join('source/format').write_text(
92 self.files.source_format,
93 encoding='utf-8',
94diff --git a/gitubuntu/source_builder_test.py b/gitubuntu/source_builder_test.py
95index 41a95de..81095ba 100644
96--- a/gitubuntu/source_builder_test.py
97+++ b/gitubuntu/source_builder_test.py
98@@ -1,4 +1,6 @@
99 import os
100+import subprocess
101+import tempfile
102
103 import pytest
104
105@@ -62,6 +64,50 @@ def test_source_create_with_versions(repo):
106 assert changelog.all_versions == ['3', '4']
107
108
109+@pytest.mark.parametrize('file_contents', [
110+ {'debian/random': 'Some contents'},
111+ {
112+ 'debian/random': 'Some contents',
113+ 'debian/subdir/random': 'Some other contents',
114+ },
115+])
116+def test_source_create_with_file_contents(repo, file_contents):
117+ with target.Source(
118+ target.SourceSpec(file_contents=file_contents)
119+ ) as f:
120+ with tempfile.TemporaryDirectory() as tmpdir:
121+ subprocess.check_call(
122+ ['dpkg-source', '-x', f, os.path.join(tmpdir, 'x')],
123+ )
124+ for _file in file_contents:
125+ assert os.path.exists(os.path.join(tmpdir, 'x', _file))
126+ with open(
127+ os.path.join(tmpdir, 'x', _file)
128+ ) as random_file:
129+ assert random_file.read() == file_contents[_file]
130+
131+
132+@pytest.mark.parametrize('_file', [
133+ 'debian/changelog',
134+ 'debian/control',
135+ 'debian/rules',
136+])
137+def test_source_create_fails_with_reserved_file_contents(repo, _file):
138+ with pytest.raises(ValueError):
139+ with target.Source(
140+ target.SourceSpec(file_contents={_file: 'Some contents'})
141+ ) as f:
142+ pass
143+
144+
145+def test_source_create_fails_with_absolute_path(repo):
146+ with pytest.raises(ValueError):
147+ with target.Source(
148+ target.SourceSpec(file_contents={'/root/path': 'Some contents'})
149+ ) as f:
150+ pass
151+
152+
153 @pytest.mark.parametrize('native,expected', [
154 (True, b"3.0 (native)\n"),
155 (False, b"3.0 (quilt)\n"),
156@@ -126,35 +172,48 @@ def test_source_quilt_with_patches_applied(repo):
157
158
159 def test_source_version_native_default(repo):
160- # The default version string for a native package should not have a '-' in
161- # it.
162+ """The default version string for a native package should not have a
163+ '-' in it.
164+ """
165 version = get_spec_changelog_version(repo, native=True)
166 assert '-' not in version
167
168
169 def test_source_version_non_native_default(repo):
170- # The default version string for a non-native package should have a '-' in
171- # it.
172+ """The default version string for a non-native package should have a
173+ '-' in it.
174+ """
175 version = get_spec_changelog_version(repo, native=False)
176 assert '-' in version
177
178
179 def test_source_version_native_specific(repo):
180- # We should be able to create a native package with a native-looking
181- # version string.
182+ """We should be able to create a native package with a
183+ native-looking version string.
184+ """
185 version = get_spec_changelog_version(repo, native=True, version='1.0')
186 assert version == '1.0'
187
188
189 def test_source_version_non_native_specific(repo):
190- # We should be able to create a non-native package with a non-native
191- # -looking version string.
192+ """We should be able to create a non-native package with a
193+ non-native-looking version string.
194+ """
195 version = get_spec_changelog_version(repo, native=False, version='1.0-1')
196 assert version == '1.0-1'
197
198
199 def test_source_non_native_version_no_hyphen_raises(repo):
200- # Creating a non-native package with a native-looking version string should
201- # fail.
202+ """Creating a non-native package with a native-looking version
203+ string should fail.
204+ """
205 with pytest.raises(ValueError):
206 get_spec_changelog_version(repo, native=False, version='1')
207+
208+
209+def test_source_native_version_hyphen_raises(repo):
210+ """Creating a native package with a non-native-looking version
211+ string should fail.
212+ """
213+ with pytest.raises(ValueError):
214+ print(get_spec_changelog_version(repo, native=True, version='1-1'))

Subscribers

People subscribed via source and target branches