-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgenerate_version.sh
More file actions
executable file
·165 lines (145 loc) · 5.53 KB
/
Copy pathgenerate_version.sh
File metadata and controls
executable file
·165 lines (145 loc) · 5.53 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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#!/usr/bin/env bash
# Generate VERSION file without building.
# Fallback chain: git tags --> existing VERSION file --> hardcoded default.
set -Eeuo pipefail
IFS=$'\n\t'
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
VERSION_FILE="${SCRIPT_DIR}/VERSION"
# Default version (last resort)
DEFAULT_MAJOR=0
DEFAULT_MINOR=0
DEFAULT_PATCH=0
# Helpers (matching build_lib.sh style)
info() { echo -e "\e[34m[INFO]\e[0m $*"; }
warn() { echo -e "\e[33m[WARN]\e[0m $*" >&2; }
read_version_field() {
local version_file_="$1"
local field_name_="$2"
[[ -f "$version_file_" ]] || return 1
awk -F': ' -v key="${field_name_}" 'index($0, key ": ") == 1 { sub(/^[^:]+: /, "", $0); print; exit }' "$version_file_"
}
compose_full_version() {
local version_core_="$1"
local version_prerelease_="$2"
local version_metadata_="$3"
local full_version_="$version_core_"
if [[ -n "$version_prerelease_" ]]; then
full_version_+="-${version_prerelease_}"
fi
if [[ -n "$version_metadata_" ]]; then
full_version_+="+${version_metadata_}"
fi
printf '%s\n' "$full_version_"
}
set_version_components() {
version_major="$1"
version_minor="$2"
version_patch="$3"
version_prerelease="$4"
version_metadata="$5"
version_core="${version_major}.${version_minor}.${version_patch}"
full_version="$(compose_full_version "$version_core" "$version_prerelease" "$version_metadata")"
}
version_major=""
version_minor=""
version_patch=""
version_core=""
version_prerelease=""
version_metadata=""
full_version=""
source=""
# 1. Try git
if command -v git >/dev/null 2>&1 && git -C "$SCRIPT_DIR" rev-parse --git-dir >/dev/null 2>&1; then
git_describe=$(git -C "$SCRIPT_DIR" describe --tags --long --dirty --always 2>/dev/null || true)
# Strip leading 'v' and match semver
clean_tag="${git_describe#v}"
if [[ "$clean_tag" =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)(-([0-9A-Za-z.-]+))?-([0-9]+)-g([0-9a-f]+)(-dirty)?$ ]]; then
version_prerelease_local="${BASH_REMATCH[5]}"
version_distance_local="${BASH_REMATCH[6]}"
version_hash_local="g${BASH_REMATCH[7]}"
version_dirty_local="${BASH_REMATCH[8]}"
version_metadata_parts=()
if [[ "$version_distance_local" != "0" ]]; then
version_metadata_parts+=("$version_distance_local")
fi
if [[ "$version_distance_local" != "0" || -n "$version_dirty_local" ]]; then
version_metadata_parts+=("$version_hash_local")
fi
if [[ -n "$version_dirty_local" ]]; then
version_metadata_parts+=("dirty")
fi
version_metadata_local=""
if (( ${#version_metadata_parts[@]} > 0 )); then
version_metadata_local="$(printf '%s.' "${version_metadata_parts[@]}")"
version_metadata_local="${version_metadata_local%.}"
fi
set_version_components \
"${BASH_REMATCH[1]}" \
"${BASH_REMATCH[2]}" \
"${BASH_REMATCH[3]}" \
"$version_prerelease_local" \
"$version_metadata_local"
source="git describe"
elif [[ "$clean_tag" =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)(-([0-9A-Za-z.-]+))?$ ]]; then
set_version_components \
"${BASH_REMATCH[1]}" \
"${BASH_REMATCH[2]}" \
"${BASH_REMATCH[3]}" \
"${BASH_REMATCH[5]}" \
""
source="git tag"
fi
fi
# 2. Try existing VERSION file
if [[ -z "$source" && -f "$VERSION_FILE" ]]; then
version_core_local="$(read_version_field "$VERSION_FILE" "Project version core" || true)"
if [[ -z "$version_core_local" ]]; then
version_core_local="$(read_version_field "$VERSION_FILE" "Project version" || true)"
fi
if [[ "$version_core_local" =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]; then
version_prerelease_local="$(read_version_field "$VERSION_FILE" "Project version prerelease" || true)"
version_metadata_local="$(read_version_field "$VERSION_FILE" "Project version metadata" || true)"
if [[ "$version_prerelease_local" == "<none>" ]]; then
version_prerelease_local=""
fi
if [[ "$version_metadata_local" == "<none>" ]]; then
version_metadata_local=""
fi
set_version_components \
"${BASH_REMATCH[1]}" \
"${BASH_REMATCH[2]}" \
"${BASH_REMATCH[3]}" \
"$version_prerelease_local" \
"$version_metadata_local"
full_version_local="$(read_version_field "$VERSION_FILE" "Full version" || true)"
if [[ -n "$full_version_local" ]]; then
full_version="$full_version_local"
fi
source="VERSION file"
else
warn "VERSION file exists but could not be parsed"
fi
fi
# 3. Fallback to hardcoded defaults
if [[ -z "$source" ]]; then
set_version_components "$DEFAULT_MAJOR" "$DEFAULT_MINOR" "$DEFAULT_PATCH" "" ""
source="hardcoded default"
warn "No git tags or VERSION file found. Using default version: ${full_version}"
fi
# Write VERSION file
{
echo "Project version: ${version_core}"
echo "Project version core: ${version_core}"
if [[ -n "$version_prerelease" ]]; then
echo "Project version prerelease: ${version_prerelease}"
else
echo "Project version prerelease: <none>"
fi
if [[ -n "$version_metadata" ]]; then
echo "Project version metadata: ${version_metadata}"
else
echo "Project version metadata: <none>"
fi
echo "Full version: ${full_version}"
} > "$VERSION_FILE"
info "Version ${full_version} (from ${source}) written to ${VERSION_FILE}"