Merge lp:~sinzui/juju-release-tools/build-package-print into lp:juju-release-tools

Proposed by Curtis Hovey
Status: Merged
Merged at revision: 246
Proposed branch: lp:~sinzui/juju-release-tools/build-package-print
Merge into: lp:juju-release-tools
Diff against target: 241 lines (+120/-21)
5 files modified
Makefile (+7/-2)
assemble-streams.bash (+3/-8)
build_package.py (+50/-2)
supported-releases.txt (+0/-9)
tests/test_build_package.py (+60/-0)
To merge this branch: bzr merge lp:~sinzui/juju-release-tools/build-package-print
Reviewer Review Type Date Requested Status
Aaron Bentley (community) Approve
Review via email: mp+282020@code.launchpad.net

Description of the change

Make build_package.py the only source for juju series information.

We want to stop building and testing vivid, but before we do, We want a single definition of the series Juju supports. This branch removes supported-releases.txt. To do so, assemble-streams.bash call a new build_package.py command to print the series associated with the package version.

The JujuSeries class gained three new methods, two of which I think we probably wont need. The crucial method is get_name_from_package_version() which matches a series name to a series version in the package version. This logic is simpler that the bash rules. The previous rules dealt with the case where agents were created from Ubuntu packages. The Ubuntu devel series never has a series version embedded in the package version. We no longer support Ubuntu packages, so I dropped the rule. The new method returns an empty string when no match is found. None would be preferred if other code used this method, but since it exists just for bash to make a decision, I choose the simplest path.

To post a comment you must log in.
Revision history for this message
Aaron Bentley (abentley) wrote :

Nice improvement.

review: Approve
247. By Curtis Hovey

Exit 1 when a --series-name-from-package-version has no match.

248. By Curtis Hovey

Fix quoting.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'Makefile'
2--- Makefile 2015-08-18 22:42:15 +0000
3+++ Makefile 2016-01-08 21:21:12 +0000
4@@ -1,6 +1,11 @@
5+p=*.py
6 test:
7- TMPDIR=/tmp python -m unittest discover -vv ./tests -p '*.py'
8+ TMPDIR=/tmp python -m unittest discover -vv ./tests -p "$(p)"
9 lint:
10- flake8 --max-line-length=80 .
11+ flake8 --max-line-length=80 $$(find . -name '*.py')
12+cover:
13+ python -m coverage run --source="./" --omit "./tests/*" -m unittest discover -vv ./tests
14+ python -m coverage report
15 clean:
16 find . -name '*.pyc' -delete
17+.PHONY: lint test cover clean
18
19=== modified file 'assemble-streams.bash'
20--- assemble-streams.bash 2015-11-09 22:28:13 +0000
21+++ assemble-streams.bash 2016-01-08 21:21:12 +0000
22@@ -221,15 +221,10 @@
23 get_series() {
24 # Defines $series.
25 control_version=$1
26- ubuntu_devel=$(grep DEVEL $SCRIPT_DIR/supported-releases.txt |
27- cut -d ' ' -f 1)
28- pkg_series=$(basename "$control_version" ~juju1 |
29- sed -r "s/([0-9]ubuntu[0-9])$/\1~$ubuntu_devel/;" |
30- sed -r "s/.*(ubuntu|~)([0-9][0-9]\.[0-9][0-9]).*/\2/")
31- series=$(cat $SCRIPT_DIR/supported-releases.txt |
32- grep $pkg_series | cut -d ' ' -f 2)
33+ series=$($SCRIPT_DIR/build_package.py \
34+ print --series-name-from-package-version $control_version || true)
35 if [[ -z $series ]]; then
36- echo "Invalid series: $control_version, saw [$pkg_series]"
37+ echo "Cannot get juju series from package version $control_version "
38 exit 3
39 fi
40 if ! distro-info --all | grep $series; then
41
42=== modified file 'build_package.py'
43--- build_package.py 2015-12-17 16:19:35 +0000
44+++ build_package.py 2016-01-08 21:21:12 +0000
45@@ -131,10 +131,41 @@
46 series = Series(*line.split())
47 self.all[series.name] = series
48
49+ def get_devel_version(self):
50+ for series in self.all.values():
51+ if series.status == 'DEVEL':
52+ return series.version
53+ else:
54+ raise AssertionError(
55+ "SUPPORTED_RELEASES is missing the DEVEL series")
56+
57 def get_living_names(self):
58 return sorted(s.name for s in self.all.values()
59 if s.status in self.LIVING_STATUSES)
60
61+ def get_name(self, version):
62+ for series in self.all.values():
63+ if series.version == version:
64+ return series.name
65+ else:
66+ raise KeyError("'%s' is not a known series" % version)
67+
68+ def get_name_from_package_version(self, package_version):
69+ """Return the series name associated with the package version.
70+
71+ The series is matched to the series version commonly embedded in
72+ backported package versions. Official juju package versions always
73+ contain the series version to indicate the tool-chain used to build.
74+
75+ Ubuntu devel packages do not have series versions, they cannot be
76+ matched to a series. As Ubuntu packages are not built with ideal rules,
77+ they are not suitable for building agents.
78+ """
79+ for series in self.all.values():
80+ if series.version in package_version:
81+ return series.name
82+ return None
83+
84 def get_version(self, name):
85 return self.all[name].version
86
87@@ -421,6 +452,16 @@
88 return 0
89
90
91+def print_series_info(package_version=None):
92+ exitcode = 1
93+ if package_version:
94+ version = juju_series.get_name_from_package_version(package_version)
95+ if version:
96+ print(version)
97+ return 0
98+ return exitcode
99+
100+
101 def main(argv):
102 """Execute the commands from the command line."""
103 exitcode = 0
104@@ -431,10 +472,13 @@
105 debemail=args.debemail, debfullname=args.debfullname,
106 gpgcmd=args.gpgcmd, branch=args.branch, upatch=args.upatch,
107 verbose=args.verbose)
108- if args.command == 'binary':
109+ elif args.command == 'binary':
110 exitcode = build_binary(
111 args.dsc, args.location, args.series, args.arch,
112 ppa=args.ppa, verbose=args.verbose)
113+ elif args.command == 'print':
114+ exitcode = print_series_info(
115+ package_version=args.series_name_from_package_version)
116 return exitcode
117
118
119@@ -473,8 +517,12 @@
120 bin_parser.add_argument("location", help="The location to build in.")
121 bin_parser.add_argument("series", help="The series to build in.")
122 bin_parser.add_argument("arch", help="The dpkg architecture to build in.")
123+ print_parser = subparsers.add_parser('print', help='Print series info')
124+ print_parser.add_argument(
125+ '--series-name-from-package-version',
126+ help="Print the series name associated with the package version.")
127 args = parser.parse_args(argv[1:])
128- if args.series == 'LIVING':
129+ if getattr(args, 'series', None) and args.series == 'LIVING':
130 args.series = juju_series.get_living_names()
131 return args
132
133
134=== removed file 'supported-releases.txt'
135--- supported-releases.txt 2015-11-26 16:31:28 +0000
136+++ supported-releases.txt 1970-01-01 00:00:00 +0000
137@@ -1,9 +0,0 @@
138-# This is the list of series that must be recognised for tools.
139-12.04 precise LTS
140-12.10 quantal HISTORIC
141-13.10 saucy HISTORIC
142-14.04 trusty LTS
143-14.10 utopic HISTORIC
144-15.04 vivid SUPPORTED
145-15.10 wily SUPPORTED
146-16.04 xenial DEVEL
147
148=== modified file 'tests/test_build_package.py'
149--- tests/test_build_package.py 2015-12-17 16:19:35 +0000
150+++ tests/test_build_package.py 2016-01-08 21:21:12 +0000
151@@ -5,6 +5,7 @@
152 patch
153 )
154 import os
155+from StringIO import StringIO
156 from textwrap import dedent
157 import unittest
158
159@@ -29,6 +30,7 @@
160 make_ubuntu_version,
161 move_debs,
162 parse_dsc,
163+ print_series_info,
164 setup_local,
165 setup_lxc,
166 Series,
167@@ -50,12 +52,38 @@
168 Series('14.10', 'utopic', 'HISTORIC'),
169 juju_series.all['utopic'])
170
171+ def test_get_devel_version(self):
172+ juju_series = _JujuSeries()
173+ [devel] = [s.version for s in juju_series.all.values()
174+ if s.status == 'DEVEL']
175+ self.assertEqual(devel, juju_series.get_devel_version())
176+
177 def test_get_living_names(self):
178 juju_series = _JujuSeries()
179 self.assertEqual(
180 ['precise', 'trusty', 'vivid', 'wily', 'xenial'],
181 juju_series.get_living_names())
182
183+ def test_get_name(self):
184+ juju_series = _JujuSeries()
185+ self.assertEqual('trusty', juju_series.get_name('14.04'))
186+ with self.assertRaises(KeyError):
187+ juju_series.get_version('13.01')
188+
189+ def test_get_name_from_package_version(self):
190+ juju_series = _JujuSeries()
191+ self.assertEqual(
192+ 'xenial',
193+ juju_series.get_name_from_package_version(
194+ '1.26-alpha3-0ubuntu1~16.04.1~juju1'))
195+ self.assertEqual(
196+ 'trusty',
197+ juju_series.get_name_from_package_version(
198+ '1.25.0-0ubuntu1~14.04.1~juju1'))
199+ self.assertIs(
200+ None,
201+ juju_series.get_name_from_package_version('1.25.0-0ubuntu1'))
202+
203 def test_get_version(self):
204 juju_series = _JujuSeries()
205 self.assertEqual('14.04', juju_series.get_version('trusty'))
206@@ -427,3 +455,35 @@
207 cc_mock.assert_called_with(
208 ['debsign -p /my/gpgcmd *.changes'],
209 shell=True, cwd='/juju-build-trusty-all', env=env)
210+
211+ def test_get_args_print(self):
212+ args = get_args(
213+ ['prog', 'print', '--series-name-from-package-version',
214+ '1.25.0-0ubuntu1~16.04.1~juju1'])
215+ self.assertEqual('print', args.command)
216+ self.assertEqual(
217+ '1.25.0-0ubuntu1~16.04.1~juju1',
218+ args.series_name_from_package_version)
219+
220+ def test_main_print(self):
221+ with patch('build_package.print_series_info', autospec=True,
222+ return_value=0) as psi_mock:
223+ code = main(
224+ ['prog', 'print', '--series-name-from-package-version',
225+ '1.25.0-0ubuntu1~16.04.1~juju1'])
226+ self.assertEqual(0, code)
227+ psi_mock.assert_called_with(
228+ package_version='1.25.0-0ubuntu1~16.04.1~juju1')
229+
230+ @patch('sys.stdout', new_callable=StringIO)
231+ def test_print_series_info(self, so_mock):
232+ # Unmatched.
233+ code = print_series_info(
234+ package_version='1.25.0-0ubuntu1')
235+ self.assertEqual(1, code)
236+ self.assertEqual('', so_mock.getvalue())
237+ # Matched.
238+ code = print_series_info(
239+ package_version='1.25.0-0ubuntu1~16.04.1~juju1')
240+ self.assertEqual(0, code)
241+ self.assertEqual('xenial\n', so_mock.getvalue())

Subscribers

People subscribed via source and target branches