mirror of
https://git.launchpad.net/livecd-rootfs
synced 2025-08-14 10:14:10 +00:00
112 lines
3.5 KiB
Python
Executable File
112 lines
3.5 KiB
Python
Executable File
#!/usr/bin/python3
|
|
|
|
import argparse
|
|
import glob
|
|
import os
|
|
import re
|
|
|
|
p = argparse.ArgumentParser()
|
|
p.add_argument('output_dir')
|
|
p.add_argument('flavour')
|
|
p.add_argument('task')
|
|
p.add_argument('what', choices=['packages', 'snaps'])
|
|
p.add_argument('arch', default='amd64')
|
|
args = p.parse_args()
|
|
|
|
if args.what == 'snaps':
|
|
ext = '.snaps'
|
|
else:
|
|
ext = ''
|
|
|
|
|
|
# begin copy/paste from ubuntu-archive-publishing's generate_extra_overrides.
|
|
def parseTaskHeaders(seedtext):
|
|
"""Parse a seed for Task headers.
|
|
|
|
seedtext is a file-like object. Return a dictionary of Task headers,
|
|
with keys canonicalised to lower-case.
|
|
"""
|
|
task_headers = {}
|
|
task_header_regex = re.compile(
|
|
r"task-(.*?):(.*)", flags=re.IGNORECASE)
|
|
for line in seedtext:
|
|
match = task_header_regex.match(line)
|
|
if match is not None:
|
|
key, value = match.groups()
|
|
task_headers[key.lower()] = value.strip()
|
|
return task_headers
|
|
|
|
def getTaskSeeds(task_headers, seedname):
|
|
"""Return the list of seeds used to generate a task from this seed.
|
|
|
|
The list of packages in this task comes from this seed plus any
|
|
other seeds listed in a Task-Seeds header.
|
|
"""
|
|
scan_seeds = set([seedname])
|
|
if "seeds" in task_headers:
|
|
scan_seeds.update(task_headers["seeds"].split())
|
|
return sorted(scan_seeds)
|
|
# end copy/paste from ubuntu-archive-publishing's generate_extra_overrides.
|
|
|
|
# This is not quite the same as the one in generate_extra_overrides,
|
|
# because for seeds that do not have flavour specific names, the Task
|
|
# override is only generated for the Ubuntu flavour rather than
|
|
# redundantly doing it for each flavour.
|
|
def getTaskName(task_headers, flavour, seedname):
|
|
"""Work out the name of the Task to be generated from this seed.
|
|
|
|
If there is a Task-Name header, it wins; otherwise, seeds with a
|
|
Task-Per-Derivative get put in an appropriate namespace. Other seeds
|
|
have a task name that matches the seed name.
|
|
"""
|
|
if "name" in task_headers:
|
|
return task_headers["name"]
|
|
elif "per-derivative" in task_headers:
|
|
return "%s-%s" % (flavour, seedname)
|
|
else:
|
|
return seedname
|
|
|
|
|
|
# An item in a Germinate seed
|
|
packages = set()
|
|
seed_pattern = re.compile(r'^\s*\*\s+(?P<raw_pkg>.+?)(?=\s+(?:\[[^\]]+\]|#)|\s*$)(?:\s+\[(?P<arch>[^\]]+)\])?(?:\s+#.*)?\s*$')
|
|
def print_seed_item(line):
|
|
m = seed_pattern.match(line)
|
|
|
|
if m:
|
|
arch_tag = m.group("arch")
|
|
if arch_tag and args.arch not in arch_tag.split():
|
|
return
|
|
|
|
raw_pkg = m.group("raw_pkg")
|
|
if args.what == "snaps" and "(classic)" in raw_pkg:
|
|
raw_pkg += "/classic"
|
|
|
|
# Remove e.g. surrounding slashes from entries
|
|
printable_m = re.match(r"^/\^(.*)\$/?$", raw_pkg)
|
|
packages.add(m.group(1) if printable_m else raw_pkg)
|
|
|
|
passed = False
|
|
for seedtext in glob.glob(f"{args.output_dir}/*.seedtext"):
|
|
hs = parseTaskHeaders(open(seedtext))
|
|
if not hs:
|
|
continue
|
|
seedname = os.path.splitext(os.path.basename(seedtext))[0]
|
|
tn = getTaskName(hs, args.flavour, seedname)
|
|
if tn != args.task:
|
|
continue
|
|
for seed in getTaskSeeds(hs, seedname):
|
|
for line in open(f"{args.output_dir}/{seed}{ext}"):
|
|
print_seed_item(line)
|
|
passed = True
|
|
break
|
|
|
|
if not passed and not packages:
|
|
if args.task != "ship-live" or not os.path.exists(f"{args.output_dir}/{args.task}.seedtext"):
|
|
raise Exception(f"Unable to find {args.task}")
|
|
|
|
for line in open(f"{args.output_dir}/{args.task}.seedtext"):
|
|
print_seed_item(line)
|
|
|
|
print(" ".join(packages))
|