統一エントリポイント ma.sh(依存ツールの推移的自動解決)(#182) - #196
Open
k-yoshimi wants to merge 19 commits into
Open
Conversation
Design for a top-level ma.sh (install/list/installed/help) that resolves an app's tool dependencies transitively, builds missing tools in order via the existing tools/*/install.sh+link.sh, then installs the app. Dependencies are declared per package as a <NAME>_REQUIRES variable in version.sh; availability is decided primarily by the installer's own env.d/<tool>vars.sh marker (find.sh only covers 15/27 tools). Metadata is populated gradually, starting with the hphi chain. Refs #182 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Address the design-review findings: - must_fix (Codex): define partial-install/resume semantics — a half-built tool (prefix present, no env.d marker) is reported with a targeted "remove <prefix> and re-run" instruction instead of silently wedging; "resumable" narrowed to completed tools. - must_fix (Antigravity): warn on install when an app has no REQUIRES, and mark apps that carry dependency metadata in `ma.sh list`, so the gradual rollout is not a silent no-op. - Clarify system-tool env propagation (find.sh-found tools need none), find.sh variable normalization, resolver POSIX-sh constraints (newline sets, exact membership, no subshell state loss, version.sh declarative-only), env.sh validation and dangling-symlink handling. - Specify CLI arg validation (no-args/-h/--help usage), tools build in default mode (documented limitation), expanded tests, and a resolved-questions + deferred (--force/--dry-run) section. Refs #182 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Specify precedence: installer-state checks (complete marker / partial prefix) are evaluated before find.sh; find.sh is consulted only when the installer has no prefix for the tool. - Add a version.sh declarative-only CI lint (assignments/comments only) so the resolver's side-effect-free sourcing cannot silently regress. Refs #182 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Validate mode up front via apps/<app>/config/<mode>/ existence, so a bad mode errors before any dependency is built (was: only caught at the final app install). - Capture ma_resolve output and check its exit status before the build loop, so a resolver error (cycle/unknown) aborts instead of being iterated as tool names. - Harden the REQUIRES/MA_HAVE variable-name normalization to map every non-alphanumeric char to '_' (valid identifier for any dir name). - Specify that `installed` scans both env.d (tools) and <app>/ (apps). - Warn when building deps for a non-default app mode (built in default mode). Document presence-based (not version-matched) availability as an explicit first-cut non-goal. Refs #182 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
9-task TDD plan: ma_reqvar/ma_requires, ma_resolve (transitive + cycle/unknown), ma_tool_status availability, ma.sh CLI skeleton + arg validation, install build loop (resume + partial guard + env reload), list/installed, version.sh declarative lint + hphi-chain REQUIRES, CI job, docs. Each task ends with a runnable shell test. Refs #182 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…l guard Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QaWKJsSQqCakkMEKZpJcvP
ma__find_have preset SCRIPT_DIR and sourced find.sh in a subshell, but 11 real find.sh files (lapack, boost, fftw, eigen3, gsl, hdf5, libffi, nfft, openssl, tcltk, zlib) ignore that and re-derive SCRIPT_DIR=$(cd "$(dirname $0)"; pwd) themselves. When a file is sourced, $0 stays the parent shell's (ma.sh), so dirname $0 resolves at repo-root depth instead of the tool-dir depth those find.sh files expect, and ../../scripts/cmake-find-package.sh can't be opened - MA_HAVE_<TOOL> silently stays empty and system-installed tools like LAPACK are never detected. Run find.sh via `sh -c` with $0 pointed at the find.sh path itself, so its own `dirname $0` resolves exactly as it does under the normal install.sh flow. Verified under dash: lapack (Accelerate via cmake on this machine) now reports MA_HAVE_LAPACK=yes instead of empty.
The existing find.sh availability test used a trivial fixture (MA_HAVE_ST2=yes) that references neither $0 nor SCRIPT_DIR, so it passed even while ma__find_have sourced find.sh with the wrong $0 (the bug fixed in the previous commit). Add a st3 fixture whose find.sh mirrors the real tools (lapack, boost, fftw, ...): it derives SCRIPT_DIR from $0 and only reports MA_HAVE_ST3=yes if it can read a sibling file next to itself. Confirmed this fails against the pre-fix ma__find_have (expected [available] got [absent]) and passes after.
ma_requires and ma_cmd_list source version.sh (external, tool/app-owned metadata) inside a `set -u` context. If a future version.sh references an unset variable before its _REQUIRES line, that reference would abort the sourcing subshell under nounset and silently produce an empty deps list -- a dropped dependency, which is the dangerous direction to fail in. Wrap the `. version.sh` sourcing with set +u/set -u, matching the pattern already used in ma_do_install/ma_cmd_installed for util.sh/env.sh. Behavior on the current (clean) tree is unchanged: `ma_resolve hphi` still resolves to cmake/openmpi/lapack/scalapack and `ma.sh list` output is identical.
The fixture app's fake install.sh always succeeded, so the "app prefix exists -> install.sh aborts" behavior the surrounding comment described was never exercised: the re-run command's exit status wasn't even checked. Make the fixture install.sh emulate the real install.sh scripts' guard (error + exit 127 if its own versioned prefix already exists), and assert the second `ma.sh install appF` now fails at the app step. Confirmed this assertion fails against the old always-succeeds fixture and passes with the guard in place, while the existing "tools not rebuilt" assertion keeps passing.
The ma job's shellcheck step only covered ma.sh, ma_deps.sh, and lint_version_sh.sh, leaving ma_deps_test.sh and ma_integration_test.sh (both nontrivial POSIX sh) unchecked in CI. Add them to the shellcheck invocation.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
概要
Fixes #182
トップレベルに
ma.shを追加し、アプリのビルドに必要なツールを推移的に解決して自動ビルドしてからアプリをインストールできるようにします。既存の個別フロー(cd apps/x; sh install.sh; sh link.sh)は一切変更していません。設計(Phase 0 AI レビュー収束済み)
version.shの任意変数<NAME>_REQUIRES="tool1 tool2"(直接依存の tool 名のみ)。未宣言のアプリは従来どおり単体インストール(警告表示)scripts/ma_deps.sh: DFS で推移的トポロジカル順を生成、循環・不明ツール検出、ダイヤモンド依存は 1 回。純 POSIX sh(localの動的スコープを利用)で単体テスト可能$MA_ROOT/env.d/<tool>vars.sh(マーカー)→ 済 / (2)find.shのMA_HAVE_<TOOL>=yes(システム提供)→ 済 / (3) それ以外 → 要ビルド。部分インストール(prefix あり・マーカー無し)は「削除して再実行」と明示中断ma_resolve hphi→ cmake, openmpi, lapack, scalapackdocs/superpowers/specs/2026-07-09-ma-entrypoint-design.md実装・レビューの経緯
subagent-driven development(タスクごとに実装→spec+品質レビュー→修正)で 9 タスクを TDD 実装し、最後にブランチ全体レビューを実施:
find.shを source する際、11 個のfind.shがSCRIPT_DIR=$(dirname $0)で再導出するため、source 時に$0が親シェルになりパスが解決できずシステムツール検出が機能しなかった(例: システム LAPACK があっても再ビルド。fail-safe = 誤スキップはしない)。sh -c '. "$0" ...' <find.sh>で$0を find.sh 自身にして修正、dash で検証set -u下で source する危険側リスク(依存の無言脱落)をset +uラップで防止、resume テストの app 側 abort 検証、CI の shellcheck 対象拡張テスト
scripts/ma_deps_test.sh): 順序・推移・ダイヤモンド・循環・不明・可用性・lintscripts/ma_integration_test.sh): ビルド順・resume スキップ・部分インストール中断・app 側 abort・list/installed(実ビルドせず ma.sh のオーケストレーションを検証)scripts/lint_version_sh.sh: version.sh 宣言専用チェック(複合コマンド;/&&/|/backtick を拒否、$(...)は許容)shとdashの両方で PASS、shellcheck(--severity=warning -s sh)が全 5 ファイルでクリーンmaジョブ追加(shellcheck + lint + 両テスト)補足(マージ順)
.shellcheckrcは 共有スクリプトのクォート修正 + shellcheck の CI 導入 #178 と重なります(内容を 共有スクリプトのクォート修正 + shellcheck の CI 導入 #178 と同一にそろえてあるので、どちらが先でも競合は自明)🤖 Generated with Claude Code