@metaverse-systems/the-seed 1.0.2 → 1.2.0
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/.aiignore +5 -0
- package/.eslintrc.json +3 -1
- package/.vscode/settings.json +14 -0
- package/README.md +530 -0
- package/dist/Build.d.ts +10 -0
- package/dist/Build.js +60 -21
- package/dist/Build.js.map +1 -1
- package/dist/Config.d.ts +2 -2
- package/dist/Config.js +7 -5
- package/dist/Config.js.map +1 -1
- package/dist/Dependencies.d.ts +7 -0
- package/dist/Dependencies.js +76 -0
- package/dist/Dependencies.js.map +1 -0
- package/dist/Package.d.ts +45 -0
- package/dist/Package.js +249 -0
- package/dist/Package.js.map +1 -0
- package/dist/ResourcePak.d.ts +26 -0
- package/dist/ResourcePak.js +110 -0
- package/dist/ResourcePak.js.map +1 -0
- package/dist/Scopes.d.ts +9 -6
- package/dist/Scopes.js.map +1 -1
- package/dist/Template.d.ts +2 -1
- package/dist/Template.js +28 -25
- package/dist/Template.js.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/scripts/BuildCLI.js +8 -5
- package/dist/scripts/BuildCLI.js.map +1 -1
- package/dist/scripts/ConfigCLI.js +1 -1
- package/dist/scripts/ConfigCLI.js.map +1 -1
- package/dist/scripts/DependenciesCLI.d.ts +3 -0
- package/dist/scripts/DependenciesCLI.js +58 -0
- package/dist/scripts/DependenciesCLI.js.map +1 -0
- package/dist/scripts/PackageCLI.d.ts +3 -0
- package/dist/scripts/PackageCLI.js +38 -0
- package/dist/scripts/PackageCLI.js.map +1 -0
- package/dist/scripts/ResourcePakCLI.d.ts +3 -0
- package/dist/scripts/ResourcePakCLI.js +37 -0
- package/dist/scripts/ResourcePakCLI.js.map +1 -0
- package/dist/scripts/the-seed.js +19 -0
- package/dist/scripts/the-seed.js.map +1 -1
- package/dist/types.d.ts +42 -1
- package/native/binding.gyp +20 -0
- package/native/src/addon.cpp +60 -0
- package/package.json +4 -1
- package/src/Build.ts +73 -23
- package/src/Config.ts +9 -7
- package/src/Dependencies.ts +73 -0
- package/src/Package.ts +287 -0
- package/src/ResourcePak.ts +129 -0
- package/src/Scopes.ts +4 -4
- package/src/Template.ts +27 -25
- package/src/index.ts +16 -0
- package/src/scripts/BuildCLI.ts +8 -5
- package/src/scripts/ConfigCLI.ts +3 -3
- package/src/scripts/DependenciesCLI.ts +57 -0
- package/src/scripts/PackageCLI.ts +42 -0
- package/src/scripts/ResourcePakCLI.ts +38 -0
- package/src/scripts/the-seed.ts +19 -0
- package/src/types.ts +46 -1
- package/structure.md +0 -3
- package/test/Build.test.ts +223 -0
- package/test/Config.test.ts +11 -5
- package/test/Dependencies.test.ts +153 -0
- package/test/Package.test.ts +631 -0
- package/test/ResourcePak.test.ts +69 -0
- package/test/Scopes.test.ts +15 -7
- package/test/Template.test.ts +187 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import Config from "../Config";
|
|
2
|
+
import Package from "../Package";
|
|
3
|
+
import { ScriptArgsType } from "../types";
|
|
4
|
+
|
|
5
|
+
const PackageCLI = (scriptConfig: ScriptArgsType) => {
|
|
6
|
+
const command = scriptConfig.args[3];
|
|
7
|
+
|
|
8
|
+
// No arguments or help subcommand
|
|
9
|
+
if (!command || command === "help") {
|
|
10
|
+
console.log("Usage: the-seed package <output-directory> <project-dir> [project-dir2] ...");
|
|
11
|
+
console.log("");
|
|
12
|
+
console.log("Package binaries with their shared library dependencies into a directory.");
|
|
13
|
+
console.log("");
|
|
14
|
+
console.log("Arguments:");
|
|
15
|
+
console.log(" output-directory Name of the output directory to create");
|
|
16
|
+
console.log(" project-dir Project directories containing src/Makefile.am");
|
|
17
|
+
console.log("");
|
|
18
|
+
console.log("The command reads src/Makefile.am to determine the binary type and name,");
|
|
19
|
+
console.log("resolves installed binaries for all build targets, uses DependencyLister");
|
|
20
|
+
console.log("to find shared library dependencies, and copies everything into the output directory.");
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const outputDir = command;
|
|
25
|
+
const projectDirs = scriptConfig.args.slice(4);
|
|
26
|
+
|
|
27
|
+
// No project directories specified
|
|
28
|
+
if (projectDirs.length === 0) {
|
|
29
|
+
console.error("Usage: the-seed package <output-directory> <project-dir> [project-dir2] ...");
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const config = new Config(scriptConfig.configDir);
|
|
34
|
+
const pkg = new Package(config);
|
|
35
|
+
const success = pkg.run(outputDir, projectDirs);
|
|
36
|
+
|
|
37
|
+
if (!success) {
|
|
38
|
+
process.exit(1);
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export default PackageCLI;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import Config from "../Config";
|
|
2
|
+
import { ScriptArgsType } from "../types";
|
|
3
|
+
import ResourcePak from "../ResourcePak";
|
|
4
|
+
import inquirer from "inquirer";
|
|
5
|
+
|
|
6
|
+
const ResourcePakCLI = (scriptConfig: ScriptArgsType) => {
|
|
7
|
+
const config = new Config(scriptConfig.configDir);
|
|
8
|
+
const command = scriptConfig.args[3];
|
|
9
|
+
const name = scriptConfig.args[4];
|
|
10
|
+
|
|
11
|
+
let rp: ResourcePak;
|
|
12
|
+
|
|
13
|
+
switch(command) {
|
|
14
|
+
case "help":
|
|
15
|
+
console.log("Available resource-pak commands:");
|
|
16
|
+
console.log(" create <name>");
|
|
17
|
+
console.log(" add <resource-name> <filename>");
|
|
18
|
+
console.log(" build");
|
|
19
|
+
break;
|
|
20
|
+
case "create":
|
|
21
|
+
rp = new ResourcePak(config);
|
|
22
|
+
inquirer.prompt(rp.askName())
|
|
23
|
+
.then((answers) => {
|
|
24
|
+
rp.createPackage(answers.scopeName, answers.pakName);
|
|
25
|
+
});
|
|
26
|
+
break;
|
|
27
|
+
case "add":
|
|
28
|
+
rp = new ResourcePak(config);
|
|
29
|
+
rp.addResource(name, scriptConfig.args[5]);
|
|
30
|
+
break;
|
|
31
|
+
case "build":
|
|
32
|
+
rp = new ResourcePak(config);
|
|
33
|
+
rp.build();
|
|
34
|
+
break;
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export default ResourcePakCLI;
|
package/src/scripts/the-seed.ts
CHANGED
|
@@ -5,6 +5,9 @@ import ConfigCLI from "./ConfigCLI";
|
|
|
5
5
|
import ScopesCLI from "./ScopesCLI";
|
|
6
6
|
import TemplateCLI from "./TemplateCLI";
|
|
7
7
|
import BuildCLI from "./BuildCLI";
|
|
8
|
+
import ResourcePakCLI from "./ResourcePakCLI";
|
|
9
|
+
import DependenciesCLI from "./DependenciesCLI";
|
|
10
|
+
import PackageCLI from "./PackageCLI";
|
|
8
11
|
import { ScriptArgsType } from "../types";
|
|
9
12
|
|
|
10
13
|
const homedir = os.homedir;
|
|
@@ -20,10 +23,13 @@ const section = scriptConfig.args[2] || "help";
|
|
|
20
23
|
switch(section)
|
|
21
24
|
{
|
|
22
25
|
case "help":
|
|
26
|
+
console.log(scriptConfig.binName + " dependencies");
|
|
23
27
|
console.log(scriptConfig.binName + " build");
|
|
24
28
|
console.log(scriptConfig.binName + " config");
|
|
25
29
|
console.log(scriptConfig.binName + " scopes");
|
|
26
30
|
console.log(scriptConfig.binName + " template");
|
|
31
|
+
console.log(scriptConfig.binName + " package");
|
|
32
|
+
console.log(scriptConfig.binName + " resource-pak");
|
|
27
33
|
break;
|
|
28
34
|
case "config":
|
|
29
35
|
ConfigCLI(scriptConfig);
|
|
@@ -36,4 +42,17 @@ switch(section)
|
|
|
36
42
|
break;
|
|
37
43
|
case "build":
|
|
38
44
|
BuildCLI(scriptConfig);
|
|
45
|
+
break;
|
|
46
|
+
case "resource-pak":
|
|
47
|
+
ResourcePakCLI(scriptConfig);
|
|
48
|
+
break;
|
|
49
|
+
case "dependencies":
|
|
50
|
+
DependenciesCLI(scriptConfig);
|
|
51
|
+
break;
|
|
52
|
+
case "package":
|
|
53
|
+
PackageCLI(scriptConfig);
|
|
54
|
+
break;
|
|
55
|
+
default:
|
|
56
|
+
console.log("Invalid command. Use 'the-seed help' for usage information.");
|
|
57
|
+
break;
|
|
39
58
|
}
|
package/src/types.ts
CHANGED
|
@@ -13,7 +13,6 @@ export interface ScopesType {
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
export interface ConfigType {
|
|
16
|
-
[index: string]: any;
|
|
17
16
|
prefix: string;
|
|
18
17
|
scopes: ScopesType;
|
|
19
18
|
}
|
|
@@ -23,3 +22,49 @@ export interface ScriptArgsType {
|
|
|
23
22
|
args: string[];
|
|
24
23
|
configDir: string;
|
|
25
24
|
}
|
|
25
|
+
|
|
26
|
+
export interface ResourceType {
|
|
27
|
+
name: string;
|
|
28
|
+
filename: string;
|
|
29
|
+
size: number;
|
|
30
|
+
attributes?: { [key: string]: string };
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface PackageType {
|
|
34
|
+
author: AuthorType;
|
|
35
|
+
name: string;
|
|
36
|
+
license: string;
|
|
37
|
+
version: string;
|
|
38
|
+
scripts: {
|
|
39
|
+
[index: string]: string;
|
|
40
|
+
};
|
|
41
|
+
resources: ResourceType[];
|
|
42
|
+
main?: string;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface ScopeAnswersType {
|
|
46
|
+
scopeName: string;
|
|
47
|
+
authorName: string;
|
|
48
|
+
authorEmail: string;
|
|
49
|
+
authorURL: string;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export interface ScopeDefaultsType {
|
|
53
|
+
name?: string;
|
|
54
|
+
email?: string;
|
|
55
|
+
url?: string;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface DependencyResultType {
|
|
59
|
+
dependencies: Record<string, string[]>;
|
|
60
|
+
errors: Record<string, string>;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export interface BuildStep {
|
|
64
|
+
/** Human-readable step name (e.g., 'autogen', 'configure', 'compile', 'install') */
|
|
65
|
+
label: string;
|
|
66
|
+
/** Shell command to execute */
|
|
67
|
+
command: string;
|
|
68
|
+
/** If true, non-zero exit codes do not abort the build (used for 'make distclean') */
|
|
69
|
+
ignoreExitCode?: boolean;
|
|
70
|
+
}
|
package/structure.md
CHANGED
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import os from "os";
|
|
4
|
+
import Config from "../src/Config";
|
|
5
|
+
import Build, { targets } from "../src/Build";
|
|
6
|
+
import { BuildStep } from "../src/types";
|
|
7
|
+
|
|
8
|
+
jest.mock("child_process", () => ({
|
|
9
|
+
execSync: jest.fn(() => Buffer.from(""))
|
|
10
|
+
}));
|
|
11
|
+
|
|
12
|
+
import { execSync } from "child_process";
|
|
13
|
+
const mockedExecSync = execSync as jest.MockedFunction<typeof execSync>;
|
|
14
|
+
|
|
15
|
+
function createTempDir(): string {
|
|
16
|
+
return fs.mkdtempSync(path.join(os.tmpdir(), "build-test-"));
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
describe("test Build", () => {
|
|
20
|
+
let configDir: string;
|
|
21
|
+
let config: Config;
|
|
22
|
+
let build: Build;
|
|
23
|
+
|
|
24
|
+
beforeAll(() => {
|
|
25
|
+
configDir = createTempDir();
|
|
26
|
+
config = new Config(configDir);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
beforeEach(() => {
|
|
30
|
+
build = new Build(config);
|
|
31
|
+
mockedExecSync.mockClear();
|
|
32
|
+
mockedExecSync.mockReturnValue(Buffer.from(""));
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
afterAll(() => {
|
|
36
|
+
fs.rmSync(configDir, { recursive: true });
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
describe("targets map", () => {
|
|
40
|
+
it("has correct target mappings", () => {
|
|
41
|
+
expect(targets["native"]).toBe("x86_64-linux-gnu");
|
|
42
|
+
expect(targets["windows"]).toBe("x86_64-w64-mingw32");
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
describe("autogen", () => {
|
|
47
|
+
it("runs autogen.sh", () => {
|
|
48
|
+
build.autogen();
|
|
49
|
+
expect(mockedExecSync).toHaveBeenCalledWith(
|
|
50
|
+
"./autogen.sh",
|
|
51
|
+
expect.objectContaining({ stdio: "pipe" })
|
|
52
|
+
);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it("propagates errors", () => {
|
|
56
|
+
mockedExecSync.mockImplementation(() => {
|
|
57
|
+
throw new Error("autogen failed");
|
|
58
|
+
});
|
|
59
|
+
expect(() => build.autogen()).toThrow("autogen failed");
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
describe("configure", () => {
|
|
64
|
+
it("runs configure for native target", () => {
|
|
65
|
+
build.target = "native";
|
|
66
|
+
build.configure();
|
|
67
|
+
|
|
68
|
+
// First call is make distclean
|
|
69
|
+
expect(mockedExecSync).toHaveBeenCalledWith(
|
|
70
|
+
"make distclean",
|
|
71
|
+
expect.anything()
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
// Second call is configure
|
|
75
|
+
const configureCalls = mockedExecSync.mock.calls.filter(
|
|
76
|
+
(call) => String(call[0]).includes("./configure")
|
|
77
|
+
);
|
|
78
|
+
expect(configureCalls.length).toBe(1);
|
|
79
|
+
const configureCmd = String(configureCalls[0][0]);
|
|
80
|
+
expect(configureCmd).toContain("--prefix=" + config.config.prefix + "/x86_64-linux-gnu");
|
|
81
|
+
expect(configureCmd).not.toContain("--host");
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it("runs configure for windows target", () => {
|
|
85
|
+
build.target = "windows";
|
|
86
|
+
build.configure();
|
|
87
|
+
|
|
88
|
+
const configureCalls = mockedExecSync.mock.calls.filter(
|
|
89
|
+
(call) => String(call[0]).includes("./configure")
|
|
90
|
+
);
|
|
91
|
+
expect(configureCalls.length).toBe(1);
|
|
92
|
+
const configureCmd = String(configureCalls[0][0]);
|
|
93
|
+
expect(configureCmd).toContain("--host=x86_64-w64-mingw32");
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it("runs distclean before configure", () => {
|
|
97
|
+
build.target = "native";
|
|
98
|
+
build.configure();
|
|
99
|
+
|
|
100
|
+
const calls = mockedExecSync.mock.calls.map((c) => String(c[0]));
|
|
101
|
+
const distcleanIndex = calls.findIndex((c) => c.includes("make distclean"));
|
|
102
|
+
const configureIndex = calls.findIndex((c) => c.includes("./configure"));
|
|
103
|
+
expect(distcleanIndex).toBeLessThan(configureIndex);
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
describe("reconfigure", () => {
|
|
108
|
+
it("chains autogen and configure", () => {
|
|
109
|
+
build.reconfigure("native");
|
|
110
|
+
|
|
111
|
+
const calls = mockedExecSync.mock.calls.map((c) => String(c[0]));
|
|
112
|
+
const autogenIndex = calls.findIndex((c) => c.includes("./autogen.sh"));
|
|
113
|
+
const configureIndex = calls.findIndex((c) => c.includes("./configure"));
|
|
114
|
+
expect(autogenIndex).toBeGreaterThanOrEqual(0);
|
|
115
|
+
expect(configureIndex).toBeGreaterThan(autogenIndex);
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
describe("compile", () => {
|
|
120
|
+
it("runs make -j", () => {
|
|
121
|
+
build.compile();
|
|
122
|
+
expect(mockedExecSync).toHaveBeenCalledWith("make -j");
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
describe("install", () => {
|
|
127
|
+
it("runs make install", () => {
|
|
128
|
+
build.install();
|
|
129
|
+
expect(mockedExecSync).toHaveBeenCalledWith("make install");
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
describe("getSteps", () => {
|
|
134
|
+
it("returns 5 steps for full native build", () => {
|
|
135
|
+
const steps: BuildStep[] = build.getSteps("native", true);
|
|
136
|
+
expect(steps).toHaveLength(5);
|
|
137
|
+
expect(steps.map(s => s.label)).toEqual([
|
|
138
|
+
"autogen", "distclean", "configure", "compile", "install"
|
|
139
|
+
]);
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
it("returns 5 steps for full windows build", () => {
|
|
143
|
+
const steps: BuildStep[] = build.getSteps("windows", true);
|
|
144
|
+
expect(steps).toHaveLength(5);
|
|
145
|
+
expect(steps.map(s => s.label)).toEqual([
|
|
146
|
+
"autogen", "distclean", "configure", "compile", "install"
|
|
147
|
+
]);
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
it("returns 2 steps for incremental build (fullReconfigure=false)", () => {
|
|
151
|
+
const steps: BuildStep[] = build.getSteps("native", false);
|
|
152
|
+
expect(steps).toHaveLength(2);
|
|
153
|
+
expect(steps.map(s => s.label)).toEqual(["compile", "install"]);
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
it("native configure step does not contain --host flag", () => {
|
|
157
|
+
const steps = build.getSteps("native", true);
|
|
158
|
+
const configureStep = steps.find(s => s.label === "configure");
|
|
159
|
+
expect(configureStep).toBeDefined();
|
|
160
|
+
expect(configureStep!.command).not.toContain("--host");
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
it("windows configure step contains --host=x86_64-w64-mingw32", () => {
|
|
164
|
+
const steps = build.getSteps("windows", true);
|
|
165
|
+
const configureStep = steps.find(s => s.label === "configure");
|
|
166
|
+
expect(configureStep).toBeDefined();
|
|
167
|
+
expect(configureStep!.command).toContain("--host=x86_64-w64-mingw32");
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
it("distclean step has ignoreExitCode set to true", () => {
|
|
171
|
+
const steps = build.getSteps("native", true);
|
|
172
|
+
const distcleanStep = steps.find(s => s.label === "distclean");
|
|
173
|
+
expect(distcleanStep).toBeDefined();
|
|
174
|
+
expect(distcleanStep!.ignoreExitCode).toBe(true);
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
it("non-distclean steps do not have ignoreExitCode set to true", () => {
|
|
178
|
+
const steps = build.getSteps("native", true);
|
|
179
|
+
const nonDistclean = steps.filter(s => s.label !== "distclean");
|
|
180
|
+
for (const step of nonDistclean) {
|
|
181
|
+
expect(step.ignoreExitCode).toBeFalsy();
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
it("configure step includes correct prefix path for native", () => {
|
|
186
|
+
const steps = build.getSteps("native", true);
|
|
187
|
+
const configureStep = steps.find(s => s.label === "configure");
|
|
188
|
+
const expectedPrefix = config.config.prefix + "/x86_64-linux-gnu";
|
|
189
|
+
expect(configureStep!.command).toContain("--prefix=" + expectedPrefix);
|
|
190
|
+
expect(configureStep!.command).toContain("PKG_CONFIG_PATH=" + expectedPrefix + "/lib/pkgconfig/");
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
it("configure step includes correct prefix path for windows", () => {
|
|
194
|
+
const steps = build.getSteps("windows", true);
|
|
195
|
+
const configureStep = steps.find(s => s.label === "configure");
|
|
196
|
+
const expectedPrefix = config.config.prefix + "/x86_64-w64-mingw32";
|
|
197
|
+
expect(configureStep!.command).toContain("--prefix=" + expectedPrefix);
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
it("autogen step command is ./autogen.sh", () => {
|
|
201
|
+
const steps = build.getSteps("native", true);
|
|
202
|
+
expect(steps[0].command).toBe("./autogen.sh");
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
it("compile step command is make -j", () => {
|
|
206
|
+
const steps = build.getSteps("native", true);
|
|
207
|
+
const compileStep = steps.find(s => s.label === "compile");
|
|
208
|
+
expect(compileStep!.command).toBe("make -j");
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
it("install step command is make install", () => {
|
|
212
|
+
const steps = build.getSteps("native", true);
|
|
213
|
+
const installStep = steps.find(s => s.label === "install");
|
|
214
|
+
expect(installStep!.command).toBe("make install");
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
it("incremental build for windows returns 2 steps", () => {
|
|
218
|
+
const steps = build.getSteps("windows", false);
|
|
219
|
+
expect(steps).toHaveLength(2);
|
|
220
|
+
expect(steps.map(s => s.label)).toEqual(["compile", "install"]);
|
|
221
|
+
});
|
|
222
|
+
});
|
|
223
|
+
});
|
package/test/Config.test.ts
CHANGED
|
@@ -1,24 +1,30 @@
|
|
|
1
1
|
import fs from "fs";
|
|
2
2
|
import os from "os";
|
|
3
|
+
import path from "path";
|
|
3
4
|
import Config from "../src/Config";
|
|
4
5
|
|
|
5
6
|
const home = os.homedir();
|
|
6
7
|
const prefix = home + "/the-seed";
|
|
7
|
-
|
|
8
|
+
|
|
9
|
+
function createTempDir(): string {
|
|
10
|
+
return fs.mkdtempSync(path.join(os.tmpdir(), "config-test-"));
|
|
11
|
+
}
|
|
8
12
|
|
|
9
13
|
describe("test Config", () => {
|
|
14
|
+
let configDir: string;
|
|
15
|
+
let config: Config;
|
|
16
|
+
|
|
10
17
|
beforeAll(() => {
|
|
11
|
-
|
|
18
|
+
configDir = createTempDir();
|
|
19
|
+
config = new Config(configDir);
|
|
12
20
|
});
|
|
13
21
|
|
|
14
|
-
const config = new Config(configDir);
|
|
15
|
-
|
|
16
22
|
it("write empty config file", () => {
|
|
17
23
|
config.saveConfig();
|
|
18
24
|
});
|
|
19
25
|
|
|
20
26
|
it("write updated config file", () => {
|
|
21
|
-
config.config
|
|
27
|
+
config.config.prefix = prefix;
|
|
22
28
|
config.saveConfig();
|
|
23
29
|
});
|
|
24
30
|
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import os from "os";
|
|
4
|
+
import Config from "../src/Config";
|
|
5
|
+
import {
|
|
6
|
+
checkLib,
|
|
7
|
+
checkLibEcs,
|
|
8
|
+
checkLibTheSeed,
|
|
9
|
+
installLib,
|
|
10
|
+
installLibEcs,
|
|
11
|
+
installLibTheSeed
|
|
12
|
+
} from "../src/Dependencies";
|
|
13
|
+
|
|
14
|
+
jest.mock("child_process", () => ({
|
|
15
|
+
execSync: jest.fn(() => Buffer.from(""))
|
|
16
|
+
}));
|
|
17
|
+
|
|
18
|
+
import { execSync } from "child_process";
|
|
19
|
+
const mockedExecSync = execSync as jest.MockedFunction<typeof execSync>;
|
|
20
|
+
|
|
21
|
+
function createTempDir(): string {
|
|
22
|
+
return fs.mkdtempSync(path.join(os.tmpdir(), "deps-test-"));
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
describe("test Dependencies", () => {
|
|
26
|
+
let configDir: string;
|
|
27
|
+
let config: Config;
|
|
28
|
+
|
|
29
|
+
beforeAll(() => {
|
|
30
|
+
configDir = createTempDir();
|
|
31
|
+
config = new Config(configDir);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
beforeEach(() => {
|
|
35
|
+
mockedExecSync.mockClear();
|
|
36
|
+
mockedExecSync.mockReturnValue(Buffer.from(""));
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
afterAll(() => {
|
|
40
|
+
fs.rmSync(configDir, { recursive: true });
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
describe("checkLib", () => {
|
|
44
|
+
it("returns true when library is found", () => {
|
|
45
|
+
mockedExecSync.mockReturnValue(Buffer.from("-l ecs-cpp -I/usr/include/ecs-cpp"));
|
|
46
|
+
const result = checkLib(config, "ecs-cpp", "native");
|
|
47
|
+
expect(result).toBe(true);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it("returns false when pkg-config throws", () => {
|
|
51
|
+
mockedExecSync.mockImplementation(() => {
|
|
52
|
+
throw new Error("pkg-config not found");
|
|
53
|
+
});
|
|
54
|
+
const result = checkLib(config, "ecs-cpp", "native");
|
|
55
|
+
expect(result).toBe(false);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it("returns false when output does not include library name", () => {
|
|
59
|
+
mockedExecSync.mockReturnValue(Buffer.from("-l other-lib"));
|
|
60
|
+
const result = checkLib(config, "ecs-cpp", "native");
|
|
61
|
+
expect(result).toBe(false);
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
describe("checkLibEcs", () => {
|
|
66
|
+
it("delegates to checkLib with ecs-cpp", () => {
|
|
67
|
+
mockedExecSync.mockReturnValue(Buffer.from("-l ecs-cpp"));
|
|
68
|
+
const result = checkLibEcs(config, "native");
|
|
69
|
+
expect(result).toBe(true);
|
|
70
|
+
expect(mockedExecSync).toHaveBeenCalledWith(
|
|
71
|
+
expect.stringContaining("ecs-cpp"),
|
|
72
|
+
expect.anything()
|
|
73
|
+
);
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
describe("checkLibTheSeed", () => {
|
|
78
|
+
it("delegates to checkLib with the-seed", () => {
|
|
79
|
+
mockedExecSync.mockReturnValue(Buffer.from("-l the-seed"));
|
|
80
|
+
const result = checkLibTheSeed(config, "native");
|
|
81
|
+
expect(result).toBe(true);
|
|
82
|
+
expect(mockedExecSync).toHaveBeenCalledWith(
|
|
83
|
+
expect.stringContaining("the-seed"),
|
|
84
|
+
expect.anything()
|
|
85
|
+
);
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
describe("installLib", () => {
|
|
90
|
+
it("returns true on success", () => {
|
|
91
|
+
mockedExecSync.mockReturnValue(Buffer.from("ok"));
|
|
92
|
+
const result = installLib(config, "https://github.com/test/repo.git", "test-dir", "native");
|
|
93
|
+
expect(result).toBe(true);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it("returns false on build failure", () => {
|
|
97
|
+
// First call (clone) succeeds, second call (build) throws
|
|
98
|
+
mockedExecSync
|
|
99
|
+
.mockReturnValueOnce(Buffer.from("cloned"))
|
|
100
|
+
.mockImplementationOnce(() => {
|
|
101
|
+
throw new Error("build failed");
|
|
102
|
+
});
|
|
103
|
+
const result = installLib(config, "https://github.com/test/repo.git", "test-dir", "native");
|
|
104
|
+
expect(result).toBe(false);
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
it("native target has no --host flag", () => {
|
|
108
|
+
mockedExecSync.mockReturnValue(Buffer.from("ok"));
|
|
109
|
+
installLib(config, "https://github.com/test/repo.git", "test-dir", "native");
|
|
110
|
+
|
|
111
|
+
const buildCall = mockedExecSync.mock.calls.find(
|
|
112
|
+
(call) => String(call[0]).includes("./configure")
|
|
113
|
+
);
|
|
114
|
+
expect(buildCall).toBeDefined();
|
|
115
|
+
expect(String(buildCall![0])).not.toContain("--host");
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it("windows target includes --host flag", () => {
|
|
119
|
+
mockedExecSync.mockReturnValue(Buffer.from("ok"));
|
|
120
|
+
installLib(config, "https://github.com/test/repo.git", "test-dir", "windows");
|
|
121
|
+
|
|
122
|
+
const buildCall = mockedExecSync.mock.calls.find(
|
|
123
|
+
(call) => String(call[0]).includes("./configure")
|
|
124
|
+
);
|
|
125
|
+
expect(buildCall).toBeDefined();
|
|
126
|
+
expect(String(buildCall![0])).toContain("--host=x86_64-w64-mingw32");
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
describe("installLibEcs", () => {
|
|
131
|
+
it("delegates to installLib with libecs-cpp repo", () => {
|
|
132
|
+
mockedExecSync.mockReturnValue(Buffer.from("ok"));
|
|
133
|
+
const result = installLibEcs(config, "native");
|
|
134
|
+
expect(result).toBe(true);
|
|
135
|
+
expect(mockedExecSync).toHaveBeenCalledWith(
|
|
136
|
+
expect.stringContaining("libecs-cpp"),
|
|
137
|
+
expect.anything()
|
|
138
|
+
);
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
describe("installLibTheSeed", () => {
|
|
143
|
+
it("delegates to installLib with libthe-seed repo", () => {
|
|
144
|
+
mockedExecSync.mockReturnValue(Buffer.from("ok"));
|
|
145
|
+
const result = installLibTheSeed(config, "native");
|
|
146
|
+
expect(result).toBe(true);
|
|
147
|
+
expect(mockedExecSync).toHaveBeenCalledWith(
|
|
148
|
+
expect.stringContaining("libthe-seed"),
|
|
149
|
+
expect.anything()
|
|
150
|
+
);
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
});
|