summaryrefslogtreecommitdiff
path: root/zephyr/zmake/zmake/version.py
blob: d026c07c2f058a97ba45de241323ec17c9758dae (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# 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 os
import subprocess

import zmake.util as util


def _get_num_commits(repo):
    """Get the number of commits that have been made.

    If a Git repository is available, return the number of commits that have
    been made. Otherwise return a fixed count.

    Args:
        repo: The path to the git repo.

    Returns:
        An integer, the number of commits that have been made.
    """
    try:
        result = subprocess.run(
            ["git", "-C", repo, "rev-list", "HEAD", "--count"],
            check=True,
            stdout=subprocess.PIPE,
            stderr=subprocess.DEVNULL,
            encoding="utf-8",
        )
    except subprocess.CalledProcessError:
        commits = "9999"
    else:
        commits = result.stdout

    return int(commits)


def _get_revision(repo):
    """Get the current revision hash.

    If a Git repository is available, return the hash of the current index.
    Otherwise return the hash of the VCSID environment variable provided by
    the packaging system.

    Args:
        repo: The path to the git repo.

    Returns:
        A string, of the current revision.
    """
    try:
        result = subprocess.run(
            ["git", "-C", repo, "log", "-n1", "--format=%H"],
            check=True,
            stdout=subprocess.PIPE,
            stderr=subprocess.DEVNULL,
            encoding="utf-8",
        )
    except subprocess.CalledProcessError:
        # Fall back to the VCSID provided by the packaging system.
        # Format is 0.0.1-r425-032666c418782c14fe912ba6d9f98ffdf0b941e9 for
        # releases and 9999-032666c418782c14fe912ba6d9f98ffdf0b941e9 for
        # 9999 ebuilds.
        vcsid = os.environ.get("VCSID", "9999-unknown")
        revision = vcsid.rsplit("-", 1)[1]
    else:
        revision = result.stdout

    return revision


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
    )