diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index bc633c5..a850a23 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -125,6 +125,7 @@ jobs: tar -xzf "rustograph-${VERSION}-darwin-arm64.tar.gz" -C "$RUNNER_TEMP" bin="$RUNNER_TEMP/rustograph-${VERSION}-darwin-arm64/rustograph" test "$("$bin" version)" = "rustograph ${VERSION}" + test "$("$bin" --version)" = "rustograph ${VERSION}" cmp README.md "$RUNNER_TEMP/rustograph-${VERSION}-darwin-arm64/README.md" scripts/verify-cli-contract.sh "$bin" diff --git a/Cargo.lock b/Cargo.lock index da71417..182896a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1378,7 +1378,7 @@ dependencies = [ [[package]] name = "rustograph" -version = "0.3.0" +version = "0.4.0" dependencies = [ "proc-macro2", "ra_ap_hir", diff --git a/Cargo.toml b/Cargo.toml index 5bda610..2dbcb95 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rustograph" -version = "0.3.0" +version = "0.4.0" edition = "2021" license = "MIT" description = "Queryable dependency graph for Rust codebases — the graph is the artifact; everything else is a query over it" diff --git a/HANDOFF.md b/HANDOFF.md index fbc45cd..a98eac1 100644 --- a/HANDOFF.md +++ b/HANDOFF.md @@ -2,7 +2,24 @@ 세션을 이어받는 에이전트가 먼저 읽는 문서입니다. -## 진행 중 — feature/client-routes (2026-09-30, API 영향 프로그램 개선 #3 Rust 부분) +## 릴리스 준비 — v0.4.0 (2026-09-30, release/v0.4.0) + +`Cargo.toml`·`Cargo.lock` 자기 항목(0.4.0, `cargo update` 없이 손으로 — ra_ap 핀 유지, `cargo build --locked` 확인)과 +README 설치 태그를 올렸다. 태그·Release·탭 갱신은 머지 뒤 별도 승인으로 한다. 릴리스 노트(v0.3.0 이후): + +- **새 명령** — `routes --role server`(axum 0.7·0.8, actix-web 4 → isthmus http `route-decl`), `routes --role client` + (reqwest·ureq, `--wrappers` http-wrappers v1, `--service` → `route-call`), `reach`·`impact --format language-traversal` + (language-traversal v1, 다중 root 단일 패스), 최상위 `--version`(= `version`, isthmus 설치 버전 대조용). +- **출력 변경** — `schema` 사실에 `symbol: {qualifiedName, usr}`(usr = 그래프 정점 ID). 읽지 못한 `cfg_attr` 속성 목록을 + 세어 limitation으로 보고한다. +- **동작 변경** — 수확의 지역 바인딩 스코프 해석을 고쳐, 지역 변수·매개변수가 같은 이름의 모듈·함수로 읽히던 거짓 + 간선이 사라졌다(자기 분석 기준 109개). `graph`·`dead`·`cycles`·`query`·`impact` 결과가 달라질 수 있다. +- **소비자 요건** — route-decl·route-call·language-traversal 문서는 isthmus `3a45450` 이후(차기 isthmus-cli 0.10.0)가 + 있어야 받는다. 발행된 isthmus-cli 0.9.0은 거부한다. 벤더링한 공유 벡터 lock은 `3a45450`. +- **알려진 결함** — 서버 `route-decl`의 위치 열(`Ctx::locate`)이 UTF-16 코드 단위로 세어진다. GRAPH-EXCHANGE는 UTF-8 + 바이트를 요구하므로 경로 인자 앞에 비ASCII 문자가 있는 줄에서 열이 어긋난다. 클라이언트 `route-call`은 UTF-8 바이트다. + +## 직전 — feature/client-routes (2026-09-30, PR #24 머지됨) `rustograph routes --role client`(isthmus http `route-call` 생산자). 규칙·근거·오라클 표는 `docs/HTTP-CLIENT.md`. diff --git a/README.ko.md b/README.ko.md index 11da218..5f862c0 100644 --- a/README.ko.md +++ b/README.ko.md @@ -37,7 +37,7 @@ Rust에는 `cargo-modules`, `cargo deps`, 그리고 syn/tree-sitter 기반 콜 ```bash brew install ictechgy/tap/rustograph # 또는 -cargo install --git https://github.com/ictechgy/rustograph --tag v0.3.0 +cargo install --git https://github.com/ictechgy/rustograph --tag v0.4.0 ``` 타입 해석 분석은 opt-in `semantic` feature 빌드가 필요합니다 diff --git a/README.md b/README.md index cb957d2..70abae2 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ over it, with a deterministic JSON contract meant for coding agents: ```bash brew install ictechgy/tap/rustograph # or -cargo install --git https://github.com/ictechgy/rustograph --tag v0.3.0 +cargo install --git https://github.com/ictechgy/rustograph --tag v0.4.0 ``` Or from source: diff --git a/docs/HTTP-ROUTES.md b/docs/HTTP-ROUTES.md index 037fead..97983e7 100644 --- a/docs/HTTP-ROUTES.md +++ b/docs/HTTP-ROUTES.md @@ -78,7 +78,7 @@ dispatch 하나만 선언한다). 둘 다 없으면 사실 0건과 `route-covera `NormalizePath::trim_trailing_slash(svc)`)이 있으면 trim은 끝 슬래시 없는 템플릿을, append는 끝 슬래시 있는 템플릿을 `optional`로 낸다. `Router::layer`·`MethodRouter::layer` 인자나 변수로 넘긴 레이어처럼 라우팅 전에 동작한다는 증거가 없으면 효과가 없다고 본다(틀리면 선언이 strict로 남아 소비자는 끝 슬래시 불일치 경고를 낸다 — 거짓 error가 아니다). -- **location**: `.route()`의 경로 인자(줄, UTF-16 열). 경로 인자가 `&str` 상수면 그 값을 쓴다. +- **location**: `.route()`의 경로 인자(줄, UTF-16 열 — 알려진 결함: GRAPH-EXCHANGE는 UTF-8 바이트 열을 요구하므로 비ASCII 줄에서 어긋난다). 경로 인자가 `&str` 상수면 그 값을 쓴다. ## actix-web diff --git a/scripts/verify-cli-contract.sh b/scripts/verify-cli-contract.sh index a267c14..6cd8be6 100755 --- a/scripts/verify-cli-contract.sh +++ b/scripts/verify-cli-contract.sh @@ -56,6 +56,12 @@ check 2 "rules no config" rules --strict check 0 "rules" rules --config "$FIX/rules.yml" check 0 "rules sarif" rules --config "$FIX/rules.yml" --format sarif check 0 "version" version +check 0 "--version" --version +# --version은 isthmus 설치 버전 대조가 읽는 별칭이다 — 하위 명령과 출력이 같아야 한다. +if [ "$("$BIN" --version)" != "$("$BIN" version)" ]; then + echo "FAIL --version: output differs from version" >&2 + fails=$((fails+1)) +fi check 2 "unknown command" frobnicate check 2 "bad level" graph --level bogus check 2 "bad format" graph --format xml diff --git a/src/cli.rs b/src/cli.rs index 457e2b6..504ed00 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -36,7 +36,7 @@ usage: rustograph routes --role server [--dir DIR] [--out FILE] [--framework axum|actix] rustograph routes --role client [--dir DIR] [--out FILE] [--wrappers FILE] [--service NAME] - rustograph version + rustograph version | --version shared flags: --deps --tests --retain-public --semantic --no-cache --focus PATH --target TRIPLE --exclude-tests @@ -74,7 +74,9 @@ fn run_inner(args: &[String], out: &mut dyn Write, err: &mut dyn Write) -> Resul Err(e) => return Err(format!("{e}\n{USAGE}")), }; match a.cmd.as_str() { - "version" => { + // `--version`은 계열 관례(isthmus verify-installed-compatibility가 + // ` --version`의 마지막 semver를 읽는다)를 위한 별칭이다 — 출력은 하위 명령과 같다. + "version" | "--version" => { writeln!(out, "rustograph {VERSION}").ok(); Ok(0) } @@ -593,6 +595,16 @@ mod tests { assert!(out.contains("rustograph")); } + #[test] + fn version_flag_matches_version_command() { + // 별칭이 따로 놀면 설치 버전 대조가 하위 명령과 다른 값을 읽게 된다. + let (code, flag_out, _) = run_cli(&["--version"]); + let (_, command_out, _) = run_cli(&["version"]); + assert_eq!(code, 0); + assert_eq!(flag_out, command_out); + assert_eq!(flag_out, format!("rustograph {VERSION}\n")); + } + #[test] fn no_command_is_usage_error() { let (code, _, err) = run_cli(&[]);