#!/bin/bash
#
# Copyright 2017 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.
#
# Generate git strings for tagging EC branches.
#
# This script builds up on ideas put by vpalatin@ into util/getversion.sh
#
# Git allows to count number of patches between the current state of the tree
# and any directly preceding tag in the tree. That is if we tag the first
# patch in the current branch, we can tell how many patches are in the branch
# above that tag. And if we tag the branch such that the tag string includes
# the branch name, we can also say what branch we are in looking at the
# closest tag in the tree.
#
# This admittedly brittle script automates the process of tagging for the EC
# git tree in Chrome OS repo, but it could be used for any other Chrome OS
# repo git tree just as well.
#
# The script is brittle because it relies on the following assumptions which
# are true for Chrome OS repo at the time of writing:
#
# - the upstream branch alias name shows up in the 'git branch -a' output
#   separated by ->
# - the upstream branch alias name has the format of
#   cros/<branch name>
# - the remote git server name shows up in 'git config -l' output in the
#   line starting with "remote.cros.url="
# - firmware branch names have format of firmware-<board>-XXXXXX
# - the current branch was cut off of <remote name>/master
#
# The tag name generated by this script would be the XXXXX string with dots,
# if any, replaced by underscores.

# Retrieve the upstream branch alias name
UPSTREAM="$(git branch -a | awk '/->/ {print $3}')"
if [[ -z "${UPSTREAM}" ]]; then
  echo "Failed to determine upstream branch alias" >&2
  exit 1
fi

export ORIGIN_NAME="cros"
ORIGIN="$(git config "remote.${ORIGIN_NAME}.url")"

# The last common patch between this branch and the master.
BRANCH_POINT="$(git merge-base "${UPSTREAM}" "${ORIGIN_NAME}/master")"
if [[ -z "${BRANCH_POINT}" ]]; then
  echo "Failed to determine cros/master branch point" >&2
  exit 1
fi

# Derive tag base string from the upstream branch name as described above.
TAG_BASE="$(sed 's/.*-//       # drop everything up to including the last -
                 s/\./_/g      # replace dots and dashes with underscores
      ' <<< "${UPSTREAM}" )"

if [[ "${TAG_BASE}" == "master" ]]; then
  echo "Nothing to tag in master branch" >&2
  exit 1
fi

TAG="v1.${TAG_BASE}.0"

#SHA1 of the first patch of this branch
BASE_SHA="$(git rev-list --ancestry-path "${BRANCH_POINT}".."${UPSTREAM}" |
    tail -1)"

echo "Will run git tag -a -m \"firmware branch ${TAG}\" ${TAG} ${BASE_SHA}"
if git tag -a -m "firmware branch ${TAG}" "${TAG}" "${BASE_SHA}"; then
  cat <<EOF

A new tag '$TAG' has been set. Use the following command
to push it to the server

git push --tags ${ORIGIN} ${TAG}

Or if you want to delete it:

git tag -d $TAG

EOF
fi
