@lizard-build/cli 4.0.67 → 4.0.69

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.
@@ -12,6 +12,9 @@ describe("lizard domain dns: names and types", () => {
12
12
  it("accepts record types in any case, redirect as URL301", () => {
13
13
  expect(parseType("cname")).toBe("CNAME");
14
14
  expect(parseType("redirect")).toBe("URL301");
15
+ expect(parseType("url")).toBe("URL");
16
+ expect(parseType("redirect302")).toBe("URL");
17
+ expect(parseType("frame")).toBe("FRAME");
15
18
  expect(() => parseType("SRV")).toThrow(/Unknown record type/);
16
19
  });
17
20
  });
@@ -26,9 +29,10 @@ describe("lizard domain <bought domain>: records it would replace", () => {
26
29
  expect(recordsToReplace(records, ["@", "www"]).map((r: { name: string }) => r.name)).toEqual(["@", "www"]);
27
30
  expect(recordsToReplace(records, ["api"])).toHaveLength(1);
28
31
  expect(recordsToReplace(records, ["blog"])).toHaveLength(0);
32
+ expect(recordsToReplace([rec("@", "URL", "https://elsewhere.example.net/page")], ["@"])).toHaveLength(1);
29
33
  });
30
34
  it("does not count the parking page or an earlier Lizard target", () => {
31
- const records = [rec("www", "CNAME", "parkingpage.namecheap.com."), rec("@", "ALIAS", "eu.onlizard.com")];
35
+ const records = [rec("www", "CNAME", "parkingpage.namecheap.com."), rec("@", "ALIAS", "eu.onlizard.com"), rec("@", "URL", "http://www.godelgate.com?from=@")];
32
36
  expect(recordsToReplace(records, ["@", "www"])).toHaveLength(0);
33
37
  });
34
38
  });
@@ -1,5 +1,9 @@
1
1
  import { describe, it, expect, afterEach, vi } from "vitest";
2
- import { repoFromRemote, qs, gitURL, helperCommand, resolveRepo, lg, segs } from "../../src/lib/lizard-git.js";
2
+ import { mkdtempSync, mkdirSync, writeFileSync, symlinkSync, unlinkSync } from "node:fs";
3
+ import { tmpdir } from "node:os";
4
+ import { join } from "node:path";
5
+ import { qs, gitURL, resolveRepo, lg, segs } from "../../src/lib/lizard-git.js";
6
+ import { changesOf, scanWorking, saveCheckout, findCheckout, sha256, unifiedDiff, type Checkout } from "../../src/lib/checkout.js";
3
7
 
4
8
  afterEach(() => {
5
9
  vi.unstubAllGlobals();
@@ -7,18 +11,6 @@ afterEach(() => {
7
11
  });
8
12
 
9
13
  describe("lizard git helpers", () => {
10
- it("reads owner/name from Lizard Git remotes only", () => {
11
- expect(repoFromRemote("https://lizard.build/git/alice/app.git")).toBe("alice/app");
12
- expect(repoFromRemote("https://lizard:liz_x@lizard.build/git/alice/app")).toBe("alice/app");
13
- expect(repoFromRemote("https://git.lizard.build/alice/app.git")).toBe("alice/app"); // older clones
14
- expect(repoFromRemote("https://lizard:liz_x@git.lizard.build/alice/app")).toBe("alice/app");
15
- expect(repoFromRemote("https://github.com/alice/app.git")).toBeNull();
16
- expect(repoFromRemote("git@github.com:alice/app.git")).toBeNull();
17
- expect(repoFromRemote("https://lizard.build/alice/app.git")).toBeNull();
18
- expect(repoFromRemote("https://lizard.build/gitx/alice/app.git")).toBeNull();
19
- expect(repoFromRemote("https://lizard.build/git/alice/app/extra.git")).toBeNull();
20
- });
21
-
22
14
  it("drops empty query values", () => {
23
15
  expect(qs("/x", { a: "1", b: undefined, c: "", d: false, e: 2 })).toBe("/x?a=1&e=2");
24
16
  });
@@ -26,12 +18,6 @@ describe("lizard git helpers", () => {
26
18
  it("honours LIZARD_GIT_URL", () => {
27
19
  vi.stubEnv("LIZARD_GIT_URL", "http://localhost:8080/");
28
20
  expect(gitURL()).toBe("http://localhost:8080");
29
- expect(repoFromRemote("http://localhost:8080/a/b.git")).toBe("a/b");
30
- expect(repoFromRemote("https://git.lizard.build/a/b.git")).toBeNull(); // another server: only it
31
- });
32
-
33
- it("runs itself as git's credential helper", () => {
34
- expect(helperCommand()).toMatch(/^!'.+' .*git credential$/);
35
21
  });
36
22
 
37
23
  it("takes owner/name or a bare name (yours) for --repo", async () => {
@@ -66,8 +52,63 @@ describe("lizard git safety", () => {
66
52
  await expect(resolveRepo("a/..")).rejects.toThrow();
67
53
  expect(() => segs("../../api/user/tokens")).toThrow(/bad path/);
68
54
  expect(segs("src/a b.js")).toBe("src/a%20b.js");
69
- expect(repoFromRemote("https://git.lizard.build/../x.git")).toBeNull();
70
- expect(repoFromRemote("https://lizard.build/git/../x.git")).toBeNull();
71
- expect(repoFromRemote("https://lizard.build/git/a/...git")).toBeNull();
55
+ });
56
+ });
57
+
58
+ describe("lizard git checkouts", () => {
59
+ const make = (files: Record<string, string>, state: Partial<Checkout> = {}) => {
60
+ const root = mkdtempSync(join(tmpdir(), "lzg-"));
61
+ const c: Checkout = { version: 1, url: "x", repo: "alice/app", branch: "main", base: "b".repeat(64), root: "r".repeat(64), sparse: null, files: {}, ...state };
62
+ for (const [p, body] of Object.entries(files)) {
63
+ mkdirSync(join(root, p, ".."), { recursive: true });
64
+ writeFileSync(join(root, p), body);
65
+ c.files[p] = { h: sha256(body), m: "100644" };
66
+ }
67
+ saveCheckout(root, c);
68
+ return { root, c };
69
+ };
70
+
71
+ it("finds its checkout from a subdirectory and the repository from it", async () => {
72
+ const { root } = make({ "src/a.ts": "a" });
73
+ expect(findCheckout(join(root, "src"))).toBe(root);
74
+ const cwd = process.cwd();
75
+ process.chdir(join(root, "src"));
76
+ try {
77
+ expect(await resolveRepo()).toBe("alice/app");
78
+ } finally {
79
+ process.chdir(cwd);
80
+ }
81
+ });
82
+
83
+ it("sees added, modified and deleted files, and nothing it shouldn't", () => {
84
+ const { root, c } = make({ "a.txt": "a", "src/b.txt": "b", "gone.txt": "g" });
85
+ writeFileSync(join(root, "a.txt"), "a2");
86
+ writeFileSync(join(root, "new.txt"), "n");
87
+ mkdirSync(join(root, ".lizard/workflows"), { recursive: true }); // a repository's CI: content like any other
88
+ writeFileSync(join(root, ".lizard/workflows/ci.yml"), "on: push\n");
89
+ writeFileSync(join(root, ".gitignore"), "*.log\nbuild/\n");
90
+ writeFileSync(join(root, "debug.log"), "x");
91
+ mkdirSync(join(root, "build"));
92
+ writeFileSync(join(root, "build/out.js"), "x");
93
+ mkdirSync(join(root, "node_modules/x"), { recursive: true });
94
+ writeFileSync(join(root, "node_modules/x/i.js"), "x");
95
+ symlinkSync("a.txt", join(root, "link"));
96
+ unlinkSync(join(root, "gone.txt"));
97
+ const ch = changesOf(c, scanWorking(root, c));
98
+ expect(ch).toEqual({ added: [".gitignore", ".lizard/workflows/ci.yml", "link", "new.txt"], modified: ["a.txt"], deleted: ["gone.txt"] });
99
+ });
100
+
101
+ it("a sparse checkout only looks inside its folders", () => {
102
+ const { root, c } = make({ "src/a.txt": "a" }, { sparse: ["src"] });
103
+ writeFileSync(join(root, "outside.txt"), "o");
104
+ writeFileSync(join(root, "src/b.txt"), "b");
105
+ expect(changesOf(c, scanWorking(root, c)).added).toEqual(["src/b.txt"]);
106
+ });
107
+
108
+ it("diffs lines", () => {
109
+ const d = unifiedDiff("a\nb\nc\n", "a\nB\nc\n", "f");
110
+ expect(d).toContain("@@ -1,4 +1,4 @@");
111
+ expect(d).toContain("-b");
112
+ expect(d).toContain("+B");
72
113
  });
73
114
  });