summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJack Rosenthal <jrosenth@chromium.org>2021-04-28 15:01:34 -0600
committerCommit Bot <commit-bot@chromium.org>2021-04-29 15:45:53 +0000
commit51b64244b59b06eca4751df760d5be793ea3b774 (patch)
tree5039444be4a6a71e4de5080272c3ce4631b121cc
parent4474767875fa4e149c64641b9f00678f79f1860e (diff)
downloadchrome-ec-51b64244b59b06eca4751df760d5be793ea3b774.tar.gz
zephyr: zmake: add utility to compute version string
Add a function, get_version_string, which generates a version string to be used in FRID, FWID, or in headers for the build. The format selected was: LAST_COMPONENT_OF_PROJECT_DIR "_v" ZEPHYR_MAJOR_VERSION "." ZEPHYR_MINOR_VERSION "." TOTAL_COMMITS "_" VCS_HASHES Where VCS_HASHES is the (sorted) list of modules + Zephyr OS commit hashes, like so: mod1:02fd7a,mod2:b5991f,os:2c65cb There is also an option for a "static" version, like in CrOS EC OS, which is not affected by Git repository state. This is useful for comparing builds across commits. In this case, TOTAL_COMMITS is fixed to zero, and VCS_HASHES is set to "STATIC". Note: This is mostly just an initial pass at the version string format, and shouldn't be considered "final" yet. We can make further iterations on the format as we deem necessary. BUG=b:184832251 BRANCH=none TEST=unit tests Signed-off-by: Jack Rosenthal <jrosenth@chromium.org> Change-Id: I7560c7d677f5d5ec5cf26ff6048eea91843515c3 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2857914 Reviewed-by: Jeremy Bettis <jbettis@chromium.org> Reviewed-by: Simon Glass <sjg@chromium.org>
-rw-r--r--zephyr/zmake/tests/test_version.py88
-rw-r--r--zephyr/zmake/zmake/version.py75
2 files changed, 163 insertions, 0 deletions
diff --git a/zephyr/zmake/tests/test_version.py b/zephyr/zmake/tests/test_version.py
new file mode 100644
index 0000000000..4235561545
--- /dev/null
+++ b/zephyr/zmake/tests/test_version.py
@@ -0,0 +1,88 @@
+# Copyright 2021 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.
+
+import subprocess
+
+import zmake.project
+import zmake.version as version
+
+
+def _git_init(repo):
+ """Create a new git repository."""
+ repo.mkdir()
+ subprocess.run(['git', '-c', 'init.defaultBranch=main', '-C', repo, 'init'],
+ check=True)
+
+
+def _git_add(repo, path, contents='example!\n'):
+ """Write contents and stage a file."""
+ path.write_text(contents)
+ subprocess.run(['git', '-C', repo, 'add', path], check=True)
+
+
+def _git_commit(repo, message='message!'):
+ env = {
+ 'GIT_AUTHOR_NAME': 'Alyssa P. Hacker',
+ 'GIT_AUTHOR_EMAIL': 'aphacker@example.org',
+ 'GIT_AUTHOR_DATE': 'Thu, 07 Apr 2005 22:13:13 +0200',
+ 'GIT_COMMITTER_NAME': 'Ben Bitdiddle',
+ 'GIT_COMMITTER_EMAIL': 'bitdiddle@example.org',
+ 'GIT_COMMITTER_DATE': 'Tue, 30 Aug 2005 10:50:30 -0700',
+ }
+ subprocess.run(['git', '-C', repo, 'commit', '-m', message], check=True,
+ env=env)
+
+
+def _setup_example_repos(tmp_path):
+ """Setup temporary project, zephyr base, and module repos.
+
+ Args:
+ tmp_path: Directory to set up files in.
+
+ Returns:
+ A 3-tuple of project, zephyr_base, modules_dict.
+ """
+ project_path = tmp_path / 'prj'
+ project_path.mkdir()
+
+ project = zmake.project.Project(
+ project_path,
+ config_dict={'board': 'foo', 'toolchain': 'bar',
+ 'output-type': 'raw',
+ 'supported-zephyr-versions': ['v2.5']})
+ # Has one commit.
+ zephyr_base = tmp_path / 'zephyr_base'
+ _git_init(zephyr_base)
+ _git_add(zephyr_base, zephyr_base / 'VERSION',
+ 'VERSION_MAJOR=2\nVERSION_MINOR=5\nPATCHLEVEL=99\n')
+ _git_commit(zephyr_base, 'Added version file')
+
+ # Has one commit.
+ mod1 = tmp_path / 'mod1'
+ _git_init(mod1)
+ _git_add(mod1, mod1 / 'file1')
+ _git_commit(mod1)
+
+ # Has two commits.
+ mod2 = tmp_path / 'mod2'
+ _git_init(mod2)
+ _git_add(mod2, mod2 / 'file2')
+ _git_commit(mod2)
+ _git_add(mod2, mod2 / 'file3')
+ _git_commit(mod2)
+
+ return project, zephyr_base, {'mod1': mod1, 'mod2': mod2}
+
+
+def test_version_string(tmp_path):
+ project, zephyr_base, modules = _setup_example_repos(tmp_path)
+ assert (version.get_version_string(project, zephyr_base, modules)
+ == 'prj_v2.5.4_mod1:02fd7a,mod2:b5991f,os:2c65cb')
+
+
+def test_version_string_static(tmp_path):
+ project, zephyr_base, modules = _setup_example_repos(tmp_path)
+ assert (version.get_version_string(project, zephyr_base, modules,
+ static=True)
+ == 'prj_v2.5.0_STATIC')
diff --git a/zephyr/zmake/zmake/version.py b/zephyr/zmake/zmake/version.py
new file mode 100644
index 0000000000..03ffada947
--- /dev/null
+++ b/zephyr/zmake/zmake/version.py
@@ -0,0 +1,75 @@
+# Copyright 2021 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.
+
+import subprocess
+
+import zmake.util as util
+
+
+def _get_num_commits(repo):
+ """Get the number of commits that have been made in a Git repository.
+
+ Args:
+ repo: The path to the git repo.
+
+ Returns:
+ An integer, the number of commits that have been made.
+ """
+ result = subprocess.run(['git', '-C', repo, 'rev-list', 'HEAD', '--count'],
+ check=True, stdout=subprocess.PIPE,
+ encoding='utf-8')
+ return int(result.stdout)
+
+
+def _get_revision(repo):
+ """Get the index's current revision of a Git repo.
+
+ Args:
+ repo: The path to the git repo.
+
+ Returns:
+ A string, of the current revision.
+ """
+ result = subprocess.run(['git', '-C', repo, 'log', '-n1', '--format=%H'],
+ check=True, stdout=subprocess.PIPE,
+ encoding='utf-8')
+ return result.stdout
+
+
+def get_version_string(project, zephyr_base, modules, static=False):
+ """Get the version string associated with a build.
+
+ Args:
+ project: a zmake.project.Project object
+ zephyr_base: the path to the zephyr directory
+ modules: a dictionary mapping module names to module paths
+ static: if set, create a version string not dependent on git
+ commits, thus allowing binaries to be compared between two
+ commits.
+
+ Returns:
+ A version string which can be placed in FRID, FWID, or used in
+ the build for the OS.
+ """
+ major_version, minor_version, *_ = util.read_zephyr_version(zephyr_base)
+ project_id = project.project_dir.parts[-1]
+ num_commits = 0
+
+ if static:
+ vcs_hashes = 'STATIC'
+ else:
+ repos = {
+ 'os': zephyr_base,
+ **modules,
+ }
+
+ for repo in repos.values():
+ num_commits += _get_num_commits(repo)
+
+ vcs_hashes = ','.join(
+ '{}:{}'.format(name, _get_revision(repo)[:6])
+ for name, repo in sorted(repos.items()))
+
+ return '{}_v{}.{}.{}_{}'.format(
+ project_id, major_version, minor_version, num_commits, vcs_hashes)