Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Formula/wtcraft.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ class Wtcraft < Formula
homepage "https://github.com/zywkloo/wtcraft"
# Update url + sha256 for each release:
# curl -sL <url> | shasum -a 256
url "https://github.com/zywkloo/wtcraft/archive/refs/tags/v0.4.1.tar.gz"
url "https://github.com/zywkloo/wtcraft/archive/refs/tags/v0.4.2.tar.gz"
sha256 "eb5fc8483016211fcd78f6869d73bf42421d59be56b31a0eebd7b3bc7fe23239"
license "Apache-2.0"
head "https://github.com/zywkloo/wtcraft.git", branch: "main"
Expand All @@ -23,6 +23,7 @@ def install
(bin/"wtcraft").write <<~SH
#!/usr/bin/env bash
export WTCRAFT_TEMPLATE_DIR="#{pkgshare}/templates"
export WTCRAFT_VERSION="#{version}"
exec "#{libexec}/wtcraft-real" "$@"
SH
end
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "wtcraft",
"version": "0.4.1",
"version": "0.4.2",
"description": "Zero-trust containment and governance for AI-generated code.",
"license": "Apache-2.0",
"bin": {
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "wtcraft"
version = "0.4.1"
version = "0.4.2"
description = "A lightweight, git-native scaffolding for bounded multi-agent coding"
license = { text = "Apache-2.0" }
requires-python = ">=3.7"
Expand Down
40 changes: 40 additions & 0 deletions scripts/bump-version.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#!/usr/bin/env bash
#
# Single entry point for bumping the wtcraft version.
#
# The version unavoidably lives in three build manifests (each build system
# reads its own): pyproject.toml, package.json, and the Homebrew formula's
# release tag. This script is the one command that keeps them in sync, so the
# version is bumped from a single place instead of edited by hand in three.
#
# The Python package (__init__.py) and the installed shell (read_cli_version)
# derive their version at runtime, so they are not edited here.
#
# Usage: scripts/bump-version.sh <semver> e.g. scripts/bump-version.sh 0.4.2
#
set -euo pipefail

new="${1:-}"
case "$new" in
"") echo "usage: bump-version.sh <semver> (e.g. 0.4.2)" >&2; exit 1 ;;
*[!0-9.]*) echo "version must contain only digits and dots: $new" >&2; exit 1 ;;
esac

root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"

# pyproject.toml: version = "x"
sed -i.bak -E "s/^version = \"[^\"]*\"/version = \"${new}\"/" "${root}/pyproject.toml"
# package.json: "version": "x" (the sole top-level version key)
sed -i.bak -E "s/(\"version\"[[:space:]]*:[[:space:]]*\")[^\"]*(\")/\1${new}\2/" "${root}/package.json"
# Formula: .../tags/v<x>.tar.gz (Homebrew derives #{version} from this)
sed -i.bak -E "s#(archive/refs/tags/v)[0-9][0-9.]*(\.tar\.gz)#\1${new}\2#" "${root}/Formula/wtcraft.rb"

rm -f "${root}/pyproject.toml.bak" "${root}/package.json.bak" "${root}/Formula/wtcraft.rb.bak"

echo "Bumped wtcraft to ${new} in:"
echo " pyproject.toml"
echo " package.json"
echo " Formula/wtcraft.rb (release tag)"
echo
echo "Still manual: Formula sha256 must be updated for the new tarball:"
echo " curl -sL https://github.com/zywkloo/wtcraft/archive/refs/tags/v${new}.tar.gz | shasum -a 256"
7 changes: 7 additions & 0 deletions scripts/wtcraft
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,13 @@ die() {
}

read_cli_version() {
# Installers stamp WTCRAFT_VERSION (brew wrapper, pip _cli.py) so the version
# survives even when no manifest sits beside the installed script.
if [ -n "${WTCRAFT_VERSION:-}" ]; then
printf '%s' "${WTCRAFT_VERSION}"
return 0
fi
# In-repo development: read it straight from the manifest next to the script.
if [ -f "${ROOT_DIR}/package.json" ]; then
awk -F'"' '/"version"[[:space:]]*:/ { print $4; exit }' "${ROOT_DIR}/package.json"
return 0
Expand Down
12 changes: 11 additions & 1 deletion src/wtcraft/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,12 @@
# wtcraft — git-native harness helper
__version__ = "0.3.8"
# Derive the version from installed package metadata so there is no second
# hardcoded literal to drift out of sync with pyproject.toml.
try:
from importlib.metadata import PackageNotFoundError, version

try:
__version__ = version("wtcraft")
except PackageNotFoundError:
__version__ = "0.0.0+source"
except ImportError: # Python < 3.8
__version__ = "0.0.0+source"
14 changes: 14 additions & 0 deletions src/wtcraft/_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,20 @@ def main() -> None:
env = os.environ.copy()
env["WTCRAFT_TEMPLATE_DIR"] = tmpl_dir

# Stamp the resolved package version so the shell reports it even when no
# manifest sits beside the installed script (the pip/pipx layout). The value
# comes from the installed package metadata, the single source of truth.
if "WTCRAFT_VERSION" not in env:
try:
from importlib.metadata import PackageNotFoundError, version

try:
env["WTCRAFT_VERSION"] = version("wtcraft")
except PackageNotFoundError:
pass
except ImportError: # Python < 3.8: leave it to the shell's fallback
pass

bash = shutil.which("bash") or r"C:\Program Files\Git\bin\bash.exe"
os.execve(bash, [bash, shell_path] + sys.argv[1:], env)

Expand Down
29 changes: 29 additions & 0 deletions tests/e2e_version.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/usr/bin/env bash
#
# Version resolution: env stamp wins, in-repo reads the manifest, and a
# manifest-less install degrades to "unknown" instead of erroring.
#
source "$(dirname "${BASH_SOURCE[0]}")/framework.sh"

fail() { echo "FAIL: $*" >&2; exit 1; }

# 1. Installer-stamped WTCRAFT_VERSION wins.
out="$(WTCRAFT_VERSION="9.9.9-test" bash "$CLI" --version)"
[ "$out" = "9.9.9-test" ] || fail "env stamp: expected 9.9.9-test, got '$out'"

# 2. In-repo (no env): reads a real manifest version, never "unknown".
out="$(env -u WTCRAFT_VERSION bash "$CLI" --version)"
case "$out" in
unknown | "") fail "in-repo --version should read a manifest, got '$out'" ;;
esac

# 3. Manifest-less install (script copied away from its manifests, no env):
# degrades to "unknown" cleanly. Mirrors the brew/pip-without-stamp layout.
base="$(mktemp -d)"
mkdir -p "${base}/sub"
cp "$CLI" "${base}/sub/wtcraft"
out="$(env -u WTCRAFT_VERSION bash "${base}/sub/wtcraft" --version)"
rm -rf "$base"
[ "$out" = "unknown" ] || fail "manifest-less --version should be 'unknown', got '$out'"

echo "Version resolution tests passed."
1 change: 1 addition & 0 deletions tests/run_all.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ bash "${SCRIPT_DIR}/unit_awk.sh"
bash "${SCRIPT_DIR}/e2e_init_patch.sh"
bash "${SCRIPT_DIR}/e2e_lifecycle.sh"
bash "${SCRIPT_DIR}/e2e_doctor_migrate.sh"
bash "${SCRIPT_DIR}/e2e_version.sh"

# Integration tests require npm and python3 (skip gracefully if unavailable)
if command -v npm >/dev/null 2>&1 && command -v python3 >/dev/null 2>&1; then
Expand Down