Skip to content

fix: handle broken tsconfig fallback and audit base config#299

Merged
BartWaardenburg merged 13 commits intofallow-rs:mainfrom
M-Hassan-Raza:fix/react-native-audit-base-resolver
May 6, 2026
Merged

fix: handle broken tsconfig fallback and audit base config#299
BartWaardenburg merged 13 commits intofallow-rs:mainfrom
M-Hassan-Raza:fix/react-native-audit-base-resolver

Conversation

@M-Hassan-Raza
Copy link
Copy Markdown
Contributor

What changed:

  • keep local tsconfig paths/baseUrl/rootDirs usable when an extends chain is broken
  • preserve audit base comparisons against the current resolved config
  • add coverage for React Native/Expo aliases, config inheritance, references, cache hits, and import edge shapes

Why:
Broken or untracked framework tsconfig bases could make valid local imports look unresolved, especially in React Native and Expo projects. Audit base snapshots also needed to compare against the same config contract as the current run.

Validation:

  • cargo fmt --all -- --check
  • cargo clippy --workspace --all-targets -- -D warnings
  • cargo test --workspace --all-targets

Copy link
Copy Markdown
Collaborator

@BartWaardenburg BartWaardenburg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the rebase, Hassan. The merge is clean now and on my side cargo check --workspace, clippy on cli/graph, and the cli/graph/core lib tests all pass.

The conceptual approach is solid: broken-extends fallback, subdir-aware base root, and current-side config all address real bugs. Three robustness improvements before merge:

1. crates/graph/src/resolve/specifier.rs:496 (and 509, 1300)

The ? propagates None out of the whole function on a single read failure, so a TOCTOU on any tsconfig in the chain (deleted or moved between chain build and this loop) abandons resolution for the remaining entries. Same pattern at line 509 and at line 1300 in try_tsconfig_root_dirs.

Suggest:

let Some(json) = read_tsconfig_json(tsconfig_path) else { continue; };

2. crates/graph/src/resolve/specifier.rs:285 glob_values_match

Bare directory include patterns like "include": ["src"] get passed to Glob::new as a literal path, which only matches the directory entry itself, not files under it. TypeScript expands a bare directory as <dir>/**/* (with implicit .ts/.tsx/etc). Result: configs with bare-directory includes get silently skipped during references chain traversal.

When a pattern resolves to an existing directory and contains no glob metacharacters, append /**/* before building the glob.

3. crates/cli/src/audit.rs:671 base_analysis_root

If current_root.canonicalize() succeeds but git_root doesn't match (race, unusual symlink layering, or a parent dir replaced mid-run), strip_prefix fails silently and the base audit runs against the worktree root instead of the expected subdirectory, producing a wrong-but-passing result.

Worth a tracing::warn! on the strip_prefix failure path so a misbehaving setup is at least visible in --explain.

@M-Hassan-Raza M-Hassan-Raza changed the title Fix broken tsconfig fallback and audit base config fix: handle broken tsconfig fallback and audit base config May 6, 2026
@M-Hassan-Raza M-Hassan-Raza force-pushed the fix/react-native-audit-base-resolver branch from 5fbe1d3 to 9b18afe Compare May 6, 2026 15:35
@M-Hassan-Raza
Copy link
Copy Markdown
Contributor Author

Thanks for the rebase, Hassan. The merge is clean now and on my side cargo check --workspace, clippy on cli/graph, and the cli/graph/core lib tests all pass.

The conceptual approach is solid: broken-extends fallback, subdir-aware base root, and current-side config all address real bugs. Three robustness improvements before merge:

1. crates/graph/src/resolve/specifier.rs:496 (and 509, 1300)

The ? propagates None out of the whole function on a single read failure, so a TOCTOU on any tsconfig in the chain (deleted or moved between chain build and this loop) abandons resolution for the remaining entries. Same pattern at line 509 and at line 1300 in try_tsconfig_root_dirs.

Suggest:

let Some(json) = read_tsconfig_json(tsconfig_path) else { continue; };

2. crates/graph/src/resolve/specifier.rs:285 glob_values_match

Bare directory include patterns like "include": ["src"] get passed to Glob::new as a literal path, which only matches the directory entry itself, not files under it. TypeScript expands a bare directory as <dir>/**/* (with implicit .ts/.tsx/etc). Result: configs with bare-directory includes get silently skipped during references chain traversal.

When a pattern resolves to an existing directory and contains no glob metacharacters, append /**/* before building the glob.

3. crates/cli/src/audit.rs:671 base_analysis_root

If current_root.canonicalize() succeeds but git_root doesn't match (race, unusual symlink layering, or a parent dir replaced mid-run), strip_prefix fails silently and the base audit runs against the worktree root instead of the expected subdirectory, producing a wrong-but-passing result.

Worth a tracing::warn! on the strip_prefix failure path so a misbehaving setup is at least visible in --explain.

Great feedback! The code should be fully airtight now (hopefully)

@BartWaardenburg BartWaardenburg merged commit 454859e into fallow-rs:main May 6, 2026
18 checks passed
@BartWaardenburg
Copy link
Copy Markdown
Collaborator

Released in v2.66.1. Thanks @M-Hassan-Raza.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants