@golem-fail/golem 0.8.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/README.md +47 -0
- package/bin/cli.js +28 -0
- package/install.js +109 -0
- package/package.json +31 -0
package/README.md
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# @golem-fail/golem
|
|
2
|
+
|
|
3
|
+
Prebuilt-binary wrapper for [golem](https://github.com/golem-fail/golem), a
|
|
4
|
+
mobile UI testing framework. Install it as a **per-project dev dependency** so
|
|
5
|
+
the version is pinned in your lockfile — which dovetails with golem's
|
|
6
|
+
host↔companion version lock for reproducible local + CI runs.
|
|
7
|
+
|
|
8
|
+
```sh
|
|
9
|
+
npm install -D @golem-fail/golem
|
|
10
|
+
# or
|
|
11
|
+
pnpm add -D @golem-fail/golem
|
|
12
|
+
bun add -d @golem-fail/golem
|
|
13
|
+
yarn add -D @golem-fail/golem
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Then run it via `npx golem` (or a `package.json` script):
|
|
17
|
+
|
|
18
|
+
```sh
|
|
19
|
+
npx golem doctor
|
|
20
|
+
npx golem run e2e/flow.test.toml
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
`postinstall` downloads a self-contained `golem` binary (iOS/Android companions
|
|
24
|
+
baked in) matched to your platform and verifies its sha256. Driving devices
|
|
25
|
+
still needs host tooling (`adb`, Xcode/simulators) — `golem doctor` checks it.
|
|
26
|
+
|
|
27
|
+
macOS arm64 only for now (Linux is planned). The pinned version is downloaded by
|
|
28
|
+
default; set `GOLEM_VERSION` to override.
|
|
29
|
+
|
|
30
|
+
## pnpm / bun
|
|
31
|
+
|
|
32
|
+
pnpm (v10+) and bun don't run dependency install scripts by default, so the
|
|
33
|
+
`postinstall` download won't fire until you allow this package:
|
|
34
|
+
|
|
35
|
+
- **pnpm** — add to your root `package.json`:
|
|
36
|
+
```json
|
|
37
|
+
{ "pnpm": { "onlyBuiltDependencies": ["@golem-fail/golem"] } }
|
|
38
|
+
```
|
|
39
|
+
(or run `pnpm approve-builds`).
|
|
40
|
+
- **bun** — add to your root `package.json`:
|
|
41
|
+
```json
|
|
42
|
+
{ "trustedDependencies": ["@golem-fail/golem"] }
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
npm and Yarn run it by default. If a download was skipped, `npx golem` prints a
|
|
46
|
+
clear "native binary missing — reinstall" error rather than failing obscurely.
|
|
47
|
+
|
package/bin/cli.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Thin launcher: spawn the vendored native `golem` binary, forwarding argv,
|
|
3
|
+
// stdio, and the exit code. The native binary is fetched by install.js
|
|
4
|
+
// (postinstall). Kept as a JS shim so the published package always has a valid
|
|
5
|
+
// `bin` target regardless of postinstall ordering.
|
|
6
|
+
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
const path = require('path');
|
|
10
|
+
const fs = require('fs');
|
|
11
|
+
const { spawnSync } = require('child_process');
|
|
12
|
+
|
|
13
|
+
const bin = path.join(__dirname, '..', 'vendor', 'golem');
|
|
14
|
+
|
|
15
|
+
if (!fs.existsSync(bin)) {
|
|
16
|
+
console.error(
|
|
17
|
+
'@golem-fail/golem: native binary missing — reinstall the package ' +
|
|
18
|
+
'(the postinstall download may have been skipped or blocked).'
|
|
19
|
+
);
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const result = spawnSync(bin, process.argv.slice(2), { stdio: 'inherit' });
|
|
24
|
+
if (result.error) {
|
|
25
|
+
console.error(`@golem-fail/golem: failed to run golem: ${result.error.message}`);
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
process.exit(result.status === null ? 1 : result.status);
|
package/install.js
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// postinstall: download the arch-matched prebuilt `golem` binary, verify its
|
|
3
|
+
// sha256, and extract it into vendor/. The binary is self-contained (companions
|
|
4
|
+
// baked in). The version is pinned to this package's version (so the lockfile
|
|
5
|
+
// dovetails with the host↔companion lock); GOLEM_VERSION overrides it.
|
|
6
|
+
//
|
|
7
|
+
// Dependency-free by design: Node built-ins + the system `tar` (present on the
|
|
8
|
+
// macOS/Linux targets we ship). GOLEM_BASE_URL points the download at a mirror
|
|
9
|
+
// or a local dir laid out as <tag>/<asset> (used for offline tests).
|
|
10
|
+
|
|
11
|
+
'use strict';
|
|
12
|
+
|
|
13
|
+
const fs = require('fs');
|
|
14
|
+
const os = require('os');
|
|
15
|
+
const path = require('path');
|
|
16
|
+
const crypto = require('crypto');
|
|
17
|
+
const { execFileSync } = require('child_process');
|
|
18
|
+
|
|
19
|
+
const pkg = require('./package.json');
|
|
20
|
+
|
|
21
|
+
const VERSION = process.env.GOLEM_VERSION || pkg.version;
|
|
22
|
+
const BASE_URL =
|
|
23
|
+
process.env.GOLEM_BASE_URL ||
|
|
24
|
+
'https://github.com/golem-fail/golem/releases/download';
|
|
25
|
+
const VENDOR = path.join(__dirname, 'vendor');
|
|
26
|
+
const BIN = path.join(VENDOR, 'golem');
|
|
27
|
+
|
|
28
|
+
function fail(msg) {
|
|
29
|
+
console.error(`@golem-fail/golem: ${msg}`);
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function target() {
|
|
34
|
+
const p = process.platform;
|
|
35
|
+
const a = process.arch;
|
|
36
|
+
if (p === 'darwin' && a === 'arm64') return 'aarch64-apple-darwin';
|
|
37
|
+
// Linux triples are ready but no artifacts are published yet (deferred).
|
|
38
|
+
fail(
|
|
39
|
+
`unsupported platform ${p}/${a} — golem ships a prebuilt binary for macOS ` +
|
|
40
|
+
`arm64 only for now (build from source: cargo install --path golem-cli)`
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// GET with redirect following, over http or https (local test servers use http).
|
|
45
|
+
function get(url, redirectsLeft = 5) {
|
|
46
|
+
return new Promise((resolve, reject) => {
|
|
47
|
+
const lib = url.startsWith('https:') ? require('https') : require('http');
|
|
48
|
+
lib
|
|
49
|
+
.get(url, (res) => {
|
|
50
|
+
const { statusCode, headers } = res;
|
|
51
|
+
if (statusCode >= 300 && statusCode < 400 && headers.location) {
|
|
52
|
+
if (redirectsLeft === 0) return reject(new Error('too many redirects'));
|
|
53
|
+
res.resume();
|
|
54
|
+
const next = new URL(headers.location, url).toString();
|
|
55
|
+
return resolve(get(next, redirectsLeft - 1));
|
|
56
|
+
}
|
|
57
|
+
if (statusCode !== 200) {
|
|
58
|
+
res.resume();
|
|
59
|
+
return reject(new Error(`HTTP ${statusCode} for ${url}`));
|
|
60
|
+
}
|
|
61
|
+
const chunks = [];
|
|
62
|
+
res.on('data', (c) => chunks.push(c));
|
|
63
|
+
res.on('end', () => resolve(Buffer.concat(chunks)));
|
|
64
|
+
})
|
|
65
|
+
.on('error', reject);
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async function main() {
|
|
70
|
+
if (process.env.GOLEM_SKIP_DOWNLOAD) {
|
|
71
|
+
console.error('@golem-fail/golem: GOLEM_SKIP_DOWNLOAD set — skipping binary download.');
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const triple = target();
|
|
76
|
+
const asset = `golem-${VERSION}-${triple}.tar.gz`;
|
|
77
|
+
const url = `${BASE_URL}/v${VERSION}/${asset}`;
|
|
78
|
+
|
|
79
|
+
console.error(`@golem-fail/golem: downloading ${asset}…`);
|
|
80
|
+
const [tarball, shaFile] = await Promise.all([get(url), get(`${url}.sha256`)]);
|
|
81
|
+
|
|
82
|
+
// Verify: the .sha256 payload is "<hex> <filename>".
|
|
83
|
+
const expected = shaFile.toString('utf8').trim().split(/\s+/)[0];
|
|
84
|
+
const actual = crypto.createHash('sha256').update(tarball).digest('hex');
|
|
85
|
+
if (!expected || expected !== actual) {
|
|
86
|
+
fail(`checksum mismatch for ${asset} (expected ${expected || '<none>'}, got ${actual})`);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Extract via system tar (no npm tar dependency).
|
|
90
|
+
fs.mkdirSync(VENDOR, { recursive: true });
|
|
91
|
+
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'golem-'));
|
|
92
|
+
const tarPath = path.join(tmp, asset);
|
|
93
|
+
fs.writeFileSync(tarPath, tarball);
|
|
94
|
+
try {
|
|
95
|
+
execFileSync('tar', ['xzf', tarPath, '-C', tmp]);
|
|
96
|
+
} catch (e) {
|
|
97
|
+
fail(`failed to extract ${asset}: ${e.message}`);
|
|
98
|
+
}
|
|
99
|
+
const extracted = path.join(tmp, 'golem');
|
|
100
|
+
if (!fs.existsSync(extracted)) fail(`archive did not contain a 'golem' binary`);
|
|
101
|
+
fs.copyFileSync(extracted, BIN);
|
|
102
|
+
fs.chmodSync(BIN, 0o755);
|
|
103
|
+
fs.rmSync(tmp, { recursive: true, force: true });
|
|
104
|
+
|
|
105
|
+
console.error(`@golem-fail/golem: installed golem ${VERSION} → ${BIN}`);
|
|
106
|
+
console.error('Next: run `npx golem doctor` to check your device toolchain.');
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
main().catch((e) => fail(e.message));
|
package/package.json
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@golem-fail/golem",
|
|
3
|
+
"version": "0.8.0",
|
|
4
|
+
"description": "Mobile UI testing framework — prebuilt binary wrapper for npm/bun/yarn",
|
|
5
|
+
"homepage": "https://golem.fail",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/golem-fail/golem.git",
|
|
9
|
+
"directory": "npm"
|
|
10
|
+
},
|
|
11
|
+
"license": "SEE LICENSE IN LICENSE",
|
|
12
|
+
"bin": {
|
|
13
|
+
"golem": "bin/cli.js"
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"bin/cli.js",
|
|
17
|
+
"install.js"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"postinstall": "node install.js"
|
|
21
|
+
},
|
|
22
|
+
"os": [
|
|
23
|
+
"darwin"
|
|
24
|
+
],
|
|
25
|
+
"cpu": [
|
|
26
|
+
"arm64"
|
|
27
|
+
],
|
|
28
|
+
"engines": {
|
|
29
|
+
"node": ">=16"
|
|
30
|
+
}
|
|
31
|
+
}
|