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
6 changes: 5 additions & 1 deletion test/tool/devfs_sweep_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,11 @@ List<String> namesIn(Directory home) {
'${home.path}/Library/Developer/CoreSimulator/Devices/DEV-1/data'
'/Containers/Data/Application/APP-1/tmp',
);
return tmp.listSync().map((e) => e.path.split('/').last).toList()..sort();
return tmp
.listSync()
.map((e) => e.path.split(Platform.pathSeparator).last)
.toList()
..sort();
}

void main() {
Expand Down
3 changes: 2 additions & 1 deletion tool/check.sh
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,10 @@ step 'codegen is up to date'
# build_info.g.dart is excluded because it can never match: it holds the hash
# of the commit it is committed in.
generated_hashes() {
require_sha256 || return
git ls-files -co --exclude-standard -- '*.g.dart' '*.freezed.dart' |
grep -v '^lib/core/build_info\.g\.dart$' |
LC_ALL=C sort | tr '\n' '\0' | xargs -0 shasum -a 256
LC_ALL=C sort | tr '\n' '\0' | xargs -0 "${SHA256[@]}"
}

codegen_check() {
Expand Down
4 changes: 2 additions & 2 deletions tool/check/intent_localization.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
def validate(root):
"""Return actionable violations; locales come from the Xcode project."""
errors = []
project = (root / "ios/Runner.xcodeproj/project.pbxproj").read_text()
project = (root / "ios/Runner.xcodeproj/project.pbxproj").read_text(encoding="utf-8")
regions = re.search(r"knownRegions\s*=\s*\((.*?)\);", project, re.S)
development = re.search(r"developmentRegion\s*=\s*([^;]+);", project)
if not regions or not development:
Expand All @@ -37,7 +37,7 @@ def validate(root):
model = plistlib.loads(definition.read_bytes())
# Use the definition's stem, matching Apple's metadata loader.
catalog_path = definition.with_suffix(".xcstrings")
catalog = json.loads(catalog_path.read_text())
catalog = json.loads(catalog_path.read_text(encoding="utf-8"))
except (OSError, ValueError, plistlib.InvalidFileException) as error:
errors.append(f"{label}: cannot load matching Intent/catalog ({error})")
continue
Expand Down
8 changes: 6 additions & 2 deletions tool/check/tooling.sh
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ for wf in .github/workflows/*.yml; do
)
done

# Every script in tool/, checked as a script.
# Every executable workflow in tool/, checked as a script. Shared libraries are
# parsed too, but are not launched directly.
#
# `tool/run.sh` runs this at launch, so these are the things worth catching
# before anything else happens: a script that does not parse, one that is not
Expand All @@ -75,7 +76,10 @@ done
while IFS= read -r script; do
bash -n "$script" 2>/dev/null || report "$script: does not parse"

[[ -x $script ]] || report "$script: is not executable (chmod +x)"
# `_lib.sh` is sourced by workflows, not launched as one. It deliberately has
# no shebang, so do not require an executable bit for this shared library.
[[ $script == tool/dev/_lib.sh || -x $script ]] ||
report "$script: is not executable (chmod +x)"

head -1 "$script" | grep -q '^#!/usr/bin/env bash$' ||
[[ $script == tool/dev/_lib.sh ]] ||
Expand Down
52 changes: 48 additions & 4 deletions tool/dev/_lib.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@ set -euo pipefail
# The repo root, whatever directory the script was invoked from.
repo_root() { cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd; }

# Git Bash, MSYS2 or Cygwin on Windows.
is_windows() {
case "$(uname -s)" in
MINGW* | MSYS* | CYGWIN*) return 0 ;;
*) return 1 ;;
esac
}

# Refuses to go on without mise, and without mise owning the toolchain.
#
# A bare `flutter` is not merely discouraged here, it is forbidden — because the
Expand Down Expand Up @@ -80,7 +88,21 @@ EOF
# is identical either way.
local owned
owned="$(cd "$root" && mise where flutter 2>/dev/null || true)"
if [[ -z $owned || $resolved != "$owned"/* ]]; then

# Git Bash receives Windows paths with backslashes from mise. Normalize both
# sides before checking containment; otherwise a valid child path is rejected
# because the POSIX glob below only matches `/` separators.
local resolved_norm="${resolved//\\//}"
local owned_norm="${owned//\\//}"
resolved_norm="${resolved_norm%/}"
owned_norm="${owned_norm%/}"
# Windows paths are case-insensitive, and mise and PATH need not agree on
# the drive letter's case. Elsewhere a case difference is a different path.
if is_windows; then
resolved_norm="$(printf '%s' "$resolved_norm" | tr '[:upper:]' '[:lower:]')"
owned_norm="$(printf '%s' "$owned_norm" | tr '[:upper:]' '[:lower:]')"
fi
if [[ -z $owned || $resolved_norm != "$owned_norm"/* ]]; then
printf '\n flutter resolves to %s\n' "$resolved" >&2
printf ' which is not inside mise (%s).\n\n' "${owned:-not installed}" >&2
printf ' Run `mise install` from %s.\n\n' "$root" >&2
Expand Down Expand Up @@ -139,15 +161,37 @@ step() { printf '\n\033[1m▸ %s\033[0m\n' "$*" >&2; }
# clean` cannot reach it, and it is per-clone.
cache_dir() { printf '%s/dpip-checks' "$(git rev-parse --git-dir)"; }

# The SHA-256 command, as an array rather than a function so that xargs can
# run it: a shell function does not exist in xargs' child process. macOS and
# Linux have `shasum`; Git Bash on Windows may have only `sha256sum`. Both
# print `<digest> <path>`.
if command -v shasum >/dev/null 2>&1; then
SHA256=(shasum -a 256)
elif command -v sha256sum >/dev/null 2>&1; then
SHA256=(sha256sum)
else
SHA256=()
fi

# Fails when there is no SHA-256 command: with an empty SHA256, `xargs` would
# run `echo` instead and every cache key would silently be a list of names.
require_sha256() {
((${#SHA256[@]})) && return 0
printf 'error: no SHA-256 utility found (shasum or sha256sum)\n' >&2
return 127
}

# A hash of every tracked and every untracked-but-not-ignored file under the
# given paths — contents *and* names, so a rename or a deletion also invalidates.
# Measured at 0.09 s over 793 files.
# One xargs batch, not one process per file: measured at 0.18 s over 1,265
# files, where a process per file took 12 s on macOS (`shasum` is Perl).
cache_key() {
require_sha256 || return
local files
files="$(git ls-files -co --exclude-standard -- "$@" | LC_ALL=C sort)"
[[ -z $files ]] && { printf 'empty'; return; }
printf '%s' "$files" | tr '\n' '\0' | xargs -0 shasum -a 256 |
shasum -a 256 | cut -d' ' -f1
printf '%s' "$files" | tr '\n' '\0' | xargs -0 "${SHA256[@]}" |
"${SHA256[@]}" | cut -d' ' -f1
}

# What each cached step reads. Anything a step's result depends on has to be in
Expand Down
17 changes: 12 additions & 5 deletions tool/gen/widget_township_resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,18 @@ def main() -> int:

outputs = generated_outputs()
if args.check:
stale = [
path
for path, expected in outputs.items()
if not path.is_file() or path.read_bytes() != expected
]
stale = []
for path, expected in outputs.items():
if not path.is_file():
stale.append(path)
continue

actual = path.read_bytes()
if path == DIRECTORY_OUTPUT:
actual = actual.replace(b"\r\n", b"\n")

if actual != expected:
stale.append(path)
if stale:
for path in stale:
print(
Expand Down
Loading