Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 22 additions & 9 deletions lib/src/http/scan.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { ZInitiateScanBodySchema } from "./types";

const context: GitContext = {
repoKey: "github.com/dittowords/cli",
repoRoot: "/Users/laura/cli",
repoRoot: "/Users/dev/cli",
commitSha: "d3c1a8148580e1869c91ee6caadda17165ceb0ea",
branch: "master",
dirty: false,
Expand All @@ -16,27 +16,38 @@ describe("buildInitiateScanBody", () => {
});

test("sends repo, sha, branch and repo-relative root when there is", () => {
expect(buildInitiateScanBody("/Users/laura/cli/lib/src", context)).toEqual({
path: "/Users/laura/cli/lib/src",
expect(buildInitiateScanBody("/Users/dev/cli/lib/src", context)).toEqual({
path: "/Users/dev/cli/lib/src",
repoKey: "github.com/dittowords/cli",
gitCommitSha: "d3c1a8148580e1869c91ee6caadda17165ceb0ea",
gitBranch: "master",
repoRelativeRoot: "lib/src",
scannedAllPaths: false,
scannedPaths: ["lib/src"],
});
});

test("sends an empty repo-relative root when scanning the repo root", () => {
const body = buildInitiateScanBody("/Users/laura/cli", context);
test("scanning the repo root covers every path, with no path list", () => {
const body = buildInitiateScanBody("/Users/dev/cli", context);
expect(body.repoRelativeRoot).toBe("");
expect(body.scannedAllPaths).toBe(true);
expect(body).not.toHaveProperty("scannedPaths");
});

test("omits the repo-relative root when the path is outside the repo", () => {
test("omits the whole scope when the path is outside the repo", () => {
const body = buildInitiateScanBody("/elsewhere/src", context);
expect(body).not.toHaveProperty("repoRelativeRoot");
expect(body).not.toHaveProperty("scannedAllPaths");
expect(body).not.toHaveProperty("scannedPaths");
});

test("scanned paths are relative to the repo root, not the scanned root", () => {
const body = buildInitiateScanBody("/Users/dev/cli/lib/src", context);
expect(body.scannedPaths).toEqual([body.repoRelativeRoot]);
});

test("sends a null branch on a detached HEAD", () => {
const body = buildInitiateScanBody("/Users/laura/cli", {
const body = buildInitiateScanBody("/Users/dev/cli", {
...context,
branch: null,
});
Expand All @@ -45,7 +56,7 @@ describe("buildInitiateScanBody", () => {
});

test("never sends repoRoot or dirty", () => {
const body = buildInitiateScanBody("/Users/laura/cli/lib", {
const body = buildInitiateScanBody("/Users/dev/cli/lib", {
...context,
dirty: true,
});
Expand All @@ -55,14 +66,16 @@ describe("buildInitiateScanBody", () => {
"path",
"repoKey",
"repoRelativeRoot",
"scannedAllPaths",
"scannedPaths",
]);
});

test("every body satisfies the request schema", () => {
for (const c of [null, context, { ...context, branch: null }]) {
expect(() =>
ZInitiateScanBodySchema.parse(
buildInitiateScanBody("/Users/laura/cli/lib", c)
buildInitiateScanBody("/Users/dev/cli/lib", c)
)
).not.toThrow();
}
Expand Down
18 changes: 17 additions & 1 deletion lib/src/http/scan.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,22 @@ function repoRelativeRoot(
return sep === "/" ? rel : rel.split(sep).join("/");
}

/**
* What the scan looked at, so the server only marks a code link removed where we
* actually looked. `scannedAllPaths` means the whole repo. Otherwise it's the one
* directory we scanned. Empty when the path is outside the repo, which the server
* treats as "looked nowhere".
*/
function scannedScope(root: string | undefined) {
if (root === undefined) return {};
if (root === "") return { repoRelativeRoot: root, scannedAllPaths: true };
return {
repoRelativeRoot: root,
scannedAllPaths: false,
scannedPaths: [root],
};
}

/**
* Builds the `POST /v2/scan` body. Without git context the body is exactly what
* the CLI has always sent, so a scan outside a repo is unaffected.
Expand All @@ -105,7 +121,7 @@ export function buildInitiateScanBody(
repoKey: gitContext.repoKey,
gitCommitSha: gitContext.commitSha,
gitBranch: gitContext.branch,
...(root === undefined ? {} : { repoRelativeRoot: root }),
...scannedScope(root),
};
}

Expand Down
2 changes: 2 additions & 0 deletions lib/src/http/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,8 @@ export const ZInitiateScanBodySchema = z.object({
repoKey: z.string().optional(),
gitCommitSha: z.string().optional(),
gitBranch: z.string().nullable().optional(),
scannedAllPaths: z.boolean().optional(),
scannedPaths: z.array(z.string()).optional(),
repoRelativeRoot: z.string().optional(),
});
export type IInitiateScanBody = z.infer<typeof ZInitiateScanBodySchema>;
Expand Down
4 changes: 2 additions & 2 deletions lib/src/scan/git.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ describe("normalizeRepoKey", () => {
"https://gitlab.com/group/sub/deeper/app.git",
"gitlab.com/group/sub/deeper/app",
],
["/Users/laura/Desktop/Ditto/cli", null],
["file:///Users/laura/Desktop/Ditto/cli", null],
["/Users/dev/Desktop/Ditto/cli", null],
["file:///Users/dev/Desktop/Ditto/cli", null],
["https://github.com/app", null],
["", null],
];
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@dittowords/cli",
"version": "5.8.0",
"version": "5.8.1",
"description": "Command Line Interface for Ditto (dittowords.com).",
"license": "MIT",
"main": "bin/ditto.js",
Expand Down
Loading