blob: 7dc8783b2a49783d5f25b98f48a3475bc2dacbf8 [file] [log] [blame]
Primiano Tucci34bc5592021-02-19 17:53:36 +01001#!/usr/bin/env python3
Primiano Tucciec590132020-11-16 14:16:44 +01002# Copyright (C) 2020 The Android Open Source Project
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15"""
16Writes the perfetto_version{.gen.h, .ts} files.
17
18This tool is run as part of a genrule from GN, SoonG and Bazel builds. It
19generates a source header (or in the case of --ts_out a TypeScript file) that
20contains:
21- The version number (e.g. v9.0) obtained parsing the CHANGELOG file.
22- The git HEAD's commit-ish (e.g. 6b330b772b0e973f79c70ba2e9bb2b0110c6715d)
Primiano Tucciec590132020-11-16 14:16:44 +010023
Primiano Tuccide775ba2021-09-07 10:20:52 +010024The latter is concatenated to the version number to disambiguate builds made
25from release tags vs builds made from the main branch vs UI builds made from the
26ui-canary/ui-stable branch.
Primiano Tucciec590132020-11-16 14:16:44 +010027"""
28
29import argparse
30import os
31import re
32import sys
33import subprocess
34
35# Note: PROJECT_ROOT is not accurate in bazel builds, where this script is
36# executed in the bazel sandbox.
37PROJECT_ROOT = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
38SCM_REV_NOT_AVAILABLE = 'N/A'
39
40
Primiano Tuccif0ed1d42020-11-18 16:30:18 +010041def get_latest_release(changelog_path):
Primiano Tucciec590132020-11-16 14:16:44 +010042 """Returns a string like 'v9.0'.
43
44 It does so by searching the latest version mentioned in the CHANGELOG."""
Primiano Tuccif0ed1d42020-11-18 16:30:18 +010045 if not changelog_path:
46 if os.path.exists('CHANGELOG'):
47 changelog_path = 'CHANGELOG'
48 else:
49 changelog_path = os.path.join(PROJECT_ROOT, 'CHANGELOG')
Primiano Tucciec590132020-11-16 14:16:44 +010050 with open(changelog_path) as f:
51 for line in f.readlines():
52 m = re.match('^(v\d+[.]\d+)\s.*$', line)
53 if m is not None:
54 return m.group(1)
55 raise Exception('Failed to fetch Perfetto version from %s' % changelog_path)
56
57
Hector Dearman3c9b8cf2021-09-01 12:56:17 +010058def get_git_sha1(commitish):
59 """Returns the SHA1 of the provided commit-ish"""
Primiano Tucciec590132020-11-16 14:16:44 +010060 commit_sha1 = SCM_REV_NOT_AVAILABLE
Primiano Tucciec590132020-11-16 14:16:44 +010061 git_dir = os.path.join(PROJECT_ROOT, '.git')
62 if os.path.exists(git_dir):
63 try:
Hector Dearman3c9b8cf2021-09-01 12:56:17 +010064 commit_sha1 = subprocess.check_output(['git', 'rev-parse', commitish],
Primiano Tucciec590132020-11-16 14:16:44 +010065 cwd=PROJECT_ROOT).strip().decode()
Primiano Tucciec590132020-11-16 14:16:44 +010066 except subprocess.CalledProcessError:
67 pass
Hector Dearman3c9b8cf2021-09-01 12:56:17 +010068 return commit_sha1
Primiano Tucciec590132020-11-16 14:16:44 +010069
70
71def write_if_unchanged(path, content):
72 prev_content = None
73 if os.path.exists(path):
74 with open(path, 'r') as fprev:
75 prev_content = fprev.read()
76 if prev_content == content:
77 return 0
78 with open(path, 'w') as fout:
79 fout.write(content)
80
81
82def main():
83 parser = argparse.ArgumentParser()
Primiano Tuccidc77d722021-10-15 13:17:52 +010084 parser.add_argument('--check_git', action='store_true')
Primiano Tucciec590132020-11-16 14:16:44 +010085 parser.add_argument(
86 '--no_git',
87 action='store_true',
88 help='Skips running git rev-parse, emits only the version from CHANGELOG')
89 parser.add_argument('--cpp_out', help='Path of the generated .h file.')
90 parser.add_argument('--ts_out', help='Path of the generated .ts file.')
Primiano Tucci7eead2e2021-02-16 11:46:04 +010091 parser.add_argument('--stdout', help='Write to stdout', action='store_true')
Primiano Tuccif0ed1d42020-11-18 16:30:18 +010092 parser.add_argument('--changelog', help='Path to CHANGELOG.')
Primiano Tucciec590132020-11-16 14:16:44 +010093 args = parser.parse_args()
94
Primiano Tuccidc77d722021-10-15 13:17:52 +010095 if args.check_git:
96 has_git = os.path.exists(os.path.join(PROJECT_ROOT, '.git', 'HEAD'))
97 print('1' if has_git else '0')
98 return 0
99
Primiano Tuccif0ed1d42020-11-18 16:30:18 +0100100 release = get_latest_release(args.changelog)
Primiano Tuccide775ba2021-09-07 10:20:52 +0100101
Primiano Tucciec590132020-11-16 14:16:44 +0100102 if args.no_git:
Hector Dearman3c9b8cf2021-09-01 12:56:17 +0100103 head_sha1 = SCM_REV_NOT_AVAILABLE
Primiano Tucciec590132020-11-16 14:16:44 +0100104 else:
Primiano Tuccide775ba2021-09-07 10:20:52 +0100105 head_sha1 = get_git_sha1('HEAD') # SCM_REV_NOT_AVAILABLE on failure.
Primiano Tucciec590132020-11-16 14:16:44 +0100106
Primiano Tuccide775ba2021-09-07 10:20:52 +0100107 if head_sha1 == SCM_REV_NOT_AVAILABLE:
Primiano Tucciec590132020-11-16 14:16:44 +0100108 version = release # e.g., 'v9.0'.
Hector Dearman3c9b8cf2021-09-01 12:56:17 +0100109 else:
Primiano Tuccide775ba2021-09-07 10:20:52 +0100110 sha1_abbrev = head_sha1[:9]
111 version = f'{release}-{sha1_abbrev}' # e.g., 'v9.0-adeadbeef'.
Primiano Tucciec590132020-11-16 14:16:44 +0100112
113 if args.cpp_out:
114 guard = '%s_' % args.cpp_out.upper()
115 guard = re.sub(r'[^\w]', '_', guard)
116 lines = []
Florian Mayer5ed03d12021-04-19 18:07:52 +0100117 lines.append('// Generated by %s' % os.path.basename(__file__))
Primiano Tucciec590132020-11-16 14:16:44 +0100118 lines.append('')
119 lines.append('#ifndef %s' % guard)
120 lines.append('#define %s' % guard)
121 lines.append('')
122 lines.append('#define PERFETTO_VERSION_STRING() "%s"' % version)
Hector Dearman3c9b8cf2021-09-01 12:56:17 +0100123 lines.append('#define PERFETTO_VERSION_SCM_REVISION() "%s"' % head_sha1)
Primiano Tucciec590132020-11-16 14:16:44 +0100124 lines.append('')
125 lines.append('#endif // %s' % guard)
126 lines.append('')
127 content = '\n'.join(lines)
128 write_if_unchanged(args.cpp_out, content)
129
130 if args.ts_out:
131 lines = []
132 lines.append('export const VERSION = "%s";' % version)
Hector Dearman3c9b8cf2021-09-01 12:56:17 +0100133 lines.append('export const SCM_REVISION = "%s";' % head_sha1)
Primiano Tucciec590132020-11-16 14:16:44 +0100134 content = '\n'.join(lines)
135 write_if_unchanged(args.ts_out, content)
136
Primiano Tucci7eead2e2021-02-16 11:46:04 +0100137 if args.stdout:
138 print(version)
139
Primiano Tucciec590132020-11-16 14:16:44 +0100140
141if __name__ == '__main__':
142 sys.exit(main())