Merge ~nacc/git-ubuntu:source_builder-file_contents into git-ubuntu:master
- Git
- lp:~nacc/git-ubuntu
- source_builder-file_contents
- Merge into master
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) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Server Team CI bot | continuous-integration | Approve | |
Andreas Hasenack | Approve | ||
Review via email:
|
Commit message
Make jenkins happy
Description of the change
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Server Team CI bot (server-team-bot) wrote : | # |
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Server Team CI bot (server-team-bot) wrote : | # |
PASSED: Continuous integration, rev:d138fb8ee58
https:/
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:/
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Andreas Hasenack (ahasenack) wrote : | # |
Comments inline. Some questions, suggestions, test improvements.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Nish Aravamudan (nacc) wrote : | # |
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/
> > index f991be3..dc0ca43 100644
> > --- a/gitubuntu/
> > +++ b/gitubuntu/
> > @@ -77,6 +78,10 @@ class SourceSpec:
> > and the changelog is generated with this list of versions instead.
> > changelog_
> > 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.
> > + reserved_
> > + f for f in self.spec.
> > + if f in self.reserved_files
> > + ]
> > + if any(reserved_
>
> This might be simpler: "if reserved_
> 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(
>
> 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.
> > + else:
> > + return {}
> > +
> > + @property
> > def source_
> > """The contents of debian/
> >
> > @@ -231,6 +265,12 @@ class Source:
> > encoding='utf-8',
> > ensure=True,
> > )
> > + for (filename, contents) in self.files.
> > + tree.joi...
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Server Team CI bot (server-team-bot) wrote : | # |
FAILED: Continuous integration, rev:03bdb46078e
https:/
Executed test runs:
SUCCESS: VM Setup
FAILED: Build
Click here to trigger a rebuild:
https:/
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Andreas Hasenack (ahasenack) wrote : | # |
Thanks! +1, as soon as CI approves it.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Server Team CI bot (server-team-bot) wrote : | # |
PASSED: Continuous integration, rev:03bdb46078e
https:/
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:/
Preview Diff
1 | diff --git a/gitubuntu/source_builder.py b/gitubuntu/source_builder.py |
2 | index 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', |
94 | diff --git a/gitubuntu/source_builder_test.py b/gitubuntu/source_builder_test.py |
95 | index 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')) |
FAILED: Continuous integration, rev:d138fb8ee58 d7d8c3025a67fe2 a33b5dd0c532f5 /jenkins. ubuntu. com/server/ job/git- ubuntu- ci/386/
https:/
Executed test runs:
SUCCESS: VM Setup
FAILED: Build
Click here to trigger a rebuild: /jenkins. ubuntu. com/server/ job/git- ubuntu- ci/386/ rebuild
https:/