cli-index-explicit-path.test.ts 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. /**
  2. * `codegraph index <path>` rebuilds <path>, never an ancestor (#1524).
  3. *
  4. * The command used to resolve an uninitialized <path> upward to the nearest
  5. * initialized parent and rebuild THAT under a normal "Done" — so
  6. * `codegraph index child` from a monorepo re-indexed the whole container and
  7. * never said so. An explicit path that is not initialized is now an error that
  8. * names the ancestor it would have picked.
  9. */
  10. import { describe, it, expect, beforeAll, afterAll } from 'vitest';
  11. import { spawnSync } from 'child_process';
  12. import * as fs from 'fs';
  13. import * as os from 'os';
  14. import * as path from 'path';
  15. import { CodeGraph } from '../src';
  16. const BIN = path.resolve(__dirname, '../dist/bin/codegraph.js');
  17. function run(cwd: string, args: string[]) {
  18. const r = spawnSync(process.execPath, [BIN, ...args], {
  19. cwd,
  20. encoding: 'utf-8',
  21. env: { ...process.env, CODEGRAPH_NO_DAEMON: '1', CODEGRAPH_WASM_RELAUNCHED: '1', NO_COLOR: '1' },
  22. });
  23. return { status: r.status, out: (r.stdout ?? '') + (r.stderr ?? '') };
  24. }
  25. describe('codegraph index <path> (#1524)', () => {
  26. let root: string;
  27. let parent: string;
  28. let child: string;
  29. beforeAll(async () => {
  30. root = fs.mkdtempSync(path.join(os.tmpdir(), 'codegraph-index-path-'));
  31. parent = path.join(root, 'parent');
  32. child = path.join(parent, 'child');
  33. fs.mkdirSync(child, { recursive: true });
  34. fs.writeFileSync(path.join(parent, 'p.py'), 'def parent_only():\n return 1\n');
  35. fs.writeFileSync(path.join(child, 'c.py'), 'def child_only():\n return 2\n');
  36. const cg = CodeGraph.initSync(parent);
  37. await cg.indexAll();
  38. cg.close();
  39. });
  40. afterAll(() => {
  41. fs.rmSync(root, { recursive: true, force: true });
  42. });
  43. it('refuses an explicit path that has no index of its own, naming the ancestor it would have rebuilt', () => {
  44. const before = fs.statSync(path.join(parent, '.codegraph', 'codegraph.db')).mtimeMs;
  45. const r = run(root, ['index', child, '--quiet']);
  46. expect(r.status).toBe(1);
  47. expect(r.out).toContain(`not initialized in ${child}`);
  48. expect(r.out).toContain(parent);
  49. // The parent's index was not touched.
  50. expect(fs.statSync(path.join(parent, '.codegraph', 'codegraph.db')).mtimeMs).toBe(before);
  51. expect(fs.existsSync(path.join(child, '.codegraph'))).toBe(false);
  52. });
  53. it('rebuilds the explicit path when it is initialized, and a bare `index` still resolves upward from a subdirectory', () => {
  54. expect(run(root, ['index', parent, '--quiet']).status).toBe(0);
  55. expect(run(child, ['index', '--quiet']).status).toBe(0);
  56. });
  57. });