Skip to content

Commit 1643a5c

Browse files
authored
build(just): split recipes into cross-platform scripts
- Move just recipe bodies into platform-specific scripts - Add shell and PowerShell helper scripts for build workflows - Preserve release install/checksum and Cargo.lock rollback semantics
1 parent c31f7b1 commit 1643a5c

14 files changed

Lines changed: 628 additions & 203 deletions

.gitattributes

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
*.sh text eol=lf
2+
*.ps1 text eol=crlf

justfile

Lines changed: 34 additions & 203 deletions
Original file line numberDiff line numberDiff line change
@@ -1,268 +1,99 @@
11
# Default: list available recipes
2+
set windows-shell := ["powershell.exe", "-NoLogo", "-NoProfile", "-ExecutionPolicy", "Bypass", "-Command"]
3+
4+
cargo_script := if os_family() == "windows" { "powershell.exe -NoLogo -NoProfile -ExecutionPolicy Bypass -File scripts/just/cargo.ps1" } else { "bash scripts/just/cargo.sh" }
5+
build_script := if os_family() == "windows" { "powershell.exe -NoLogo -NoProfile -ExecutionPolicy Bypass -File scripts/just/build.ps1" } else { "bash scripts/just/build.sh" }
6+
install_script := if os_family() == "windows" { "powershell.exe -NoLogo -NoProfile -ExecutionPolicy Bypass -File scripts/just/install.ps1" } else { "bash scripts/just/install.sh" }
7+
migration_check_script := if os_family() == "windows" { "powershell.exe -NoLogo -NoProfile -ExecutionPolicy Bypass -File scripts/migration/check-immutability.ps1" } else { "bash scripts/migration/check-immutability.sh" }
8+
migration_check_test_script := if os_family() == "windows" { "powershell.exe -NoLogo -NoProfile -ExecutionPolicy Bypass -File scripts/migration/check-immutability.test.ps1" } else { "bash scripts/migration/check-immutability.test.sh" }
9+
auto_commit_script := if os_family() == "windows" { "powershell.exe -NoLogo -NoProfile -ExecutionPolicy Bypass -File scripts/just/auto-commit-fixes.ps1" } else { "bash scripts/just/auto-commit-fixes.sh" }
10+
update_aionrs_script := if os_family() == "windows" { "powershell.exe -NoLogo -NoProfile -ExecutionPolicy Bypass -File scripts/just/update-aionrs.ps1" } else { "bash scripts/just/update-aionrs.sh" }
11+
cat_config_script := if os_family() == "windows" { "powershell.exe -NoLogo -NoProfile -ExecutionPolicy Bypass -File scripts/just/cat-config.ps1" } else { "bash scripts/just/cat-config.sh" }
12+
213
default:
314
@just --list
415

516
# Enable pre-commit hooks (run once after clone)
617
setup:
718
git config core.hooksPath .githooks
8-
@echo "Git hooks enabled"
19+
@echo "Git hooks enabled"
920

1021
# Run cargo with optional local aionrs SDK patches.
1122
_cargo *ARGS:
12-
#!/usr/bin/env bash
13-
set -euo pipefail
14-
15-
restore_cargo_lock=false
16-
cargo_lock_snapshot=""
17-
cargo_config_file=".cargo/config.toml"
18-
cargo_config_snapshot=""
19-
cargo_config_created=false
20-
aionrs_root=""
21-
22-
restore_local_state() {
23-
local status=$?
24-
25-
if [[ -n "$cargo_lock_snapshot" && -f "$cargo_lock_snapshot" ]]; then
26-
if [[ "$restore_cargo_lock" == "true" || "$status" -ne 0 ]]; then
27-
cp "$cargo_lock_snapshot" Cargo.lock || status=$?
28-
fi
29-
fi
30-
if [[ -n "$cargo_lock_snapshot" ]]; then
31-
rm -f "$cargo_lock_snapshot"
32-
fi
33-
34-
if [[ -n "$cargo_config_snapshot" && -f "$cargo_config_snapshot" ]]; then
35-
cp "$cargo_config_snapshot" "$cargo_config_file" || status=$?
36-
rm -f "$cargo_config_snapshot"
37-
elif [[ "$cargo_config_created" == "true" ]]; then
38-
rm -f "$cargo_config_file"
39-
rmdir .cargo 2>/dev/null || true
40-
fi
41-
42-
return "$status"
43-
}
44-
trap restore_local_state EXIT
45-
46-
verify_local_aionrs_patch() {
47-
local crate expected_path pkgid
48-
for crate in "${crates[@]}"; do
49-
expected_path="$aionrs_root/crates/$crate"
50-
pkgid=$(cargo pkgid -p "$crate")
51-
52-
if ! python3 -c 'import sys; from pathlib import Path; from urllib.parse import unquote, urlparse; pkgid=sys.argv[1]; expected=str(Path(sys.argv[2]).resolve()); ok=pkgid.startswith("path+file://") and str(Path(unquote(urlparse(pkgid[len("path+"):]).path)).resolve()) == expected; sys.exit(0 if ok else 1)' "$pkgid" "$expected_path"
53-
then
54-
echo "AIONRS patch was not used for $crate." >&2
55-
echo " resolved: $pkgid" >&2
56-
echo " expected: $expected_path" >&2
57-
exit 1
58-
fi
59-
done
60-
}
61-
62-
if [[ -n "${AIONRS:-}" ]]; then
63-
if [[ ! -d "$AIONRS" ]]; then
64-
echo "AIONRS does not exist or is not a directory: $AIONRS" >&2
65-
exit 1
66-
fi
67-
68-
aionrs_root=$(cd "$AIONRS" && pwd -P)
69-
crates=(
70-
aion-agent
71-
aion-compact
72-
aion-config
73-
aion-mcp
74-
aion-memory
75-
aion-process
76-
aion-protocol
77-
aion-providers
78-
aion-skills
79-
aion-tools
80-
aion-types
81-
)
82-
83-
patch_config=$(mktemp)
84-
{
85-
echo
86-
echo "[patch.'https://github.com/iOfficeAI/aionrs.git']"
87-
} > "$patch_config"
88-
89-
for crate in "${crates[@]}"; do
90-
crate_dir="$aionrs_root/crates/$crate"
91-
if [[ ! -f "$crate_dir/Cargo.toml" ]]; then
92-
echo "AIONRS is missing $crate: $crate_dir/Cargo.toml" >&2
93-
exit 1
94-
fi
95-
96-
toml_path=${crate_dir//\\/\\\\}
97-
toml_path=${toml_path//\"/\\\"}
98-
echo "$crate = { path = \"$toml_path\" }" >> "$patch_config"
99-
done
100-
101-
mkdir -p .cargo
102-
if [[ -f "$cargo_config_file" ]]; then
103-
cargo_config_snapshot=$(mktemp)
104-
cp "$cargo_config_file" "$cargo_config_snapshot"
105-
else
106-
cargo_config_created=true
107-
fi
108-
cat "$patch_config" >> "$cargo_config_file"
109-
rm -f "$patch_config"
110-
111-
echo "Using local aionrs SDK: $aionrs_root" >&2
112-
113-
if [[ -f Cargo.lock ]]; then
114-
cargo_lock_snapshot=$(mktemp)
115-
cp Cargo.lock "$cargo_lock_snapshot"
116-
117-
if git diff --quiet -- Cargo.lock && git diff --cached --quiet -- Cargo.lock; then
118-
restore_cargo_lock=true
119-
else
120-
echo "Cargo.lock already has changes; leaving successful AIONRS lockfile updates in place." >&2
121-
fi
122-
fi
123-
124-
echo "Resolving Cargo.lock against local aionrs SDK" >&2
125-
update_args=()
126-
for crate in "${crates[@]}"; do
127-
update_args+=(-p "$crate")
128-
done
129-
cargo update "${update_args[@]}"
130-
verify_local_aionrs_patch
131-
fi
132-
133-
args=({{ARGS}})
134-
135-
set +e
136-
cargo "${args[@]}"
137-
status=$?
138-
set -e
139-
exit "$status"
23+
@{{cargo_script}} {{ARGS}}
14024

141-
# Build in release mode and install to ~/.cargo/bin
25+
# Build in release mode and install to cargo bin
14226
# Use `just build --force` to skip cache check
14327
build *FLAGS: lint-fix fmt
144-
#!/usr/bin/env bash
145-
set -euo pipefail
146-
just _cargo build --release
147-
new_sum=$(shasum -a 256 target/release/aioncore | cut -d' ' -f1)
148-
force=false
149-
for flag in {{FLAGS}}; do
150-
if [[ "$flag" == "--force" || "$flag" == "-f" ]]; then
151-
force=true
152-
fi
153-
done
154-
old_sum=""
155-
if [[ -f target/.build-sum ]] && [[ "$force" == "false" ]]; then
156-
old_sum=$(cat target/.build-sum)
157-
fi
158-
if [[ "$new_sum" == "$old_sum" ]]; then
159-
echo -e "\n⏭️ Binary unchanged — skipping install (sha256: ${new_sum:0:16}…)"
160-
else
161-
cp target/release/aioncore ~/.cargo/bin/
162-
codesign --force --sign - ~/.cargo/bin/aioncore
163-
echo "$new_sum" > target/.build-sum
164-
echo -e "\n✅ Build complete — sha256: ${new_sum:0:16}"
165-
fi
28+
@{{build_script}} release {{FLAGS}}
16629

16730
# Build in debug mode
16831
# Use `just build-debug --force` to skip cache check
16932
build-debug *FLAGS:
170-
#!/usr/bin/env bash
171-
set -euo pipefail
172-
just _cargo build
173-
new_sum=$(shasum -a 256 target/debug/aioncore | cut -d' ' -f1)
174-
force=false
175-
for flag in {{FLAGS}}; do
176-
if [[ "$flag" == "--force" || "$flag" == "-f" ]]; then
177-
force=true
178-
fi
179-
done
180-
old_sum=""
181-
if [[ -f target/.build-debug-sum ]] && [[ "$force" == "false" ]]; then
182-
old_sum=$(cat target/.build-debug-sum)
183-
fi
184-
if [[ "$new_sum" == "$old_sum" ]]; then
185-
echo -e "\n⏭️ Debug binary unchanged (sha256: ${new_sum:0:16}…)"
186-
else
187-
echo "$new_sum" > target/.build-debug-sum
188-
echo -e "\n✅ Debug build complete — sha256: ${new_sum:0:16}"
189-
fi
33+
@{{build_script}} debug {{FLAGS}}
19034

19135
install:
192-
cp target/release/aioncore ~/.cargo/bin/
193-
codesign --force --sign - ~/.cargo/bin/aioncore
36+
@{{install_script}} release
19437

19538
# Run all tests
19639
test:
197-
just _cargo nextest run --workspace
40+
@just _cargo nextest run --workspace
19841

19942
# Ensure already-shipped database migrations stay immutable
20043
migration-check:
201-
scripts/check-migration-immutability.sh
44+
@{{migration_check_script}}
20245

20346
# Test the migration immutability guard itself
20447
migration-check-test:
205-
scripts/check-migration-immutability.test.sh
48+
@{{migration_check_test_script}}
20649

20750
# Lint (warnings = errors)
20851
lint:
209-
just _cargo clippy --workspace -- -D warnings
52+
@just _cargo clippy --workspace -- -D warnings
21053

21154
lint-fix:
212-
just _cargo fix --allow-dirty --allow-staged
213-
just _cargo clippy --fix --workspace --allow-dirty --allow-staged -- -D warnings
55+
@just _cargo fix --allow-dirty --allow-staged
56+
@just _cargo clippy --fix --workspace --allow-dirty --allow-staged -- -D warnings
21457

21558
# Format code
21659
fmt:
217-
cargo fmt --all
60+
@cargo fmt --all
21861

21962
# Check formatting (CI)
22063
fmt-check:
221-
cargo fmt --all -- --check
64+
@cargo fmt --all -- --check
22265

22366
# Lint + format check + migration check + test
22467
check: migration-check lint fmt-check test
22568

22669
# Run the server (debug)
22770
run *ARGS:
228-
just _cargo run --bin aioncore -- {{ARGS}}
71+
@just _cargo run --bin aioncore -- {{ARGS}}
22972

23073
# Run the server (release)
23174
run-release *ARGS:
232-
just _cargo run --release --bin aioncore -- {{ARGS}}
75+
@just _cargo run --release --bin aioncore -- {{ARGS}}
23376

23477
# Pre-push gate: migration check, format, lint, auto-commit fixes, test, then push
23578
push *ARGS: migration-check lint-fix fmt _auto-commit-fixes test
236-
git push {{ ARGS }}
79+
git push {{ARGS}}
23780

23881
# Auto-commit any formatting/lint fixes if there are changes
23982
_auto-commit-fixes:
240-
#!/usr/bin/env bash
241-
if [ -n "$(git diff --name-only)" ]; then
242-
git add -A
243-
git commit -m "chore: apply auto-fixes (fmt + clippy)"
244-
fi
83+
@{{auto_commit_script}}
24584

24685
# Update aionrs dependency (e.g. just update-aionrs or just update-aionrs v0.1.19)
24786
update-aionrs *TAG:
248-
#!/usr/bin/env bash
249-
set -euo pipefail
250-
tag="{{ TAG }}"
251-
if [ -z "$tag" ]; then
252-
tag=$(git ls-remote --tags https://github.com/iOfficeAI/aionrs.git | awk -F/ '{print $NF}' | grep -v '\\^{}' | sort -V | tail -1)
253-
echo "Using latest tag: $tag"
254-
fi
255-
sed -i '' "s|git = \"https://github.com/iOfficeAI/aionrs.git\", tag = \"[^\"]*\"|git = \"https://github.com/iOfficeAI/aionrs.git\", tag = \"$tag\"|g" Cargo.toml
256-
cargo check --workspace
87+
@{{update_aionrs_script}} {{TAG}}
25788

25889
# Security audit
25990
audit:
260-
cargo audit
91+
@cargo audit
26192

26293
# Clean build artifacts
26394
clean:
264-
cargo clean
95+
@cargo clean
26596

266-
# Decode dev config and copy to clipboard
97+
# Decode dev config and copy to clipboard when possible
26798
cat-config:
268-
@base64 -D -i ~/.aionui-config-dev/aionui-config.txt | python3 -c 'import sys, urllib.parse; print(urllib.parse.unquote(sys.stdin.read()))' | pbcopy
99+
@{{cat_config_script}}

scripts/just/auto-commit-fixes.ps1

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
$ErrorActionPreference = "Stop"
2+
3+
$changed = git diff --name-only
4+
if ($LASTEXITCODE -ne 0) {
5+
exit $LASTEXITCODE
6+
}
7+
8+
if (-not [string]::IsNullOrWhiteSpace(($changed -join "`n"))) {
9+
git add -A
10+
if ($LASTEXITCODE -ne 0) {
11+
exit $LASTEXITCODE
12+
}
13+
14+
git commit -m "chore: apply auto-fixes (fmt + clippy)"
15+
exit $LASTEXITCODE
16+
}

scripts/just/auto-commit-fixes.sh

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
if [[ -n "$(git diff --name-only)" ]]; then
5+
git add -A
6+
git commit -m "chore: apply auto-fixes (fmt + clippy)"
7+
fi

scripts/just/build.ps1

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
param(
2+
[ValidateSet("release", "debug")]
3+
[string] $Mode = "release",
4+
[Parameter(ValueFromRemainingArguments = $true)]
5+
[string[]] $Flags
6+
)
7+
8+
$ErrorActionPreference = "Stop"
9+
10+
function Invoke-Native {
11+
param(
12+
[Parameter(Mandatory = $true)]
13+
[string] $Command,
14+
[string[]] $Arguments = @()
15+
)
16+
17+
& $Command @Arguments
18+
if ($LASTEXITCODE -ne 0) {
19+
exit $LASTEXITCODE
20+
}
21+
}
22+
23+
$force = $Flags -contains "--force" -or $Flags -contains "-f"
24+
25+
if ($Mode -eq "release") {
26+
Invoke-Native "just" @("_cargo", "build", "--release")
27+
$binary = "target/release/aioncore.exe"
28+
$sumFile = "target/.build-sum"
29+
$label = "Build"
30+
} else {
31+
Invoke-Native "just" @("_cargo", "build")
32+
$binary = "target/debug/aioncore.exe"
33+
$sumFile = "target/.build-debug-sum"
34+
$label = "Debug build"
35+
}
36+
37+
$newSum = (Get-FileHash -Algorithm SHA256 -LiteralPath $binary).Hash.ToLowerInvariant()
38+
$oldSum = ""
39+
if ((Test-Path -LiteralPath $sumFile -PathType Leaf) -and -not $force) {
40+
$oldSum = (Get-Content -LiteralPath $sumFile -Raw).Trim()
41+
}
42+
43+
if ($newSum -eq $oldSum) {
44+
Write-Output ""
45+
Write-Output "$label unchanged (sha256: $($newSum.Substring(0, 16)))"
46+
} else {
47+
if ($Mode -eq "release") {
48+
Invoke-Native "powershell.exe" @("-NoLogo", "-NoProfile", "-ExecutionPolicy", "Bypass", "-File", "scripts/just/install.ps1", "release")
49+
}
50+
Set-Content -LiteralPath $sumFile -Value $newSum -NoNewline
51+
Write-Output ""
52+
Write-Output "$label complete (sha256: $($newSum.Substring(0, 16)))"
53+
}

0 commit comments

Comments
 (0)