@balena/compose-parser 0.0.9 → 0.0.10
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/dist/compose.js +2 -2
- package/lib/go.mod +1 -1
- package/lib/main.go +2 -2
- package/package.json +10 -14
- package/scripts/fetch-binary.js +134 -0
- package/scripts/rename-binary.js +0 -31
package/dist/compose.js
CHANGED
|
@@ -20,8 +20,8 @@ async function parse(composeFilePaths) {
|
|
|
20
20
|
const projectName = (0, crypto_1.randomUUID)();
|
|
21
21
|
const fileFlags = filePaths.map((filePath) => `-f ${filePath}`).join(' ');
|
|
22
22
|
const binaryName = process.platform === 'win32'
|
|
23
|
-
? '
|
|
24
|
-
: '
|
|
23
|
+
? 'balena-compose-parser.exe'
|
|
24
|
+
: 'balena-compose-parser';
|
|
25
25
|
const binaryPath = path.join(__dirname, '..', 'bin', binaryName);
|
|
26
26
|
const result = await exec(`${binaryPath} ${fileFlags} ${projectName}`, {
|
|
27
27
|
env: process.env,
|
package/lib/go.mod
CHANGED
package/lib/main.go
CHANGED
|
@@ -21,7 +21,7 @@ type ErrorResponse struct {
|
|
|
21
21
|
|
|
22
22
|
// Usage message
|
|
23
23
|
const usage = `
|
|
24
|
-
Usage:
|
|
24
|
+
Usage: balena-compose-parser -f <compose-file> [-f <compose-file>...] <project-name>
|
|
25
25
|
|
|
26
26
|
Parses one or more docker-compose files and outputs a structured response.
|
|
27
27
|
|
|
@@ -31,7 +31,7 @@ Arguments:
|
|
|
31
31
|
the project name need to be removed for normalization into a compose acceptable by balena.
|
|
32
32
|
|
|
33
33
|
Example:
|
|
34
|
-
|
|
34
|
+
balena-compose-parser -f docker-compose.yml -f docker-compose.override.yml my-project-name
|
|
35
35
|
`
|
|
36
36
|
|
|
37
37
|
func main() {
|
package/package.json
CHANGED
|
@@ -1,28 +1,27 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@balena/compose-parser",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.10",
|
|
4
4
|
"description": "Wraps compose-go to parse balena-compatible docker-compose.yml files",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"clean": "rimraf dist",
|
|
7
7
|
"lint": "balena-lint lib/ test/ && tsc --noEmit",
|
|
8
8
|
"lint-fix": "balena-lint --fix lib/ test/",
|
|
9
9
|
"build": "npm run clean && tsc --project tsconfig.release.json",
|
|
10
|
-
"build:go": "CGO_ENABLED=0 go build -C lib -ldflags='-s -w' -o \"../bin/
|
|
10
|
+
"build:go": "echo 'Building Go binary from source...' && CGO_ENABLED=0 go build -C lib -ldflags='-s -w' -o \"../bin/balena-compose-parser$(go env GOEXE)\"",
|
|
11
11
|
"test": "npm run lint && npm run test:unit",
|
|
12
12
|
"test:unit": "ts-mocha 'test/**/*unit.spec.ts'",
|
|
13
13
|
"test:integration": "ts-mocha 'test/**/*.spec.ts'",
|
|
14
14
|
"test:compose": "(docker compose -f docker-compose.test.yml run --build --rm sut || docker compose logs); npm run compose:down",
|
|
15
15
|
"compose:down": "docker compose -f docker-compose.test.yml down --volumes",
|
|
16
16
|
"prepack": "npm run build",
|
|
17
|
-
"
|
|
18
|
-
"postinstall": "node scripts/rename-binary.js"
|
|
17
|
+
"postinstall": "node scripts/fetch-binary.js || npm run build:go"
|
|
19
18
|
},
|
|
20
19
|
"files": [
|
|
21
20
|
"dist/",
|
|
22
21
|
"lib/go.mod",
|
|
23
22
|
"lib/go.sum",
|
|
24
23
|
"lib/main.go",
|
|
25
|
-
"scripts/
|
|
24
|
+
"scripts/fetch-binary.js"
|
|
26
25
|
],
|
|
27
26
|
"repository": {
|
|
28
27
|
"type": "git",
|
|
@@ -39,36 +38,33 @@
|
|
|
39
38
|
"main": "dist/index.js",
|
|
40
39
|
"types": "dist/index.d.ts",
|
|
41
40
|
"binary": {
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"host": "https://github.com/balena-io-experimental/balena-compose-parser/releases/download/"
|
|
41
|
+
"moduleName": "balena-compose-parser",
|
|
42
|
+
"modulePath": "bin/",
|
|
43
|
+
"packageName": "balena-compose-parser-{platform}-{arch}.tar.gz",
|
|
44
|
+
"remotePath": "https://github.com/balena-io-experimental/balena-compose-parser/releases/download/v{version}/"
|
|
47
45
|
},
|
|
48
46
|
"devDependencies": {
|
|
49
47
|
"@balena/lint": "^9.3.3",
|
|
50
48
|
"@types/chai": "^5.2.2",
|
|
51
|
-
"@types/js-yaml": "^4.0.9",
|
|
52
49
|
"@types/mocha": "^10.0.10",
|
|
53
50
|
"@types/node": "^24.3.1",
|
|
54
51
|
"@types/semver": "^7.7.1",
|
|
55
52
|
"@types/sinon": "^17.0.4",
|
|
56
53
|
"chai": "^6.0.1",
|
|
57
|
-
"js-yaml": "^4.1.0",
|
|
58
54
|
"mocha": "^11.7.2",
|
|
59
55
|
"rimraf": "^6.0.1",
|
|
60
56
|
"sinon": "^21.0.0",
|
|
57
|
+
"tar": "^7.4.3",
|
|
61
58
|
"ts-mocha": "^11.1.0",
|
|
62
59
|
"ts-node": "^10.9.2",
|
|
63
60
|
"tsconfig-paths": "^4.2.0",
|
|
64
61
|
"typescript": "^5.9.2"
|
|
65
62
|
},
|
|
66
63
|
"dependencies": {
|
|
67
|
-
"@mapbox/node-pre-gyp": "^2.0.0",
|
|
68
64
|
"semver": "^7.7.2",
|
|
69
65
|
"typed-error": "^3.2.2"
|
|
70
66
|
},
|
|
71
67
|
"versionist": {
|
|
72
|
-
"publishedAt": "2025-09-
|
|
68
|
+
"publishedAt": "2025-09-17T18:50:38.541Z"
|
|
73
69
|
}
|
|
74
70
|
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const https = require('https');
|
|
4
|
+
const { promises: fs } = require('fs');
|
|
5
|
+
const path = require('path');
|
|
6
|
+
const { pipeline } = require('stream');
|
|
7
|
+
const { promisify } = require('util');
|
|
8
|
+
const zlib = require('zlib');
|
|
9
|
+
const tar = require('tar');
|
|
10
|
+
const packageJson = require('../package.json');
|
|
11
|
+
|
|
12
|
+
const streamPipeline = promisify(pipeline);
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
(async () => {
|
|
16
|
+
console.log('Fetching prebuilt Go binary...');
|
|
17
|
+
await fetchBinary();
|
|
18
|
+
})();
|
|
19
|
+
|
|
20
|
+
function getPlatform() {
|
|
21
|
+
const platform = process.platform;
|
|
22
|
+
switch (platform) {
|
|
23
|
+
case 'darwin':
|
|
24
|
+
return 'darwin';
|
|
25
|
+
case 'linux':
|
|
26
|
+
return 'linux';
|
|
27
|
+
case 'win32':
|
|
28
|
+
return 'windows';
|
|
29
|
+
default:
|
|
30
|
+
throw new Error(`Unsupported platform: ${platform}`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function getArch() {
|
|
35
|
+
const arch = process.arch;
|
|
36
|
+
switch (arch) {
|
|
37
|
+
case 'x64':
|
|
38
|
+
return 'amd64';
|
|
39
|
+
case 'arm64':
|
|
40
|
+
return 'arm64';
|
|
41
|
+
default:
|
|
42
|
+
throw new Error(`Unsupported architecture: ${arch}`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function getBinaryUrl() {
|
|
47
|
+
const config = packageJson.binary;
|
|
48
|
+
if (!config) {
|
|
49
|
+
throw new Error('No binary configuration found in package.json');
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const platform = getPlatform();
|
|
53
|
+
const arch = getArch();
|
|
54
|
+
const version = packageJson.version;
|
|
55
|
+
|
|
56
|
+
const packageName = config.packageName
|
|
57
|
+
.replace('{platform}', platform)
|
|
58
|
+
.replace('{arch}', arch);
|
|
59
|
+
|
|
60
|
+
const url = config.remotePath
|
|
61
|
+
.replace('{version}', version) + packageName;
|
|
62
|
+
|
|
63
|
+
return url;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function downloadFile(url) {
|
|
67
|
+
return new Promise((resolve, reject) => {
|
|
68
|
+
console.log(`Downloading binary from: ${url}`);
|
|
69
|
+
|
|
70
|
+
https.get(url, (response) => {
|
|
71
|
+
if (response.statusCode === 302 || response.statusCode === 301) {
|
|
72
|
+
// Follow redirect
|
|
73
|
+
return downloadFile(response.headers.location).then(resolve).catch(reject);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (response.statusCode !== 200) {
|
|
77
|
+
reject(new Error(`Failed to download: HTTP ${response.statusCode}`));
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
resolve(response);
|
|
82
|
+
}).on('error', reject);
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
async function extractTarGz(stream, targetDir) {
|
|
87
|
+
await streamPipeline(
|
|
88
|
+
stream,
|
|
89
|
+
zlib.createGunzip(),
|
|
90
|
+
tar.extract({
|
|
91
|
+
cwd: targetDir,
|
|
92
|
+
strip: 0
|
|
93
|
+
})
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
async function fetchBinary() {
|
|
98
|
+
try {
|
|
99
|
+
const config = packageJson.binary;
|
|
100
|
+
const binDir = path.join(__dirname, '..', config.modulePath);
|
|
101
|
+
const binaryName = `${config.moduleName}${process.platform === 'win32' ? '.exe' : ''}`;
|
|
102
|
+
const binaryPath = path.join(binDir, binaryName);
|
|
103
|
+
|
|
104
|
+
// Check if binary already exists
|
|
105
|
+
if (await fs.exists(binaryPath)) {
|
|
106
|
+
console.log(`Binary already exists at ${binaryPath}`);
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Create bin directory if it doesn't exist
|
|
111
|
+
if (!(await fs.exists(binDir))) {
|
|
112
|
+
await fs.mkdir(binDir, { recursive: true });
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Download binary
|
|
116
|
+
const url = getBinaryUrl();
|
|
117
|
+
const response = await downloadFile(url);
|
|
118
|
+
|
|
119
|
+
// Extract tar.gz to bin directory
|
|
120
|
+
console.log(`Extracting binary to ${binDir}`);
|
|
121
|
+
await extractTarGz(response, binDir);
|
|
122
|
+
|
|
123
|
+
// Make binary executable on Unix systems
|
|
124
|
+
if (process.platform !== 'win32') {
|
|
125
|
+
await fs.chmod(binaryPath, 0o755);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
console.log(`Binary successfully installed at ${binaryPath}`);
|
|
129
|
+
process.exit(0);
|
|
130
|
+
} catch (error) {
|
|
131
|
+
console.error(`Failed to fetch binary: ${error.message}`);
|
|
132
|
+
process.exit(1);
|
|
133
|
+
}
|
|
134
|
+
}
|
package/scripts/rename-binary.js
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
const fs = require('fs');
|
|
4
|
-
const path = require('path');
|
|
5
|
-
|
|
6
|
-
const binDir = path.join(__dirname, '..', 'bin');
|
|
7
|
-
|
|
8
|
-
if (!fs.existsSync(binDir)) {
|
|
9
|
-
console.debug('Binary directory does not exist, skipping rename');
|
|
10
|
-
process.exit(0);
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
// Find file matching balena_compose_parser.node
|
|
14
|
-
const files = fs.readdirSync(binDir).filter(f => f.match(/^balena_compose_parser\.node$/));
|
|
15
|
-
|
|
16
|
-
if (files.length === 0) {
|
|
17
|
-
console.debug('No binary file found, skipping rename');
|
|
18
|
-
process.exit(0);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
const sourceFile = path.join(binDir, files[0]);
|
|
22
|
-
const targetFile = path.join(binDir, `balena_compose_parser${process.platform === 'win32' ? '.exe' : ''}`);
|
|
23
|
-
|
|
24
|
-
// Rename the file
|
|
25
|
-
try {
|
|
26
|
-
fs.renameSync(sourceFile, targetFile);
|
|
27
|
-
console.debug('Binary file renamed successfully');
|
|
28
|
-
} catch (err) {
|
|
29
|
-
console.error(`Failed to rename binary file: ${err.message}`);
|
|
30
|
-
process.exit(1);
|
|
31
|
-
}
|