Nagi本体へ初めて貢献する
Docsの目次 · 不具合を再現して動かす · リポジトリの貢献方針
この手順は、Nagiのcompiler、runtime、標準library、Docsへ最初の変更を送る人向けです。ここでは、既存の契約とtestを調べ、nullableを扱うconformance fixtureを1件追加してPRを送る流れを説明します。構文、型、ownership、失敗、非同期処理、resourceの終了方法を変える提案は、実装前にIssueで挙動と互換性を相談してください。
このページの目次
1. 作業環境とbranchを用意する
Git、stable Rust/Cargo、rustfmt、Clippy、Cのビルド環境を用意します。OSごとのRust・C toolchainはセットアップにあります。GitHubでNagiのforkを作ってから、YOUR_GITHUB_NAMEを自分のGitHub名へ置き換えてcloneします。rootでupstreamの最新mainから作業branchを作ります。
git clone https://github.com/YOUR_GITHUB_NAME/Nagi.git
cd Nagi
git remote add upstream https://github.com/disnana/Nagi.git
git fetch upstream
git switch -c test/nullable-default upstream/main
git remote -v
cargo --version
rustc --version
cargo build --locked -p nagic
git remote -vには書き込み先のfork originと、本家の読み取り用upstreamが表示されます。forkを使わず本家へpushする権限がある場合は、本家をoriginにしても構いません。
compilerの開発buildはtarget/debug/nagic(Windowsはtarget\debug\nagic.exe)にできます。次で起動を確かめます。
./target/debug/nagic --version
期待する表示はnagic 0.1.11です。Cargoが見つからない場合はRust導入とPATHを確認して新しいterminalを開きます。C compilerやlinkerのエラーは、Nagiの型検査失敗とは分けてOSのbuild準備を確認してください。
Windows PowerShellでは実行ファイルを& .\target\debug\nagic.exe --versionで起動します。以下の./target/debug/nagicは以降この開発buildを表します。
2. 変更する層と検査を見つける
リポジトリrootをcurrent directoryにします。まずNagi compilerの流れと内部のpipeline mapを読み、公開挙動を変える可能性があれば言語・runtimeの契約も確認します。
| 調べる場所 | 主な役割 |
|---|---|
compiler/src/lexer.rs、parser.rs |
High/Lowのtoken化と構文解析 |
compiler/src/check.rs、view_flow.rs |
型、ownership、borrow、asyncの検査 |
compiler/src/emit.rs |
HighからLow、checked programからRustへの生成、CLI |
runtime/src/ |
HTTP、SQLite、Task、Actorなどの実行時API |
compiler/tests/、tests/conformance/ |
単体・統合testとHigh/Lowの回帰corpus |
docs/、docs/en/、website/ |
日本語・英語Docsと静的サイト |
ここでいうコードマップは、Nagiアプリをnagic mapで静的に図にする機能です。Rustで書かれたリポジトリ自体を解析する図ではありません。ソースの場所はrgで検索し、parser/checker/codegenの役割は上記のcompiler資料でたどります。
rg(ripgrep)が使える場合、アプリ例にあるparse_i64の使用箇所とcompilerの登録場所をrootから次のように探せます。
rg -n 'parse_i64' compiler/src runtime/src tests/conformance compiler/tests
出力には、例の呼び出し元に加えてcompiler/src/stdlib.rsのような登録箇所が含まれます。期待するfileが見つからない場合は、まず検索語を短くし、rg --files compiler/src runtime/src compiler/testsで候補fileを確認します。
rgをまだ導入していない場合は、Gitに含まれるfileをgit grep -n 'parse_i64' -- compiler/src runtime/src tests/conformance compiler/testsで検索できます。
3. 問題を小さい例で再現する
Issueの再現codeを別fileへ保存し、まずNagi compilerの検査段階を記録します。既存のtutorial例はrootから次のように検査できます。
./target/debug/nagic check examples/tutorial/first_app.nagi
成功時は終了コード0でNagiの診断がありません。実行結果も必要なcompiler/runtimeの変更では、stdinを与えて実行します。
printf '1000\n' | ./target/debug/nagic run examples/tutorial/first_app.nagi
Windows PowerShellでは、たとえば"1000" | & .\target\debug\nagic.exe run examples\tutorial\first_app.nagiを使います。実行例の期待結果はCLIアプリの入力表にあります。
失敗段階を区別してください。checkはNagi parser/checker、buildは生成Rust・Cargo/rustcも含み、runはさらにアプリを実行します。build環境や外部crateの失敗を、Nagiの構文・ownership不具合の証拠として扱わないでください。逆に、Nagiが受理したcodeをNagiの型・move・lifetimeの問題で生成Rustが拒否するなら、compiler bugとして扱います。
4. 最小の修正と回帰を用意する
担当fileの実装と、既存testが何を保証するかを先に読みます。syntaxやcheckerの変更では、期待する有効例と拒否例、High/Low、診断の元file・lineを揃えます。codegenやownershipの変更では、実際のRust build/runと観測値が必要です。runtime変更では正常終了と失敗・panic・取消・resource終了のうち、影響する境界を既存harnessに沿って確認します。
テストを重複させず、既存のsuiteを広げられるか確認します。
cargo test --locked -p nagic --test conformance
cargo test --locked -p nagic --test explicit_moves
cargo test --locked -p nagi-runtime --lib
最初の2つはcompiler regression corpusと明示moveのHigh/Low/Rust検査、3つ目はruntime library testを実行します。変更した範囲に合うtargetを選びます。--testを指定したtest binaryが存在しない場合は、compiler/tests/のfile名とcargo test --locked -p nagic --test <file-name>を合わせてください。testの段階、corpusの書き方、失敗の切り分けはcompiler test guideを参照します。
最終確認では、変更したRustにcargo fmt --all -- --checkと対象testを実行します。compiler/runtimeの修正ではClippyとcargo test --lockedも必要です。Docsだけの変更ならRust全suiteは不要で、日英の対応、リンク、変更した実行例を確認します。
小さな例:nullableのconformance fixtureを追加する
この例では実装を変えず、SomeとNoneを処理する回帰fixtureを追加します。repository rootで新しいtests/conformance/nullable_default.nagiを作ります。
def number_or_zero(value: i64?) -> i64:
match value:
case Some(number):
return number
case None:
return 0
次にtests/conformance/corpus.jsonの配列へ、次のcaseを加えます。ほかのcaseと同じく、各項目の間にcommaを置いてください。
{
"name": "nullable_default",
"source": "nullable_default.nagi",
"high": true,
"expected": "run-pass",
"oracle": "assert_eq!(number_or_zero(Some(42i64)), 42i64); assert_eq!(number_or_zero(None), 0i64);",
"diagnostic": "",
"line": 0
}
high: trueの正例はHighと保存Lowを検査し、oracleは両方のnative実行結果を照合します。まずソースをcheckし、続けてこのsuite内のcorpus+生成caseを実行します。どちらもrepository rootから実行します。
./target/debug/nagic check tests/conformance/nullable_default.nagi
cargo test --locked -p nagic --test conformance corpus_and_bounded_generated_contracts_reach_native_execution -- --exact
check成功時はchecked tests/conformance/nullable_default.nagiと表示します。test成功時は指定testがokとなり、summaryが1 passedです。このtestは新caseだけでなく、登録済みcorpusと既定のbounded generated casesも実行します。失敗時は報告されたcase名・stage・元行と、fixture・corpus.jsonのsource/oracleを確認します。期待値を変えて結果を合わせる前に、契約と独立した正しい挙動を確認してください。
サイトDocsを更新したときはPython 3.12以降とwebsite/requirements.txtの依存を用意し、rootから次を実行します。
python website/build.py --base-path / --out build/website-preview
成功するとbuild/website-preview/に日本語・英語のHTMLが生成され、リンクと見出しanchorも検査されます。ModuleNotFoundErrorならwebsiteの手元での確認の仮想環境を使います。リンクが失敗したら、表示されたMarkdownのsource linkとanchorを修正して再実行します。
5. 差分を見直す
repository rootから、無関係な変更や生成物が混ざっていないか確認して、今回の2 fileをstageします。
git add tests/conformance/corpus.json tests/conformance/nullable_default.nagi
git diff --cached --check
git status --short
git diff --cached -- tests/conformance/corpus.json tests/conformance/nullable_default.nagi
期待するのは、空白エラーがなく、corpus.jsonの変更とfixture追加だけが見えることです。違うfileが出たらcommit前に外し、原因を確認します。
6. commitしてforkからPRを出す
差分を自分で確認した後、repository rootからcommitします。
git commit -m "Add nullable conformance case"
git status --short
git push -u origin test/nullable-default
commit後のgit status --shortが空なら、未commitの変更はありません。pushが成功すると、originのtest/nullable-defaultへbranchが作成されます。GitHubでforkの Pull requests → New pull request を開き、base repositoryをdisnana/Nagi、base branchをmain、compare repositoryを自分のfork、compare branchをtest/nullable-defaultに選びます。差分を確認し、タイトル、問題、変更後の動作、実行したtestと結果、未確認の範囲を記入してPRを作成します。
PRは必ず最新main向けです。forkでbranchが見つからない場合はpush先のremoteとbranch名を確認します。pull requestの基準はrootのCONTRIBUTINGを参照してください。
困ったとき
| 症状 | 次に確認する場所 |
|---|---|
nagicでは新しい変更が見えない |
PATH上の公開版でなく./target/debug/nagicを実行し、必要なら再build |
checkは通るがbuildが失敗 |
生成Rust・Cargo/rustc診断とbuild環境を分ける。compiler internalsも参照 |
| testが失敗する | 最初の失敗stage、expected/actual、元source lineを確認。仕様契約を緩めて通さない |
| site buildでimport error | websiteのPython venvを有効にし、pip install -r website/requirements.txtを実行 |
| 手を付けるべき場所が決まらない | Issueの再現からrgで使用箇所を探し、既存testと契約から変更範囲を決める。契約変更なら先に相談 |