Merge ~lgp171188/lpci:set-sensible-defaults-some-package-repository-fields into lpci:main

Proposed by Guruprasad
Status: Merged
Merged at revision: 6f08091455d9d6d022f1eaa11671fdb052d20c40
Proposed branch: ~lgp171188/lpci:set-sensible-defaults-some-package-repository-fields
Merge into: lpci:main
Diff against target: 221 lines (+88/-32)
4 files modified
NEWS.rst (+2/-1)
docs/configuration.rst (+10/-6)
lpcraft/config.py (+47/-22)
lpcraft/tests/test_config.py (+29/-3)
Reviewer Review Type Date Requested Status
Colin Watson (community) Approve
Review via email: mp+435356@code.launchpad.net

Commit message

Set sensible default values for some package repository fields

Also, simplify the package repository cross-field validation.

To post a comment you must log in.
Revision history for this message
Colin Watson (cjwatson) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/NEWS.rst b/NEWS.rst
2index 4defd5a..f351e3f 100644
3--- a/NEWS.rst
4+++ b/NEWS.rst
5@@ -5,8 +5,9 @@ Version history
6 0.0.40 (unreleased)
7 ===================
8
9-- Fix the leakage of package repositories from a job to the next
10+- Fix the leakage of package repositories from a job to the next.
11 - Add support for Python 3.11.
12+- Set sensible default values for some package repository fields.
13
14 0.0.39 (2023-01-06)
15 ===================
16diff --git a/docs/configuration.rst b/docs/configuration.rst
17index 180734c..d25c96d 100644
18--- a/docs/configuration.rst
19+++ b/docs/configuration.rst
20@@ -190,13 +190,15 @@ Adding a PPA
21 Specifies the type of package-repository.
22 Currently only ``apt`` is supported.
23
24-``formats`` (required)
25+``formats`` (optional)
26 Specifies the format of the package-repository.
27- Supported values: ``deb`` and ``deb-src``.
28+ Supported values: ``deb`` and ``deb-src``. If unspecified,
29+ the format is assumed to be ``deb`` , i.e. ``[deb]``
30
31-``suites`` (required)
32+``suites`` (optional)
33 Specifies the suite of the package-repository.
34- One or several of ``bionic``, ``focal``, ``jammy``.
35+ One or several of ``bionic``, ``focal``, ``jammy``. If unspecified,
36+ the suite is assumed to be the corresponding job's ``series`` value.
37
38 ``ppa`` (required)
39 Specifies the PPA to be used as the package repository in the short form,
40@@ -228,11 +230,13 @@ Adding a deb repository
41
42 ``formats`` (required)
43 Specifies the format of the package-repository.
44- Supported values: ``deb`` and ``deb-src``.
45+ Supported values: ``deb`` and ``deb-src``. If unspecified,
46+ the format is assumed to be ``deb``, i.e. ``[deb]``.
47
48 ``suites`` (required)
49 Specifies the suite of the package-repository.
50- One or several of ``bionic``, ``focal``, ``jammy``.
51+ One or several of ``bionic``, ``focal``, ``jammy``. If unspecified,
52+ the suite is assumed to be the corresponding job's ``series`` value.
53
54 ``components`` (required)
55 Specifies the component of the package-repository,
56diff --git a/lpcraft/config.py b/lpcraft/config.py
57index 7c36713..d228270 100644
58--- a/lpcraft/config.py
59+++ b/lpcraft/config.py
60@@ -152,9 +152,9 @@ class PackageRepository(ModelConfigDefaults):
61
62 type: PackageType # e.g. `apt``
63 ppa: Optional[PPAShortFormURL] # e.g. `launchpad/ubuntu/ppa`
64- formats: List[PackageFormat] # e.g. `[deb, deb-src]`
65+ formats: Optional[List[PackageFormat]] # e.g. `[deb, deb-src]`
66 components: Optional[List[PackageComponent]] # e.g. `[main, universe]`
67- suites: List[PackageSuite] # e.g. `[bionic, focal]`
68+ suites: Optional[List[PackageSuite]] # e.g. `[bionic, focal]`
69 url: Optional[AnyHttpUrl]
70 trusted: Optional[bool]
71
72@@ -162,26 +162,29 @@ class PackageRepository(ModelConfigDefaults):
73 def validate_multiple_fields(
74 cls, values: Dict[str, Any]
75 ) -> Dict[str, Any]:
76- if "url" not in values and "ppa" not in values:
77- raise ValueError(
78- "One of the following keys is required with an appropriate"
79- " value: 'url', 'ppa'."
80- )
81- elif "url" in values and "ppa" in values:
82- raise ValueError(
83- "Only one of the following keys can be specified:"
84- " 'url', 'ppa'."
85- )
86- elif "ppa" not in values and "components" not in values:
87- raise ValueError(
88- "One of the following keys is required with an appropriate"
89- " value: 'components', 'ppa'."
90- )
91- elif "ppa" in values and "components" in values:
92- raise ValueError(
93- "The 'components' key is not allowed when the 'ppa' key is"
94- " specified. PPAs only support the 'main' component."
95- )
96+ if "url" in values:
97+ if "ppa" in values:
98+ raise ValueError(
99+ "Only one of the following keys can be specified:"
100+ " 'url', 'ppa'."
101+ )
102+ if "components" not in values:
103+ raise ValueError(
104+ "The 'components' key is required when the 'url' key"
105+ " is specified."
106+ )
107+ else:
108+ if "ppa" not in values:
109+ raise ValueError(
110+ "One of the following keys is required with an appropriate"
111+ " value: 'url', 'ppa'."
112+ )
113+ if "components" in values:
114+ raise ValueError(
115+ "The 'components' key is not allowed when the 'ppa' key is"
116+ " specified. PPAs only support the 'main' component."
117+ )
118+
119 return values
120
121 @validator("components", pre=True, always=True)
122@@ -206,6 +209,14 @@ class PackageRepository(ModelConfigDefaults):
123 )
124 return v
125
126+ @validator("formats", pre=True, always=True)
127+ def set_formats_default_value(
128+ cls, v: List[PackageFormat]
129+ ) -> List[PackageFormat]:
130+ if not v:
131+ v = [PackageFormat.deb]
132+ return v
133+
134 @validator("trusted")
135 def convert_trusted(cls, v: bool) -> str:
136 # trusted is True or False, but we need `yes` or `no`
137@@ -216,6 +227,8 @@ class PackageRepository(ModelConfigDefaults):
138
139 e.g. 'deb https://canonical.example.org/artifactory/jammy-golang-backport focal main'
140 """ # noqa: E501
141+ assert self.formats is not None
142+ assert self.suites is not None
143 for format in self.formats:
144 for suite in self.suites:
145 assert self.components is not None
146@@ -254,6 +267,18 @@ class Job(ModelConfigDefaults):
147 v = [v]
148 return v
149
150+ @pydantic.validator("package_repositories")
151+ def validate_package_repositories(
152+ cls, v: List[PackageRepository], values: Dict[StrictStr, Any]
153+ ) -> List[PackageRepository]:
154+ package_repositories = None
155+ for index, package_repository in enumerate(v):
156+ if not package_repository.suites:
157+ if not package_repositories:
158+ package_repositories = v.copy()
159+ package_repositories[index].suites = [values["series"]]
160+ return package_repositories or v
161+
162 @pydantic.root_validator(pre=True)
163 def move_plugin_config_settings(
164 cls, values: Dict[StrictStr, Any]
165diff --git a/lpcraft/tests/test_config.py b/lpcraft/tests/test_config.py
166index b68e20b..6c69eab 100644
167--- a/lpcraft/tests/test_config.py
168+++ b/lpcraft/tests/test_config.py
169@@ -579,6 +579,32 @@ class TestConfig(TestCase):
170 get_ppa_url_parts(PPAShortFormURL("example/debian/bar")),
171 )
172
173+ def test_default_values_for_package_repository_suites_and_formats(self):
174+ path = self.create_config(
175+ dedent(
176+ """
177+ pipeline:
178+ - test
179+ jobs:
180+ test:
181+ series: focal
182+ architectures: amd64
183+ packages: [foo]
184+ package-repositories:
185+ - type: apt
186+ ppa: launchpad/ubuntu/ppa
187+ - type: apt
188+ url: https://canonical.example.org/ubuntu
189+ components: [main]
190+ """
191+ )
192+ )
193+ config = Config.load(path)
194+
195+ for package_repository in config.jobs["test"][0].package_repositories:
196+ self.assertEqual(["deb"], package_repository.formats)
197+ self.assertEqual(["focal"], package_repository.suites)
198+
199 def test_missing_ppa_and_url(self):
200 path = self.create_config(
201 dedent(
202@@ -634,7 +660,7 @@ class TestConfig(TestCase):
203 path,
204 )
205
206- def test_missing_ppa_and_components(self):
207+ def test_missing_components_when_url_is_specified(self):
208 path = self.create_config(
209 dedent(
210 """
211@@ -655,8 +681,8 @@ class TestConfig(TestCase):
212 )
213 self.assertRaisesRegex(
214 ValidationError,
215- r"One of the following keys is required with an appropriate"
216- r" value: 'components', 'ppa'.",
217+ r"The 'components' key is required when the 'url' key"
218+ r" is specified.",
219 Config.load,
220 path,
221 )

Subscribers

People subscribed via source and target branches