blob: 423545a66ae80c7a493d480066d9028edc59d9d9 [file] [log] [blame]
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright 2020 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Create the package information file in JSON format.
To get the package information, use the library at
https://cos.googlesource.com/cos/tools/+/refs/heads/master/src/pkg/cos/pkg_info.go
instead of accessing the JSON file directly.
For information on the JSON format, see http://go/cos-package-list-design .
"""
from __future__ import print_function
import collections
import getopt
import json
import re
import sys
# The following regular expresssions are used for extracting the category name,
# the package name, the package version without the revision, and the package
# revision from a string that looks like
#
# category_name/package_name-1.2.3.4_beta1_rc2-r1
#
# These regular expressions follow the Gentoo package manager specification at
# https://www.gentoo.org/proj/en/qa/pms.xml . They are similar to what SplitPV
# function (in chromite/lib/portage_util.py) uses.
CATEGORY_RE = r'(?P<category>\w[\w\+\.\-]*)'
PACKAGE_RE = r'(?P<package>\w[\w+-]*)'
VERSION_NUMLETTER_RE = r'\d+(\.\d+)*[a-z]?'
VERSION_SUFFIX_RE = r'_(pre|p|beta|alpha|rc)\d*'
VERSION_NO_REV_RE = r'(?P<version_no_rev>%s(%s)*)' % (VERSION_NUMLETTER_RE,
VERSION_SUFFIX_RE)
REVISION_RE = r'-r(?P<revision>\d+)'
CPV_RE = r'^%s\/%s-%s(%s)?$' % (CATEGORY_RE, PACKAGE_RE,
VERSION_NO_REV_RE, REVISION_RE)
def PrintHelp():
print('usage: create_pkg_list.py --input=<input file> --output=<output file>')
def CreateList(input_lines):
cpv_re = re.compile(CPV_RE, re.VERBOSE)
package_list = []
for line in input_lines:
match = cpv_re.match(line.strip())
if match is not None:
package_list.append(match.groupdict())
return package_list
def WriteJson(package_list, output_file):
installed_packages = []
for p in package_list:
package_info = collections.OrderedDict(
[('category', p['category']),
('name', p['package']),
('version', p['version_no_rev'])
]
)
if 'revision' in p and p['revision'] is not None:
package_info['revision'] = p['revision']
installed_packages.append(package_info)
result = {}
result['installedPackages'] = installed_packages
json.dump(result, output_file, indent=4)
return 0
def main(argv):
input_fn = ''
output_fn = ''
try:
opts, args_left = getopt.getopt(argv, '', ['help', 'input=', 'output='])
except getopt.GetoptError:
PrintHelp()
return -1
if len(args_left) != 0:
PrintHelp()
return -1
for opt, arg in opts:
if opt == '--help':
PrintHelp()
elif opt == '--input':
input_fn = arg
elif opt == '--output':
output_fn = arg
if input_fn == '' or output_fn == '':
PrintHelp()
return -1
input_lines = []
try:
with open(input_fn) as input_file:
input_lines = input_file.readlines()
except OSError:
print('error: Failed to open input file: %s' % input_fn)
return -1
if len(input_lines) == 0:
print('error: No input lines')
return -1
package_list = CreateList(input_lines)
if len(package_list) == 0:
print('error: Empty package list')
return -1
try:
with open(output_fn, 'w') as output_file:
ret = WriteJson(package_list, output_file)
if ret != 0:
print('error: Failed to write package list')
return ret
except OSError:
print('error: Failed to open input file: %s' % input_fn)
return -1
return 0
if __name__ == '__main__':
sys.exit(main(sys.argv[1:]))