Skip to content

Commit df89024

Browse files
committed
Getting rid of colon separated arguments
1 parent a41c5f7 commit df89024

File tree

2 files changed

+97
-64
lines changed

2 files changed

+97
-64
lines changed

src/repopulator/__main__.py

+95-64
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,20 @@ def add_parser(self, key: str, subparsers: argparse._SubParsersAction[argparse.A
3535
def handle(self, args: argparse.Namespace) -> int:
3636
...
3737

38+
3839
class _AlpineHandler(_Handler):
40+
class _ExtendPackageAction(argparse._ExtendAction):
41+
def __call__(self,
42+
parser: argparse.ArgumentParser,
43+
namespace: argparse.Namespace,
44+
values: str | Sequence[Any] | None,
45+
option_string: str | None = None) -> None:
46+
if isinstance(values, list):
47+
value = [(x, namespace.arch) for x in values]
48+
else:
49+
value = (values, namespace.arch)
50+
super().__call__(parser, namespace, value, option_string)
51+
3952
def add_parser(self, key: str, subparsers: argparse._SubParsersAction[argparse.ArgumentParser]):
4053
parser: argparse.ArgumentParser = subparsers.add_parser(key, description='Create Alpine apk repo')
4154

@@ -54,9 +67,13 @@ def add_parser(self, key: str, subparsers: argparse._SubParsersAction[argparse.A
5467
parser.add_argument('-s', '--signer', type=str, dest='signer',
5568
help='name of the signer. This can be used to override name deduced from the key filename')
5669

57-
parser.add_argument('-p', '--packages', nargs='+', metavar='PACKAGE',
58-
help='.apk file(s) to add to repository. To override apk architecture use filename:arch format. '
59-
'For example foo-doc-1.1-r0.apk:x86_64')
70+
parser.add_argument('-a', '--arch', dest='arch', metavar='ARCH', nargs='?', default=None,
71+
help='override architecture of subsequent packages. To cancel override use -a/--arch '
72+
'with no arguments')
73+
74+
parser.add_argument('-p', '--packages', nargs='+', metavar='PACKAGE',
75+
action=_AlpineHandler._ExtendPackageAction,
76+
help='.apk file(s) to add to repository')
6077

6178

6279
def handle(self, args: argparse.Namespace):
@@ -77,14 +94,13 @@ def handle(self, args: argparse.Namespace):
7794
print(f'Signing as {signer_name}')
7895

7996
repo = AlpineRepo(desc)
80-
for p in packages:
81-
parts = p.split(':', 2)
82-
if len(parts) == 2:
83-
print(f'Adding {parts[0]} with architecture {parts[1]}')
84-
repo.add_package(parts[0], force_arch=parts[1])
97+
for name, arch in packages:
98+
if arch is not None:
99+
print(f'Adding {name} with architecture {arch}')
100+
repo.add_package(name, force_arch=arch)
85101
else:
86-
print(f'Adding {parts[0]}')
87-
repo.add_package(parts[0])
102+
print(f'Adding {name}')
103+
repo.add_package(name)
88104
signer = PkiSigner(key_path, key_password)
89105

90106
repo.export(dest, signer, signer_name)
@@ -192,42 +208,62 @@ def handle(self, args: argparse.Namespace):
192208

193209
return 0
194210

195-
class _AptDistroAction(argparse.Action):
196-
def __call__(self,
197-
parser: argparse.ArgumentParser,
198-
namespace: argparse.Namespace,
199-
values: str | Sequence[Any] | None,
200-
option_string: str | None = None) -> None:
201-
if not isinstance(values, str):
202-
raise argparse.ArgumentError(self, 'distribution option must have a single value')
203-
if not hasattr(namespace, 'distros'):
204-
namespace.distros = {}
205-
distro = namespace.distros.get(values)
206-
if distro is None:
207-
distro = argparse.Namespace()
208-
distro.origin = None
209-
distro.label = None
210-
distro.suite = None
211-
distro.codename = None
212-
distro.version = None
213-
distro.desc = None
214-
distro.packages = []
215-
namespace.distros[values] = distro
216-
namespace.current_distro = distro
217-
218-
219-
class _AptStoreAction(argparse._StoreAction):
220-
def __call__(self,
221-
parser: argparse.ArgumentParser,
222-
namespace: argparse.Namespace,
223-
values: str | Sequence[Any] | None,
224-
option_string: str | None = None) -> None:
225-
if not hasattr(namespace, 'distros'):
226-
name = argparse._get_action_name(self)
227-
raise argparse.ArgumentError(self, f'you must use --distro before {name}')
228-
super().__call__(parser, namespace.current_distro, values, option_string)
229211

230212
class _AptHandler(_Handler):
213+
class _DistroAction(argparse.Action):
214+
def __call__(self,
215+
parser: argparse.ArgumentParser,
216+
namespace: argparse.Namespace,
217+
values: str | Sequence[Any] | None,
218+
option_string: str | None = None) -> None:
219+
if not isinstance(values, str):
220+
raise argparse.ArgumentError(self, 'distribution option must have a single value')
221+
if not hasattr(namespace, 'distros'):
222+
namespace.distros = {}
223+
distro = namespace.distros.get(values)
224+
if distro is None:
225+
distro = argparse.Namespace()
226+
distro.component = None
227+
distro.origin = None
228+
distro.label = None
229+
distro.suite = None
230+
distro.codename = None
231+
distro.version = None
232+
distro.desc = None
233+
distro.packages = []
234+
namespace.distros[values] = distro
235+
namespace.current_distro = distro
236+
237+
238+
class _StoreAction(argparse._StoreAction):
239+
def __call__(self,
240+
parser: argparse.ArgumentParser,
241+
namespace: argparse.Namespace,
242+
values: str | Sequence[Any] | None,
243+
option_string: str | None = None) -> None:
244+
if not hasattr(namespace, 'distros'):
245+
name = argparse._get_action_name(self)
246+
raise argparse.ArgumentError(self, f'you must use --distro before {name}')
247+
super().__call__(parser, namespace.current_distro, values, option_string)
248+
249+
class _ExtendPackageAction(argparse._ExtendAction):
250+
def __call__(self,
251+
parser: argparse.ArgumentParser,
252+
namespace: argparse.Namespace,
253+
values: str | Sequence[Any] | None,
254+
option_string: str | None = None) -> None:
255+
if not hasattr(namespace, 'distros'):
256+
name = argparse._get_action_name(self)
257+
raise argparse.ArgumentError(self, f'you must use --distro before {name}')
258+
259+
if (component := namespace.current_distro.component) is None:
260+
component = 'main'
261+
if isinstance(values, list):
262+
value = [(x, component) for x in values]
263+
else:
264+
value = (values, component)
265+
super().__call__(parser, namespace.current_distro, value, option_string)
266+
231267
def add_parser(self, key: str, subparsers: argparse._SubParsersAction[argparse.ArgumentParser]):
232268
parser: argparse.ArgumentParser = subparsers.add_parser(key, description='Create APT repo')
233269

@@ -238,29 +274,31 @@ def add_parser(self, key: str, subparsers: argparse._SubParsersAction[argparse.A
238274
parser.add_argument('-w', '--password', type=str, dest='key_password', metavar='PASSWORD', required=True,
239275
help='GPG key password')
240276

241-
parser.add_argument('-d', '--distro', type=str, dest='distro', metavar='DISTRO', required=True, action=_AptDistroAction,
277+
parser.add_argument('-d', '--distro', type=str, dest='distro', metavar='DISTRO', required=True, action=_AptHandler._DistroAction,
242278
help='Distribution name. This can be a relative path like `stable/updates`. All subsequent '
243279
'per-distribution options apply to this distribution '
244280
'Conversely this option is required to precede all per-distribution options. Multiple '
245281
'distributions may be specified on the same command line')
246282

247-
parser.add_argument('-g', '--origin', type=str, dest='origin', metavar='STRING', required=False, action=_AptStoreAction,
283+
parser.add_argument('-c', '--comp', type=str, dest='component', metavar='STRING',
284+
nargs='?', default=None, action=_AptHandler._StoreAction,
285+
help='Component for subsequent packages in the current distribution. If not '
286+
'specified, defaults to `main`')
287+
parser.add_argument('--origin', type=str, dest='origin', metavar='STRING', action=_AptHandler._StoreAction,
248288
help='current distribution origin')
249-
parser.add_argument('-l', '--label', type=str, dest='label', metavar='STRING', required=False, action=_AptStoreAction,
289+
parser.add_argument('--label', type=str, dest='label', metavar='STRING', action=_AptHandler._StoreAction,
250290
help='current distribution label')
251-
parser.add_argument('-s', '--suite', type=str, dest='suite', metavar='STRING', required=False, action=_AptStoreAction,
291+
parser.add_argument('--suite', type=str, dest='suite', metavar='STRING', action=_AptHandler._StoreAction,
252292
help='current distribution suite')
253-
parser.add_argument('-c', '--codename', type=str, dest='codename', metavar='STRING', required=False, action=_AptStoreAction,
293+
parser.add_argument('--codename', type=str, dest='codename', metavar='STRING', action=_AptHandler._StoreAction,
254294
help='current distribution codename')
255-
parser.add_argument('--dist-version', type=str, dest='version', metavar='STRING', required=False, action=_AptStoreAction,
295+
parser.add_argument('--distro-version', type=str, dest='version', metavar='STRING', action=_AptHandler._StoreAction,
256296
help='current distribution version')
257-
parser.add_argument('--desc', type=str, dest='desc', metavar='STRING', required=False, action=_AptStoreAction,
297+
parser.add_argument('--desc', type=str, dest='desc', metavar='STRING', action=_AptHandler._StoreAction,
258298
help='current distribution description')
259-
parser.add_argument('-p', '--packages', nargs='+', metavar='PACKAGE', action=_AptStoreAction,
260-
help='.deb file(s) to add to the current distribution. To specify a component for each package '
261-
'use `filename:component` format. For example `foo-1.2.3_amd64.deb:contrib` will assign '
262-
'foo-1.2.3_amd64.deb to contrib component. '
263-
'If no component is specified `main` is assumed.')
299+
300+
parser.add_argument('-p', '--packages', nargs='+', metavar='PACKAGE', action=_AptHandler._ExtendPackageAction,
301+
help='.deb file(s) to add to the current distribution')
264302

265303
def handle(self, args: argparse.Namespace):
266304
distros: dict[str, argparse.Namespace] = args.distros
@@ -272,14 +310,7 @@ def handle(self, args: argparse.Namespace):
272310

273311
all_packages: dict[str, AptPackage] = {}
274312
for distro_path, distro_args in distros.items():
275-
# normalize the list of packages to set((name, component))
276-
normalized: set[Tuple[str, str]] = set()
277-
if distro_args.packages is not None:
278-
for package in distro_args.packages:
279-
name, _, component = package.partition(':')
280-
if len(component) == 0:
281-
component = 'main'
282-
normalized.add((name, component))
313+
normalized: set[Tuple[str, str]] = set(distro_args.packages) if distro_args.packages is not None else set()
283314

284315
print(f'Adding distribution: {distro_path}')
285316
distro = repo.add_distribution(distro_path,

tests/test_apt.py

+2
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,8 @@ def test_cmd(binaries_path, output_path, pgp_cmd):
177177
'-p',
178178
binaries_path / 'wget_1.10-2ubuntu0.1_sparc.deb',
179179
binaries_path / 'wget_1.10.2-1ubuntu1.2_sparc.deb',
180+
'-c', 'haha',
181+
'-p',
180182
binaries_path / 'nano-udeb_1.3.10-1_amd64.udeb',
181183
'-d', 'world',
182184
'-p',

0 commit comments

Comments
 (0)