86 lines
2.6 KiB
TypeScript
86 lines
2.6 KiB
TypeScript
import { readFileSync } from "node:fs";
|
|
|
|
import git from "@agentos-software/git";
|
|
import { describe, expect, it } from "vitest";
|
|
|
|
import {
|
|
getExecutableGitSoftware,
|
|
makeGitExecutablesRunnable,
|
|
} from "./agent-os-git-software";
|
|
|
|
const TAR_BLOCK_SIZE = 512;
|
|
const READ_ONLY_EXECUTABLE_MODE = Buffer.from([0xa4, 0x81, 0x00, 0x00]);
|
|
const RUNNABLE_EXECUTABLE_MODE = Buffer.from([0xed, 0x81, 0x00, 0x00]);
|
|
|
|
const readTarModes = (packageBytes: Buffer): Map<string, number> => {
|
|
const tarOffset =
|
|
16 + packageBytes.readUInt32LE(8) + packageBytes.readUInt32LE(12);
|
|
const modes = new Map<string, number>();
|
|
let offset = tarOffset;
|
|
|
|
while (
|
|
offset + TAR_BLOCK_SIZE <= packageBytes.length &&
|
|
packageBytes
|
|
.subarray(offset, offset + TAR_BLOCK_SIZE)
|
|
.some((byte) => byte !== 0)
|
|
) {
|
|
const [name = ""] = packageBytes
|
|
.subarray(offset, offset + 100)
|
|
.toString("utf-8")
|
|
.split("\0");
|
|
const mode = Number.parseInt(
|
|
packageBytes
|
|
.subarray(offset + 100, offset + 108)
|
|
.toString("ascii")
|
|
.replaceAll("\0", "")
|
|
.trim(),
|
|
8
|
|
);
|
|
const size = Number.parseInt(
|
|
packageBytes
|
|
.subarray(offset + 124, offset + 136)
|
|
.toString("ascii")
|
|
.replaceAll("\0", "")
|
|
.trim() || "0",
|
|
8
|
|
);
|
|
|
|
modes.set(name, mode);
|
|
offset +=
|
|
TAR_BLOCK_SIZE + Math.ceil(size / TAR_BLOCK_SIZE) * TAR_BLOCK_SIZE;
|
|
}
|
|
|
|
return modes;
|
|
};
|
|
|
|
describe("AgentOS Git software", () => {
|
|
it("marks the packaged Git commands executable", () => {
|
|
const repaired = makeGitExecutablesRunnable(readFileSync(git.packagePath));
|
|
const modes = readTarModes(repaired);
|
|
|
|
expect(modes.get("./bin/git")).toBe(0o755);
|
|
expect(modes.get("./bin/git-remote-http")).toBe(0o755);
|
|
expect(modes.get("./bin/git-remote-https")).toBe(0o755);
|
|
expect(repaired.includes(Buffer.from("0.3.0-zp.1", "ascii"))).toBe(true);
|
|
|
|
const mountIndexOffset = 16 + repaired.readUInt32LE(8);
|
|
const tarOffset = mountIndexOffset + repaired.readUInt32LE(12);
|
|
const mountIndex = repaired.subarray(mountIndexOffset, tarOffset);
|
|
expect(mountIndex.includes(READ_ONLY_EXECUTABLE_MODE)).toBe(false);
|
|
expect(
|
|
mountIndex.toString("hex").split(RUNNABLE_EXECUTABLE_MODE.toString("hex"))
|
|
.length - 1
|
|
).toBe(3);
|
|
});
|
|
|
|
it("writes a stable repaired package for the AgentOS registry", () => {
|
|
const first = getExecutableGitSoftware();
|
|
const second = getExecutableGitSoftware();
|
|
|
|
expect(second).toEqual(first);
|
|
expect(readTarModes(readFileSync(first.packagePath)).get("./bin/git")).toBe(
|
|
0o755
|
|
);
|
|
});
|
|
});
|