Skip to content

Commit 6f3e2fb

Browse files
refactor: extract inline shell tasks to mise-tasks file-tasks; add shellcheck + shfmt (#299)
* refactor: extract inline shell tasks to mise-tasks file-tasks; add shellcheck + shfmt All multi-line inline shell scripts in mise.toml and mise.dev.toml are moved to standalone executable files under mise-tasks/. Filenames ending in .sh are used where a directory of the same base name already exists (test.sh, dev.sh, build/web.sh, test/e2e.sh) so that both the parent task and its colon-namespaced children can coexist on the filesystem. New file-tasks added: mise-tasks/analyze (was inline in mise.toml) mise-tasks/coverage (was inline in mise.toml) mise-tasks/test.sh (was inline in mise.toml) mise-tasks/dev.sh (was inline in mise.dev.toml) mise-tasks/build/web.sh (was inline in mise.dev.toml) mise-tasks/serve/release (was inline in mise.dev.toml) mise-tasks/test/e2e.sh (was inline in mise.dev.toml) mise-tasks/test/e2e/ui (was inline in mise.dev.toml) mise-tasks/test/e2e/headed (was inline in mise.dev.toml) mise-tasks/test/check-page (was inline in mise.dev.toml) mise-tasks/screenshots/batch (was inline in mise.dev.toml) shellcheck and shfmt added as mise tools (mise.toml). Two new tasks: mise-tasks/shell/check — shellcheck on all .sh files + mise-tasks/ mise-tasks/shell/format — shfmt -w on all .sh files + mise-tasks/ shell:check is wired into `check`; shell:format into `format`. All 22 shell files pass shellcheck; shfmt normalises indentation to tabs. * refactor: standardise all mise-tasks files with .sh extension Consistent convention: every file-task in mise-tasks/ has a .sh extension regardless of whether the name conflicts with a subdirectory. Previously only conflict cases (test.sh, dev.sh, build/web.sh, test/e2e.sh) had the extension. Renamed: analyze -> analyze.sh coverage -> coverage.sh build/web/prod -> build/web/prod.sh dev/tunnel -> dev/tunnel.sh serve/release -> serve/release.sh setup/playwright -> setup/playwright.sh setup/tunnel -> setup/tunnel.sh shell/check -> shell/check.sh shell/format -> shell/format.sh test/check-page -> test/check-page.sh test/e2e/headed -> test/e2e/headed.sh test/e2e/ui -> test/e2e/ui.sh Also adds mise-tasks/screenshots/ gitignore exception (the screenshots/ rule was blocking mise-tasks/screenshots/batch.sh from being tracked), and simplifies shell:check / shell:format to a single find *.sh pass now that the grep-for-shebang fallback is no longer needed. * fix: use #USAGE headers for task args; pin shellcheck/shfmt versions Replace broken #MISE usage= multi-line strings with the correct #USAGE per-line syntax (the format mise actually parses for argument docs). Reverts positional-arg fallback back to $usage_* env vars now that the header syntax is correct. Also pins shellcheck = "0.9.0" and shfmt = "3.8.0" instead of "latest" so mise tools resolve without hitting GitHub releases API. * feat: pass args through test and analyze tasks; update descriptions Both tasks now forward $@ so agents can run a subset without resorting to mise exec: mise run test test/widgets/drink_card_test.dart mise run analyze lib/screens/ Descriptions rewritten to answer "when to run" rather than "what it does", and to clarify that the log file is auto-created (not a required input). AGENTS.md updated to show the task form instead of the mise exec workaround. * fix: scope shellcheck/shfmt as task-level tools; drop from global [tools] Declaring them in [tools] caused mise to attempt installation on every task run, blocking all tasks when GitHub's API is rate-limited. Moving them to #MISE tools={} in the tasks that actually need them means they're only resolved for shell:check and shell:format. * fix: suppress flutter root warning; fix set -e masking grep hints on failure The "Woah! You appear to be running flutter as root" warning on stderr was filtered out with grep -v in the test/analyze/coverage pipelines. Also fixes a latent bug: set -euo pipefail caused the script to exit immediately on flutter failure, so the "Grep with:" hint was never printed on failure — exactly when it's most needed. Replaced with set -uo pipefail and EXIT_CODE=${PIPESTATUS[0]} to capture flutter's exit code while letting the hint always print. * fix: add export mode to get_version_info.sh; fix comments and error message - get_version_info.sh: add 'export' mode (eval-safe VAR=value lines) that prod.sh was already calling but was falling through to the human-readable default, causing eval to fail on the "Version: ..." output. Also switch == to = in [ ] comparisons (shellcheck SC2039). - serve/release.sh: error hint now points to the correct MISE_ENV=dev ./bin/mise invocation instead of bare `mise`. - mise.dev.toml: update task→file mapping comments to include .sh extension to match the actual committed filenames. * fix: drop deprecated #MISE tools={system}; exclude .mise/ from shell scans 'system' version in #MISE tools={} is deprecated in mise. Removing the declaration entirely — shellcheck and shfmt are expected on PATH (install via apt/brew). Also adds -not -path "./.mise/*" to the find commands so the Flutter SDK's own shell scripts in .mise/http-tarballs/ are not included in shellcheck/shfmt runs. * fix: restore shellcheck/shfmt to [tools] for mise-managed installation 'system' is not a valid mise version. The correct approach is to pin versions in [tools] so mise installs and manages them. In environments where they are already available (e.g. this sandbox, devcontainers), set MISE_DISABLE_TOOLS=shellcheck,shfmt to skip installation and use the PATH versions instead. * fix: use printf %q for shell-safe eval output in export mode --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 11f744f commit 6f3e2fb

22 files changed

Lines changed: 218 additions & 178 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,4 +144,5 @@ app.*.symbols
144144
!test/*.mocks.dart
145145
!test/**/*.mocks.dart
146146
screenshots/
147+
!mise-tasks/screenshots/
147148
test/failures/

AGENTS.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,11 @@ MISE_ENV=dev ./bin/mise run build:web
122122
`test` and `analyze` automatically save output to a temp file, print the path before the run starts, and print a ready-to-use grep command at the end. Run once, grep the file as many times as needed — do not re-run to grep different things.
123123

124124
```bash
125-
# Run a specific test file
126-
./bin/mise exec flutter -- flutter test test/my_test.dart
125+
# Run a specific test file or directory
126+
./bin/mise run test test/widgets/drink_card_test.dart
127+
128+
# Run a specific analysis path
129+
./bin/mise run analyze lib/screens/
127130
```
128131

129132
> `TEST_LOG` and `ANALYZE_LOG` env vars let you override the temp file path if you need a stable location across multiple runs.

mise-tasks/analyze.sh

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#!/usr/bin/env bash
2+
#MISE description="Run after Dart changes — pass a path to limit scope; grep output with the path printed at start"
3+
#MISE depends=["generate"]
4+
5+
set -uo pipefail
6+
ANALYZE_LOG="${ANALYZE_LOG:-$(mktemp /tmp/analyze-XXXXXX.log)}"
7+
echo "ANALYZE_LOG=$ANALYZE_LOG"
8+
flutter analyze --no-fatal-infos "$@" 2>&1 \
9+
| grep -v -E "Woah! You appear|superuser privileges" \
10+
| tee "$ANALYZE_LOG"
11+
EXIT_CODE=${PIPESTATUS[0]}
12+
echo "---"
13+
echo "Grep with: grep -n 'error\|warning' $ANALYZE_LOG"
14+
exit "$EXIT_CODE"

mise-tasks/build/web.sh

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#!/usr/bin/env bash
2+
#MISE description="Build Flutter web app in release mode (for local testing/e2e)"
3+
4+
set -euo pipefail
5+
echo "Building Flutter web app in release mode..."
6+
flutter build web --release --base-href "/"
7+
echo ""
8+
echo "Build complete! Output at: build/web/"
9+
echo ""
10+
echo "To serve locally for testing:"
11+
echo " npx http-server build/web -p 8080"
Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,19 @@ echo "Building Flutter web app for production..."
77

88
# Get version information
99
if [ -x "scripts/get_version_info.sh" ]; then
10-
echo "Gathering version information..."
11-
eval "$(scripts/get_version_info.sh export)"
10+
echo "Gathering version information..."
11+
eval "$(scripts/get_version_info.sh export)"
1212
else
13-
echo "Warning: scripts/get_version_info.sh not found, building without version info"
13+
echo "Warning: scripts/get_version_info.sh not found, building without version info"
1414
fi
1515

1616
# Build with version information
1717
flutter build web --release --base-href "/" \
18-
${GIT_TAG:+--dart-define=GIT_TAG=$GIT_TAG} \
19-
${GIT_COMMIT:+--dart-define=GIT_COMMIT=$GIT_COMMIT} \
20-
${GIT_BRANCH:+--dart-define=GIT_BRANCH=$GIT_BRANCH} \
21-
${BUILD_VERSION:+--dart-define=BUILD_VERSION=$BUILD_VERSION} \
22-
${BUILD_TIME:+--dart-define=BUILD_TIME=$BUILD_TIME}
18+
${GIT_TAG:+--dart-define=GIT_TAG=$GIT_TAG} \
19+
${GIT_COMMIT:+--dart-define=GIT_COMMIT=$GIT_COMMIT} \
20+
${GIT_BRANCH:+--dart-define=GIT_BRANCH=$GIT_BRANCH} \
21+
${BUILD_VERSION:+--dart-define=BUILD_VERSION=$BUILD_VERSION} \
22+
${BUILD_TIME:+--dart-define=BUILD_TIME=$BUILD_TIME}
2323

2424
echo ""
2525
echo "✅ Production build complete! Output at: build/web/"

mise-tasks/coverage.sh

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#!/usr/bin/env bash
2+
#MISE description="Run tests with coverage reporting (output: coverage/lcov.info)"
3+
#MISE depends=["generate"]
4+
5+
set -uo pipefail
6+
flutter test --coverage 2>&1 | grep -v -E "Woah! You appear|superuser privileges"
7+
EXIT_CODE=${PIPESTATUS[0]}
8+
echo "Coverage report generated at coverage/lcov.info"
9+
echo "To view HTML report, install lcov and run: genhtml coverage/lcov.info -o coverage/html"
10+
exit "$EXIT_CODE"

mise-tasks/dev.sh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#!/usr/bin/env bash
2+
#MISE description="Start Flutter dev server on localhost:8080"
3+
4+
set -euo pipefail
5+
echo "Starting Flutter dev server on http://localhost:8080"
6+
flutter run -d web-server --web-port 8080 --pid-file flutter-dev.pid
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@ echo ""
2121

2222
# Cleanup function
2323
cleanup() {
24-
echo ""
25-
echo "Stopping tunnel..."
26-
kill $TUNNEL_PID 2>/dev/null
27-
exit
24+
echo ""
25+
echo "Stopping tunnel..."
26+
kill $TUNNEL_PID 2>/dev/null
27+
exit
2828
}
2929

3030
# Set up cleanup on exit

mise-tasks/screenshots/batch.sh

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#!/usr/bin/env bash
2+
#MISE description="Capture screenshots of multiple pages from config file"
3+
#USAGE arg "[config]" help="Config file path" default="screenshots.config.json"
4+
#USAGE arg "[output]" help="Output directory" default="screenshots"
5+
6+
set -euo pipefail
7+
CONFIG="${usage_config:-screenshots.config.json}"
8+
OUTPUT="${usage_output:-screenshots}"
9+
10+
echo "Running batch screenshot capture..."
11+
echo "Config: $CONFIG"
12+
echo "Output: $OUTPUT"
13+
node scripts/screenshot-batch.mjs -c "$CONFIG" -o "$OUTPUT"

mise-tasks/serve/release.sh

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#!/usr/bin/env bash
2+
#MISE description="Serve release build with http-server (SPA mode for deep linking)"
3+
4+
set -euo pipefail
5+
if [ ! -d "build/web" ]; then
6+
echo "Error: build/web directory not found"
7+
echo "Run: MISE_ENV=dev ./bin/mise run build:web first"
8+
exit 1
9+
fi
10+
11+
echo "Starting http-server with SPA routing..."
12+
echo "Available at: http://localhost:8080"
13+
echo "Press Ctrl+C to stop"
14+
npx http-server build/web -p 8080 --proxy http://localhost:8080?

0 commit comments

Comments
 (0)