mirror of
https://github.com/colbymchenry/codegraph.git
synced 2026-10-21 00:38:18 +08:00
fix(extraction): a build folder inside src/ is indexed for its Go and C# files too (#2687)
A folder named build below src/ was indexed only for its TypeScript, JSX, Vue, Svelte and Astro files, so Go's own src/go/build package, a module's src/build/version.go or a .NET solution's src/Build project stayed out of the graph. Go and .NET toolchains never write source into a build folder (their output is binaries, bin/ and obj/), so .go and .cs files there are hand-written and now indexed as well. Rust waits: its name matching doesn't yet keep a private item to its own module, so indexing dioxus's src/build/patch.rs, which declares a private type Result, moved 158 Result references off the crate's own alias. A test pins .rs as still excluded. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+1
-1
@@ -198,7 +198,7 @@ and adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
- In JavaScript and TypeScript, a call to a method whose name contains a `$` now links to that method through its receiver's type, like any other method call: RxJS-style `this.organizationService.organizations$(userId)`, or vscode's `this._proxy.$acceptModelChanged(…)` on the interface its RPC proxy is declared with. Before, such a call linked nothing, however well its receiver was typed. Re-index JavaScript and TypeScript projects after upgrading.
|
||||
- In JavaScript and TypeScript, an import written from a jsconfig or tsconfig `baseUrl`, like `import MainLayout from 'layout/MainLayout'` under `"baseUrl": "src"`, or through a catch-all `"paths": { "*": ["./src/*"] }`, now links to the file it names, read with the config of the app the importing file belongs to, and so does an import of a single name like `'config'` or `'themes'`. Create React App and Vite admin templates such as Berry, Mantis and MatX write nearly every import this way. Before, each one was taken for an npm package, so it linked nothing, its names were matched by name alone, which could reach a same-named component in another app of the same repository, and a React Router route whose page loads through `lazy(() => import('views/dashboard/Default'))` pointed at that loader instead of the page and its layout. A package the app's `package.json` declares, or a Node built-in, never links to a project module of the same name, only to type declarations the project keeps for it, and only a file the index holds counts, never a folder or something in `node_modules`. `codegraph sync` and the file watcher link such an import too when the file it names is added later or gains what it imports. Re-index JavaScript and TypeScript projects after upgrading.
|
||||
- `codegraph sync` and the file watcher now relink an import that reaches a module through a barrel file passing it on under another name, like `import { MatxLoading } from './components'` when `components/index.js` says `export { default as MatxLoading } from './MatxLoading'`, once an edit gives that module what is imported. Before, the import and every call through it stayed unlinked, or stayed on something else in the project with the same name, until the importing file itself changed or the project was indexed again.
|
||||
- In JavaScript and TypeScript projects, a folder named `build` inside `src/` is now indexed for its TypeScript, JSX, Vue, Svelte and Astro files, so a feature kept there, like the `src/build/` pages of luci-go's milo, shows up in `codegraph_explore` and the routes that lazily load its pages link to them. Before, every folder named `build` was skipped as build output. The JavaScript, declaration and other files such a folder holds are still left out, since a build may have written them, and so is every `build` folder outside `src/`.
|
||||
- A folder named `build` inside `src/` is now indexed for its TypeScript, JSX, Vue, Svelte, Astro, Go and C# files, so a feature or package kept there, like the `src/build/` pages of luci-go's milo or Go's own `src/go/build` package, shows up in `codegraph_explore`, and the routes that lazily load its pages link to them. Before, every folder named `build` was skipped as build output. The JavaScript, declaration and other files such a folder holds are still left out, since a build may have written them, and so is every `build` folder outside `src/`.
|
||||
- On Windows, a Swift call written after `try!`, like `try! Message2(data: data)` or `try! Settings.Defaults.load()`, now links to what it calls, as it already did on macOS and Linux. Before, the `!` was read as a logical not, so the call linked to nothing, and a call made through a type lost the type it was made on. Re-index Swift projects on Windows after upgrading.
|
||||
- In JavaScript and TypeScript, a barrel's `export { A, B as C } from './x'` now links each name it passes on to what `./x` exports, following barrels that pass it on in turn. Before, each name was looked up by itself and could link to a same-named symbol elsewhere in the project, such as another folder's `Provider`, and a name passed on from a package, like `export { debounce } from 'lodash'`, could link to a project function of that name. Re-index JavaScript and TypeScript projects after upgrading.
|
||||
- In Swift, a call written after `!` or another prefix operator, or chained after `try` or `await`, now links to what it calls. `if !isReady()` links to `isReady`, `!store.contains(id)` and `try! JSONDecoder().decode(…)` link to the method of the type they're called on rather than to whichever `contains` or `decode` came first, and `!Settings.Defaults.isOn()` lands on the type it names. Re-index Swift projects after upgrading.
|
||||
|
||||
@@ -652,8 +652,8 @@ What it skips out of the box:
|
||||
[supported stack](#supported-languages) — so the graph is your code, not
|
||||
third-party noise. This holds even with no `.gitignore`. A `build` folder
|
||||
inside `src/` is the exception: no build step writes TypeScript, JSX, Vue,
|
||||
Svelte or Astro files, so those are indexed from it, and a Java, Kotlin or
|
||||
Scala package named `build` is indexed whole.
|
||||
Svelte, Astro, Go or C# files into one, so those are indexed from it,
|
||||
and a Java, Kotlin or Scala package named `build` is indexed whole.
|
||||
- **Anything in your `.gitignore`** — honored in git repos via git, and in
|
||||
non-git projects by reading `.gitignore` directly (root and nested).
|
||||
- **Files larger than 1 MB** — generated bundles, minified JS, vendored blobs.
|
||||
|
||||
@@ -6,10 +6,12 @@
|
||||
* was indexed and those routes linked nothing.
|
||||
*
|
||||
* Such a folder is now walked and its hand-written source (TypeScript, JSX,
|
||||
* Vue, Svelte, Astro) indexed, while what a build step writes there —
|
||||
* JavaScript, declarations, CSS, HTML, maps — stays out, as does every `build/`
|
||||
* folder outside `src/`. Both enumeration paths, the git-status sync and the
|
||||
* watcher share the rule (#1728).
|
||||
* Vue, Svelte, Astro, and Go and C#, as in Go's `src/go/build` or a .NET
|
||||
* solution's `src/Build/` project) indexed, while what a build step writes there —
|
||||
* JavaScript, declarations, CSS, HTML, maps, a frozen app's Python, CMake's
|
||||
* C — stays out, as does every `build/` folder outside `src/`. Both
|
||||
* enumeration paths, the git-status sync and the watcher share the rule
|
||||
* (#1728).
|
||||
*/
|
||||
import { describe, it, expect, afterEach, vi } from 'vitest';
|
||||
import { execFileSync } from 'child_process';
|
||||
@@ -69,6 +71,9 @@ describe('the scope of a build folder below src', () => {
|
||||
'src/routes/build/+page.svelte',
|
||||
'src/pages/build/BuildPage.jsx',
|
||||
'src/content/build/Card.astro',
|
||||
// Go and C# toolchains write their output elsewhere.
|
||||
'src/go/build/build.go',
|
||||
'tools/src/Build/BuildManager.cs',
|
||||
// A JVM package named `build` keeps every file, as before (#1642).
|
||||
'src/main/java/com/acme/build/Script.js',
|
||||
];
|
||||
@@ -83,6 +88,14 @@ describe('the scope of a build folder below src', () => {
|
||||
'src/client/build/static/js/main.4f3a2b1c.js',
|
||||
'src/main/resources/static/build/bundle.js',
|
||||
'src/main/resources/build/Generated.java',
|
||||
// Builds copy or generate these into a build folder: a frozen app's `.py`,
|
||||
// CMake's C and C++, WordPress's PHP.
|
||||
'src/build/lib/app/main.py',
|
||||
'src/build/CMakeFiles/feature_tests.c',
|
||||
'src/build/CMakeFiles/feature_tests.cxx',
|
||||
'src/build/routes.php',
|
||||
// Rust waits until its name matching keeps a private item to its module.
|
||||
'crates/cli/src/build/mod.rs',
|
||||
// The other defaults still apply inside such a folder.
|
||||
'src/build/node_modules/pkg/index.ts',
|
||||
'src/build/dist/index.ts',
|
||||
@@ -165,6 +178,21 @@ describe('the scope of a build folder below src', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('a module kept in a build folder below src', () => {
|
||||
it('is indexed for Go and C#', async () => {
|
||||
const root = tempDir();
|
||||
write(root, {
|
||||
'src/go/build/build.go': 'package build\n\nfunc Import(path string) error {\n\treturn nil\n}\n',
|
||||
'tools/src/Build/BuildManager.cs': 'namespace Tools.Build\n{\n public class BuildManager\n {\n public void Run() { }\n }\n}\n',
|
||||
});
|
||||
const cg = await CodeGraph.init(root, { index: true });
|
||||
graphs.push(cg);
|
||||
const names = (file: string) => cg.getNodesInFile(file).map((n) => n.name);
|
||||
expect(names('src/go/build/build.go')).toContain('Import');
|
||||
expect(names('tools/src/Build/BuildManager.cs')).toEqual(expect.arrayContaining(['BuildManager', 'Run']));
|
||||
}, 60_000);
|
||||
});
|
||||
|
||||
describe('a JS/TS feature kept in src/build', () => {
|
||||
const FILES: Record<string, string> = {
|
||||
'package.json': JSON.stringify({ name: 'ui', private: true, dependencies: { react: '^18', 'react-router': '^7' } }),
|
||||
|
||||
@@ -7,7 +7,7 @@ Next to none — CodeGraph is **zero-config by default**, with nothing to write
|
||||
|
||||
## What it skips out of the box
|
||||
|
||||
- **Dependency, build, and cache directories** — `node_modules`, `vendor`, `dist`, `build`, `target`, `.venv`, `Pods`, `.next`, and the like across every [supported stack](/codegraph/reference/languages/) — so the graph is your code, not third-party noise. This holds even with no `.gitignore`. A `build` folder inside `src/` is the exception: no build step writes TypeScript, JSX, Vue, Svelte or Astro files, so those are indexed from it, and a Java, Kotlin or Scala package named `build` is indexed whole.
|
||||
- **Dependency, build, and cache directories** — `node_modules`, `vendor`, `dist`, `build`, `target`, `.venv`, `Pods`, `.next`, and the like across every [supported stack](/codegraph/reference/languages/) — so the graph is your code, not third-party noise. This holds even with no `.gitignore`. A `build` folder inside `src/` is the exception: no build step writes TypeScript, JSX, Vue, Svelte, Astro, Go or C# files into one, so those are indexed from it, and a Java, Kotlin or Scala package named `build` is indexed whole.
|
||||
- **Anything in your `.gitignore`** — honored in git repos via git, and in non-git projects by reading `.gitignore` directly (root and nested).
|
||||
- **Files larger than 1 MB** — generated bundles, minified JS, vendored blobs.
|
||||
|
||||
|
||||
+21
-12
@@ -290,18 +290,26 @@ const DEFAULT_IGNORE_PATTERNS: string[] = [
|
||||
// Keep JVM packages named `build` (#1642). Unignore only the directory, not
|
||||
// its subtree: other defaults still apply.
|
||||
...JVM_BUILD_PACKAGE_DIRS.map((d) => `!${d}`),
|
||||
// Walk a `build` folder below `src/` too: a JS/TS app can keep a whole
|
||||
// feature there. Only its hand-written source files are indexed — see
|
||||
// buildOutputFolderUnderSrc. Other defaults still apply inside it.
|
||||
// Walk a `build` folder below `src/` too: a project can keep a whole
|
||||
// feature or module there. Only its hand-written source files are indexed
|
||||
// — see buildOutputFolderUnderSrc. Other defaults still apply inside it.
|
||||
'!**/src/**/build/',
|
||||
];
|
||||
|
||||
/**
|
||||
* Source files no compiler or bundler writes: TypeScript (with its module and
|
||||
* ArkTS variants), JSX, and Vue, Svelte and Astro components. Build steps emit
|
||||
* JavaScript, declarations, CSS, HTML and source maps instead.
|
||||
* Source files no compiler or bundler writes into a build folder: TypeScript
|
||||
* (with its module and ArkTS variants), JSX, and Vue, Svelte and Astro
|
||||
* components, whose builds emit JavaScript, declarations, CSS, HTML and
|
||||
* source maps instead; and Go and C#, whose toolchains write elsewhere (Go's
|
||||
* binaries, .NET's `bin/` and `obj/`). Python, C and C++, PHP and Java are
|
||||
* left out: setuptools and frozen apps copy `.py` into `build/`, CMake
|
||||
* generates C and C++ there, WordPress builds `build/*.php`. Rust waits too,
|
||||
* though Cargo writes to `target/`: its name matching doesn't yet keep a
|
||||
* private item to its own module, so dioxus's `src/build/patch.rs`, with a
|
||||
* private `type Result`, took 158 `Result` references the crate's own
|
||||
* `pub(crate) type Result` should keep.
|
||||
*/
|
||||
const HAND_WRITTEN_SOURCE = /\.(?:[mc]?ts|tsx|ets|jsx|vue|svelte|astro)$/i;
|
||||
const HAND_WRITTEN_SOURCE = /\.(?:[mc]?ts|tsx|ets|jsx|vue|svelte|astro|go|cs)$/i;
|
||||
/** TypeScript declarations, which `tsc` writes beside its JavaScript. */
|
||||
const DECLARATION_FILE = /\.d\.(?:[mc]?ts|ets)$/i;
|
||||
/** Matches the JVM packages named `build`, whose whole subtree stays indexed. */
|
||||
@@ -332,11 +340,12 @@ function srcBuildFolderOf(rel: string): string | null {
|
||||
* When `rel` is a file in a `build` folder below `src/` that a build step could
|
||||
* have written, that folder (see {@link srcBuildFolderOf}); otherwise null.
|
||||
*
|
||||
* The folder itself is walked: JS/TS apps keep real source there (luci-go
|
||||
* milo's whole `src/build/` feature). But an output tree built or copied into
|
||||
* `src/` — a nested CRA app's `build/`, a vendored pdf.js, a Laravel
|
||||
* `public/build` — holds JavaScript, CSS, HTML and maps, never TypeScript, JSX
|
||||
* or components, so only those hand-written types are indexed from it. Paths
|
||||
* The folder itself is walked: projects keep real source there (luci-go
|
||||
* milo's whole `src/build/` feature, Go's `src/go/build`, a .NET solution's
|
||||
* `src/Build/` project). But an output tree built or copied into `src/` — a
|
||||
* nested CRA app's `build/`, a vendored pdf.js, a Laravel `public/build` —
|
||||
* holds JavaScript, CSS, HTML and maps, never {@link HAND_WRITTEN_SOURCE}, so
|
||||
* only those hand-written types are indexed from it. Paths
|
||||
* without an extension are left alone: they are directories (a watcher event
|
||||
* for a removed folder carries no trailing slash), never files a build writes.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user