@specific.dev/spectest 0.60.1 → 0.60.2

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/daemon.js CHANGED
@@ -3115,6 +3115,26 @@ async function runCoverageAdapters(svc) {
3115
3115
  clearTimeout(timer);
3116
3116
  }
3117
3117
  }
3118
+ /** Container name → its working directory, read once per container
3119
+ * (`docker inspect`); forks with the env like the rest of module memory.
3120
+ * Empty when the image sets none (paths are then reported from `/`). */
3121
+ const COVERAGE_ROOTS = new Map();
3122
+ async function coverageRoot(service) {
3123
+ const cached = COVERAGE_ROOTS.get(service);
3124
+ if (cached !== undefined)
3125
+ return cached;
3126
+ let root = "";
3127
+ try {
3128
+ const r = await docker(["inspect", "-f", "{{.Config.WorkingDir}}", service], 10_000);
3129
+ if (r.code === 0)
3130
+ root = r.stdout.trim();
3131
+ }
3132
+ catch {
3133
+ // Best-effort: the tree then falls back to a common-prefix guess.
3134
+ }
3135
+ COVERAGE_ROOTS.set(service, root);
3136
+ return root;
3137
+ }
3118
3138
  async function captureServiceCoverage() {
3119
3139
  const l = loaded;
3120
3140
  if (!l)
@@ -3130,6 +3150,9 @@ async function captureServiceCoverage() {
3130
3150
  if (error)
3131
3151
  return { service: svc.name, reports: [], error };
3132
3152
  const read = await readCoverageDir(svc.name, coverageHostDir(WORKSPACE, svc.name));
3153
+ const root = await coverageRoot(svc.name);
3154
+ if (root)
3155
+ read.root = root;
3133
3156
  // What ships is what ran during this capture, whatever the tool
3134
3157
  // counts: cumulative lcov is subtracted against the previous
3135
3158
  // capture (module memory, forks with the env); a delta adapter's
@@ -17,6 +17,12 @@ export interface CoverageReport {
17
17
  export interface ServiceCoverageCapture {
18
18
  service: string;
19
19
  reports: CoverageReport[];
20
+ /** The container's working directory (`docker inspect`), the root
21
+ * the reported container paths are relative to for a `COPY . <dir>`
22
+ * image. The server strips it to draw a project-relative tree; it
23
+ * never has to fetch code to do so. Absent for a container it could
24
+ * not be read from. */
25
+ root?: string;
20
26
  /** Set when the capture failed: the command failed, the directory was
21
27
  * empty, no file held an `SF:` record, or the reports were too large.
22
28
  * A case with an error here fails — a hole in the coverage data must
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@specific.dev/spectest",
3
- "version": "0.60.1",
3
+ "version": "0.60.2",
4
4
  "description": "Spectest SDK for defining test environments in TypeScript.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
package/src/daemon.ts CHANGED
@@ -3759,6 +3759,25 @@ async function runCoverageAdapters(
3759
3759
  }
3760
3760
  }
3761
3761
 
3762
+ /** Container name → its working directory, read once per container
3763
+ * (`docker inspect`); forks with the env like the rest of module memory.
3764
+ * Empty when the image sets none (paths are then reported from `/`). */
3765
+ const COVERAGE_ROOTS = new Map<string, string>();
3766
+
3767
+ async function coverageRoot(service: string): Promise<string> {
3768
+ const cached = COVERAGE_ROOTS.get(service);
3769
+ if (cached !== undefined) return cached;
3770
+ let root = "";
3771
+ try {
3772
+ const r = await docker(["inspect", "-f", "{{.Config.WorkingDir}}", service], 10_000);
3773
+ if (r.code === 0) root = r.stdout.trim();
3774
+ } catch {
3775
+ // Best-effort: the tree then falls back to a common-prefix guess.
3776
+ }
3777
+ COVERAGE_ROOTS.set(service, root);
3778
+ return root;
3779
+ }
3780
+
3762
3781
  async function captureServiceCoverage(): Promise<ServiceCoverageCapture[]> {
3763
3782
  const l = loaded;
3764
3783
  if (!l) return [];
@@ -3771,6 +3790,8 @@ async function captureServiceCoverage(): Promise<ServiceCoverageCapture[]> {
3771
3790
  const { error, deltaReports } = await runCoverageAdapters(svc);
3772
3791
  if (error) return { service: svc.name, reports: [], error };
3773
3792
  const read = await readCoverageDir(svc.name, coverageHostDir(WORKSPACE, svc.name));
3793
+ const root = await coverageRoot(svc.name);
3794
+ if (root) read.root = root;
3774
3795
  // What ships is what ran during this capture, whatever the tool
3775
3796
  // counts: cumulative lcov is subtracted against the previous
3776
3797
  // capture (module memory, forks with the env); a delta adapter's
@@ -57,6 +57,12 @@ export interface CoverageReport {
57
57
  export interface ServiceCoverageCapture {
58
58
  service: string;
59
59
  reports: CoverageReport[];
60
+ /** The container's working directory (`docker inspect`), the root
61
+ * the reported container paths are relative to for a `COPY . <dir>`
62
+ * image. The server strips it to draw a project-relative tree; it
63
+ * never has to fetch code to do so. Absent for a container it could
64
+ * not be read from. */
65
+ root?: string;
60
66
  /** Set when the capture failed: the command failed, the directory was
61
67
  * empty, no file held an `SF:` record, or the reports were too large.
62
68
  * A case with an error here fails — a hole in the coverage data must