Skip to content

Commit

Permalink
Replace multiple version scripts with a Python script
Browse files Browse the repository at this point in the history
In the past, I've had trouble keeping the current set of version scripts
to correctly output the version, especially in light of how we append
Git suffixes for a non-tagged commit and dirty state. This change
replaces those scripts with a single Python one which, though much more
wordy than the previous one, may be easier for contributors to read and
modify. The original scripts relied on Perl; this one relies on Python,
which seems like a fair exchange. Having a single script also makes it
easier to solve #372.
  • Loading branch information
abrown committed Mar 19, 2024
1 parent 96bbd95 commit 2436b99
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 15 deletions.
5 changes: 3 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

ROOT_DIR=${CURDIR}
LLVM_PROJ_DIR?=$(ROOT_DIR)/src/llvm-project
VERSION_SCRIPT=python3 ./version.py

# Windows needs munging
ifeq ($(OS),Windows_NT)
Expand Down Expand Up @@ -45,8 +46,8 @@ endif
TARGETS = wasm32-wasi wasm32-wasip1 wasm32-wasip2 wasm32-wasip1-threads wasm32-wasi-threads

# Only the major version is needed for Clang, see https://reviews.llvm.org/D125860.
CLANG_VERSION=$(shell $(BASH) ./llvm_version_major.sh $(LLVM_PROJ_DIR))
VERSION:=$(shell $(BASH) ./version.sh)
CLANG_VERSION=$(shell $(VERSION_SCRIPT) llvm-major --llvm-dir=$(LLVM_PROJ_DIR))
VERSION:=$(shell $(VERSION_SCRIPT))
DEBUG_PREFIX_MAP=-fdebug-prefix-map=$(ROOT_DIR)=wasisdk://v$(VERSION)

default: build
Expand Down
2 changes: 1 addition & 1 deletion RELEASING.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
To publish a new version of `wasi-sdk` as a GitHub release:

1. Tag a commit with an annotated tag. Note that this must be an annotated tag,
not a lightweight tag, so that `version.sh` can use it for calculating the
not a lightweight tag, so that `version.py` can use it for calculating the
package version (use `git show wasi-sdk-...` to show other tag messages).
Note that you may need to clear the repository cache to avoid problems with
cached artifacts [^cache].
Expand Down
2 changes: 1 addition & 1 deletion deb_from_installation.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ fi
if [ -n "$2" ]; then
VERSION="$2"
else
VERSION=`./version.sh`
VERSION=`./version.py`
fi

if [ -n "$3" ]; then
Expand Down
4 changes: 0 additions & 4 deletions llvm_version_major.sh

This file was deleted.

2 changes: 1 addition & 1 deletion tar_from_installation.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ fi
if [ -n "$2" ]; then
VERSION="$2"
else
VERSION=`./version.sh`
VERSION=`./version.py`
fi

if [ -n "$3" ]; then
Expand Down
122 changes: 122 additions & 0 deletions version.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
#!/usr/bin/env python3

# This script finds and prints the various versions in this project: wasi-sdk
# itself, LLVM, and the Git revisions of dependencies.
#
# Usage: version [wasi-sdk|llvm|llvm-major|dump] [--llvm-dir=<non-project dir>]

import sys
import argparse
import subprocess

# The number of characters to use for the abbreviated Git revision.
GIT_REF_LEN = 12


def exec(command, cwd=None):
result = subprocess.run(command, stdout=subprocess.PIPE,
universal_newlines=True, check=True, cwd=cwd)
return result.stdout.strip()


def git_commit(dir='.'):
return exec(['git', 'rev-parse', f'--short={GIT_REF_LEN}', 'HEAD'], dir)


def parse_git_version(version):
# Parse, e.g.: wasi-sdk-21-0-g317548590b40+m
parts = version.replace('+', '-').split('-')
assert parts.pop(0) == 'wasi'
assert parts.pop(0) == 'sdk'

major, minor = parts.pop(0), parts.pop(0)
git = None
dirty = False

if parts:
# Check: git|dirty.
next = parts.pop(0)
if next == 'm':
dirty = True
else:
git = next[1:]

# Check: dirty.
if parts:
assert parts.pop(0) == 'm', f'expected dirty flag: +m'
dirty = True

assert not parts, f'unexpected suffixes: {parts}'
return major, minor, git, dirty


# Some inline tests to check Git version parsing:
assert parse_git_version(
'wasi-sdk-21-0-g317548590b40+m') == ('21', '0', '317548590b40', True)
assert parse_git_version('wasi-sdk-21-2+m') == ('21', '2', None, True)
assert parse_git_version(
'wasi-sdk-23-0-g317548590b40') == ('23', '0', '317548590b40', False)


def git_version():
version = exec(['git', 'describe', '--long', '--candidates=999',
'--match=wasi-sdk-*', '--dirty=+m', f'--abbrev={GIT_REF_LEN}'])
major, minor, git, dirty = parse_git_version(version)
version = f'{major}.{minor}'
if git:
version += f'g{git}'
if dirty:
version += '+m'
return version


def parse_cmake_set(line):
return line.split(' ')[1].split(')')[0]


def llvm_cmake_version(llvm_dir):
with open(f'{llvm_dir}/llvm/CMakeLists.txt') as file:
for line in file:
line = line.strip()
if line.startswith('set(LLVM_VERSION_MAJOR'):
llvm_version_major = parse_cmake_set(line)
elif line.startswith('set(LLVM_VERSION_MINOR'):
llvm_version_minor = parse_cmake_set(line)
elif line.startswith('set(LLVM_VERSION_PATCH'):
llvm_version_patch = parse_cmake_set(line)
return llvm_version_major, llvm_version_minor, llvm_version_patch


def main(action, llvm_dir):
if action == 'wasi-sdk':
print(git_version())
elif action == 'llvm':
major, minor, path = llvm_cmake_version(llvm_dir)
print(f'{major}.{minor}.{path}')
elif action == 'llvm-major':
major, _, _ = llvm_cmake_version(llvm_dir)
print(major)
elif action == 'dump':
print(git_version())
print(f'wasi-libc: {git_commit("src/wasi-libc")}')
print(f'llvm: {git_commit(llvm_dir)}')
major, minor, path = llvm_cmake_version(llvm_dir)
print(f'llvm-version: {major}.{minor}.{path}')
print(f'config: {git_commit("src/config")}')


if __name__ == '__main__':
parser = argparse.ArgumentParser(
description='Print the various kinds of versions in wasi-sdk')
parser.add_argument('action',
choices=['wasi-sdk', 'llvm', 'llvm-major', 'dump'],
nargs='?',
default='wasi-sdk',
help='Which kind of version to print (default: wasi-sdk).')
parser.add_argument('--llvm-dir',
nargs='?',
default='src/llvm-project',
help='Override the location of the LLVM source directory (default: src/llvm-project).')
args = parser.parse_args()
main(args.action, args.llvm_dir)
sys.exit(0)
6 changes: 0 additions & 6 deletions version.sh

This file was deleted.

0 comments on commit 2436b99

Please sign in to comment.