Files
fish-shell/build_tools/check.sh
Daniel Rainer 4e3898d0d7 feat: xtask gettext
Rewrite the PO file handling logic in Rust and make it available via an
xtask. Replaces the
`build_tools/{update_translations,fish_xgettext}.fish` scripts.

Main benefits:
- Better ergonomics
- Better error handling
- Eliminates the need for a fish executable for updating PO files,
  which is particularly useful in CI
- Improved performance, mainly due to concurrent threads working on the
  PO files in parallel

The behavior is mostly unchanged, with the minor exception that section
headers for empty sections are now omitted in PO files.
The interface for invoking the tooling is quite different. Instead of
working with flags, `cargo xtask gettext` has 3 subcommands:
- `update` modifies the PO files to match the current sources
- `check` is like update, but instead of modifying the PO files, it
  shows diffs between the current version of the PO files and what they
  would look like after updating. When there is a difference, the xtask
  exits non-zero, making it useful for checks to detect outdated PO
  files.
- `new` creates a new PO file for the given language.

Both the `update` and `check` command take any number of file paths to
specify the PO files to consider. If none are specified, all files in
`localization/po/` are considered.

Extracting gettext messages from Rust still requires compiling with the
`gettext-extract` feature active. In situations where compilation is
needed for other purposes as well, it can make sense to only build once
and then tell the gettext xtask about the directory into which the
messages have been extracted. This can be done via the
`--rust-extraction-dir` flag. If we stop having gettext messages in
Rust, this logic can be removed.

Closes #12676
2026-04-30 17:31:03 +00:00

158 lines
4.1 KiB
Bash
Executable File

#!/bin/sh
{
set -ex
lint=true
if [ "$FISH_CHECK_LINT" = false ]; then
lint=false
fi
case "$(uname)" in
MSYS*)
is_cygwin=true
cygwin_var=MSYS
;;
CYGWIN*)
is_cygwin=true
cygwin_var=CYGWIN
;;
*)
is_cygwin=false
;;
esac
check_dependency_versions=false
if [ "${FISH_CHECK_DEPENDENCY_VERSIONS:-false}" != false ]; then
check_dependency_versions=true
fi
green='\e[0;32m'
yellow='\e[1;33m'
reset='\e[m'
if $check_dependency_versions; then
command -v curl
command -v jq
command -v rustup
command -v uv
sort --version-sort </dev/null
# To match existing behavior, only check Rust/dockerfiles for now.
# TODO: remove this from this script.
updatecli diff --config=updatecli.d/docker.yml --config=updatecli.d/rust.yml
fi
cargo_args=$FISH_CHECK_CARGO_ARGS
target_triple=$FISH_CHECK_TARGET_TRIPLE
if [ -n "$target_triple" ]; then
cargo_args="$cargo_args --target=$FISH_CHECK_TARGET_TRIPLE"
fi
cargo() {
subcmd=$1
shift
if [ -n "$FISH_CHECK_RUST_TOOLCHAIN" ]; then
# shellcheck disable=2086
command cargo "+$FISH_CHECK_RUST_TOOLCHAIN" "$subcmd" $cargo_args "$@"
else
# shellcheck disable=2086
command cargo "$subcmd" $cargo_args "$@"
fi
}
# shellcheck disable=2317,2329
cleanup () {
if [ -n "$gettext_template_dir" ] && [ -e "$gettext_template_dir" ]; then
rm -r "$gettext_template_dir"
fi
}
trap cleanup EXIT INT TERM HUP
if $lint; then
export RUSTFLAGS="--deny=warnings ${RUSTFLAGS}"
export RUSTDOCFLAGS="--deny=warnings ${RUSTDOCFLAGS}"
fi
workspace_root="$(dirname "$0")/.."
target_dir=${CARGO_TARGET_DIR:-$workspace_root/target}
if [ -n "$target_triple" ]; then
target_dir="$target_dir/$target_triple"
fi
# The directory containing the binaries produced by cargo/rustc.
# Currently, all builds are debug builds.
build_dir="$target_dir/debug"
if [ -n "$FISH_TEST_MAX_CONCURRENCY" ]; then
export RUST_TEST_THREADS="$FISH_TEST_MAX_CONCURRENCY"
export CARGO_BUILD_JOBS="$FISH_TEST_MAX_CONCURRENCY"
fi
gettext_template_dir=$(mktemp -d)
(
# shellcheck disable=2030
export FISH_GETTEXT_EXTRACTION_DIR="$gettext_template_dir"
cargo build --workspace --all-targets --features=gettext-extract
)
if $lint; then
if command -v cargo-deny >/dev/null; then
cargo deny --all-features --locked --exclude-dev check licenses
fi
if command -v shellcheck >/dev/null || { test -n "$CI" && ! $is_cygwin; }; then
cargo xtask shellcheck
fi
PATH="$build_dir:$PATH" cargo xtask format --all --check
for features in "" --no-default-features --all-features; do
cargo clippy --workspace --all-targets $features
done
cargo xtask gettext --rust-extraction-dir="$gettext_template_dir" check
fi
# When running `cargo test`, some binaries (e.g. `fish_gettext_extraction`)
# are dynamically linked against Rust's `std-xxx.dll` instead of being
# statically link as they usually are.
# On Cygwin, `PATH`is not properly updated to point to the `std-xxx.dll`
# location, so we have to do it manually.
# See:
# - https://github.com/rust-lang/rust/issues/149050
# - https://github.com/msys2/MSYS2-packages/issues/5784
(
if $is_cygwin; then
PATH="$PATH:$(rustc --print target-libdir)"
export PATH
fi
cargo test --no-default-features --workspace --all-targets
)
cargo test --doc --workspace
if $lint; then
cargo doc --workspace --no-deps
fi
# Using "()" not "{}" because we do want a subshell (for the export)
system_tests() (
# shellcheck disable=2163
[ -n "$*" ] && export "$@"
"$workspace_root/tests/test_driver.py" "$build_dir"
)
if $is_cygwin; then
# shellcheck disable=2059
printf "=== Running ${green}integration tests ${yellow}with${green} symlinks${reset}\n"
system_tests "$cygwin_var"=winsymlinks
# shellcheck disable=2059
printf "=== Running ${green}integration tests ${yellow}without${green} symlinks${reset}\n"
system_tests "$cygwin_var"=
else
# shellcheck disable=2059
printf "=== Running ${green}integration tests${reset}\n"
system_tests
fi
exit
}