Skip to content

Commit 60ef421

Browse files
committed
Extend version generation script with prelease tags
1 parent d8b9929 commit 60ef421

1 file changed

Lines changed: 112 additions & 25 deletions

File tree

generate_version.sh

Lines changed: 112 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -16,41 +16,121 @@ DEFAULT_PATCH=0
1616
# Helpers (matching build_lib.sh style)
1717
info() { echo -e "\e[34m[INFO]\e[0m $*"; }
1818
warn() { echo -e "\e[33m[WARN]\e[0m $*" >&2; }
19+
read_version_field() {
20+
local version_file_="$1"
21+
local field_name_="$2"
22+
[[ -f "$version_file_" ]] || return 1
23+
awk -F': ' -v key="${field_name_}" 'index($0, key ": ") == 1 { sub(/^[^:]+: /, "", $0); print; exit }' "$version_file_"
24+
}
25+
compose_full_version() {
26+
local version_core_="$1"
27+
local version_prerelease_="$2"
28+
local version_metadata_="$3"
29+
local full_version_="$version_core_"
30+
31+
if [[ -n "$version_prerelease_" ]]; then
32+
full_version_+="-${version_prerelease_}"
33+
fi
34+
if [[ -n "$version_metadata_" ]]; then
35+
full_version_+="+${version_metadata_}"
36+
fi
37+
38+
printf '%s\n' "$full_version_"
39+
}
40+
set_version_components() {
41+
version_major="$1"
42+
version_minor="$2"
43+
version_patch="$3"
44+
version_prerelease="$4"
45+
version_metadata="$5"
46+
version_core="${version_major}.${version_minor}.${version_patch}"
47+
full_version="$(compose_full_version "$version_core" "$version_prerelease" "$version_metadata")"
48+
}
1949

2050
version_major=""
2151
version_minor=""
2252
version_patch=""
53+
version_core=""
54+
version_prerelease=""
55+
version_metadata=""
2356
full_version=""
2457
source=""
2558

2659
# 1. Try git
2760
if command -v git >/dev/null 2>&1 && git -C "$SCRIPT_DIR" rev-parse --git-dir >/dev/null 2>&1; then
28-
git_tag=$(git -C "$SCRIPT_DIR" describe --tags --always 2>/dev/null || true)
29-
git_hash=$(git -C "$SCRIPT_DIR" rev-parse --short=7 HEAD 2>/dev/null || true)
61+
git_describe=$(git -C "$SCRIPT_DIR" describe --tags --long --dirty --always 2>/dev/null || true)
3062

3163
# Strip leading 'v' and match semver
32-
clean_tag="${git_tag#v}"
33-
if [[ "$clean_tag" =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)(-.*)? ]]; then
34-
version_major="${BASH_REMATCH[1]}"
35-
version_minor="${BASH_REMATCH[2]}"
36-
version_patch="${BASH_REMATCH[3]}"
37-
full_version="${version_major}.${version_minor}.${version_patch}+${git_hash}"
38-
source="git"
64+
clean_tag="${git_describe#v}"
65+
if [[ "$clean_tag" =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)(-([0-9A-Za-z.-]+))?-([0-9]+)-g([0-9a-f]+)(-dirty)?$ ]]; then
66+
version_prerelease_local="${BASH_REMATCH[5]}"
67+
version_distance_local="${BASH_REMATCH[6]}"
68+
version_hash_local="g${BASH_REMATCH[7]}"
69+
version_dirty_local="${BASH_REMATCH[8]}"
70+
version_metadata_parts=()
71+
72+
if [[ "$version_distance_local" != "0" ]]; then
73+
version_metadata_parts+=("$version_distance_local")
74+
fi
75+
if [[ "$version_distance_local" != "0" || -n "$version_dirty_local" ]]; then
76+
version_metadata_parts+=("$version_hash_local")
77+
fi
78+
if [[ -n "$version_dirty_local" ]]; then
79+
version_metadata_parts+=("dirty")
80+
fi
81+
82+
version_metadata_local=""
83+
if (( ${#version_metadata_parts[@]} > 0 )); then
84+
version_metadata_local="$(printf '%s.' "${version_metadata_parts[@]}")"
85+
version_metadata_local="${version_metadata_local%.}"
86+
fi
87+
88+
set_version_components \
89+
"${BASH_REMATCH[1]}" \
90+
"${BASH_REMATCH[2]}" \
91+
"${BASH_REMATCH[3]}" \
92+
"$version_prerelease_local" \
93+
"$version_metadata_local"
94+
source="git describe"
95+
elif [[ "$clean_tag" =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)(-([0-9A-Za-z.-]+))?$ ]]; then
96+
set_version_components \
97+
"${BASH_REMATCH[1]}" \
98+
"${BASH_REMATCH[2]}" \
99+
"${BASH_REMATCH[3]}" \
100+
"${BASH_REMATCH[5]}" \
101+
""
102+
source="git tag"
39103
fi
40104
fi
41105

42106
# 2. Try existing VERSION file
43107
if [[ -z "$source" && -f "$VERSION_FILE" ]]; then
44-
if grep -qP 'Project version: \d+\.\d+\.\d+' "$VERSION_FILE"; then
45-
line=$(grep -oP 'Project version: \K\d+\.\d+\.\d+' "$VERSION_FILE")
46-
IFS='.' read -r version_major version_minor version_patch <<< "$line"
47-
48-
# Try to read full version line
49-
full_line=$(grep -oP 'Full version: \K.+' "$VERSION_FILE" 2>/dev/null || true)
50-
if [[ -n "$full_line" ]]; then
51-
full_version="$full_line"
52-
else
53-
full_version="${version_major}.${version_minor}.${version_patch}"
108+
version_core_local="$(read_version_field "$VERSION_FILE" "Project version core" || true)"
109+
if [[ -z "$version_core_local" ]]; then
110+
version_core_local="$(read_version_field "$VERSION_FILE" "Project version" || true)"
111+
fi
112+
113+
if [[ "$version_core_local" =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]; then
114+
version_prerelease_local="$(read_version_field "$VERSION_FILE" "Project version prerelease" || true)"
115+
version_metadata_local="$(read_version_field "$VERSION_FILE" "Project version metadata" || true)"
116+
117+
if [[ "$version_prerelease_local" == "<none>" ]]; then
118+
version_prerelease_local=""
119+
fi
120+
if [[ "$version_metadata_local" == "<none>" ]]; then
121+
version_metadata_local=""
122+
fi
123+
124+
set_version_components \
125+
"${BASH_REMATCH[1]}" \
126+
"${BASH_REMATCH[2]}" \
127+
"${BASH_REMATCH[3]}" \
128+
"$version_prerelease_local" \
129+
"$version_metadata_local"
130+
131+
full_version_local="$(read_version_field "$VERSION_FILE" "Full version" || true)"
132+
if [[ -n "$full_version_local" ]]; then
133+
full_version="$full_version_local"
54134
fi
55135
source="VERSION file"
56136
else
@@ -60,18 +140,25 @@ fi
60140

61141
# 3. Fallback to hardcoded defaults
62142
if [[ -z "$source" ]]; then
63-
version_major=$DEFAULT_MAJOR
64-
version_minor=$DEFAULT_MINOR
65-
version_patch=$DEFAULT_PATCH
66-
full_version="${version_major}.${version_minor}.${version_patch}"
143+
set_version_components "$DEFAULT_MAJOR" "$DEFAULT_MINOR" "$DEFAULT_PATCH" "" ""
67144
source="hardcoded default"
68145
warn "No git tags or VERSION file found. Using default version: ${full_version}"
69146
fi
70147

71148
# Write VERSION file
72-
version_string="${version_major}.${version_minor}.${version_patch}"
73149
{
74-
echo "Project version: ${version_string}"
150+
echo "Project version: ${version_core}"
151+
echo "Project version core: ${version_core}"
152+
if [[ -n "$version_prerelease" ]]; then
153+
echo "Project version prerelease: ${version_prerelease}"
154+
else
155+
echo "Project version prerelease: <none>"
156+
fi
157+
if [[ -n "$version_metadata" ]]; then
158+
echo "Project version metadata: ${version_metadata}"
159+
else
160+
echo "Project version metadata: <none>"
161+
fi
75162
echo "Full version: ${full_version}"
76163
} > "$VERSION_FILE"
77164

0 commit comments

Comments
 (0)