xref: /aosp_15_r20/external/gsc-utils/util/getversion.sh (revision 4f2df630800bdcf1d4f0decf95d8a1cb87344f5f)
1*4f2df630SAndroid Build Coastguard Worker#!/bin/bash
2*4f2df630SAndroid Build Coastguard Worker#
3*4f2df630SAndroid Build Coastguard Worker# Copyright 2012 The ChromiumOS Authors
4*4f2df630SAndroid Build Coastguard Worker# Use of this source code is governed by a BSD-style license that can be
5*4f2df630SAndroid Build Coastguard Worker# found in the LICENSE file.
6*4f2df630SAndroid Build Coastguard Worker#
7*4f2df630SAndroid Build Coastguard Worker# Generate version information for the EC binary
8*4f2df630SAndroid Build Coastguard Worker
9*4f2df630SAndroid Build Coastguard Worker# Use this symbol as a separator to be able to reliably concatenate strings of
10*4f2df630SAndroid Build Coastguard Worker# text.
11*4f2df630SAndroid Build Coastguard Workerdc=$'\001'
12*4f2df630SAndroid Build Coastguard Worker
13*4f2df630SAndroid Build Coastguard Worker# Default marker to indicate 'dirty' repositories
14*4f2df630SAndroid Build Coastguard Workerdirty_marker='+'
15*4f2df630SAndroid Build Coastguard Worker
16*4f2df630SAndroid Build Coastguard Worker# This function examines the state of the current directory and attempts to
17*4f2df630SAndroid Build Coastguard Worker# extract its version information: the latest tag, if any, how many patches
18*4f2df630SAndroid Build Coastguard Worker# are there since the latest tag, the top sha1, and if there are local
19*4f2df630SAndroid Build Coastguard Worker# modifications.
20*4f2df630SAndroid Build Coastguard Worker#
21*4f2df630SAndroid Build Coastguard Worker# Local modifications are reported by concatenating the revision string and
22*4f2df630SAndroid Build Coastguard Worker# the string '-dirty' using the $dc symbol as the separator.
23*4f2df630SAndroid Build Coastguard Worker#
24*4f2df630SAndroid Build Coastguard Worker# If there is no tags defined in this git repository, the base version is
25*4f2df630SAndroid Build Coastguard Worker# considered to be 0.0.
26*4f2df630SAndroid Build Coastguard Worker#
27*4f2df630SAndroid Build Coastguard Worker# If current directory is not a git depository, this function prints out
28*4f2df630SAndroid Build Coastguard Worker# "no_version"
29*4f2df630SAndroid Build Coastguard Worker
30*4f2df630SAndroid Build Coastguard Workerget_tree_version() {
31*4f2df630SAndroid Build Coastguard Worker  local marker
32*4f2df630SAndroid Build Coastguard Worker  local ghash
33*4f2df630SAndroid Build Coastguard Worker  local numcommits
34*4f2df630SAndroid Build Coastguard Worker  local tag
35*4f2df630SAndroid Build Coastguard Worker  local vbase
36*4f2df630SAndroid Build Coastguard Worker  local ver_branch
37*4f2df630SAndroid Build Coastguard Worker  local ver_major
38*4f2df630SAndroid Build Coastguard Worker
39*4f2df630SAndroid Build Coastguard Worker  if ghash=`git rev-parse --short --verify HEAD 2>/dev/null`; then
40*4f2df630SAndroid Build Coastguard Worker    if gdesc=`git describe --dirty --match='v*' 2>/dev/null`; then
41*4f2df630SAndroid Build Coastguard Worker      IFS="-" fields=($gdesc)
42*4f2df630SAndroid Build Coastguard Worker      tag="${fields[0]}"
43*4f2df630SAndroid Build Coastguard Worker      IFS="." vernum=($tag)
44*4f2df630SAndroid Build Coastguard Worker      numcommits=$((${vernum[2]}+${fields[1]:-0}))
45*4f2df630SAndroid Build Coastguard Worker      ver_major="${vernum[0]}"
46*4f2df630SAndroid Build Coastguard Worker      ver_branch="${vernum[1]}"
47*4f2df630SAndroid Build Coastguard Worker    else
48*4f2df630SAndroid Build Coastguard Worker      numcommits=`git rev-list HEAD | wc -l`
49*4f2df630SAndroid Build Coastguard Worker      ver_major="v0"
50*4f2df630SAndroid Build Coastguard Worker      ver_branch="0"
51*4f2df630SAndroid Build Coastguard Worker    fi
52*4f2df630SAndroid Build Coastguard Worker    # avoid putting the -dirty attribute if only the timestamp
53*4f2df630SAndroid Build Coastguard Worker    # changed
54*4f2df630SAndroid Build Coastguard Worker    git status > /dev/null 2>&1
55*4f2df630SAndroid Build Coastguard Worker
56*4f2df630SAndroid Build Coastguard Worker    if [ -n "$(git diff-index --name-only HEAD 2>/dev/null)" ]; then
57*4f2df630SAndroid Build Coastguard Worker      marker="${dirty_marker}"
58*4f2df630SAndroid Build Coastguard Worker    else
59*4f2df630SAndroid Build Coastguard Worker      marker="-"
60*4f2df630SAndroid Build Coastguard Worker    fi
61*4f2df630SAndroid Build Coastguard Worker    vbase="${ver_major}.${ver_branch}.${numcommits}${marker}${ghash}"
62*4f2df630SAndroid Build Coastguard Worker  else
63*4f2df630SAndroid Build Coastguard Worker    # Fall back to the VCSID provided by the packaging system if available.
64*4f2df630SAndroid Build Coastguard Worker    if ghash=${VCSID##*-}; then
65*4f2df630SAndroid Build Coastguard Worker      vbase="1.1.9999-${ghash:0:7}"
66*4f2df630SAndroid Build Coastguard Worker    else
67*4f2df630SAndroid Build Coastguard Worker      # then ultimately fails to "no_version"
68*4f2df630SAndroid Build Coastguard Worker      vbase="no_version"
69*4f2df630SAndroid Build Coastguard Worker    fi
70*4f2df630SAndroid Build Coastguard Worker  fi
71*4f2df630SAndroid Build Coastguard Worker  if [[ "${marker}" == "${dirty_marker}" ]]; then
72*4f2df630SAndroid Build Coastguard Worker      echo "${vbase}${dc}${marker}"
73*4f2df630SAndroid Build Coastguard Worker  else
74*4f2df630SAndroid Build Coastguard Worker      echo "${vbase}${dc}"
75*4f2df630SAndroid Build Coastguard Worker  fi
76*4f2df630SAndroid Build Coastguard Worker}
77*4f2df630SAndroid Build Coastguard Worker
78*4f2df630SAndroid Build Coastguard Worker
79*4f2df630SAndroid Build Coastguard Workermain() {
80*4f2df630SAndroid Build Coastguard Worker  local component
81*4f2df630SAndroid Build Coastguard Worker  local dir_list
82*4f2df630SAndroid Build Coastguard Worker  local gitdate
83*4f2df630SAndroid Build Coastguard Worker  local most_recents
84*4f2df630SAndroid Build Coastguard Worker  local most_recent_file
85*4f2df630SAndroid Build Coastguard Worker  local root
86*4f2df630SAndroid Build Coastguard Worker  local timestamp
87*4f2df630SAndroid Build Coastguard Worker  local tool_ver
88*4f2df630SAndroid Build Coastguard Worker  local values
89*4f2df630SAndroid Build Coastguard Worker  local vbase
90*4f2df630SAndroid Build Coastguard Worker  local ver
91*4f2df630SAndroid Build Coastguard Worker
92*4f2df630SAndroid Build Coastguard Worker  IFS="${dc}"
93*4f2df630SAndroid Build Coastguard Worker  ver="${CR50_DEV:+DBG/}${CRYPTO_TEST:+CT/}${BOARD}_"
94*4f2df630SAndroid Build Coastguard Worker  tool_ver=""
95*4f2df630SAndroid Build Coastguard Worker  most_recents=()    # Non empty if any of the component repos is 'dirty'.
96*4f2df630SAndroid Build Coastguard Worker  dir_list=( . )   # list of component directories, always includes the EC tree
97*4f2df630SAndroid Build Coastguard Worker
98*4f2df630SAndroid Build Coastguard Worker  if [[ -n ${BOARD} ]]; then
99*4f2df630SAndroid Build Coastguard Worker    case "${BOARD}" in
100*4f2df630SAndroid Build Coastguard Worker      (cr50)
101*4f2df630SAndroid Build Coastguard Worker        dir_list+=( ../../third_party/tpm2 )
102*4f2df630SAndroid Build Coastguard Worker        dir_list+=( ../pinweaver )
103*4f2df630SAndroid Build Coastguard Worker        ;;
104*4f2df630SAndroid Build Coastguard Worker      (*_fp)
105*4f2df630SAndroid Build Coastguard Worker        dir_list+=( ./private )
106*4f2df630SAndroid Build Coastguard Worker        ;;
107*4f2df630SAndroid Build Coastguard Worker      (*)
108*4f2df630SAndroid Build Coastguard Worker        # For private-crX boards add their git root and cryptoc.
109*4f2df630SAndroid Build Coastguard Worker        for root in private-cr5*; do
110*4f2df630SAndroid Build Coastguard Worker          if [[ -d "${root}/board/${BOARD}" ]]; then
111*4f2df630SAndroid Build Coastguard Worker            dir_list+=( "${root}" ../../third_party/cryptoc )
112*4f2df630SAndroid Build Coastguard Worker          fi
113*4f2df630SAndroid Build Coastguard Worker        done
114*4f2df630SAndroid Build Coastguard Worker        ;;
115*4f2df630SAndroid Build Coastguard Worker    esac
116*4f2df630SAndroid Build Coastguard Worker  fi
117*4f2df630SAndroid Build Coastguard Worker  # Create a combined version string for all component directories.
118*4f2df630SAndroid Build Coastguard Worker  for git_dir in ${dir_list[@]}; do
119*4f2df630SAndroid Build Coastguard Worker    pushd "${git_dir}" > /dev/null
120*4f2df630SAndroid Build Coastguard Worker    component="$(basename "${git_dir}")"
121*4f2df630SAndroid Build Coastguard Worker    values=( $(get_tree_version) )
122*4f2df630SAndroid Build Coastguard Worker    vbase="${values[0]}"             # Retrieved version information.
123*4f2df630SAndroid Build Coastguard Worker    if [[ -n "${values[1]}" ]]; then
124*4f2df630SAndroid Build Coastguard Worker      # From each modified repo get the most recently modified file.
125*4f2df630SAndroid Build Coastguard Worker      most_recent_file="$(git status --porcelain | \
126*4f2df630SAndroid Build Coastguard Worker                                       awk '$1 ~ /[M|A|?]/ {print $2}' |  \
127*4f2df630SAndroid Build Coastguard Worker                                       xargs ls -t | head -1)"
128*4f2df630SAndroid Build Coastguard Worker      most_recents+=("$(realpath "${most_recent_file}")")
129*4f2df630SAndroid Build Coastguard Worker    fi
130*4f2df630SAndroid Build Coastguard Worker    if [ "${component}" != "." ]; then
131*4f2df630SAndroid Build Coastguard Worker      ver+=" ${component}:"
132*4f2df630SAndroid Build Coastguard Worker    fi
133*4f2df630SAndroid Build Coastguard Worker    ver+="${vbase}"
134*4f2df630SAndroid Build Coastguard Worker    tool_ver+="${vbase}"
135*4f2df630SAndroid Build Coastguard Worker    popd > /dev/null
136*4f2df630SAndroid Build Coastguard Worker  done
137*4f2df630SAndroid Build Coastguard Worker
138*4f2df630SAndroid Build Coastguard Worker  # On some boards where the version number consists of multiple components we
139*4f2df630SAndroid Build Coastguard Worker  # want to separate the first word of the version string as the version of the
140*4f2df630SAndroid Build Coastguard Worker  # EC tree.
141*4f2df630SAndroid Build Coastguard Worker  IFS=' ' first_word=(${ver})
142*4f2df630SAndroid Build Coastguard Worker
143*4f2df630SAndroid Build Coastguard Worker  echo "/* This file is generated by util/getversion.sh */"
144*4f2df630SAndroid Build Coastguard Worker
145*4f2df630SAndroid Build Coastguard Worker  echo "/* Version string, truncated to 31 chars (+ terminating null = 32) */"
146*4f2df630SAndroid Build Coastguard Worker  echo "#define CROS_EC_VERSION32 \"${first_word:0:31}\""
147*4f2df630SAndroid Build Coastguard Worker
148*4f2df630SAndroid Build Coastguard Worker  echo "/* Version string for ectool. */"
149*4f2df630SAndroid Build Coastguard Worker  echo "#define CROS_ECTOOL_VERSION \"${tool_ver}\""
150*4f2df630SAndroid Build Coastguard Worker
151*4f2df630SAndroid Build Coastguard Worker  echo "/* Version string for stm32mon. */"
152*4f2df630SAndroid Build Coastguard Worker  echo "#define CROS_STM32MON_VERSION \"${tool_ver}\""
153*4f2df630SAndroid Build Coastguard Worker
154*4f2df630SAndroid Build Coastguard Worker  echo "/* Sub-fields for use in Makefile.rules and to form build info string"
155*4f2df630SAndroid Build Coastguard Worker  echo " * in common/version.c. */"
156*4f2df630SAndroid Build Coastguard Worker  echo "#define VERSION \"${ver}\""
157*4f2df630SAndroid Build Coastguard Worker  if [ "$REPRODUCIBLE_BUILD" = 1 ]; then
158*4f2df630SAndroid Build Coastguard Worker    echo '#define BUILDER "reproducible@build"'
159*4f2df630SAndroid Build Coastguard Worker  else
160*4f2df630SAndroid Build Coastguard Worker    echo "#define BUILDER \"${USER}@`hostname`\""
161*4f2df630SAndroid Build Coastguard Worker  fi
162*4f2df630SAndroid Build Coastguard Worker
163*4f2df630SAndroid Build Coastguard Worker  if [[ ${#most_recents[@]} != 0 ]]; then
164*4f2df630SAndroid Build Coastguard Worker    # There are modified files, use the timestamp of the most recent one as
165*4f2df630SAndroid Build Coastguard Worker    # the build version timestamp.
166*4f2df630SAndroid Build Coastguard Worker    most_recent_file="$(ls -t "${most_recents[@]}" | head -1)"
167*4f2df630SAndroid Build Coastguard Worker    timestamp="$(stat -c '%y' "${most_recent_file}" | sed 's/\..*//')"
168*4f2df630SAndroid Build Coastguard Worker    echo "/* Repo is dirty, using time of most recent file modification. */"
169*4f2df630SAndroid Build Coastguard Worker    echo "#define DATE \"${timestamp}\""
170*4f2df630SAndroid Build Coastguard Worker  else
171*4f2df630SAndroid Build Coastguard Worker    echo "/* Repo is clean, use the commit date of the last commit. */"
172*4f2df630SAndroid Build Coastguard Worker    # If called from an ebuild we won't have a git repo, so redirect stderr
173*4f2df630SAndroid Build Coastguard Worker    # to avoid annoying 'Not a git repository' errors.
174*4f2df630SAndroid Build Coastguard Worker    gitdate="$(
175*4f2df630SAndroid Build Coastguard Worker      for git_dir in "${dir_list[@]}"; do
176*4f2df630SAndroid Build Coastguard Worker        git -C "${git_dir}" log -1 --format='%ct %ci' HEAD 2>/dev/null
177*4f2df630SAndroid Build Coastguard Worker      done | sort | tail -1 | cut -d ' ' -f '2 3')"
178*4f2df630SAndroid Build Coastguard Worker    echo "#define DATE \"${gitdate}\""
179*4f2df630SAndroid Build Coastguard Worker  fi
180*4f2df630SAndroid Build Coastguard Worker}
181*4f2df630SAndroid Build Coastguard Worker
182*4f2df630SAndroid Build Coastguard Workermain
183