143 lines
4.6 KiB
Python
Executable File
143 lines
4.6 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
# Copyright (C) 2020 The Android Open Source Project
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
"""
|
|
Writes the perfetto_version{.gen.h, .ts} files.
|
|
|
|
This tool is run as part of a genrule from GN, SoonG and Bazel builds. It
|
|
generates a source header (or in the case of --ts_out a TypeScript file) that
|
|
contains:
|
|
- The version number (e.g. v9.0) obtained parsing the CHANGELOG file.
|
|
- The git HEAD's commit-ish (e.g. 6b330b772b0e973f79c70ba2e9bb2b0110c6715d)
|
|
|
|
The latter is concatenated to the version number to disambiguate builds made
|
|
from release tags vs builds made from the main branch vs UI builds made from the
|
|
ui-canary/ui-stable branch.
|
|
"""
|
|
|
|
import argparse
|
|
import os
|
|
import re
|
|
import sys
|
|
import subprocess
|
|
|
|
# Note: PROJECT_ROOT is not accurate in bazel builds, where this script is
|
|
# executed in the bazel sandbox.
|
|
PROJECT_ROOT = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
|
|
SCM_REV_NOT_AVAILABLE = 'N/A'
|
|
|
|
|
|
def get_latest_release(changelog_path):
|
|
"""Returns a string like 'v9.0'.
|
|
|
|
It does so by searching the latest version mentioned in the CHANGELOG."""
|
|
if not changelog_path:
|
|
if os.path.exists('CHANGELOG'):
|
|
changelog_path = 'CHANGELOG'
|
|
else:
|
|
changelog_path = os.path.join(PROJECT_ROOT, 'CHANGELOG')
|
|
with open(changelog_path) as f:
|
|
for line in f.readlines():
|
|
m = re.match('^(v\d+[.]\d+)\s.*$', line)
|
|
if m is not None:
|
|
return m.group(1)
|
|
raise Exception('Failed to fetch Perfetto version from %s' % changelog_path)
|
|
|
|
|
|
def get_git_sha1(commitish):
|
|
"""Returns the SHA1 of the provided commit-ish"""
|
|
commit_sha1 = SCM_REV_NOT_AVAILABLE
|
|
git_dir = os.path.join(PROJECT_ROOT, '.git')
|
|
if os.path.exists(git_dir):
|
|
try:
|
|
commit_sha1 = subprocess.check_output(['git', 'rev-parse', commitish],
|
|
cwd=PROJECT_ROOT).strip().decode()
|
|
except subprocess.CalledProcessError:
|
|
pass
|
|
return commit_sha1
|
|
|
|
|
|
def write_if_unchanged(path, content):
|
|
prev_content = None
|
|
if os.path.exists(path):
|
|
with open(path, 'r') as fprev:
|
|
prev_content = fprev.read()
|
|
if prev_content == content:
|
|
return 0
|
|
with open(path, 'w') as fout:
|
|
fout.write(content)
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument('--check_git', action='store_true')
|
|
parser.add_argument(
|
|
'--no_git',
|
|
action='store_true',
|
|
help='Skips running git rev-parse, emits only the version from CHANGELOG')
|
|
parser.add_argument('--cpp_out', help='Path of the generated .h file.')
|
|
parser.add_argument('--ts_out', help='Path of the generated .ts file.')
|
|
parser.add_argument('--stdout', help='Write to stdout', action='store_true')
|
|
parser.add_argument('--changelog', help='Path to CHANGELOG.')
|
|
args = parser.parse_args()
|
|
|
|
if args.check_git:
|
|
has_git = os.path.exists(os.path.join(PROJECT_ROOT, '.git', 'HEAD'))
|
|
print('1' if has_git else '0')
|
|
return 0
|
|
|
|
release = get_latest_release(args.changelog)
|
|
|
|
if args.no_git:
|
|
head_sha1 = SCM_REV_NOT_AVAILABLE
|
|
else:
|
|
head_sha1 = get_git_sha1('HEAD') # SCM_REV_NOT_AVAILABLE on failure.
|
|
|
|
if head_sha1 == SCM_REV_NOT_AVAILABLE:
|
|
version = release # e.g., 'v9.0'.
|
|
else:
|
|
sha1_abbrev = head_sha1[:9]
|
|
version = f'{release}-{sha1_abbrev}' # e.g., 'v9.0-adeadbeef'.
|
|
|
|
if args.cpp_out:
|
|
guard = '%s_' % args.cpp_out.upper()
|
|
guard = re.sub(r'[^\w]', '_', guard)
|
|
lines = []
|
|
lines.append('// Generated by %s' % os.path.basename(__file__))
|
|
lines.append('')
|
|
lines.append('#ifndef %s' % guard)
|
|
lines.append('#define %s' % guard)
|
|
lines.append('')
|
|
lines.append('#define PERFETTO_VERSION_STRING() "%s"' % version)
|
|
lines.append('#define PERFETTO_VERSION_SCM_REVISION() "%s"' % head_sha1)
|
|
lines.append('')
|
|
lines.append('#endif // %s' % guard)
|
|
lines.append('')
|
|
content = '\n'.join(lines)
|
|
write_if_unchanged(args.cpp_out, content)
|
|
|
|
if args.ts_out:
|
|
lines = []
|
|
lines.append('export const VERSION = "%s";' % version)
|
|
lines.append('export const SCM_REVISION = "%s";' % head_sha1)
|
|
content = '\n'.join(lines)
|
|
write_if_unchanged(args.ts_out, content)
|
|
|
|
if args.stdout:
|
|
print(version)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
sys.exit(main())
|