blob: 66cfa9e82236feddae98c2f2cf7d75091c72c3b0 [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.
"""Generatea a package override protobuf.
Protobuf describes a package being overridden from the standard system
software using a source repo for determination.
"""
from __future__ import print_function
import argparse
import datetime
import os
import re
import sys
from chromiumos.config.api.test.results.v1 import package_pb2
import results_database
from results_database import error
def init_argparse():
"""Creates argument parser.
Returns:
An ArgumentParser.
"""
parser = argparse.ArgumentParser(
usage='%(prog)s [OPTION] DIR...',
description='Generate package override',
)
parser.add_argument('--name',
help='Name of package')
parser.add_argument('--git_dir',
help='Path to git repo')
parser.add_argument('--git_hash',
help='Git hash to assign')
parser.add_argument('--version',
help='Version to assign')
parser.add_argument('--noautoversion', action='store_false',
dest='autoversion',
help='Disable auto version detection.')
parser.add_argument('--output', '-o',
help='File to write output to')
parser.add_argument('dir', nargs='?',
help='Path to git work tree including repo')
return parser
def find_mesa_version(path):
"""Find the version from a mesa repo.
Args:
path: The path to the repo.
Returns:
A string of the version, or None if it cannot be determined.
"""
file = os.path.join(path, 'VERSION')
if os.path.exists(file):
with open(file) as f:
return f.readline().rstrip()
return None
def find_apitrace_version(path):
"""Find the version from an apitrace repo.
Args:
path: The path to the repo.
Returns:
A string of the version, or None if it cannot be determined.
"""
# git describe --tags doesn't work if we're merging in to a local tree.
file = os.path.join(path, 'CMakeLists.txt')
if os.path.exists(file):
with open(file) as f:
d = {}
for l in f.readlines():
m = re.match(
r'^set \(CPACK_PACKAGE_VERSION_(MAJOR|MINOR) "(\d+)"\)$',
l)
if m:
d[m.group(1)] = m.group(2)
if 'MAJOR' in d and 'MINOR' in d:
return '.'.join([d['MAJOR'], d['MINOR']])
return None
def main():
"""Main function."""
args = init_argparse().parse_args()
package = package_pb2.Package()
# Figure out a git dir.
if args.git_dir:
git_dir = args.git_dir
elif args.dir:
path = os.path.join(args.dir, '.git')
if os.path.exists(path):
git_dir = path
else:
git_dir = None
# Figure out the name.
if args.name:
package.name = args.name
elif args.dir:
if not os.path.exists(args.dir):
error('ERROR: cannot find dir %s' % args.dir)
sys.exit(1)
package.name = os.path.split(os.path.realpath(args.dir))[-1]
else:
error('ERROR: name is not specified and cannot be determined')
sys.exit(1)
# Get information from git if possible.
if git_dir:
if not os.path.exists(git_dir):
error('ERROR: cannot find git_dir %s' % git_dir)
sys.exit(1)
git_cmd = ['git', '--git-dir', git_dir, '--work-tree', args.dir]
# Current git hash.
package.git_hash = (args.git_hash
if args.git_hash
else results_database.get_cmd_output(
git_cmd + ['rev-parse', 'HEAD']))
# Current branch.
branch = results_database.get_cmd_output(
git_cmd + ['rev-parse', '--abbrev-ref', 'HEAD'])
if branch != 'HEAD':
package.branch = branch
# Last commit date.
raw = results_database.get_cmd_output(
git_cmd + ['log', '-1', '--format=%ad', '--date=unix'])
dt = datetime.datetime.utcfromtimestamp(int(raw))
# pylint: disable=no-member
package.commit_date.FromDatetime(dt)
# Is the repo clean?
package.repo_dirty = len(results_database.get_cmd_output(
git_cmd + ['status', '--porcelain']))
if args.version:
package.version = args.version
elif args.autoversion:
# Try best to determine the version based on the contents of the repo.
# pylint: disable=no-member
if package.name == 'mesa':
version = find_mesa_version(args.dir)
elif package.name == 'apitrace':
version = find_apitrace_version(args.dir)
elif git_dir:
version = results_database.get_cmd_output(
git_cmd + ['describe', '--tags'])
# Add the version and record if it is autogenerated. The version should
# roughly indicate the pedigree of the code, but label it clearly so as
# not to confuse it with an actual labeled version.
if version:
package.version = version + ' (autogenerated)'
results_database.output_pb(package, args.output)
main()