Repository navigation
Expand file tree
/
Copy pathwrite_git_properties.sh
More file actions
executable file
·124 lines (111 loc) · 5.05 KB
/
Copy pathwrite_git_properties.sh
File metadata and controls
executable file
·124 lines (111 loc) · 5.05 KB
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#!/bin/bash
################################################################################
# Write the build stamp (git.properties) that /status reports.
#
# Usage: write_git_properties.sh <output-file>
#
# Why a script and not git-commit-id-maven-plugin: that plugin bundles JGit 6.7,
# which has no `commondir` support, so it cannot read a linked worktree's gitdir.
# Its GitDirLocator.resolveWorktree() works around that by collapsing
# <main>/.git/worktrees/<name> back to <main>/.git — meaning every build run from
# a worktree stamped the MAIN checkout's branch and commit. On top of that its
# PropertiesFileGenerator skips rewriting whenever the only changed key is
# git.build.time, so the stamp froze at the first build. The git CLI is
# worktree-aware by construction and we rewrite unconditionally, so both go away.
#
# Never fails the build: with no git binary or no repository we still emit a
# well-formed stamp with git.commit.id=unknown (the plugin behaved the same way
# via failOnNoGitDirectory=false, and source-tarball builds rely on it).
################################################################################
set -u
OUT="${1:-}"
if [[ -z "$OUT" ]]; then
echo "write_git_properties.sh: output file argument is required" >&2
exit 1
fi
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# Resolve the repository from the script's own location, not the caller's cwd:
# Maven invokes this from a module directory, and `git` must run against the
# working copy that owns this script.
REPO_ROOT="$(git -C "$SCRIPT_DIR" rev-parse --show-toplevel 2>/dev/null || true)"
g() {
# Echo a git command's first line, empty string on any failure.
git -C "$REPO_ROOT" "$@" 2>/dev/null | head -1 || true
}
if [[ -n "$REPO_ROOT" ]]; then
BRANCH="$(g rev-parse --abbrev-ref HEAD)"
COMMIT_ID="$(g rev-parse HEAD)"
COMMIT_ABBREV="$(g rev-parse --short=7 HEAD)"
COMMIT_TIME="$(g log -1 --format=%cI)"
COMMIT_USER_NAME="$(g log -1 --format=%an)"
COMMIT_USER_EMAIL="$(g log -1 --format=%ae)"
COMMIT_MESSAGE_SHORT="$(g log -1 --format=%s)"
DESCRIBE="$(g describe --always --dirty --abbrev=7)"
TAGS="$(git -C "$REPO_ROOT" tag --points-at HEAD 2>/dev/null | paste -sd, - || true)"
REMOTE_URL="$(g config --get remote.origin.url)"
BUILD_USER_NAME="$(g config --get user.name)"
BUILD_USER_EMAIL="$(g config --get user.email)"
# Tracked modifications only, matching what git-commit-id reported: untracked
# scratch files (build logs, editor state) are always present in a working
# checkout and would pin the flag to true, which is exactly the "renders the
# same either way" problem 6727bd372 set out to fix.
if [[ -n "$(git -C "$REPO_ROOT" status --porcelain --untracked-files=no 2>/dev/null)" ]]; then
DIRTY="true"
else
DIRTY="false"
fi
else
BRANCH=""
COMMIT_ID="unknown"
COMMIT_ABBREV="unknown"
COMMIT_TIME=""
COMMIT_USER_NAME=""
COMMIT_USER_EMAIL=""
COMMIT_MESSAGE_SHORT=""
DESCRIBE=""
TAGS=""
REMOTE_URL=""
BUILD_USER_NAME=""
BUILD_USER_EMAIL=""
DIRTY="false"
fi
[[ -z "$COMMIT_ID" ]] && COMMIT_ID="unknown"
[[ -z "$COMMIT_ABBREV" ]] && COMMIT_ABBREV="unknown"
# BSD date (macOS) has no %:z, so put the colon into the numeric offset by hand
# and keep the ISO-8601 shape the previous stamps used.
BUILD_TIME="$(date +%Y-%m-%dT%H:%M:%S%z | sed -E 's/([+-][0-9]{2})([0-9]{2})$/\1:\2/')"
BUILD_HOST="$(hostname 2>/dev/null || echo unknown)"
# java.util.Properties treats \ : = # ! specially in values; escape what can occur
# here. Timestamps and URLs carry ':', commit subjects can carry anything.
esc() {
printf '%s' "$1" | sed -e 's/\\/\\\\/g' -e 's/:/\\:/g' -e 's/=/\\=/g' -e 's/#/\\#/g' -e 's/!/\\!/g'
}
OUT_DIR="$(dirname "$OUT")"
mkdir -p "$OUT_DIR"
{
echo "#Generated by scripts/write_git_properties.sh"
echo "git.branch=$(esc "$BRANCH")"
echo "git.build.host=$(esc "$BUILD_HOST")"
echo "git.build.time=$(esc "$BUILD_TIME")"
echo "git.build.user.email=$(esc "$BUILD_USER_EMAIL")"
echo "git.build.user.name=$(esc "$BUILD_USER_NAME")"
echo "git.commit.id=$(esc "$COMMIT_ID")"
echo "git.commit.id.abbrev=$(esc "$COMMIT_ABBREV")"
echo "git.commit.id.describe=$(esc "$DESCRIBE")"
echo "git.commit.message.short=$(esc "$COMMIT_MESSAGE_SHORT")"
echo "git.commit.time=$(esc "$COMMIT_TIME")"
echo "git.commit.user.email=$(esc "$COMMIT_USER_EMAIL")"
echo "git.commit.user.name=$(esc "$COMMIT_USER_NAME")"
echo "git.dirty=$DIRTY"
echo "git.remote.origin.url=$(esc "$REMOTE_URL")"
echo "git.tags=$(esc "$TAGS")"
} > "$OUT"
# Legacy stamps written by git-commit-id into the source tree. They are build
# output (gitignored), and obp-commons' copy would otherwise keep shipping a
# stale git.properties that can shadow this one on the runtime classpath.
if [[ -n "$REPO_ROOT" ]]; then
rm -f "$REPO_ROOT/obp-api/src/main/resources/git.properties" \
"$REPO_ROOT/obp-commons/src/main/resources/git.properties" \
"$REPO_ROOT/obp-commons/target/classes/git.properties" 2>/dev/null || true
fi
exit 0