Skip to content

Commit 641dcc6

Browse files
committed
Extract fileChanges normalization
1 parent 997ec5e commit 641dcc6

9 files changed

Lines changed: 235 additions & 420 deletions

File tree

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,14 @@
5555
"@graphql-codegen/cli": "^7.1.2",
5656
"@tsconfig/node22": "^22.0.5",
5757
"@types/node": "^25.9.1",
58+
"fs-fixture": "^2.14.0",
5859
"oxfmt": "^0.53.0",
5960
"oxlint": "^1.68.0",
6061
"oxlint-tsgolint": "^0.23.0",
6162
"pino": "^9.3.2",
6263
"pino-pretty": "^11.2.2",
6364
"publint": "^0.3.21",
65+
"tinyexec": "^1.2.4",
6466
"tsdown": "^0.22.1",
6567
"typescript": "^6.0.3",
6668
"vitest": "^4.1.8"

pnpm-lock.yaml

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

src/fs.ts

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,37 @@
11
import { promises as fs } from "fs";
22
import * as path from "path";
3+
import { commitFilesFromBase64 } from "./core.ts";
34
import type {
4-
CommitFilesFromBuffersArgs,
5+
CommitFilesFromBase64Args,
56
CommitFilesFromDirectoryArgs,
67
CommitFilesResult,
78
} from "./interface.ts";
8-
import { commitFilesFromBuffers } from "./node.ts";
99

10-
export const commitFilesFromDirectory = async ({
10+
export async function commitFilesFromDirectory({
1111
cwd,
1212
fileChanges,
1313
...otherArgs
14-
}: CommitFilesFromDirectoryArgs): Promise<CommitFilesResult> => {
15-
const additions: CommitFilesFromBuffersArgs["fileChanges"]["additions"] =
16-
await Promise.all(
17-
(fileChanges.additions || []).map(async (p) => {
18-
return {
19-
path: p,
20-
contents: await fs.readFile(path.join(cwd, p)),
21-
};
22-
}),
23-
);
24-
25-
return commitFilesFromBuffers({
14+
}: CommitFilesFromDirectoryArgs): Promise<CommitFilesResult> {
15+
return await commitFilesFromBase64({
2616
...otherArgs,
27-
fileChanges: {
28-
additions,
29-
deletions: fileChanges.deletions,
30-
},
17+
fileChanges: await normalizeFileChanges(fileChanges, cwd),
3118
});
32-
};
19+
}
20+
21+
// Exported for testing only
22+
export async function normalizeFileChanges(
23+
fileChanges: CommitFilesFromDirectoryArgs["fileChanges"],
24+
cwd: string,
25+
): Promise<CommitFilesFromBase64Args["fileChanges"]> {
26+
return {
27+
additions: fileChanges.additions
28+
? await Promise.all(
29+
fileChanges.additions.map(async (a) => ({
30+
path: a,
31+
contents: await fs.readFile(path.join(cwd, a), "base64"),
32+
})),
33+
)
34+
: undefined,
35+
deletions: fileChanges.deletions?.map((d) => ({ path: d })),
36+
};
37+
}

src/git.ts

Lines changed: 31 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import { promises as fs } from "fs";
22
import { relative, resolve } from "path";
33
import git from "isomorphic-git";
4+
import { commitFilesFromBase64 } from "./core.ts";
45
import type {
56
CommitChangesFromRepoArgs,
6-
CommitFilesFromBuffersArgs,
7+
CommitFilesFromBase64Args,
78
CommitFilesResult,
89
} from "./interface.ts";
9-
import { commitFilesFromBuffers } from "./node.ts";
1010

1111
/**
1212
* @see https://isomorphic-git.org/docs/en/walk#walkerentry-mode
@@ -23,7 +23,6 @@ export const commitChangesFromRepo = async ({
2323
cwd: workingDirectory,
2424
recursivelyFindRoot = true,
2525
filterFiles,
26-
log,
2726
...otherArgs
2827
}: CommitChangesFromRepoArgs): Promise<CommitFilesResult> => {
2928
const ref = base?.commit ?? "HEAD";
@@ -44,6 +43,27 @@ export const commitChangesFromRepo = async ({
4443
throw new Error(`Could not determine oid for ${ref}`);
4544
}
4645

46+
return await commitFilesFromBase64({
47+
...otherArgs,
48+
fileChanges: await getFileChanges(
49+
workingDirectory,
50+
repoRoot,
51+
oid,
52+
filterFiles,
53+
),
54+
base: {
55+
commit: oid,
56+
},
57+
});
58+
};
59+
60+
// Exported for testing only
61+
export async function getFileChanges(
62+
cwd: string,
63+
repoRoot: string,
64+
ref: string,
65+
filterFiles?: CommitChangesFromRepoArgs["filterFiles"],
66+
): Promise<CommitFilesFromBase64Args["fileChanges"]> {
4767
/**
4868
* The directory to add files from. This is relative to the repository
4969
* root, and is used to filter files.
@@ -52,13 +72,10 @@ export const commitChangesFromRepo = async ({
5272
cwd === repoRoot ? null : relative(repoRoot, cwd) + "/";
5373

5474
// Determine changed files
55-
const trees = [git.TREE({ ref: oid }), git.WORKDIR()];
56-
const additions: CommitFilesFromBuffersArgs["fileChanges"]["additions"] = [];
57-
const deletions: CommitFilesFromBuffersArgs["fileChanges"]["deletions"] = [];
58-
const fileChanges = {
59-
additions,
60-
deletions,
61-
};
75+
const trees = [git.TREE({ ref }), git.WORKDIR()];
76+
const additions: CommitFilesFromBase64Args["fileChanges"]["additions"] = [];
77+
const deletions: CommitFilesFromBase64Args["fileChanges"]["deletions"] = [];
78+
6279
await git.walk({
6380
fs,
6481
dir: repoRoot,
@@ -115,7 +132,7 @@ export const commitChangesFromRepo = async ({
115132
}
116133
if (!workdir) {
117134
// File was deleted
118-
deletions.push(filepath);
135+
deletions.push({ path: filepath });
119136
return null;
120137
} else {
121138
// File was added / updated
@@ -125,19 +142,12 @@ export const commitChangesFromRepo = async ({
125142
}
126143
additions.push({
127144
path: filepath,
128-
contents: Buffer.from(arr),
145+
contents: Buffer.from(arr).toString("base64"),
129146
});
130147
}
131148
return true;
132149
},
133150
});
134151

135-
return commitFilesFromBuffers({
136-
...otherArgs,
137-
fileChanges,
138-
log,
139-
base: {
140-
commit: oid,
141-
},
142-
});
143-
};
152+
return { additions, deletions };
153+
}

src/node.ts

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,29 @@
11
import { commitFilesFromBase64 } from "./core.js";
22
import type {
3+
CommitFilesFromBase64Args,
34
CommitFilesFromBuffersArgs,
45
CommitFilesResult,
56
} from "./interface.ts";
67

7-
export const commitFilesFromBuffers = async ({
8+
export async function commitFilesFromBuffers({
89
fileChanges,
910
...otherArgs
10-
}: CommitFilesFromBuffersArgs): Promise<CommitFilesResult> => {
11-
return commitFilesFromBase64({
11+
}: CommitFilesFromBuffersArgs): Promise<CommitFilesResult> {
12+
return await commitFilesFromBase64({
1213
...otherArgs,
13-
fileChanges: {
14-
additions: fileChanges.additions?.map(({ path, contents }) => ({
15-
path,
16-
contents: contents.toString("base64"),
17-
})),
18-
deletions: fileChanges.deletions?.map((path) => ({ path })),
19-
},
14+
fileChanges: normalizeFileChanges(fileChanges),
2015
});
21-
};
16+
}
17+
18+
// Exported for testing only
19+
export function normalizeFileChanges(
20+
fileChanges: CommitFilesFromBuffersArgs["fileChanges"],
21+
): CommitFilesFromBase64Args["fileChanges"] {
22+
return {
23+
additions: fileChanges.additions?.map((a) => ({
24+
path: a.path,
25+
contents: a.contents.toString("base64"),
26+
})),
27+
deletions: fileChanges.deletions?.map((d) => ({ path: d })),
28+
};
29+
}

tests/fs.test.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { createFixture } from "fs-fixture";
2+
import { describe, expect, it } from "vitest";
3+
import { normalizeFileChanges } from "../src/fs.ts";
4+
5+
describe("normalizeFileChanges", () => {
6+
it("should convert file contents to base64", async () => {
7+
await using fixture = await createFixture({
8+
"foo.txt": "Hello, world!",
9+
});
10+
11+
const result = await normalizeFileChanges(
12+
{
13+
additions: ["foo.txt"],
14+
deletions: ["bar.txt"],
15+
},
16+
fixture.path,
17+
);
18+
19+
expect(result).toEqual({
20+
additions: [
21+
{
22+
path: "foo.txt",
23+
contents: await fixture.readFile("foo.txt", "base64"),
24+
},
25+
],
26+
deletions: [{ path: "bar.txt" }],
27+
});
28+
});
29+
30+
it("should pass through empty file changes", async () => {
31+
const result = await normalizeFileChanges(
32+
{ additions: [], deletions: [] },
33+
"/",
34+
);
35+
36+
expect(result).toEqual({ additions: [], deletions: [] });
37+
});
38+
});

0 commit comments

Comments
 (0)