Skip to content

Commit ec9609a

Browse files
ref(core): extract getCallingFile utility for plugins to share
The tinybench and benchmark.js plugins each carried their own near-identical implementation of "what file called withCodSpeed()", built on stack-trace + find-up + getGitDir to compute a path relative to the enclosing git repository. Move the helper into @codspeed/core (next to getGitDir, which it already depends on), accept a `depth` argument to skip indirection frames the way benchmark.js needs, and rewire both plugins to import from core. Drop the now-redundant stack-trace dependency from each plugin's package.json — it lives on core alone now. The benchmark.js-plugin integ tests mock @codspeed/core wholesale; add getCallingFile to the un-mocked names alongside getGitDir so the URI derivation still works under test. Refs COD-2721 Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 99c5a9f commit ec9609a

10 files changed

Lines changed: 50 additions & 65 deletions

File tree

packages/benchmark.js-plugin/package.json

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,12 @@
3333
"@babel/preset-env": "^7.22.5",
3434
"@types/benchmark": "^2.1.2",
3535
"@types/lodash": "^4.14.195",
36-
"@types/stack-trace": "^0.0.30",
3736
"benchmark": "^2.1.4",
3837
"jest-mock-extended": "^3.0.4"
3938
},
4039
"dependencies": {
4140
"@codspeed/core": "workspace:^5.4.0",
42-
"lodash": "^4.17.10",
43-
"stack-trace": "1.0.0-pre2"
41+
"lodash": "^4.17.10"
4442
},
4543
"peerDependencies": {
4644
"benchmark": "^2.1.0"

packages/benchmark.js-plugin/src/buildSuiteAdd.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1+
import { getCallingFile } from "@codspeed/core";
12
import { Options, Suite } from "benchmark";
23
import { isFunction, isPlainObject } from "lodash";
3-
import getCallingFile from "./getCallingFile";
44

55
function isOptions(options: unknown): options is Options {
66
return isPlainObject(options);

packages/benchmark.js-plugin/src/getCallingFile.ts

Lines changed: 0 additions & 17 deletions
This file was deleted.

packages/benchmark.js-plugin/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import {
2+
getCallingFile,
23
InstrumentHooks,
34
mongoMeasurement,
45
optimizeFunction,
@@ -11,7 +12,6 @@ import {
1112
} from "@codspeed/core";
1213
import Benchmark from "benchmark";
1314
import buildSuiteAdd from "./buildSuiteAdd";
14-
import getCallingFile from "./getCallingFile";
1515
import { CodSpeedBenchmark } from "./types";
1616

1717
declare const __VERSION__: string;

packages/benchmark.js-plugin/tests/index.integ.test.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ import { registerBenchmarks } from "./registerBenchmarks";
88
import { registerOtherBenchmarks } from "./registerOtherBenchmarks";
99

1010
jest.mock("@codspeed/core", () => {
11-
mockCore.getGitDir = jest.requireActual("@codspeed/core").getGitDir;
11+
const actual = jest.requireActual("@codspeed/core");
12+
mockCore.getGitDir = actual.getGitDir;
13+
mockCore.getCallingFile = actual.getCallingFile;
1214
return mockCore;
1315
});
1416

packages/core/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
"license": "Apache-2.0",
3434
"devDependencies": {
3535
"@types/find-up": "^4.0.0",
36+
"@types/stack-trace": "^0.0.30",
3637
"node-addon-api": "^5.1.0",
3738
"node-gyp": "^12.2.0",
3839
"openapi-typescript-codegen": "^0.23.0",
@@ -42,6 +43,7 @@
4243
"axios": "^1.4.0",
4344
"find-up": "^6.3.0",
4445
"form-data": "^4.0.4",
45-
"node-gyp-build": "^4.6.0"
46+
"node-gyp-build": "^4.6.0",
47+
"stack-trace": "1.0.0-pre2"
4648
}
4749
}

packages/core/src/utils.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { Options as FindupOptions, findUpSync } from "find-up";
2-
import { dirname } from "path";
2+
import path, { dirname } from "path";
3+
import { get as getStackTrace } from "stack-trace";
4+
import { fileURLToPath } from "url";
35

46
export function getGitDir(path: string): string | undefined {
57
const dotGitPath = findUpSync(".git", {
@@ -9,6 +11,28 @@ export function getGitDir(path: string): string | undefined {
911
return dotGitPath ? dirname(dotGitPath) : undefined;
1012
}
1113

14+
/**
15+
* Return the file that called the function this is invoked from, expressed as
16+
* a path relative to the enclosing git repository root.
17+
*
18+
* The `depth` parameter is the number of stack frames to skip past
19+
* `getCallingFile` itself. Pass `0` to get the file of the function that
20+
* called `getCallingFile`, `1` to skip one further frame (for indirection
21+
* through a helper), and so on.
22+
*/
23+
export function getCallingFile(depth: number): string {
24+
const stack = getStackTrace();
25+
let callingFile = stack[depth + 1].getFileName();
26+
const gitDir = getGitDir(callingFile);
27+
if (gitDir === undefined) {
28+
throw new Error("Could not find a git repository");
29+
}
30+
if (callingFile.startsWith("file://")) {
31+
callingFile = fileURLToPath(callingFile);
32+
}
33+
return path.relative(gitDir, callingFile);
34+
}
35+
1236
/**
1337
* Log debug messages if the environment variable `CODSPEED_DEBUG` is set.
1438
*/

packages/tinybench-plugin/package.json

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,12 @@
3636
"homepage": "https://codspeed.io",
3737
"license": "Apache-2.0",
3838
"devDependencies": {
39-
"@types/stack-trace": "^0.0.30",
4039
"esbuild-register": "^3.4.2",
4140
"tinybench": "^4.0.1",
4241
"vitest": "^3.2.4"
4342
},
4443
"dependencies": {
45-
"@codspeed/core": "workspace:^5.4.0",
46-
"stack-trace": "1.0.0-pre2"
44+
"@codspeed/core": "workspace:^5.4.0"
4745
},
4846
"peerDependencies": {
4947
"tinybench": ">=4.0.1"

packages/tinybench-plugin/src/index.ts

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
11
import {
2+
getCallingFile,
23
getCodspeedRunnerMode,
3-
getGitDir,
44
getInstrumentMode,
55
InstrumentHooks,
66
mongoMeasurement,
77
SetupInstrumentsRequestBody,
88
SetupInstrumentsResponse,
99
tryIntrospect,
1010
} from "@codspeed/core";
11-
import path from "path";
12-
import { get as getStackTrace } from "stack-trace";
1311
import { Bench } from "tinybench";
14-
import { fileURLToPath } from "url";
1512
import { setupCodspeedAnalysisBench } from "./analysis";
1613
import { getOrCreateUriMap } from "./uri";
1714
import { setupCodspeedWalltimeBench } from "./walltime";
@@ -24,13 +21,13 @@ export function withCodSpeed(bench: Bench): Bench {
2421
return bench;
2522
}
2623

27-
const rootCallingFile = getCallingFile();
24+
const rootCallingFile = getCallingFile(1);
2825

2926
// Compute and register URI for bench
3027
const uriMap = getOrCreateUriMap(bench);
3128
const rawAdd = bench.add;
3229
bench.add = (name, fn, opts?) => {
33-
const callingFile = getCallingFile();
30+
const callingFile = getCallingFile(1);
3431
let uri = callingFile;
3532
if (bench.name !== undefined) {
3633
uri += `::${bench.name}`;
@@ -50,19 +47,6 @@ export function withCodSpeed(bench: Bench): Bench {
5047
return bench;
5148
}
5249

53-
function getCallingFile(): string {
54-
const stack = getStackTrace();
55-
let callingFile = stack[2].getFileName(); // [here, withCodSpeed, actual caller]
56-
const gitDir = getGitDir(callingFile);
57-
if (gitDir === undefined) {
58-
throw new Error("Could not find a git repository");
59-
}
60-
if (callingFile.startsWith("file://")) {
61-
callingFile = fileURLToPath(callingFile);
62-
}
63-
return path.relative(gitDir, callingFile);
64-
}
65-
6650
/**
6751
* Dynamically setup the CodSpeed instruments.
6852
*/

pnpm-lock.yaml

Lines changed: 12 additions & 18 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)