mirror of
https://github.com/italicsjenga/agb.git
synced 2025-01-11 09:31:34 +11:00
Merge pull request #315 from gwilymk/release-script-in-rust
Release script in rust
This commit is contained in:
commit
416f238062
|
@ -20,7 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
- Fixed the fast magnitude function in agb_fixnum. This is also used in fast_normalise. Previously only worked for positive (x, y).
|
- Fixed the fast magnitude function in agb_fixnum. This is also used in fast_normalise. Previously only worked for positive (x, y).
|
||||||
- Fixed formatting of fixed point numbers in the range (-1, 0), which previously appeared positive.
|
- Fixed formatting of fixed point numbers in the range (-1, 0), which previously appeared positive.
|
||||||
|
|
||||||
## Changed
|
### Changed
|
||||||
- `testing` is now a default feature, so you no longer need to add a separate `dev-dependencies` line for `agb` in order to enable unit tests for your project.
|
- `testing` is now a default feature, so you no longer need to add a separate `dev-dependencies` line for `agb` in order to enable unit tests for your project.
|
||||||
|
|
||||||
## [0.11.1] - 2022/08/02
|
## [0.11.1] - 2022/08/02
|
||||||
|
|
5
justfile
5
justfile
|
@ -68,8 +68,11 @@ update-linker-scripts:
|
||||||
|
|
||||||
publish: (_run-tool "publish")
|
publish: (_run-tool "publish")
|
||||||
|
|
||||||
|
release +args: (_run-tool "release" args)
|
||||||
|
|
||||||
_run-tool +tool:
|
_run-tool +tool:
|
||||||
cargo run --manifest-path "{{justfile_directory() + "/tools/Cargo.toml"}}" -- {{tool}}
|
(cd tools && cargo build)
|
||||||
|
"$CARGO_TARGET_DIR/debug/tools" {{tool}}
|
||||||
|
|
||||||
_build-rom folder name:
|
_build-rom folder name:
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
96
release.sh
96
release.sh
|
@ -1,96 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# Fail if any command fails
|
|
||||||
set -e
|
|
||||||
set -x
|
|
||||||
|
|
||||||
VERSION=$1
|
|
||||||
NO_COMMIT=$2
|
|
||||||
|
|
||||||
# Sanity check that we actually have a version
|
|
||||||
if [ "$VERSION" = "" ]; then
|
|
||||||
echo "Usage $0 <version> [--no-commit]"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check the format of version
|
|
||||||
if echo "$VERSION" | grep -q -Ev "^[0-9]+\.[0-9]+\.[0-9]+$"; then
|
|
||||||
echo "Version must be of the form x.y.z, got $VERSION"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check if no commit option is valid
|
|
||||||
if [ ! "$NO_COMMIT" = "" ] && [ ! "$NO_COMMIT" = "--no-commit" ]; then
|
|
||||||
echo "Must pass either no last argument or --no-commit"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
function maybe_git() {
|
|
||||||
if [ "$NO_COMMIT" = "--no-commit" ]; then
|
|
||||||
echo "Would run: git $*"
|
|
||||||
else
|
|
||||||
git "$@"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Check that no out-standing changes in git
|
|
||||||
if [ "$NO_COMMIT" = "" ] && [ -n "$(git status --porcelain)" ]; then
|
|
||||||
echo "Uncommitted changes, please commit first"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check that we are in the master branch, but only if actually committing
|
|
||||||
if [ ! "$NO_COMMIT" = "--no-commit" ] && [ "$(git symbolic-ref --short HEAD)" != "master" ]; then
|
|
||||||
echo "You must be in the master branch before releasing"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
TAGNAME="v$VERSION"
|
|
||||||
|
|
||||||
for PROJECT_TOML_FILE in agb/Cargo.toml agb-*/Cargo.toml; do
|
|
||||||
DIRECTORY=$(dirname "$PROJECT_TOML_FILE")
|
|
||||||
|
|
||||||
# Update the version in Cargo.toml
|
|
||||||
sed -i -e "s/^version = \".*\"/version = \"$VERSION\"/" "$DIRECTORY/Cargo.toml"
|
|
||||||
|
|
||||||
# Also update the lock file
|
|
||||||
(cd "$DIRECTORY" && cargo update)
|
|
||||||
|
|
||||||
if [ "$DIRECTORY" = "agb" ]; then
|
|
||||||
# also update the agb version in the template and the examples
|
|
||||||
sed -i -e "s/^agb = \".*\"/agb = \"$VERSION\"/" template/Cargo.toml
|
|
||||||
|
|
||||||
for EXAMPLE_TOML_FILE in examples/*/Cargo.toml book/games/*/Cargo.toml template/Cargo.toml; do
|
|
||||||
EXAMPLE_DIR=$(dirname "$EXAMPLE_TOML_FILE")
|
|
||||||
sed -E -i -e "/agb =/ s/version = \"[^\"]+\"/version = \"$VERSION\"/" "$EXAMPLE_DIR/Cargo.toml"
|
|
||||||
done
|
|
||||||
for EXAMPLE_TOML_FILE in examples/*/Cargo.toml book/games/*/Cargo.toml; do
|
|
||||||
EXAMPLE_DIR=$(dirname "$EXAMPLE_TOML_FILE")
|
|
||||||
(cd "$EXAMPLE_DIR" && cargo update)
|
|
||||||
done
|
|
||||||
else
|
|
||||||
PROJECT_NAME_WITH_UNDERSCORES=$(echo -n "$DIRECTORY" | tr - _)
|
|
||||||
|
|
||||||
for CARGO_TOML_FILE in agb-*/Cargo.toml agb/Cargo.toml examples/*/Cargo.toml book/games/*/Cargo.toml; do
|
|
||||||
sed -i -E -e "s/($PROJECT_NAME_WITH_UNDERSCORES = .*version = \")[^\"]+(\".*)/\1$VERSION\2/" "$CARGO_TOML_FILE"
|
|
||||||
(cd "$(dirname "$CARGO_TOML_FILE")" && cargo generate-lockfile)
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
# Sanity check to make sure the build works
|
|
||||||
just ci
|
|
||||||
|
|
||||||
for EXAMPLE_TOML_FILE in examples/*/Cargo.toml book/games/*/Cargo.toml; do
|
|
||||||
EXAMPLE_DIR=$(dirname "$EXAMPLE_TOML_FILE")
|
|
||||||
(cd "$EXAMPLE_DIR" && cargo check --release)
|
|
||||||
done
|
|
||||||
|
|
||||||
# Commit the Cargo.toml changes
|
|
||||||
maybe_git commit -am "Release v$VERSION"
|
|
||||||
|
|
||||||
# Tag the version
|
|
||||||
maybe_git tag -a "$TAGNAME" -m "v$VERSION"
|
|
||||||
|
|
||||||
echo "Done! Push with"
|
|
||||||
echo "git push --atomic origin master $TAGNAME"
|
|
212
tools/Cargo.lock
generated
212
tools/Cargo.lock
generated
|
@ -2,6 +2,15 @@
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "android_system_properties"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "atty"
|
name = "atty"
|
||||||
version = "0.2.14"
|
version = "0.2.14"
|
||||||
|
@ -25,12 +34,39 @@ version = "1.3.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bumpalo"
|
||||||
|
version = "3.11.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c1ad822118d20d2c234f427000d5acc36eabe1e29a348c89b63dd60b13f28e5d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bytes"
|
name = "bytes"
|
||||||
version = "1.2.1"
|
version = "1.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db"
|
checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "chrono"
|
||||||
|
version = "0.4.22"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bfd4d1b31faaa3a89d7934dbded3111da0d2ef28e3ebccdb4f0179f5929d1ef1"
|
||||||
|
dependencies = [
|
||||||
|
"iana-time-zone",
|
||||||
|
"js-sys",
|
||||||
|
"num-integer",
|
||||||
|
"num-traits",
|
||||||
|
"time",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "4.0.7"
|
version = "4.0.7"
|
||||||
|
@ -63,12 +99,24 @@ dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "core-foundation-sys"
|
||||||
|
version = "0.8.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "either"
|
name = "either"
|
||||||
version = "1.8.0"
|
version = "1.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797"
|
checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "glob"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "hashbrown"
|
||||||
version = "0.12.3"
|
version = "0.12.3"
|
||||||
|
@ -84,6 +132,19 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "iana-time-zone"
|
||||||
|
version = "0.1.50"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fd911b35d940d2bd0bea0f9100068e5b97b51a1cbe13d13382f132e0365257a0"
|
||||||
|
dependencies = [
|
||||||
|
"android_system_properties",
|
||||||
|
"core-foundation-sys",
|
||||||
|
"js-sys",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "indexmap"
|
name = "indexmap"
|
||||||
version = "1.9.1"
|
version = "1.9.1"
|
||||||
|
@ -103,30 +164,102 @@ dependencies = [
|
||||||
"either",
|
"either",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "js-sys"
|
||||||
|
version = "0.3.60"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47"
|
||||||
|
dependencies = [
|
||||||
|
"wasm-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.134"
|
version = "0.2.134"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "329c933548736bc49fd575ee68c89e8be4d260064184389a5b77517cddd99ffb"
|
checksum = "329c933548736bc49fd575ee68c89e8be4d260064184389a5b77517cddd99ffb"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "log"
|
||||||
|
version = "0.4.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
version = "2.5.0"
|
version = "2.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-integer"
|
||||||
|
version = "0.1.45"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
"num-traits",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-traits"
|
||||||
|
version = "0.2.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "once_cell"
|
||||||
|
version = "1.15.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e82dad04139b71a90c080c8463fe0dc7902db5192d939bd0950f074d014339e1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "os_str_bytes"
|
name = "os_str_bytes"
|
||||||
version = "6.3.0"
|
version = "6.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9ff7415e9ae3fff1225851df9e0d9e4e5479f947619774677a63572e55e80eff"
|
checksum = "9ff7415e9ae3fff1225851df9e0d9e4e5479f947619774677a63572e55e80eff"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.46"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "94e2ef8dbfc347b10c094890f778ee2e36ca9bb4262e86dc99cd217e35f3470b"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.21"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strsim"
|
name = "strsim"
|
||||||
version = "0.10.0"
|
version = "0.10.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "1.0.101"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e90cde112c4b9690b8cbe810cba9ddd8bc1d7472e2cae317b69e9438c1cba7d2"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "termcolor"
|
name = "termcolor"
|
||||||
version = "1.1.3"
|
version = "1.1.3"
|
||||||
|
@ -136,6 +269,17 @@ dependencies = [
|
||||||
"winapi-util",
|
"winapi-util",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "time"
|
||||||
|
version = "0.1.44"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"wasi",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml_edit"
|
name = "toml_edit"
|
||||||
version = "0.14.4"
|
version = "0.14.4"
|
||||||
|
@ -151,10 +295,78 @@ dependencies = [
|
||||||
name = "tools"
|
name = "tools"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"chrono",
|
||||||
"clap",
|
"clap",
|
||||||
|
"glob",
|
||||||
"toml_edit",
|
"toml_edit",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-ident"
|
||||||
|
version = "1.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dcc811dc4066ac62f84f11307873c4850cb653bfa9b1719cee2bd2204a4bc5dd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasi"
|
||||||
|
version = "0.10.0+wasi-snapshot-preview1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen"
|
||||||
|
version = "0.2.83"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"wasm-bindgen-macro",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-backend"
|
||||||
|
version = "0.2.83"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142"
|
||||||
|
dependencies = [
|
||||||
|
"bumpalo",
|
||||||
|
"log",
|
||||||
|
"once_cell",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"wasm-bindgen-shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-macro"
|
||||||
|
version = "0.2.83"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810"
|
||||||
|
dependencies = [
|
||||||
|
"quote",
|
||||||
|
"wasm-bindgen-macro-support",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-macro-support"
|
||||||
|
version = "0.2.83"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"wasm-bindgen-backend",
|
||||||
|
"wasm-bindgen-shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-shared"
|
||||||
|
version = "0.2.83"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi"
|
name = "winapi"
|
||||||
version = "0.3.9"
|
version = "0.3.9"
|
||||||
|
|
|
@ -8,3 +8,5 @@ edition = "2021"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = "4"
|
clap = "4"
|
||||||
toml_edit = "0.14"
|
toml_edit = "0.14"
|
||||||
|
glob = "0.3"
|
||||||
|
chrono = "0.4"
|
||||||
|
|
|
@ -2,19 +2,35 @@
|
||||||
use clap::Command;
|
use clap::Command;
|
||||||
|
|
||||||
mod publish;
|
mod publish;
|
||||||
|
mod release;
|
||||||
|
mod utils;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum Error {
|
||||||
|
PublishError(publish::Error),
|
||||||
|
ReleaseError(release::Error),
|
||||||
|
}
|
||||||
|
|
||||||
fn cli() -> Command {
|
fn cli() -> Command {
|
||||||
Command::new("Agb tools")
|
Command::new("Agb tools")
|
||||||
.subcommand_required(true)
|
.subcommand_required(true)
|
||||||
.arg_required_else_help(true)
|
.arg_required_else_help(true)
|
||||||
.subcommand(publish::command())
|
.subcommand(publish::command())
|
||||||
|
.subcommand(release::command())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let matches = cli().get_matches();
|
let matches = cli().get_matches();
|
||||||
|
|
||||||
let result = match matches.subcommand() {
|
let result = match matches.subcommand() {
|
||||||
Some(("publish", arg_matches)) => publish::publish(arg_matches),
|
Some(("publish", arg_matches)) => {
|
||||||
|
publish::publish(arg_matches).map_err(Error::PublishError)
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(("release", arg_matches)) => {
|
||||||
|
release::release(arg_matches).map_err(Error::ReleaseError)
|
||||||
|
}
|
||||||
|
|
||||||
_ => unreachable!("Exhausted list of subcommands and subcommand_required prevents `None`"),
|
_ => unreachable!("Exhausted list of subcommands and subcommand_required prevents `None`"),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
use clap::{Arg, ArgAction, ArgMatches};
|
use clap::{Arg, ArgAction, ArgMatches};
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::Path;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
use std::thread;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use std::{env, thread};
|
|
||||||
use toml_edit::Document;
|
use toml_edit::Document;
|
||||||
|
|
||||||
|
use crate::utils::*;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
FindRootDirectory,
|
FindRootDirectory,
|
||||||
|
@ -31,7 +33,7 @@ pub fn command() -> clap::Command {
|
||||||
pub fn publish(matches: &ArgMatches) -> Result<(), Error> {
|
pub fn publish(matches: &ArgMatches) -> Result<(), Error> {
|
||||||
let dry_run = matches.get_one::<bool>("Dry run").expect("defined by clap");
|
let dry_run = matches.get_one::<bool>("Dry run").expect("defined by clap");
|
||||||
|
|
||||||
let root_directory = find_agb_root_directory()?;
|
let root_directory = find_agb_root_directory().map_err(|_| Error::FindRootDirectory)?;
|
||||||
|
|
||||||
let mut fully_published_crates: HashSet<String> = HashSet::new();
|
let mut fully_published_crates: HashSet<String> = HashSet::new();
|
||||||
let mut published_crates: HashSet<String> = HashSet::new();
|
let mut published_crates: HashSet<String> = HashSet::new();
|
||||||
|
@ -60,11 +62,12 @@ pub fn publish(matches: &ArgMatches) -> Result<(), Error> {
|
||||||
if *dry_run {
|
if *dry_run {
|
||||||
println!("Would execute cargo publish for {publishable_crate}");
|
println!("Would execute cargo publish for {publishable_crate}");
|
||||||
} else {
|
} else {
|
||||||
Command::new("cargo")
|
assert!(Command::new("cargo")
|
||||||
.arg("publish")
|
.arg("publish")
|
||||||
.current_dir(&root_directory.join(publishable_crate))
|
.current_dir(&root_directory.join(publishable_crate))
|
||||||
.spawn()
|
.status()
|
||||||
.map_err(|_| Error::PublishCrate)?;
|
.map_err(|_| Error::PublishCrate)?
|
||||||
|
.success());
|
||||||
}
|
}
|
||||||
|
|
||||||
published_crates.insert(publishable_crate.to_string());
|
published_crates.insert(publishable_crate.to_string());
|
||||||
|
@ -86,19 +89,6 @@ pub fn publish(matches: &ArgMatches) -> Result<(), Error> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_agb_root_directory() -> Result<PathBuf, Error> {
|
|
||||||
let mut current_path = env::current_dir().map_err(|_| Error::FindRootDirectory)?;
|
|
||||||
|
|
||||||
while !current_path.clone().join("justfile").exists() {
|
|
||||||
current_path = current_path
|
|
||||||
.parent()
|
|
||||||
.ok_or(Error::FindRootDirectory)?
|
|
||||||
.to_owned();
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(current_path)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn check_if_released(crate_to_publish: &str, expected_version: &str) -> Result<bool, Error> {
|
fn check_if_released(crate_to_publish: &str, expected_version: &str) -> Result<bool, Error> {
|
||||||
let url_to_poll = &get_url_to_poll(crate_to_publish);
|
let url_to_poll = &get_url_to_poll(crate_to_publish);
|
||||||
|
|
||||||
|
@ -220,16 +210,9 @@ mod test {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn should_find_root_directory() -> Result<(), Error> {
|
|
||||||
assert_ne!(find_agb_root_directory()?.to_string_lossy(), "");
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn should_read_version() -> Result<(), Error> {
|
fn should_read_version() -> Result<(), Error> {
|
||||||
let root_directory = find_agb_root_directory()?;
|
let root_directory = crate::utils::find_agb_root_directory().unwrap();
|
||||||
let my_version = read_cargo_toml_version(&root_directory.join("tools"))?;
|
let my_version = read_cargo_toml_version(&root_directory.join("tools"))?;
|
||||||
|
|
||||||
assert_eq!(my_version, "0.1.0");
|
assert_eq!(my_version, "0.1.0");
|
||||||
|
@ -238,7 +221,7 @@ mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn should_detect_dependencies() -> Result<(), Error> {
|
fn should_detect_dependencies() -> Result<(), Error> {
|
||||||
let root_directory = find_agb_root_directory()?;
|
let root_directory = crate::utils::find_agb_root_directory().unwrap();
|
||||||
let deps = get_agb_dependencies(&root_directory.join("agb"))?;
|
let deps = get_agb_dependencies(&root_directory.join("agb"))?;
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
|
305
tools/src/release.rs
Normal file
305
tools/src/release.rs
Normal file
|
@ -0,0 +1,305 @@
|
||||||
|
use std::{path::Path, process::Command};
|
||||||
|
|
||||||
|
use crate::utils::find_agb_root_directory;
|
||||||
|
|
||||||
|
pub fn command() -> clap::Command {
|
||||||
|
clap::Command::new("release")
|
||||||
|
.about("Prepares and commits the changes required to release agb")
|
||||||
|
.arg(
|
||||||
|
clap::Arg::new("version")
|
||||||
|
.required(true)
|
||||||
|
.help("New version to release")
|
||||||
|
.value_parser(version_parser),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
clap::Arg::new("Dry run")
|
||||||
|
.long("dry-run")
|
||||||
|
.help("Don't do anything with git (but does everything else)")
|
||||||
|
.action(clap::ArgAction::SetTrue),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn release(matches: &clap::ArgMatches) -> Result<(), Error> {
|
||||||
|
let dry_run = matches.get_one::<bool>("Dry run").expect("defined by clap");
|
||||||
|
let version = matches
|
||||||
|
.get_one::<Version>("version")
|
||||||
|
.expect("defined by clap");
|
||||||
|
|
||||||
|
let root_directory = find_agb_root_directory().map_err(|_| Error::FindRootDirectory)?;
|
||||||
|
|
||||||
|
// if not dry run, check that there are no out-standing changes in git
|
||||||
|
if !dry_run && !execute_git_command(&root_directory, &["status", "--porcelain"])?.is_empty() {
|
||||||
|
println!("Uncommitted changes, please commit first");
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that we are in the master branch
|
||||||
|
if !dry_run
|
||||||
|
&& execute_git_command(&root_directory, &["symbolic-ref", "--short", "HEAD"])? != "master"
|
||||||
|
{
|
||||||
|
println!("You must be on the master branch before releasing");
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
let project_toml_files = glob_many(&root_directory, &["agb-*/Cargo.toml"])?;
|
||||||
|
let agb_cargo_toml = root_directory.join("agb/Cargo.toml");
|
||||||
|
|
||||||
|
update_to_version(&root_directory, &agb_cargo_toml, version)?;
|
||||||
|
|
||||||
|
for toml_file in &project_toml_files {
|
||||||
|
update_to_version(&root_directory, toml_file, version)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert!(Command::new("just")
|
||||||
|
.arg("ci")
|
||||||
|
.current_dir(&root_directory)
|
||||||
|
.status()
|
||||||
|
.map_err(|_| Error::JustCiFailed)?
|
||||||
|
.success());
|
||||||
|
|
||||||
|
let changelog_text = update_changelog(&root_directory, version)?;
|
||||||
|
|
||||||
|
println!("Content of changelog:\n{changelog_text}");
|
||||||
|
|
||||||
|
if !dry_run {
|
||||||
|
execute_git_command(
|
||||||
|
&root_directory,
|
||||||
|
&["commit", "-am", &format!("Release v{version}")],
|
||||||
|
)?;
|
||||||
|
execute_git_command(
|
||||||
|
&root_directory,
|
||||||
|
&[
|
||||||
|
"tag",
|
||||||
|
"-a",
|
||||||
|
&version.to_string(),
|
||||||
|
"-m",
|
||||||
|
&format!("#v{version}\n{changelog_text}"),
|
||||||
|
],
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("Done! Push with");
|
||||||
|
println!("git push --atomic origin master v{version}");
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_to_version(
|
||||||
|
root_directory: &Path,
|
||||||
|
toml_file: &Path,
|
||||||
|
new_version: &Version,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
let directory_name = toml_file.parent().unwrap().file_name().unwrap();
|
||||||
|
let project_name = directory_name.to_string_lossy().replace('-', "_");
|
||||||
|
|
||||||
|
let toml_file_content = std::fs::read_to_string(toml_file).map_err(|_| Error::ReadTomlFile)?;
|
||||||
|
let mut cargo_toml = toml_file_content
|
||||||
|
.parse::<toml_edit::Document>()
|
||||||
|
.map_err(|_| Error::InvalidToml(toml_file.to_string_lossy().into_owned()))?;
|
||||||
|
|
||||||
|
let new_version = format!("{new_version}");
|
||||||
|
cargo_toml["package"]["version"] = toml_edit::value(&new_version);
|
||||||
|
|
||||||
|
std::fs::write(toml_file, cargo_toml.to_string()).map_err(|_| Error::WriteTomlFile)?;
|
||||||
|
|
||||||
|
for cargo_toml_file in glob_many(
|
||||||
|
root_directory,
|
||||||
|
&[
|
||||||
|
"agb-*/Cargo.toml",
|
||||||
|
"agb/Cargo.toml",
|
||||||
|
"examples/*/Cargo.toml",
|
||||||
|
"book/games/*/Cargo.toml",
|
||||||
|
"template/Cargo.toml",
|
||||||
|
],
|
||||||
|
)? {
|
||||||
|
let toml_file_content =
|
||||||
|
std::fs::read_to_string(&cargo_toml_file).map_err(|_| Error::ReadTomlFile)?;
|
||||||
|
let mut cargo_toml = toml_file_content
|
||||||
|
.parse::<toml_edit::Document>()
|
||||||
|
.map_err(|_| Error::InvalidToml(cargo_toml_file.to_string_lossy().into_owned()))?;
|
||||||
|
|
||||||
|
if let Some(this_dep) = cargo_toml["dependencies"].get_mut(&project_name) {
|
||||||
|
match this_dep {
|
||||||
|
toml_edit::Item::Value(s @ toml_edit::Value::String(_)) => {
|
||||||
|
*s = new_version.clone().into()
|
||||||
|
}
|
||||||
|
toml_edit::Item::Value(toml_edit::Value::InlineTable(t)) => {
|
||||||
|
t["version"] = new_version.clone().into()
|
||||||
|
}
|
||||||
|
toml_edit::Item::None => continue,
|
||||||
|
_ => {
|
||||||
|
return Err(Error::InvalidToml(format!(
|
||||||
|
"{:?} while seaching dependencies in {}",
|
||||||
|
this_dep,
|
||||||
|
cargo_toml_file.to_string_lossy()
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::fs::write(cargo_toml_file, cargo_toml.to_string())
|
||||||
|
.map_err(|_| Error::WriteTomlFile)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_changelog(root_directory: &Path, new_version: &Version) -> Result<String, Error> {
|
||||||
|
use chrono::Datelike;
|
||||||
|
|
||||||
|
let changelog_file = root_directory.join("CHANGELOG.md");
|
||||||
|
let changelog_content =
|
||||||
|
std::fs::read_to_string(&changelog_file).map_err(|_| Error::FailedToReadChangelog)?;
|
||||||
|
|
||||||
|
let today = chrono::Local::today();
|
||||||
|
let formatted_date = format!(
|
||||||
|
"{:04}/{:02}/{:02}",
|
||||||
|
today.year(),
|
||||||
|
today.month(),
|
||||||
|
today.day()
|
||||||
|
);
|
||||||
|
|
||||||
|
const UNRELEASED_HEADER: &str = "## [Unreleased]";
|
||||||
|
|
||||||
|
let unreleased_bit_start = changelog_content
|
||||||
|
.find(UNRELEASED_HEADER)
|
||||||
|
.ok_or(Error::FailedToParseChangelog)?
|
||||||
|
+ UNRELEASED_HEADER.len();
|
||||||
|
let unreleased_bit_end = changelog_content[unreleased_bit_start..]
|
||||||
|
.find("\n## [") // the start of the next entry
|
||||||
|
.ok_or(Error::FailedToParseChangelog)?
|
||||||
|
+ unreleased_bit_start;
|
||||||
|
|
||||||
|
let change_content = changelog_content[unreleased_bit_start..unreleased_bit_end].to_owned();
|
||||||
|
|
||||||
|
let changelog_content = changelog_content.replacen(
|
||||||
|
UNRELEASED_HEADER,
|
||||||
|
&format!("{UNRELEASED_HEADER}\n\n## [{new_version}] - {formatted_date}"),
|
||||||
|
1,
|
||||||
|
);
|
||||||
|
|
||||||
|
std::fs::write(&changelog_file, &changelog_content)
|
||||||
|
.map_err(|_| Error::FailedToWriteChangelog)?;
|
||||||
|
|
||||||
|
Ok(change_content)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn execute_git_command(root_directory: &Path, args: &[&str]) -> Result<String, Error> {
|
||||||
|
let git_cmd = Command::new("git")
|
||||||
|
.args(args)
|
||||||
|
.current_dir(root_directory)
|
||||||
|
.output()
|
||||||
|
.map_err(|_| Error::Git("Failed to run command"))?;
|
||||||
|
|
||||||
|
assert!(git_cmd.status.success());
|
||||||
|
|
||||||
|
String::from_utf8(git_cmd.stdout).map_err(|_| Error::Git("Output not utf-8"))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn glob_many(root_directory: &Path, globs: &[&str]) -> Result<Vec<std::path::PathBuf>, Error> {
|
||||||
|
let mut result = vec![];
|
||||||
|
|
||||||
|
for g in globs.iter() {
|
||||||
|
for path in glob::glob(&root_directory.join(g).to_string_lossy()).expect("Invalid glob") {
|
||||||
|
result.push(path.map_err(|_| Error::Glob)?);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum Error {
|
||||||
|
FindRootDirectory,
|
||||||
|
Git(&'static str),
|
||||||
|
Glob,
|
||||||
|
ReadTomlFile,
|
||||||
|
InvalidToml(String),
|
||||||
|
WriteTomlFile,
|
||||||
|
JustCiFailed,
|
||||||
|
CargoUpdateFailed,
|
||||||
|
FailedToReadChangelog,
|
||||||
|
FailedToWriteChangelog,
|
||||||
|
FailedToParseChangelog,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
struct Version {
|
||||||
|
major: u32,
|
||||||
|
minor: u32,
|
||||||
|
patch: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Version {
|
||||||
|
#[cfg(test)]
|
||||||
|
pub fn new(major: u32, minor: u32, patch: u32) -> Self {
|
||||||
|
Self {
|
||||||
|
major,
|
||||||
|
minor,
|
||||||
|
patch,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Display for Version {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
write!(f, "{}.{}.{}", self.major, self.minor, self.patch)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
|
struct ParseVersionError;
|
||||||
|
|
||||||
|
impl std::str::FromStr for Version {
|
||||||
|
type Err = ParseVersionError;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
let version_array: Vec<_> = s
|
||||||
|
.split('.')
|
||||||
|
.map(|v| v.parse())
|
||||||
|
.collect::<Result<Vec<_>, _>>()
|
||||||
|
.map_err(|_| ParseVersionError)?;
|
||||||
|
|
||||||
|
if version_array.len() > 3 || version_array.is_empty() {
|
||||||
|
return Err(ParseVersionError);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Version {
|
||||||
|
major: version_array[0],
|
||||||
|
minor: *version_array.get(1).unwrap_or(&0),
|
||||||
|
patch: *version_array.get(2).unwrap_or(&0),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn version_parser(maybe_version: &str) -> Result<Version, &'static str> {
|
||||||
|
maybe_version
|
||||||
|
.parse()
|
||||||
|
.map_err(|_| "Failed to parse version, must be of the format x.y.z")
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn verify_cli() {
|
||||||
|
command().debug_assert();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn can_parse_versions() {
|
||||||
|
assert_eq!(Version::from_str("0.1.2").unwrap(), Version::new(0, 1, 2));
|
||||||
|
assert_eq!(Version::from_str("0.1").unwrap(), Version::new(0, 1, 0));
|
||||||
|
assert_eq!(
|
||||||
|
Version::from_str("33.23.4000").unwrap(),
|
||||||
|
Version::new(33, 23, 4000)
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(Version::from_str("abc").unwrap_err(), ParseVersionError);
|
||||||
|
assert_eq!(Version::from_str("").unwrap_err(), ParseVersionError);
|
||||||
|
assert_eq!(Version::from_str("0.2.4.5").unwrap_err(), ParseVersionError);
|
||||||
|
assert_eq!(Version::from_str("0.2.4a").unwrap_err(), ParseVersionError);
|
||||||
|
}
|
||||||
|
}
|
27
tools/src/utils.rs
Normal file
27
tools/src/utils.rs
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
use std::{env, path::PathBuf};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct FindRootDirectoryError;
|
||||||
|
|
||||||
|
pub fn find_agb_root_directory() -> Result<PathBuf, FindRootDirectoryError> {
|
||||||
|
let mut current_path = env::current_dir().map_err(|_| FindRootDirectoryError)?;
|
||||||
|
|
||||||
|
while !current_path.clone().join("justfile").exists() {
|
||||||
|
current_path = current_path
|
||||||
|
.parent()
|
||||||
|
.ok_or(FindRootDirectoryError)?
|
||||||
|
.to_owned();
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(current_path)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::find_agb_root_directory;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn find_agb_root_directory_works() {
|
||||||
|
find_agb_root_directory().unwrap();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue