894e21291e
According to PEP 627, the RECORD file is optional and doesn't make sense to keep it for system packages. Moreover, its absence should indicate to other tools like pip that they should not touch such packages. Now, we process content of all RECORD files to one pyproject-record (JSON) which is then used in %pyproject_save_files. That way, we can remove the original files in %pyproject_install and keep their content for later. PEP 627: https://www.python.org/dev/peps/pep-0627/#optional-record-file
87 lines
2.9 KiB
Python
87 lines
2.9 KiB
Python
import argparse
|
|
import csv
|
|
import json
|
|
import os
|
|
from pathlib import PosixPath
|
|
|
|
from pyproject_save_files import BuildrootPath
|
|
|
|
|
|
def read_record(record_path):
|
|
"""
|
|
A generator yielding individual RECORD triplets.
|
|
|
|
https://www.python.org/dev/peps/pep-0376/#record
|
|
|
|
The triplet is str-path, hash, size -- the last two optional.
|
|
We will later care only for the paths anyway.
|
|
|
|
Example:
|
|
|
|
>>> g = read_record(PosixPath('./test_RECORD'))
|
|
>>> next(g)
|
|
['../../../bin/__pycache__/tldr.cpython-....pyc', '', '']
|
|
>>> next(g)
|
|
['../../../bin/tldr', 'sha256=...', '12766']
|
|
>>> next(g)
|
|
['../../../bin/tldr.py', 'sha256=...', '12766']
|
|
"""
|
|
with open(record_path, newline="", encoding="utf-8") as f:
|
|
yield from csv.reader(
|
|
f, delimiter=",", quotechar='"', lineterminator=os.linesep
|
|
)
|
|
|
|
|
|
def parse_record(record_path, record_content):
|
|
"""
|
|
Returns a list with BuildrootPaths parsed from record_content
|
|
|
|
params:
|
|
record_path: RECORD BuildrootPath
|
|
record_content: list of RECORD triplets
|
|
first item is a str-path relative to directory where dist-info directory is
|
|
(it can also be absolute according to the standard, but not from pip)
|
|
|
|
Examples:
|
|
|
|
>>> next(parse_record(BuildrootPath('/usr/lib/python3.7/site-packages/requests-2.22.0.dist-info/RECORD'),
|
|
... [('requests/sessions.py', 'sha256=xxx', '666'), ...]))
|
|
BuildrootPath('/usr/lib/python3.7/site-packages/requests/sessions.py')
|
|
|
|
>>> next(parse_record(BuildrootPath('/usr/lib/python3.7/site-packages/tldr-0.5.dist-info/RECORD'),
|
|
... [('../../../bin/tldr', 'sha256=yyy', '777'), ...]))
|
|
BuildrootPath('/usr/bin/tldr')
|
|
"""
|
|
sitedir = record_path.parent.parent # trough the dist-info directory
|
|
# / with absolute right operand will remove the left operand
|
|
# any .. parts are resolved via normpath
|
|
return [str((sitedir / row[0]).normpath()) for row in record_content]
|
|
|
|
|
|
def save_parsed_record(record_path, parsed_record, output_file):
|
|
content = {}
|
|
if output_file.is_file():
|
|
content = json.loads(output_file.read_text())
|
|
content[str(record_path)] = parsed_record
|
|
output_file.write_text(json.dumps(content))
|
|
|
|
|
|
def main(cli_args):
|
|
record_path = BuildrootPath.from_real(cli_args.record, root=cli_args.buildroot)
|
|
parsed_record = parse_record(record_path, read_record(cli_args.record))
|
|
save_parsed_record(record_path, parsed_record, cli_args.output)
|
|
|
|
|
|
def argparser():
|
|
parser = argparse.ArgumentParser()
|
|
r = parser.add_argument_group("required arguments")
|
|
r.add_argument("--buildroot", type=PosixPath, required=True)
|
|
r.add_argument("--record", type=PosixPath, required=True)
|
|
r.add_argument("--output", type=PosixPath, required=True)
|
|
return parser
|
|
|
|
|
|
if __name__ == "__main__":
|
|
cli_args = argparser().parse_args()
|
|
main(cli_args)
|