gitnexus 1.6.4-rc.38 → 1.6.4-rc.39
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index-repo.js +2 -2
- package/dist/core/group/extractors/grpc-extractor.js +13 -2
- package/dist/core/group/extractors/http-route-extractor.js +9 -1
- package/dist/core/group/extractors/topic-extractor.js +14 -14
- package/dist/core/run-analyze.js +4 -5
- package/dist/storage/repo-manager.d.ts +2 -2
- package/dist/storage/repo-manager.js +31 -11
- package/package.json +1 -1
package/dist/cli/index-repo.js
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
*/
|
|
11
11
|
import path from 'path';
|
|
12
12
|
import fs from 'fs/promises';
|
|
13
|
-
import { getStoragePaths, loadMeta,
|
|
13
|
+
import { getStoragePaths, loadMeta, ensureGitNexusIgnored, registerRepo, } from '../storage/repo-manager.js';
|
|
14
14
|
import { getGitRoot, getRemoteUrl, isGitRepo } from '../storage/git.js';
|
|
15
15
|
export const indexCommand = async (inputPathParts, options) => {
|
|
16
16
|
console.log('\n GitNexus Index\n');
|
|
@@ -96,7 +96,7 @@ export const indexCommand = async (inputPathParts, options) => {
|
|
|
96
96
|
meta.remoteUrl = getRemoteUrl(repoPath);
|
|
97
97
|
}
|
|
98
98
|
await registerRepo(repoPath, meta);
|
|
99
|
-
await
|
|
99
|
+
await ensureGitNexusIgnored(repoPath);
|
|
100
100
|
const projectName = path.basename(repoPath);
|
|
101
101
|
const { stats } = meta;
|
|
102
102
|
console.log(` Repository registered: ${projectName}`);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as path from 'node:path';
|
|
2
2
|
import { glob } from 'glob';
|
|
3
3
|
import Parser from 'tree-sitter';
|
|
4
|
+
import { createIgnoreFilter } from '../../../config/ignore-service.js';
|
|
4
5
|
import { readSafe } from './fs-utils.js';
|
|
5
6
|
import { GRPC_SCAN_GLOB, getPluginForFile, hasProtoPlugin, } from './grpc-patterns/index.js';
|
|
6
7
|
/**
|
|
@@ -185,11 +186,16 @@ function longestSharedSegmentRun(aPath, bPath) {
|
|
|
185
186
|
}
|
|
186
187
|
async function buildProtoContext(repoPath) {
|
|
187
188
|
const servicesByName = new Map();
|
|
189
|
+
// `.gitnexusignore` / `.gitignore` honoured via the shared IgnoreService —
|
|
190
|
+
// see `filesystem-walker.ts` for the canonical pattern. Replaces a
|
|
191
|
+
// hardcoded `[node_modules, .git, vendor]` array; those names plus the
|
|
192
|
+
// rest of `DEFAULT_IGNORE_LIST` are still excluded by default (#1185).
|
|
193
|
+
const protoIgnoreFilter = await createIgnoreFilter(repoPath);
|
|
188
194
|
const protoFiles = await glob('**/*.proto', {
|
|
189
195
|
cwd: repoPath,
|
|
190
196
|
absolute: false,
|
|
191
197
|
nodir: true,
|
|
192
|
-
ignore:
|
|
198
|
+
ignore: protoIgnoreFilter,
|
|
193
199
|
});
|
|
194
200
|
const contents = new Map();
|
|
195
201
|
for (const rel of protoFiles) {
|
|
@@ -324,9 +330,14 @@ export class GrpcExtractor {
|
|
|
324
330
|
}
|
|
325
331
|
}
|
|
326
332
|
// ─── Source files (+ .proto when plugin available) ────────────
|
|
333
|
+
// Honour `.gitnexusignore` / `.gitignore` via the shared IgnoreService —
|
|
334
|
+
// mirrors `filesystem-walker.ts`. Replaces a hardcoded
|
|
335
|
+
// `[node_modules, .git, vendor, dist, build]` array; those names are all
|
|
336
|
+
// in `DEFAULT_IGNORE_LIST`, so default behaviour is preserved (#1185).
|
|
337
|
+
const sourceIgnoreFilter = await createIgnoreFilter(repoPath);
|
|
327
338
|
const sourceFiles = await glob(GRPC_SCAN_GLOB, {
|
|
328
339
|
cwd: repoPath,
|
|
329
|
-
ignore:
|
|
340
|
+
ignore: sourceIgnoreFilter,
|
|
330
341
|
nodir: true,
|
|
331
342
|
});
|
|
332
343
|
const parser = new Parser();
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as path from 'node:path';
|
|
2
2
|
import { glob } from 'glob';
|
|
3
3
|
import Parser from 'tree-sitter';
|
|
4
|
+
import { createIgnoreFilter } from '../../../config/ignore-service.js';
|
|
4
5
|
import { readSafe } from './fs-utils.js';
|
|
5
6
|
import { getPluginForFile, HTTP_SCAN_GLOB } from './http-patterns/index.js';
|
|
6
7
|
/**
|
|
@@ -183,9 +184,16 @@ export class HttpRouteExtractor {
|
|
|
183
184
|
return [...providers, ...consumers];
|
|
184
185
|
}
|
|
185
186
|
async scanFiles(repoPath) {
|
|
187
|
+
// Honour `.gitnexusignore` and `.gitignore` via the shared IgnoreService
|
|
188
|
+
// so contract extraction respects the same exclusion rules as the rest of
|
|
189
|
+
// the ingestion pipeline. Mirrors `filesystem-walker.ts` which uses the
|
|
190
|
+
// same shape. Replaces a hardcoded `[node_modules, .git, dist, build,
|
|
191
|
+
// vendor]` array — those names are still in `DEFAULT_IGNORE_LIST`, so
|
|
192
|
+
// default behaviour is preserved (#1185).
|
|
193
|
+
const ignoreFilter = await createIgnoreFilter(repoPath);
|
|
186
194
|
return glob(HTTP_SCAN_GLOB, {
|
|
187
195
|
cwd: repoPath,
|
|
188
|
-
ignore:
|
|
196
|
+
ignore: ignoreFilter,
|
|
189
197
|
nodir: true,
|
|
190
198
|
});
|
|
191
199
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { glob } from 'glob';
|
|
2
2
|
import Parser from 'tree-sitter';
|
|
3
|
+
import { createIgnoreFilter } from '../../../config/ignore-service.js';
|
|
3
4
|
import { readSafe } from './fs-utils.js';
|
|
4
5
|
import { scanFile, unquoteLiteral } from './tree-sitter-scanner.js';
|
|
5
6
|
import { TOPIC_SCAN_GLOB, getProviderForFile, } from './topic-patterns/index.js';
|
|
@@ -40,22 +41,21 @@ export class TopicExtractor {
|
|
|
40
41
|
return true;
|
|
41
42
|
}
|
|
42
43
|
async extract(_dbExecutor, repoPath, _repo) {
|
|
44
|
+
// Honour `.gitnexusignore` / `.gitignore` via the shared IgnoreService —
|
|
45
|
+
// mirrors `filesystem-walker.ts`. The 5-name hardcoded list
|
|
46
|
+
// (`node_modules, .git, vendor, dist, build`) is preserved because every
|
|
47
|
+
// entry is in `DEFAULT_IGNORE_LIST`, so default behaviour is unchanged
|
|
48
|
+
// (#1185). The Go-specific `**/*_test.go` filter is layered on top via a
|
|
49
|
+
// small wrapper so glob-level pruning is preserved (we never read those
|
|
50
|
+
// files); the wrapper short-circuits before calling the base filter.
|
|
51
|
+
const baseFilter = await createIgnoreFilter(repoPath);
|
|
52
|
+
const ignoreFilter = {
|
|
53
|
+
ignored: (p) => p.relative().endsWith('_test.go') || baseFilter.ignored(p),
|
|
54
|
+
childrenIgnored: (p) => baseFilter.childrenIgnored(p),
|
|
55
|
+
};
|
|
43
56
|
const files = await glob(TOPIC_SCAN_GLOB, {
|
|
44
57
|
cwd: repoPath,
|
|
45
|
-
ignore:
|
|
46
|
-
'**/node_modules/**',
|
|
47
|
-
'**/.git/**',
|
|
48
|
-
'**/vendor/**',
|
|
49
|
-
'**/dist/**',
|
|
50
|
-
'**/build/**',
|
|
51
|
-
// Language-level test file conventions. Go test files
|
|
52
|
-
// `*_test.go` live next to source; other languages either use
|
|
53
|
-
// separate test directories (Python's `tests/`, Java's
|
|
54
|
-
// `src/test/`) or are already covered by the dist/build ignores.
|
|
55
|
-
// Pushed to the glob level so the orchestrator stays
|
|
56
|
-
// language-agnostic.
|
|
57
|
-
'**/*_test.go',
|
|
58
|
-
],
|
|
58
|
+
ignore: ignoreFilter,
|
|
59
59
|
nodir: true,
|
|
60
60
|
});
|
|
61
61
|
// One parser reused across files; the scanner calls `setLanguage` per
|
package/dist/core/run-analyze.js
CHANGED
|
@@ -13,7 +13,7 @@ import fs from 'fs/promises';
|
|
|
13
13
|
import { runPipelineFromRepo } from './ingestion/pipeline.js';
|
|
14
14
|
import { initLbug, loadGraphToLbug, getLbugStats, executeQuery, executeWithReusedStatement, closeLbug, loadCachedEmbeddings, } from './lbug/lbug-adapter.js';
|
|
15
15
|
import { createSearchFTSIndexes } from './search/fts-indexes.js';
|
|
16
|
-
import { getStoragePaths, saveMeta, loadMeta,
|
|
16
|
+
import { getStoragePaths, saveMeta, loadMeta, ensureGitNexusIgnored, registerRepo, cleanupOldKuzuFiles, } from '../storage/repo-manager.js';
|
|
17
17
|
import { getCurrentCommit, getRemoteUrl, hasGitDir, getInferredRepoName } from '../storage/git.js';
|
|
18
18
|
import { generateAIContextFiles } from '../cli/ai-context.js';
|
|
19
19
|
import { EMBEDDING_TABLE_NAME } from './lbug/schema.js';
|
|
@@ -69,6 +69,7 @@ export async function runFullAnalysis(repoPath, options, callbacks) {
|
|
|
69
69
|
if (existingMeta && !options.force && existingMeta.lastCommit === currentCommit) {
|
|
70
70
|
// Non-git folders have currentCommit = '' — always rebuild since we can't detect changes
|
|
71
71
|
if (currentCommit !== '') {
|
|
72
|
+
await ensureGitNexusIgnored(repoPath);
|
|
72
73
|
return {
|
|
73
74
|
repoName: options.registryName ?? getInferredRepoName(repoPath) ?? path.basename(repoPath),
|
|
74
75
|
repoPath,
|
|
@@ -302,10 +303,8 @@ export async function runFullAnalysis(repoPath, options, callbacks) {
|
|
|
302
303
|
name: options.registryName,
|
|
303
304
|
allowDuplicateName: options.allowDuplicateName,
|
|
304
305
|
});
|
|
305
|
-
//
|
|
306
|
-
|
|
307
|
-
await addToGitignore(repoPath);
|
|
308
|
-
}
|
|
306
|
+
// Keep generated .gitnexus contents ignored without editing the user's root .gitignore.
|
|
307
|
+
await ensureGitNexusIgnored(repoPath);
|
|
309
308
|
// ── Generate AI context files (best-effort) ───────────────────────
|
|
310
309
|
let aggregatedClusterCount = 0;
|
|
311
310
|
if (pipelineResult.communityResult?.communities) {
|
|
@@ -128,9 +128,9 @@ export declare const loadRepo: (repoPath: string) => Promise<IndexedRepo | null>
|
|
|
128
128
|
*/
|
|
129
129
|
export declare const findRepo: (startPath: string) => Promise<IndexedRepo | null>;
|
|
130
130
|
/**
|
|
131
|
-
*
|
|
131
|
+
* Keep generated index files ignored without modifying the user's root .gitignore.
|
|
132
132
|
*/
|
|
133
|
-
export declare const
|
|
133
|
+
export declare const ensureGitNexusIgnored: (repoPath: string) => Promise<void>;
|
|
134
134
|
/**
|
|
135
135
|
* Get the path to the global GitNexus directory
|
|
136
136
|
*/
|
|
@@ -50,6 +50,7 @@ export const canonicalizePath = (p) => {
|
|
|
50
50
|
}
|
|
51
51
|
};
|
|
52
52
|
const GITNEXUS_DIR = '.gitnexus';
|
|
53
|
+
const GITNEXUS_EXCLUDE_ENTRY = `${GITNEXUS_DIR}/`;
|
|
53
54
|
// ─── Local Storage Helpers ─────────────────────────────────────────────
|
|
54
55
|
/**
|
|
55
56
|
* Get the .gitnexus storage path for a repository
|
|
@@ -185,23 +186,42 @@ export const findRepo = async (startPath) => {
|
|
|
185
186
|
return null;
|
|
186
187
|
};
|
|
187
188
|
/**
|
|
188
|
-
*
|
|
189
|
+
* Keep generated index files ignored without modifying the user's root .gitignore.
|
|
189
190
|
*/
|
|
190
|
-
export const
|
|
191
|
-
const gitignorePath = path.join(repoPath, '.gitignore');
|
|
191
|
+
export const ensureGitNexusIgnored = async (repoPath) => {
|
|
192
|
+
const gitignorePath = path.join(getStoragePath(repoPath), '.gitignore');
|
|
193
|
+
await fs.mkdir(path.dirname(gitignorePath), { recursive: true });
|
|
194
|
+
await fs.writeFile(gitignorePath, '*\n', 'utf-8');
|
|
195
|
+
await ensureGitInfoExclude(repoPath);
|
|
196
|
+
};
|
|
197
|
+
const ensureGitInfoExclude = async (repoPath) => {
|
|
198
|
+
const gitDirPath = path.join(path.resolve(repoPath), '.git');
|
|
199
|
+
const excludePath = path.join(gitDirPath, 'info', 'exclude');
|
|
192
200
|
try {
|
|
193
|
-
const
|
|
194
|
-
if (
|
|
201
|
+
const gitDir = await fs.stat(gitDirPath);
|
|
202
|
+
if (!gitDir.isDirectory())
|
|
195
203
|
return;
|
|
196
|
-
const newContent = content.endsWith('\n')
|
|
197
|
-
? `${content}${GITNEXUS_DIR}\n`
|
|
198
|
-
: `${content}\n${GITNEXUS_DIR}\n`;
|
|
199
|
-
await fs.writeFile(gitignorePath, newContent, 'utf-8');
|
|
200
204
|
}
|
|
201
205
|
catch {
|
|
202
|
-
|
|
203
|
-
await fs.writeFile(gitignorePath, `${GITNEXUS_DIR}\n`, 'utf-8');
|
|
206
|
+
return;
|
|
204
207
|
}
|
|
208
|
+
await fs.mkdir(path.dirname(excludePath), { recursive: true });
|
|
209
|
+
let content = '';
|
|
210
|
+
try {
|
|
211
|
+
content = await fs.readFile(excludePath, 'utf-8');
|
|
212
|
+
}
|
|
213
|
+
catch (err) {
|
|
214
|
+
if (err?.code !== 'ENOENT')
|
|
215
|
+
throw err;
|
|
216
|
+
}
|
|
217
|
+
const excludes = content
|
|
218
|
+
.split(/\r?\n/)
|
|
219
|
+
.map((line) => line.trim())
|
|
220
|
+
.filter((line) => line && !line.startsWith('#'));
|
|
221
|
+
if (excludes.includes(GITNEXUS_DIR) || excludes.includes(GITNEXUS_EXCLUDE_ENTRY))
|
|
222
|
+
return;
|
|
223
|
+
const separator = content.length === 0 || content.endsWith('\n') ? '' : '\n';
|
|
224
|
+
await fs.writeFile(excludePath, `${content}${separator}${GITNEXUS_EXCLUDE_ENTRY}\n`, 'utf-8');
|
|
205
225
|
};
|
|
206
226
|
// ─── Global Registry (~/.gitnexus/registry.json) ───────────────────────
|
|
207
227
|
/**
|
package/package.json
CHANGED