@platforma-sdk/package-builder-lib 1.4.0 → 1.4.2
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/_virtual/_rolldown/runtime.cjs +2 -3
- package/dist/_virtual/_rolldown/runtime.js +1 -2
- package/dist/core/archive.cjs +1 -2
- package/dist/core/archive.cjs.map +1 -1
- package/dist/core/archive.js +1 -2
- package/dist/core/conda/builder.cjs +1 -2
- package/dist/core/conda/builder.cjs.map +1 -1
- package/dist/core/conda/builder.js +1 -2
- package/dist/core/conda/builder.js.map +1 -1
- package/dist/core/conda/validate-spec.cjs +1 -2
- package/dist/core/conda/validate-spec.js +1 -2
- package/dist/core/core.cjs +11 -12
- package/dist/core/core.cjs.map +1 -1
- package/dist/core/core.d.ts +3 -5
- package/dist/core/core.d.ts.map +1 -1
- package/dist/core/core.js +13 -13
- package/dist/core/core.js.map +1 -1
- package/dist/core/docker-conda.cjs +1 -2
- package/dist/core/docker-conda.js +1 -2
- package/dist/core/docker-coverage.cjs +1 -2
- package/dist/core/docker-coverage.d.ts +1 -3
- package/dist/core/docker-coverage.d.ts.map +1 -1
- package/dist/core/docker-coverage.js +3 -3
- package/dist/core/docker-coverage.js.map +1 -1
- package/dist/core/docker-python.cjs +1 -2
- package/dist/core/docker-python.js +1 -2
- package/dist/core/docker.cjs +3 -5
- package/dist/core/docker.cjs.map +1 -1
- package/dist/core/docker.js +3 -5
- package/dist/core/docker.js.map +1 -1
- package/dist/core/envs.cjs +1 -2
- package/dist/core/envs.d.ts +0 -1
- package/dist/core/envs.js +1 -2
- package/dist/core/package-info.cjs +13 -12
- package/dist/core/package-info.cjs.map +1 -1
- package/dist/core/package-info.d.ts +4 -5
- package/dist/core/package-info.d.ts.map +1 -1
- package/dist/core/package-info.js +13 -12
- package/dist/core/package-info.js.map +1 -1
- package/dist/core/paths.cjs +1 -2
- package/dist/core/paths.cjs.map +1 -1
- package/dist/core/paths.js +1 -2
- package/dist/core/paths.js.map +1 -1
- package/dist/core/push-guard.cjs +1 -2
- package/dist/core/push-guard.cjs.map +1 -1
- package/dist/core/push-guard.d.ts +0 -2
- package/dist/core/push-guard.d.ts.map +1 -1
- package/dist/core/push-guard.js +1 -2
- package/dist/core/resolver.cjs +1 -2
- package/dist/core/resolver.js +1 -2
- package/dist/core/schemas/artifacts.cjs +1 -2
- package/dist/core/schemas/artifacts.d.ts +1 -169
- package/dist/core/schemas/artifacts.d.ts.map +1 -1
- package/dist/core/schemas/artifacts.js +1 -2
- package/dist/core/schemas/entrypoints.cjs +1 -2
- package/dist/core/schemas/entrypoints.d.ts +1 -352
- package/dist/core/schemas/entrypoints.d.ts.map +1 -1
- package/dist/core/schemas/entrypoints.js +1 -2
- package/dist/core/schemas/sw-json.cjs +1 -2
- package/dist/core/schemas/sw-json.js +1 -2
- package/dist/core/storage.cjs +1 -2
- package/dist/core/storage.js +1 -2
- package/dist/core/sw-json-render.cjs +1 -2
- package/dist/core/sw-json-render.js +1 -2
- package/dist/core/util.cjs +1 -2
- package/dist/core/util.cjs.map +1 -1
- package/dist/core/util.d.ts +0 -1
- package/dist/core/util.js +1 -2
- package/dist/defaults.cjs +1 -2
- package/dist/defaults.d.ts +0 -1
- package/dist/defaults.js +1 -2
- package/dist/index.cjs +1 -2
- package/dist/index.d.ts +0 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -2
- package/package.json +20 -15
- package/src/core/__tests__/docker-build.test.ts +51 -0
- package/src/core/conda/builder.ts +1 -1
- package/src/core/docker.ts +2 -7
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
// \0rolldown/runtime.js
|
|
2
2
|
var __create = Object.create;
|
|
3
3
|
var __defProp = Object.defineProperty;
|
|
4
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -24,10 +24,9 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
24
24
|
}
|
|
25
25
|
return to;
|
|
26
26
|
};
|
|
27
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
27
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
|
|
28
28
|
value: mod,
|
|
29
29
|
enumerable: true
|
|
30
30
|
}) : target, mod));
|
|
31
|
-
//#endregion
|
|
32
31
|
exports.__exportAll = __exportAll;
|
|
33
32
|
exports.__toESM = __toESM;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
// \0rolldown/runtime.js
|
|
2
2
|
var __defProp = Object.defineProperty;
|
|
3
3
|
var __exportAll = (all, no_symbols) => {
|
|
4
4
|
let target = {};
|
|
@@ -9,5 +9,4 @@ var __exportAll = (all, no_symbols) => {
|
|
|
9
9
|
if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
10
10
|
return target;
|
|
11
11
|
};
|
|
12
|
-
//#endregion
|
|
13
12
|
export { __exportAll };
|
package/dist/core/archive.cjs
CHANGED
|
@@ -7,7 +7,7 @@ node_path = require_runtime.__toESM(node_path, 1);
|
|
|
7
7
|
let node_crypto = require("node:crypto");
|
|
8
8
|
let archiver = require("archiver");
|
|
9
9
|
archiver = require_runtime.__toESM(archiver, 1);
|
|
10
|
-
|
|
10
|
+
// src/core/archive.ts
|
|
11
11
|
function getPath(options) {
|
|
12
12
|
const packageName = options.packageName.replaceAll("/", "-").replaceAll("\\", "-");
|
|
13
13
|
if (options && !options.crossplatform) return node_path.default.resolve(options.packageRoot, `pkg-${packageName}-${options.packageVersion}-${options.os}-${options.arch}.${options.ext}`);
|
|
@@ -45,7 +45,6 @@ async function create(logger, contentRoot, dstArchivePath, hasher) {
|
|
|
45
45
|
a.finalize().catch(reject);
|
|
46
46
|
});
|
|
47
47
|
}
|
|
48
|
-
//#endregion
|
|
49
48
|
exports.create = create;
|
|
50
49
|
exports.getPath = getPath;
|
|
51
50
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"archive.cjs","names":["path","fs"],"sources":["../../src/core/archive.ts"],"sourcesContent":["import archiver from \"archiver\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport type * as winston from \"winston\";\nimport * as util from \"./util\";\nimport type { Hash } from \"node:crypto\";\nimport { createHash } from \"node:crypto\";\n\nconst tarArchiveType = \"tgz\";\nconst zipArchiveType = \"zip\";\nexport const allArchiveTypes = [tarArchiveType, zipArchiveType];\nexport type archiveType = (typeof allArchiveTypes)[number];\n\nexport type archiveOptions = {\n packageRoot: string;\n packageName: string;\n packageVersion: string;\n\n crossplatform: boolean;\n os: util.OSType;\n arch: util.ArchType;\n ext: archiveType;\n};\n\nexport function getPath(options: archiveOptions): string {\n const packageName = options.packageName.replaceAll(\"/\", \"-\").replaceAll(\"\\\\\", \"-\");\n\n if (options && !options.crossplatform) {\n return path.resolve(\n options.packageRoot,\n `pkg-${packageName}-${options.packageVersion}-${options.os}-${options.arch}.${options.ext}`,\n );\n }\n\n return path.resolve(\n options.packageRoot,\n `pkg-${packageName}-${options.packageVersion}.${options.ext}`,\n );\n}\n\nexport async function create(\n logger: winston.Logger,\n contentRoot: string,\n dstArchivePath: string,\n hasher?: Hash,\n): Promise<Hash> {\n const compressionLevel = 9;\n\n let format = \"\";\n if (dstArchivePath.endsWith(\".tgz\") || dstArchivePath.endsWith(\".tar.gz\")) {\n format = \"tar\";\n }\n if (dstArchivePath.endsWith(\".zip\")) {\n format = \"zip\";\n }\n\n if (format == \"\") {\n throw util.CLIError(\n `Archive ${dstArchivePath} has unsupported extension. Cannot create archive of unknown format`,\n );\n }\n\n const output = fs.createWriteStream(dstArchivePath);\n const hash = hasher ? hasher : createHash(\"sha256\");\n\n const a = archiver.create(format, {\n gzip: true,\n gzipOptions: { level: compressionLevel },\n zlib: { level: compressionLevel },\n });\n\n return new Promise((resolve, reject) => {\n // Waits for the output stream to be closed.\n output.on(\"close\", function () {\n logger.debug(`archive created. Total data processed: ${a.pointer()} bytes`);\n resolve(hash);\n });\n\n output.on(\"error\", function (err) {\n reject(err);\n });\n\n // Catch errors\n a.on(\"error\", function (err) {\n reject(err);\n });\n\n // Update hash with every chunk of data written to the archive\n a.on(\"data\", function (chunk) {\n hash.update(chunk);\n });\n\n // Pipe archive data to the file\n a.pipe(output);\n\n // Append files from sourceDir without prefix\n a.directory(contentRoot, false);\n\n // Finalize the archive (i.e. we are done appending files but streams have to finish yet)\n a.finalize().catch(reject);\n });\n}\n"],"mappings":";;;;;;;;;;AAwBA,SAAgB,QAAQ,SAAiC;CACvD,MAAM,cAAc,QAAQ,YAAY,WAAW,KAAK,GAAG,CAAC,CAAC,WAAW,MAAM,GAAG;CAEjF,IAAI,WAAW,CAAC,QAAQ,eACtB,OAAOA,UAAAA,QAAK,QACV,QAAQ,aACR,OAAO,YAAY,GAAG,QAAQ,eAAe,GAAG,QAAQ,GAAG,GAAG,QAAQ,KAAK,GAAG,QAAQ,KACxF;CAGF,OAAOA,UAAAA,QAAK,QACV,QAAQ,aACR,OAAO,YAAY,GAAG,QAAQ,eAAe,GAAG,QAAQ,KAC1D;AACF;AAEA,eAAsB,OACpB,QACA,aACA,gBACA,QACe;CACf,MAAM,mBAAmB;CAEzB,IAAI,SAAS;CACb,IAAI,eAAe,SAAS,MAAM,KAAK,eAAe,SAAS,SAAS,GACtE,SAAS;CAEX,IAAI,eAAe,SAAS,MAAM,GAChC,SAAS;CAGX,IAAI,UAAU,IACZ,MAAA,aAAA,SACE,WAAW,eAAe,oEAC5B;CAGF,MAAM,SAASC,QAAAA,QAAG,kBAAkB,cAAc;CAClD,MAAM,OAAO,SAAS,UAAA,
|
|
1
|
+
{"version":3,"file":"archive.cjs","names":["path","fs","createHash"],"sources":["../../src/core/archive.ts"],"sourcesContent":["import archiver from \"archiver\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport type * as winston from \"winston\";\nimport * as util from \"./util\";\nimport type { Hash } from \"node:crypto\";\nimport { createHash } from \"node:crypto\";\n\nconst tarArchiveType = \"tgz\";\nconst zipArchiveType = \"zip\";\nexport const allArchiveTypes = [tarArchiveType, zipArchiveType];\nexport type archiveType = (typeof allArchiveTypes)[number];\n\nexport type archiveOptions = {\n packageRoot: string;\n packageName: string;\n packageVersion: string;\n\n crossplatform: boolean;\n os: util.OSType;\n arch: util.ArchType;\n ext: archiveType;\n};\n\nexport function getPath(options: archiveOptions): string {\n const packageName = options.packageName.replaceAll(\"/\", \"-\").replaceAll(\"\\\\\", \"-\");\n\n if (options && !options.crossplatform) {\n return path.resolve(\n options.packageRoot,\n `pkg-${packageName}-${options.packageVersion}-${options.os}-${options.arch}.${options.ext}`,\n );\n }\n\n return path.resolve(\n options.packageRoot,\n `pkg-${packageName}-${options.packageVersion}.${options.ext}`,\n );\n}\n\nexport async function create(\n logger: winston.Logger,\n contentRoot: string,\n dstArchivePath: string,\n hasher?: Hash,\n): Promise<Hash> {\n const compressionLevel = 9;\n\n let format = \"\";\n if (dstArchivePath.endsWith(\".tgz\") || dstArchivePath.endsWith(\".tar.gz\")) {\n format = \"tar\";\n }\n if (dstArchivePath.endsWith(\".zip\")) {\n format = \"zip\";\n }\n\n if (format == \"\") {\n throw util.CLIError(\n `Archive ${dstArchivePath} has unsupported extension. Cannot create archive of unknown format`,\n );\n }\n\n const output = fs.createWriteStream(dstArchivePath);\n const hash = hasher ? hasher : createHash(\"sha256\");\n\n const a = archiver.create(format, {\n gzip: true,\n gzipOptions: { level: compressionLevel },\n zlib: { level: compressionLevel },\n });\n\n return new Promise((resolve, reject) => {\n // Waits for the output stream to be closed.\n output.on(\"close\", function () {\n logger.debug(`archive created. Total data processed: ${a.pointer()} bytes`);\n resolve(hash);\n });\n\n output.on(\"error\", function (err) {\n reject(err);\n });\n\n // Catch errors\n a.on(\"error\", function (err) {\n reject(err);\n });\n\n // Update hash with every chunk of data written to the archive\n a.on(\"data\", function (chunk) {\n hash.update(chunk);\n });\n\n // Pipe archive data to the file\n a.pipe(output);\n\n // Append files from sourceDir without prefix\n a.directory(contentRoot, false);\n\n // Finalize the archive (i.e. we are done appending files but streams have to finish yet)\n a.finalize().catch(reject);\n });\n}\n"],"mappings":";;;;;;;;;;AAwBA,SAAgB,QAAQ,SAAiC;CACvD,MAAM,cAAc,QAAQ,YAAY,WAAW,KAAK,GAAG,CAAC,CAAC,WAAW,MAAM,GAAG;CAEjF,IAAI,WAAW,CAAC,QAAQ,eACtB,OAAOA,UAAAA,QAAK,QACV,QAAQ,aACR,OAAO,YAAY,GAAG,QAAQ,eAAe,GAAG,QAAQ,GAAG,GAAG,QAAQ,KAAK,GAAG,QAAQ,KACxF;CAGF,OAAOA,UAAAA,QAAK,QACV,QAAQ,aACR,OAAO,YAAY,GAAG,QAAQ,eAAe,GAAG,QAAQ,KAC1D;AACF;AAEA,eAAsB,OACpB,QACA,aACA,gBACA,QACe;CACf,MAAM,mBAAmB;CAEzB,IAAI,SAAS;CACb,IAAI,eAAe,SAAS,MAAM,KAAK,eAAe,SAAS,SAAS,GACtE,SAAS;CAEX,IAAI,eAAe,SAAS,MAAM,GAChC,SAAS;CAGX,IAAI,UAAU,IACZ,MAAA,aAAA,SACE,WAAW,eAAe,oEAC5B;CAGF,MAAM,SAASC,QAAAA,QAAG,kBAAkB,cAAc;CAClD,MAAM,OAAO,SAAS,UAAA,GAASC,YAAAA,WAAAA,CAAW,QAAQ;CAElD,MAAM,IAAI,SAAA,QAAS,OAAO,QAAQ;EAChC,MAAM;EACN,aAAa,EAAE,OAAO,iBAAiB;EACvC,MAAM,EAAE,OAAO,iBAAiB;CAClC,CAAC;CAED,OAAO,IAAI,SAAS,SAAS,WAAW;EAEtC,OAAO,GAAG,SAAS,WAAY;GAC7B,OAAO,MAAM,0CAA0C,EAAE,QAAQ,EAAE,OAAO;GAC1E,QAAQ,IAAI;EACd,CAAC;EAED,OAAO,GAAG,SAAS,SAAU,KAAK;GAChC,OAAO,GAAG;EACZ,CAAC;EAGD,EAAE,GAAG,SAAS,SAAU,KAAK;GAC3B,OAAO,GAAG;EACZ,CAAC;EAGD,EAAE,GAAG,QAAQ,SAAU,OAAO;GAC5B,KAAK,OAAO,KAAK;EACnB,CAAC;EAGD,EAAE,KAAK,MAAM;EAGb,EAAE,UAAU,aAAa,KAAK;EAG9B,EAAE,SAAS,CAAC,CAAC,MAAM,MAAM;CAC3B,CAAC;AACH"}
|
package/dist/core/archive.js
CHANGED
|
@@ -3,7 +3,7 @@ import fs from "node:fs";
|
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { createHash } from "node:crypto";
|
|
5
5
|
import archiver from "archiver";
|
|
6
|
-
|
|
6
|
+
// src/core/archive.ts
|
|
7
7
|
function getPath(options) {
|
|
8
8
|
const packageName = options.packageName.replaceAll("/", "-").replaceAll("\\", "-");
|
|
9
9
|
if (options && !options.crossplatform) return path.resolve(options.packageRoot, `pkg-${packageName}-${options.packageVersion}-${options.os}-${options.arch}.${options.ext}`);
|
|
@@ -41,7 +41,6 @@ async function create(logger, contentRoot, dstArchivePath, hasher) {
|
|
|
41
41
|
a.finalize().catch(reject);
|
|
42
42
|
});
|
|
43
43
|
}
|
|
44
|
-
//#endregion
|
|
45
44
|
export { create, getPath };
|
|
46
45
|
|
|
47
46
|
//# sourceMappingURL=archive.js.map
|
|
@@ -9,7 +9,7 @@ node_path = require_runtime.__toESM(node_path, 1);
|
|
|
9
9
|
let node_child_process = require("node:child_process");
|
|
10
10
|
let undici = require("undici");
|
|
11
11
|
undici = require_runtime.__toESM(undici, 1);
|
|
12
|
-
|
|
12
|
+
// src/core/conda/builder.ts
|
|
13
13
|
const defaultEnvironmentName = "default";
|
|
14
14
|
var micromamba = class {
|
|
15
15
|
logger;
|
|
@@ -223,7 +223,6 @@ async function downloadFile(logger, url, outputPath) {
|
|
|
223
223
|
});
|
|
224
224
|
});
|
|
225
225
|
}
|
|
226
|
-
//#endregion
|
|
227
226
|
exports.downloadMicromamba = downloadMicromamba;
|
|
228
227
|
exports.micromamba = micromamba;
|
|
229
228
|
exports.micromambaDownloadUrl = micromambaDownloadUrl;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builder.cjs","names":["path","fs","fsp"],"sources":["../../../src/core/conda/builder.ts"],"sourcesContent":["import fs from \"node:fs\";\nimport fsp from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { spawnSync, type SpawnSyncOptions } from \"node:child_process\";\nimport * as undici from \"undici\";\nimport type winston from \"winston\";\n\nimport * as util from \"../util\";\n\nconst defaultEnvironmentName = \"default\";\n\nexport interface BuilderOptions {\n mambaRootPrefix: string; // root directory for all conda data\n logger: winston.Logger;\n micromambaVersion?: string; // use specific version of micromamba\n}\n\nexport interface MicromambaDownloadOptions {\n platform: util.PlatformType;\n outputPath: string; // output path for the binary\n\n version?: string; // defalut: latest\n}\n\nexport interface EnvCreateOptions {\n /** Environment name */\n environmentName?: string;\n /** Prefix where to create the environment */\n environmentPrefix?: string;\n /** Path to the environment specification file */\n specFile: string;\n}\n\nexport interface EnvExportOptions {\n /** Name of the environment to export */\n environmentName?: string;\n /** Prefix of the environment to export */\n environmentPrefix?: string;\n /** Export in JSON format */\n json?: boolean;\n /** Output file path for the exported specification */\n outputFile?: string;\n}\n\nexport interface EnvDeleteOptions {\n /** Environment name */\n environmentName?: string;\n /** Prefix where to create the environment */\n environmentPrefix?: string;\n}\n\nexport class micromamba {\n constructor(\n private readonly logger: winston.Logger,\n private readonly rootPrefix: string,\n private readonly binaryVersion: string = \"latest\",\n private readonly binaryPath: string = \"\",\n ) {\n if (!binaryPath) {\n this.binaryPath = path.join(rootPrefix, \"micromamba\");\n }\n\n if (util.currentOS() === \"windows\" && !this.binaryPath.endsWith(\".exe\")) {\n this.binaryPath += \".exe\";\n }\n }\n\n public async downloadBinary(): Promise<void> {\n if (fs.existsSync(this.binaryPath)) {\n try {\n await fsp.access(this.binaryPath, fs.constants.X_OK);\n this.logger.debug(\n `micromamba binary '${this.binaryPath}' exists and executable. Download was skipped`,\n );\n return;\n } catch {\n this.logger.debug(\n `file exists but is not executable: ${this.binaryPath}. Fixing permissions`,\n );\n await fsp.chmod(this.binaryPath, 0o755);\n }\n }\n\n await downloadMicromamba(this.logger, {\n platform: util.currentPlatform(),\n outputPath: this.binaryPath,\n version: this.binaryVersion,\n });\n }\n\n public getVersion(): string {\n return this.execSync([\"--version\"])!;\n }\n\n public createEnvironment(opts: EnvCreateOptions): void {\n const { environmentName, environmentPrefix, specFile } = opts;\n this.logger.debug(\n `Creating conda environment '${environmentName ?? environmentPrefix ?? defaultEnvironmentName}'...`,\n );\n\n const args = [\"env\", \"create\", \"--file\", specFile, \"--yes\"];\n if (environmentPrefix) {\n args.push(\"--prefix\", environmentPrefix);\n } else if (environmentName) {\n args.push(\"--name\", environmentName);\n } else {\n args.push(\"--name\", defaultEnvironmentName);\n }\n\n this.execSync(args, {\n stdio: \"inherit\",\n });\n }\n\n public exportEnvironment(opts: {\n environmentName?: string;\n environmentPrefix?: string;\n json?: boolean;\n }): string;\n public exportEnvironment(opts: {\n environmentName?: string;\n environmentPrefix?: string;\n json?: boolean;\n outputFile: string;\n }): void;\n public exportEnvironment(opts: EnvExportOptions): void | string {\n const { environmentName, environmentPrefix, json, outputFile } = opts;\n this.logger.debug(\n `Exporting conda environment '${environmentName ?? environmentPrefix ?? defaultEnvironmentName}'...`,\n );\n\n const file = outputFile ? fs.openSync(outputFile, \"w\") : \"pipe\";\n\n const args = [\"env\", \"export\"];\n if (environmentPrefix) {\n args.push(\"--prefix\", environmentPrefix);\n } else if (environmentName) {\n args.push(\"--name\", environmentName);\n } else {\n args.push(\"--name\", defaultEnvironmentName);\n }\n if (json) {\n args.push(\"--json\");\n }\n\n try {\n const envInfo = this.execSync(args, {\n stdio: [\"inherit\", file, \"inherit\"],\n });\n\n if (!outputFile) {\n return envInfo;\n }\n } catch (error) {\n if (file !== \"pipe\") {\n fs.closeSync(file);\n }\n if (outputFile) {\n fs.rmSync(outputFile, { force: true });\n }\n throw error;\n }\n\n if (file !== \"pipe\") {\n fs.closeSync(file);\n }\n }\n\n public deleteEnvironment(opts: EnvDeleteOptions): void {\n const { environmentName, environmentPrefix } = opts;\n\n if (environmentPrefix) {\n this.logger.debug(\n `Deleting conda environment '${environmentName ?? environmentPrefix ?? defaultEnvironmentName}'...`,\n );\n fs.rmSync(environmentPrefix, { recursive: true });\n return;\n }\n\n const result = this.exportEnvironment({ environmentName, environmentPrefix, json: true });\n const envInfo = JSON.parse(result ?? \"{}\") as Record<string, unknown>;\n\n if (envInfo.prefix) {\n this.logger.debug(\n `Deleting conda environment '${environmentName ?? environmentPrefix ?? defaultEnvironmentName}'...`,\n );\n fs.rmSync(envInfo.prefix as string, { recursive: true });\n } else {\n const errMsg =\n \"Failed to delete environment: cannot get environment location from micromamba tool\";\n this.logger.error(errMsg);\n throw new Error(errMsg);\n }\n }\n\n // FIXME: IMHO better to have async exec with promises. I just am not skilled enough to implement it fast. :(\n private execSync(args: string[], opts?: SpawnSyncOptions): string | void {\n this.logger.debug(`Executing micromamba: ${this.binaryPath} ${args.join(\" \")}`);\n\n const result = spawnSync(this.binaryPath, args, {\n encoding: \"utf8\",\n stdio: \"pipe\",\n ...opts,\n env: {\n ...process.env,\n MAMBA_ROOT_PREFIX: this.rootPrefix,\n CONDA_PKGS_DIRS: path.join(this.rootPrefix, \"pkgs\"),\n ...opts?.env,\n },\n });\n\n if (result.error) {\n throw new Error(`Failed to get micromamba version: ${result.error.message}`);\n }\n\n if (result.status !== 0) {\n const errMsg = `micromamba command failed with status ${result.status}: ${result.stderr?.toString().trim() ?? \"no piped stderr\"}`;\n this.logger.error(errMsg);\n throw new Error(errMsg);\n }\n\n if (!result.stdout) {\n return;\n }\n\n return result.stdout.toString().trim();\n }\n}\n\nexport function micromambaDownloadUrl(version: string, platform: util.PlatformType): string {\n return version === \"latest\"\n ? `https://github.com/mamba-org/micromamba-releases/releases/latest/download/${micromambaAssetName(platform)}`\n : `https://github.com/mamba-org/micromamba-releases/releases/download/${version}/${micromambaAssetName(platform)}`;\n}\n\n/**\n * Downloads micromamba binary for the specified platform and version\n */\nexport async function downloadMicromamba(\n logger: winston.Logger,\n options: MicromambaDownloadOptions,\n): Promise<string> {\n const { version = \"latest\", platform, outputPath } = options;\n\n const targetPlatform = platform ?? util.currentPlatform();\n const binaryPath = outputPath;\n\n logger.debug(`Downloading micromamba version ${version} for platform ${targetPlatform}`);\n\n const downloadUrl = micromambaDownloadUrl(version, targetPlatform);\n\n logger.debug(`Download URL: ${downloadUrl}`);\n\n await downloadFile(logger, downloadUrl, binaryPath);\n\n logger.debug(`making binary executable: ${binaryPath}`);\n await fsp.chmod(binaryPath, 0o755);\n\n logger.info(`Micromamba downloaded to: ${binaryPath}`);\n return binaryPath;\n}\n\n/**\n * Get correct asset name with micromamba binary for particular platform,\n * as they are available in micromamba-releases repo.\n */\nfunction micromambaAssetName(platform: util.PlatformType): string {\n const { os, arch } = util.splitPlatform(platform);\n switch (os) {\n case \"linux\": {\n switch (arch) {\n case \"x64\":\n return \"micromamba-linux-64\";\n case \"aarch64\":\n return \"micromamba-linux-aarch64\";\n default:\n util.assertNever(arch);\n }\n break;\n }\n case \"macosx\": {\n switch (arch) {\n case \"x64\":\n return \"micromamba-osx-64\";\n case \"aarch64\":\n return \"micromamba-osx-arm64\";\n default:\n util.assertNever(arch);\n }\n break;\n }\n case \"windows\": {\n switch (arch) {\n case \"x64\":\n return \"micromamba-win-64\";\n case \"aarch64\":\n throw new Error(\"Micromamba does not support ARM64 on Windows\");\n default:\n util.assertNever(arch);\n }\n break;\n }\n default:\n util.assertNever(os);\n }\n throw new Error(\"calm down linter, this code is unreachable\");\n}\n\n/**\n * Downloads a file from URL to local path\n */\nasync function downloadFile(\n logger: winston.Logger,\n url: string,\n outputPath: string,\n): Promise<void> {\n type responseInfo = {\n statusCode: number;\n body: NodeJS.ReadableStream;\n location: string;\n };\n\n let response: responseInfo;\n const maxRedirects = 5;\n const maxAttempts = 3;\n\n let redirCount = 0;\n let attempt = 0;\n for (; attempt <= maxAttempts; ) {\n attempt++;\n\n logger.debug(`Trying to download: ${url}`);\n try {\n const requestResult = await undici.request(url, {\n method: \"GET\",\n });\n response = {\n statusCode: requestResult.statusCode,\n location: requestResult.headers[\"location\"]?.toString() ?? \"\",\n body: requestResult.body,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to make request: ${errorMessage}`);\n }\n\n if (response.statusCode === 301 || response.statusCode === 302) {\n if (redirCount >= maxRedirects) {\n throw new Error(`Too many redirects: ${redirCount}, last location: ${response.location}`);\n }\n\n logger.debug(`Processing redirect. New location: ${response.location}`);\n redirCount++;\n url = response.location;\n continue;\n }\n\n if (response.statusCode === 200) {\n break;\n }\n\n logger.error(`Failed to download: ${response.statusCode}, attempt ${attempt}`);\n }\n\n if (response!.statusCode !== 200) {\n throw new Error(`Failed to download: last attempt status code: ${response!.statusCode}`);\n }\n\n const fileStream = fs.createWriteStream(outputPath);\n\n response!.body.pipe(fileStream);\n\n return new Promise((resolve, reject) => {\n fileStream.on(\"finish\", () => {\n fileStream.close();\n resolve();\n });\n\n fileStream.on(\"error\", (err) => {\n fs.unlink(outputPath, () => {}); // Delete the file on error\n reject(err);\n });\n });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"builder.cjs","names":["path","fs","fsp","spawnSync"],"sources":["../../../src/core/conda/builder.ts"],"sourcesContent":["import fs from \"node:fs\";\nimport fsp from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { spawnSync, type SpawnSyncOptions } from \"node:child_process\";\nimport * as undici from \"undici\";\nimport type winston from \"winston\";\n\nimport * as util from \"../util\";\n\nconst defaultEnvironmentName = \"default\";\n\nexport interface BuilderOptions {\n mambaRootPrefix: string; // root directory for all conda data\n logger: winston.Logger;\n micromambaVersion?: string; // use specific version of micromamba\n}\n\nexport interface MicromambaDownloadOptions {\n platform: util.PlatformType;\n outputPath: string; // output path for the binary\n\n version?: string; // defalut: latest\n}\n\nexport interface EnvCreateOptions {\n /** Environment name */\n environmentName?: string;\n /** Prefix where to create the environment */\n environmentPrefix?: string;\n /** Path to the environment specification file */\n specFile: string;\n}\n\nexport interface EnvExportOptions {\n /** Name of the environment to export */\n environmentName?: string;\n /** Prefix of the environment to export */\n environmentPrefix?: string;\n /** Export in JSON format */\n json?: boolean;\n /** Output file path for the exported specification */\n outputFile?: string;\n}\n\nexport interface EnvDeleteOptions {\n /** Environment name */\n environmentName?: string;\n /** Prefix where to create the environment */\n environmentPrefix?: string;\n}\n\nexport class micromamba {\n constructor(\n private readonly logger: winston.Logger,\n private readonly rootPrefix: string,\n private readonly binaryVersion: string = \"latest\",\n private readonly binaryPath: string = \"\",\n ) {\n if (!binaryPath) {\n this.binaryPath = path.join(rootPrefix, \"micromamba\");\n }\n\n if (util.currentOS() === \"windows\" && !this.binaryPath.endsWith(\".exe\")) {\n this.binaryPath += \".exe\";\n }\n }\n\n public async downloadBinary(): Promise<void> {\n if (fs.existsSync(this.binaryPath)) {\n try {\n await fsp.access(this.binaryPath, fs.constants.X_OK);\n this.logger.debug(\n `micromamba binary '${this.binaryPath}' exists and executable. Download was skipped`,\n );\n return;\n } catch {\n this.logger.debug(\n `file exists but is not executable: ${this.binaryPath}. Fixing permissions`,\n );\n await fsp.chmod(this.binaryPath, 0o755);\n }\n }\n\n await downloadMicromamba(this.logger, {\n platform: util.currentPlatform(),\n outputPath: this.binaryPath,\n version: this.binaryVersion,\n });\n }\n\n public getVersion(): string {\n return this.execSync([\"--version\"])!;\n }\n\n public createEnvironment(opts: EnvCreateOptions): void {\n const { environmentName, environmentPrefix, specFile } = opts;\n this.logger.debug(\n `Creating conda environment '${environmentName ?? environmentPrefix ?? defaultEnvironmentName}'...`,\n );\n\n const args = [\"env\", \"create\", \"--file\", specFile, \"--yes\"];\n if (environmentPrefix) {\n args.push(\"--prefix\", environmentPrefix);\n } else if (environmentName) {\n args.push(\"--name\", environmentName);\n } else {\n args.push(\"--name\", defaultEnvironmentName);\n }\n\n this.execSync(args, {\n stdio: \"inherit\",\n });\n }\n\n public exportEnvironment(opts: {\n environmentName?: string;\n environmentPrefix?: string;\n json?: boolean;\n }): string;\n public exportEnvironment(opts: {\n environmentName?: string;\n environmentPrefix?: string;\n json?: boolean;\n outputFile: string;\n }): void;\n public exportEnvironment(opts: EnvExportOptions): void | string {\n const { environmentName, environmentPrefix, json, outputFile } = opts;\n this.logger.debug(\n `Exporting conda environment '${environmentName ?? environmentPrefix ?? defaultEnvironmentName}'...`,\n );\n\n const file = outputFile ? fs.openSync(outputFile, \"w\") : \"pipe\";\n\n const args = [\"env\", \"export\"];\n if (environmentPrefix) {\n args.push(\"--prefix\", environmentPrefix);\n } else if (environmentName) {\n args.push(\"--name\", environmentName);\n } else {\n args.push(\"--name\", defaultEnvironmentName);\n }\n if (json) {\n args.push(\"--json\");\n }\n\n try {\n const envInfo = this.execSync(args, {\n stdio: [\"inherit\", file, \"inherit\"],\n });\n\n if (!outputFile) {\n return envInfo;\n }\n } catch (error) {\n if (file !== \"pipe\") {\n fs.closeSync(file);\n }\n if (outputFile) {\n fs.rmSync(outputFile, { force: true });\n }\n throw error;\n }\n\n if (file !== \"pipe\") {\n fs.closeSync(file);\n }\n }\n\n public deleteEnvironment(opts: EnvDeleteOptions): void {\n const { environmentName, environmentPrefix } = opts;\n\n if (environmentPrefix) {\n this.logger.debug(\n `Deleting conda environment '${environmentName ?? environmentPrefix ?? defaultEnvironmentName}'...`,\n );\n fs.rmSync(environmentPrefix, { recursive: true });\n return;\n }\n\n const result = this.exportEnvironment({ environmentName, environmentPrefix, json: true });\n const envInfo = JSON.parse(result ?? \"{}\") as Record<string, unknown>;\n\n if (envInfo.prefix) {\n this.logger.debug(\n `Deleting conda environment '${environmentName ?? environmentPrefix ?? defaultEnvironmentName}'...`,\n );\n fs.rmSync(envInfo.prefix as string, { recursive: true });\n } else {\n const errMsg =\n \"Failed to delete environment: cannot get environment location from micromamba tool\";\n this.logger.error(errMsg);\n throw new Error(errMsg);\n }\n }\n\n // FIXME: IMHO better to have async exec with promises. I just am not skilled enough to implement it fast. :(\n private execSync(args: string[], opts?: SpawnSyncOptions): string | void {\n this.logger.debug(`Executing micromamba: ${this.binaryPath} ${args.join(\" \")}`);\n\n const result = spawnSync(this.binaryPath, args, {\n encoding: \"utf8\",\n stdio: \"pipe\",\n ...opts,\n env: {\n ...process.env,\n MAMBA_ROOT_PREFIX: this.rootPrefix,\n CONDA_PKGS_DIRS: path.join(this.rootPrefix, \"pkgs\"),\n ...opts?.env,\n },\n });\n\n if (result.error) {\n throw new Error(`Failed to get micromamba version: ${result.error.message}`);\n }\n\n if (result.status !== 0) {\n const errMsg = `micromamba command failed with status ${result.status}: ${result.stderr?.toString().trim() ?? \"no piped stderr\"}`;\n this.logger.error(errMsg);\n throw new Error(errMsg);\n }\n\n if (!result.stdout) {\n return;\n }\n\n return result.stdout.toString().trim();\n }\n}\n\nexport function micromambaDownloadUrl(version: string, platform: util.PlatformType): string {\n return version === \"latest\"\n ? `https://github.com/mamba-org/micromamba-releases/releases/latest/download/${micromambaAssetName(platform)}`\n : `https://github.com/mamba-org/micromamba-releases/releases/download/${version}/${micromambaAssetName(platform)}`;\n}\n\n/**\n * Downloads micromamba binary for the specified platform and version\n */\nexport async function downloadMicromamba(\n logger: winston.Logger,\n options: MicromambaDownloadOptions,\n): Promise<string> {\n const { version = \"latest\", platform, outputPath } = options;\n\n const targetPlatform = platform ?? util.currentPlatform();\n const binaryPath = outputPath;\n\n logger.debug(`Downloading micromamba version ${version} for platform ${targetPlatform}`);\n\n const downloadUrl = micromambaDownloadUrl(version, targetPlatform);\n\n logger.debug(`Download URL: ${downloadUrl}`);\n\n await downloadFile(logger, downloadUrl, binaryPath);\n\n logger.debug(`making binary executable: ${binaryPath}`);\n await fsp.chmod(binaryPath, 0o755);\n\n logger.info(`Micromamba downloaded to: ${binaryPath}`);\n return binaryPath;\n}\n\n/**\n * Get correct asset name with micromamba binary for particular platform,\n * as they are available in micromamba-releases repo.\n */\nfunction micromambaAssetName(platform: util.PlatformType): string {\n const { os, arch } = util.splitPlatform(platform);\n switch (os) {\n case \"linux\": {\n switch (arch) {\n case \"x64\":\n return \"micromamba-linux-64\";\n case \"aarch64\":\n return \"micromamba-linux-aarch64\";\n default:\n util.assertNever(arch);\n }\n break;\n }\n case \"macosx\": {\n switch (arch) {\n case \"x64\":\n return \"micromamba-osx-64\";\n case \"aarch64\":\n return \"micromamba-osx-arm64\";\n default:\n util.assertNever(arch);\n }\n break;\n }\n case \"windows\": {\n switch (arch) {\n case \"x64\":\n return \"micromamba-win-64\";\n case \"aarch64\":\n throw new Error(\"Micromamba does not support ARM64 on Windows\");\n default:\n util.assertNever(arch);\n }\n break;\n }\n default:\n util.assertNever(os);\n }\n throw new Error(\"calm down linter, this code is unreachable\");\n}\n\n/**\n * Downloads a file from URL to local path\n */\nasync function downloadFile(\n logger: winston.Logger,\n url: string,\n outputPath: string,\n): Promise<void> {\n type responseInfo = {\n statusCode: number;\n body: NodeJS.ReadableStream;\n location: string;\n };\n\n let response: responseInfo;\n const maxRedirects = 5;\n const maxAttempts = 3;\n\n let redirCount = 0;\n let attempt = 0;\n for (; attempt <= maxAttempts;) {\n attempt++;\n\n logger.debug(`Trying to download: ${url}`);\n try {\n const requestResult = await undici.request(url, {\n method: \"GET\",\n });\n response = {\n statusCode: requestResult.statusCode,\n location: requestResult.headers[\"location\"]?.toString() ?? \"\",\n body: requestResult.body,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to make request: ${errorMessage}`);\n }\n\n if (response.statusCode === 301 || response.statusCode === 302) {\n if (redirCount >= maxRedirects) {\n throw new Error(`Too many redirects: ${redirCount}, last location: ${response.location}`);\n }\n\n logger.debug(`Processing redirect. New location: ${response.location}`);\n redirCount++;\n url = response.location;\n continue;\n }\n\n if (response.statusCode === 200) {\n break;\n }\n\n logger.error(`Failed to download: ${response.statusCode}, attempt ${attempt}`);\n }\n\n if (response!.statusCode !== 200) {\n throw new Error(`Failed to download: last attempt status code: ${response!.statusCode}`);\n }\n\n const fileStream = fs.createWriteStream(outputPath);\n\n response!.body.pipe(fileStream);\n\n return new Promise((resolve, reject) => {\n fileStream.on(\"finish\", () => {\n fileStream.close();\n resolve();\n });\n\n fileStream.on(\"error\", (err) => {\n fs.unlink(outputPath, () => {}); // Delete the file on error\n reject(err);\n });\n });\n}\n"],"mappings":"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"}
|
|
@@ -4,7 +4,7 @@ import fsp from "node:fs/promises";
|
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import { spawnSync } from "node:child_process";
|
|
6
6
|
import * as undici from "undici";
|
|
7
|
-
|
|
7
|
+
// src/core/conda/builder.ts
|
|
8
8
|
const defaultEnvironmentName = "default";
|
|
9
9
|
var micromamba = class {
|
|
10
10
|
logger;
|
|
@@ -218,7 +218,6 @@ async function downloadFile(logger, url, outputPath) {
|
|
|
218
218
|
});
|
|
219
219
|
});
|
|
220
220
|
}
|
|
221
|
-
//#endregion
|
|
222
221
|
export { downloadMicromamba, micromamba, micromambaDownloadUrl };
|
|
223
222
|
|
|
224
223
|
//# sourceMappingURL=builder.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builder.js","names":["util.currentOS","util.currentPlatform","util.splitPlatform"],"sources":["../../../src/core/conda/builder.ts"],"sourcesContent":["import fs from \"node:fs\";\nimport fsp from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { spawnSync, type SpawnSyncOptions } from \"node:child_process\";\nimport * as undici from \"undici\";\nimport type winston from \"winston\";\n\nimport * as util from \"../util\";\n\nconst defaultEnvironmentName = \"default\";\n\nexport interface BuilderOptions {\n mambaRootPrefix: string; // root directory for all conda data\n logger: winston.Logger;\n micromambaVersion?: string; // use specific version of micromamba\n}\n\nexport interface MicromambaDownloadOptions {\n platform: util.PlatformType;\n outputPath: string; // output path for the binary\n\n version?: string; // defalut: latest\n}\n\nexport interface EnvCreateOptions {\n /** Environment name */\n environmentName?: string;\n /** Prefix where to create the environment */\n environmentPrefix?: string;\n /** Path to the environment specification file */\n specFile: string;\n}\n\nexport interface EnvExportOptions {\n /** Name of the environment to export */\n environmentName?: string;\n /** Prefix of the environment to export */\n environmentPrefix?: string;\n /** Export in JSON format */\n json?: boolean;\n /** Output file path for the exported specification */\n outputFile?: string;\n}\n\nexport interface EnvDeleteOptions {\n /** Environment name */\n environmentName?: string;\n /** Prefix where to create the environment */\n environmentPrefix?: string;\n}\n\nexport class micromamba {\n constructor(\n private readonly logger: winston.Logger,\n private readonly rootPrefix: string,\n private readonly binaryVersion: string = \"latest\",\n private readonly binaryPath: string = \"\",\n ) {\n if (!binaryPath) {\n this.binaryPath = path.join(rootPrefix, \"micromamba\");\n }\n\n if (util.currentOS() === \"windows\" && !this.binaryPath.endsWith(\".exe\")) {\n this.binaryPath += \".exe\";\n }\n }\n\n public async downloadBinary(): Promise<void> {\n if (fs.existsSync(this.binaryPath)) {\n try {\n await fsp.access(this.binaryPath, fs.constants.X_OK);\n this.logger.debug(\n `micromamba binary '${this.binaryPath}' exists and executable. Download was skipped`,\n );\n return;\n } catch {\n this.logger.debug(\n `file exists but is not executable: ${this.binaryPath}. Fixing permissions`,\n );\n await fsp.chmod(this.binaryPath, 0o755);\n }\n }\n\n await downloadMicromamba(this.logger, {\n platform: util.currentPlatform(),\n outputPath: this.binaryPath,\n version: this.binaryVersion,\n });\n }\n\n public getVersion(): string {\n return this.execSync([\"--version\"])!;\n }\n\n public createEnvironment(opts: EnvCreateOptions): void {\n const { environmentName, environmentPrefix, specFile } = opts;\n this.logger.debug(\n `Creating conda environment '${environmentName ?? environmentPrefix ?? defaultEnvironmentName}'...`,\n );\n\n const args = [\"env\", \"create\", \"--file\", specFile, \"--yes\"];\n if (environmentPrefix) {\n args.push(\"--prefix\", environmentPrefix);\n } else if (environmentName) {\n args.push(\"--name\", environmentName);\n } else {\n args.push(\"--name\", defaultEnvironmentName);\n }\n\n this.execSync(args, {\n stdio: \"inherit\",\n });\n }\n\n public exportEnvironment(opts: {\n environmentName?: string;\n environmentPrefix?: string;\n json?: boolean;\n }): string;\n public exportEnvironment(opts: {\n environmentName?: string;\n environmentPrefix?: string;\n json?: boolean;\n outputFile: string;\n }): void;\n public exportEnvironment(opts: EnvExportOptions): void | string {\n const { environmentName, environmentPrefix, json, outputFile } = opts;\n this.logger.debug(\n `Exporting conda environment '${environmentName ?? environmentPrefix ?? defaultEnvironmentName}'...`,\n );\n\n const file = outputFile ? fs.openSync(outputFile, \"w\") : \"pipe\";\n\n const args = [\"env\", \"export\"];\n if (environmentPrefix) {\n args.push(\"--prefix\", environmentPrefix);\n } else if (environmentName) {\n args.push(\"--name\", environmentName);\n } else {\n args.push(\"--name\", defaultEnvironmentName);\n }\n if (json) {\n args.push(\"--json\");\n }\n\n try {\n const envInfo = this.execSync(args, {\n stdio: [\"inherit\", file, \"inherit\"],\n });\n\n if (!outputFile) {\n return envInfo;\n }\n } catch (error) {\n if (file !== \"pipe\") {\n fs.closeSync(file);\n }\n if (outputFile) {\n fs.rmSync(outputFile, { force: true });\n }\n throw error;\n }\n\n if (file !== \"pipe\") {\n fs.closeSync(file);\n }\n }\n\n public deleteEnvironment(opts: EnvDeleteOptions): void {\n const { environmentName, environmentPrefix } = opts;\n\n if (environmentPrefix) {\n this.logger.debug(\n `Deleting conda environment '${environmentName ?? environmentPrefix ?? defaultEnvironmentName}'...`,\n );\n fs.rmSync(environmentPrefix, { recursive: true });\n return;\n }\n\n const result = this.exportEnvironment({ environmentName, environmentPrefix, json: true });\n const envInfo = JSON.parse(result ?? \"{}\") as Record<string, unknown>;\n\n if (envInfo.prefix) {\n this.logger.debug(\n `Deleting conda environment '${environmentName ?? environmentPrefix ?? defaultEnvironmentName}'...`,\n );\n fs.rmSync(envInfo.prefix as string, { recursive: true });\n } else {\n const errMsg =\n \"Failed to delete environment: cannot get environment location from micromamba tool\";\n this.logger.error(errMsg);\n throw new Error(errMsg);\n }\n }\n\n // FIXME: IMHO better to have async exec with promises. I just am not skilled enough to implement it fast. :(\n private execSync(args: string[], opts?: SpawnSyncOptions): string | void {\n this.logger.debug(`Executing micromamba: ${this.binaryPath} ${args.join(\" \")}`);\n\n const result = spawnSync(this.binaryPath, args, {\n encoding: \"utf8\",\n stdio: \"pipe\",\n ...opts,\n env: {\n ...process.env,\n MAMBA_ROOT_PREFIX: this.rootPrefix,\n CONDA_PKGS_DIRS: path.join(this.rootPrefix, \"pkgs\"),\n ...opts?.env,\n },\n });\n\n if (result.error) {\n throw new Error(`Failed to get micromamba version: ${result.error.message}`);\n }\n\n if (result.status !== 0) {\n const errMsg = `micromamba command failed with status ${result.status}: ${result.stderr?.toString().trim() ?? \"no piped stderr\"}`;\n this.logger.error(errMsg);\n throw new Error(errMsg);\n }\n\n if (!result.stdout) {\n return;\n }\n\n return result.stdout.toString().trim();\n }\n}\n\nexport function micromambaDownloadUrl(version: string, platform: util.PlatformType): string {\n return version === \"latest\"\n ? `https://github.com/mamba-org/micromamba-releases/releases/latest/download/${micromambaAssetName(platform)}`\n : `https://github.com/mamba-org/micromamba-releases/releases/download/${version}/${micromambaAssetName(platform)}`;\n}\n\n/**\n * Downloads micromamba binary for the specified platform and version\n */\nexport async function downloadMicromamba(\n logger: winston.Logger,\n options: MicromambaDownloadOptions,\n): Promise<string> {\n const { version = \"latest\", platform, outputPath } = options;\n\n const targetPlatform = platform ?? util.currentPlatform();\n const binaryPath = outputPath;\n\n logger.debug(`Downloading micromamba version ${version} for platform ${targetPlatform}`);\n\n const downloadUrl = micromambaDownloadUrl(version, targetPlatform);\n\n logger.debug(`Download URL: ${downloadUrl}`);\n\n await downloadFile(logger, downloadUrl, binaryPath);\n\n logger.debug(`making binary executable: ${binaryPath}`);\n await fsp.chmod(binaryPath, 0o755);\n\n logger.info(`Micromamba downloaded to: ${binaryPath}`);\n return binaryPath;\n}\n\n/**\n * Get correct asset name with micromamba binary for particular platform,\n * as they are available in micromamba-releases repo.\n */\nfunction micromambaAssetName(platform: util.PlatformType): string {\n const { os, arch } = util.splitPlatform(platform);\n switch (os) {\n case \"linux\": {\n switch (arch) {\n case \"x64\":\n return \"micromamba-linux-64\";\n case \"aarch64\":\n return \"micromamba-linux-aarch64\";\n default:\n util.assertNever(arch);\n }\n break;\n }\n case \"macosx\": {\n switch (arch) {\n case \"x64\":\n return \"micromamba-osx-64\";\n case \"aarch64\":\n return \"micromamba-osx-arm64\";\n default:\n util.assertNever(arch);\n }\n break;\n }\n case \"windows\": {\n switch (arch) {\n case \"x64\":\n return \"micromamba-win-64\";\n case \"aarch64\":\n throw new Error(\"Micromamba does not support ARM64 on Windows\");\n default:\n util.assertNever(arch);\n }\n break;\n }\n default:\n util.assertNever(os);\n }\n throw new Error(\"calm down linter, this code is unreachable\");\n}\n\n/**\n * Downloads a file from URL to local path\n */\nasync function downloadFile(\n logger: winston.Logger,\n url: string,\n outputPath: string,\n): Promise<void> {\n type responseInfo = {\n statusCode: number;\n body: NodeJS.ReadableStream;\n location: string;\n };\n\n let response: responseInfo;\n const maxRedirects = 5;\n const maxAttempts = 3;\n\n let redirCount = 0;\n let attempt = 0;\n for (; attempt <= maxAttempts; ) {\n attempt++;\n\n logger.debug(`Trying to download: ${url}`);\n try {\n const requestResult = await undici.request(url, {\n method: \"GET\",\n });\n response = {\n statusCode: requestResult.statusCode,\n location: requestResult.headers[\"location\"]?.toString() ?? \"\",\n body: requestResult.body,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to make request: ${errorMessage}`);\n }\n\n if (response.statusCode === 301 || response.statusCode === 302) {\n if (redirCount >= maxRedirects) {\n throw new Error(`Too many redirects: ${redirCount}, last location: ${response.location}`);\n }\n\n logger.debug(`Processing redirect. New location: ${response.location}`);\n redirCount++;\n url = response.location;\n continue;\n }\n\n if (response.statusCode === 200) {\n break;\n }\n\n logger.error(`Failed to download: ${response.statusCode}, attempt ${attempt}`);\n }\n\n if (response!.statusCode !== 200) {\n throw new Error(`Failed to download: last attempt status code: ${response!.statusCode}`);\n }\n\n const fileStream = fs.createWriteStream(outputPath);\n\n response!.body.pipe(fileStream);\n\n return new Promise((resolve, reject) => {\n fileStream.on(\"finish\", () => {\n fileStream.close();\n resolve();\n });\n\n fileStream.on(\"error\", (err) => {\n fs.unlink(outputPath, () => {}); // Delete the file on error\n reject(err);\n });\n });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"builder.js","names":["util.currentOS","util.currentPlatform","util.splitPlatform"],"sources":["../../../src/core/conda/builder.ts"],"sourcesContent":["import fs from \"node:fs\";\nimport fsp from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { spawnSync, type SpawnSyncOptions } from \"node:child_process\";\nimport * as undici from \"undici\";\nimport type winston from \"winston\";\n\nimport * as util from \"../util\";\n\nconst defaultEnvironmentName = \"default\";\n\nexport interface BuilderOptions {\n mambaRootPrefix: string; // root directory for all conda data\n logger: winston.Logger;\n micromambaVersion?: string; // use specific version of micromamba\n}\n\nexport interface MicromambaDownloadOptions {\n platform: util.PlatformType;\n outputPath: string; // output path for the binary\n\n version?: string; // defalut: latest\n}\n\nexport interface EnvCreateOptions {\n /** Environment name */\n environmentName?: string;\n /** Prefix where to create the environment */\n environmentPrefix?: string;\n /** Path to the environment specification file */\n specFile: string;\n}\n\nexport interface EnvExportOptions {\n /** Name of the environment to export */\n environmentName?: string;\n /** Prefix of the environment to export */\n environmentPrefix?: string;\n /** Export in JSON format */\n json?: boolean;\n /** Output file path for the exported specification */\n outputFile?: string;\n}\n\nexport interface EnvDeleteOptions {\n /** Environment name */\n environmentName?: string;\n /** Prefix where to create the environment */\n environmentPrefix?: string;\n}\n\nexport class micromamba {\n constructor(\n private readonly logger: winston.Logger,\n private readonly rootPrefix: string,\n private readonly binaryVersion: string = \"latest\",\n private readonly binaryPath: string = \"\",\n ) {\n if (!binaryPath) {\n this.binaryPath = path.join(rootPrefix, \"micromamba\");\n }\n\n if (util.currentOS() === \"windows\" && !this.binaryPath.endsWith(\".exe\")) {\n this.binaryPath += \".exe\";\n }\n }\n\n public async downloadBinary(): Promise<void> {\n if (fs.existsSync(this.binaryPath)) {\n try {\n await fsp.access(this.binaryPath, fs.constants.X_OK);\n this.logger.debug(\n `micromamba binary '${this.binaryPath}' exists and executable. Download was skipped`,\n );\n return;\n } catch {\n this.logger.debug(\n `file exists but is not executable: ${this.binaryPath}. Fixing permissions`,\n );\n await fsp.chmod(this.binaryPath, 0o755);\n }\n }\n\n await downloadMicromamba(this.logger, {\n platform: util.currentPlatform(),\n outputPath: this.binaryPath,\n version: this.binaryVersion,\n });\n }\n\n public getVersion(): string {\n return this.execSync([\"--version\"])!;\n }\n\n public createEnvironment(opts: EnvCreateOptions): void {\n const { environmentName, environmentPrefix, specFile } = opts;\n this.logger.debug(\n `Creating conda environment '${environmentName ?? environmentPrefix ?? defaultEnvironmentName}'...`,\n );\n\n const args = [\"env\", \"create\", \"--file\", specFile, \"--yes\"];\n if (environmentPrefix) {\n args.push(\"--prefix\", environmentPrefix);\n } else if (environmentName) {\n args.push(\"--name\", environmentName);\n } else {\n args.push(\"--name\", defaultEnvironmentName);\n }\n\n this.execSync(args, {\n stdio: \"inherit\",\n });\n }\n\n public exportEnvironment(opts: {\n environmentName?: string;\n environmentPrefix?: string;\n json?: boolean;\n }): string;\n public exportEnvironment(opts: {\n environmentName?: string;\n environmentPrefix?: string;\n json?: boolean;\n outputFile: string;\n }): void;\n public exportEnvironment(opts: EnvExportOptions): void | string {\n const { environmentName, environmentPrefix, json, outputFile } = opts;\n this.logger.debug(\n `Exporting conda environment '${environmentName ?? environmentPrefix ?? defaultEnvironmentName}'...`,\n );\n\n const file = outputFile ? fs.openSync(outputFile, \"w\") : \"pipe\";\n\n const args = [\"env\", \"export\"];\n if (environmentPrefix) {\n args.push(\"--prefix\", environmentPrefix);\n } else if (environmentName) {\n args.push(\"--name\", environmentName);\n } else {\n args.push(\"--name\", defaultEnvironmentName);\n }\n if (json) {\n args.push(\"--json\");\n }\n\n try {\n const envInfo = this.execSync(args, {\n stdio: [\"inherit\", file, \"inherit\"],\n });\n\n if (!outputFile) {\n return envInfo;\n }\n } catch (error) {\n if (file !== \"pipe\") {\n fs.closeSync(file);\n }\n if (outputFile) {\n fs.rmSync(outputFile, { force: true });\n }\n throw error;\n }\n\n if (file !== \"pipe\") {\n fs.closeSync(file);\n }\n }\n\n public deleteEnvironment(opts: EnvDeleteOptions): void {\n const { environmentName, environmentPrefix } = opts;\n\n if (environmentPrefix) {\n this.logger.debug(\n `Deleting conda environment '${environmentName ?? environmentPrefix ?? defaultEnvironmentName}'...`,\n );\n fs.rmSync(environmentPrefix, { recursive: true });\n return;\n }\n\n const result = this.exportEnvironment({ environmentName, environmentPrefix, json: true });\n const envInfo = JSON.parse(result ?? \"{}\") as Record<string, unknown>;\n\n if (envInfo.prefix) {\n this.logger.debug(\n `Deleting conda environment '${environmentName ?? environmentPrefix ?? defaultEnvironmentName}'...`,\n );\n fs.rmSync(envInfo.prefix as string, { recursive: true });\n } else {\n const errMsg =\n \"Failed to delete environment: cannot get environment location from micromamba tool\";\n this.logger.error(errMsg);\n throw new Error(errMsg);\n }\n }\n\n // FIXME: IMHO better to have async exec with promises. I just am not skilled enough to implement it fast. :(\n private execSync(args: string[], opts?: SpawnSyncOptions): string | void {\n this.logger.debug(`Executing micromamba: ${this.binaryPath} ${args.join(\" \")}`);\n\n const result = spawnSync(this.binaryPath, args, {\n encoding: \"utf8\",\n stdio: \"pipe\",\n ...opts,\n env: {\n ...process.env,\n MAMBA_ROOT_PREFIX: this.rootPrefix,\n CONDA_PKGS_DIRS: path.join(this.rootPrefix, \"pkgs\"),\n ...opts?.env,\n },\n });\n\n if (result.error) {\n throw new Error(`Failed to get micromamba version: ${result.error.message}`);\n }\n\n if (result.status !== 0) {\n const errMsg = `micromamba command failed with status ${result.status}: ${result.stderr?.toString().trim() ?? \"no piped stderr\"}`;\n this.logger.error(errMsg);\n throw new Error(errMsg);\n }\n\n if (!result.stdout) {\n return;\n }\n\n return result.stdout.toString().trim();\n }\n}\n\nexport function micromambaDownloadUrl(version: string, platform: util.PlatformType): string {\n return version === \"latest\"\n ? `https://github.com/mamba-org/micromamba-releases/releases/latest/download/${micromambaAssetName(platform)}`\n : `https://github.com/mamba-org/micromamba-releases/releases/download/${version}/${micromambaAssetName(platform)}`;\n}\n\n/**\n * Downloads micromamba binary for the specified platform and version\n */\nexport async function downloadMicromamba(\n logger: winston.Logger,\n options: MicromambaDownloadOptions,\n): Promise<string> {\n const { version = \"latest\", platform, outputPath } = options;\n\n const targetPlatform = platform ?? util.currentPlatform();\n const binaryPath = outputPath;\n\n logger.debug(`Downloading micromamba version ${version} for platform ${targetPlatform}`);\n\n const downloadUrl = micromambaDownloadUrl(version, targetPlatform);\n\n logger.debug(`Download URL: ${downloadUrl}`);\n\n await downloadFile(logger, downloadUrl, binaryPath);\n\n logger.debug(`making binary executable: ${binaryPath}`);\n await fsp.chmod(binaryPath, 0o755);\n\n logger.info(`Micromamba downloaded to: ${binaryPath}`);\n return binaryPath;\n}\n\n/**\n * Get correct asset name with micromamba binary for particular platform,\n * as they are available in micromamba-releases repo.\n */\nfunction micromambaAssetName(platform: util.PlatformType): string {\n const { os, arch } = util.splitPlatform(platform);\n switch (os) {\n case \"linux\": {\n switch (arch) {\n case \"x64\":\n return \"micromamba-linux-64\";\n case \"aarch64\":\n return \"micromamba-linux-aarch64\";\n default:\n util.assertNever(arch);\n }\n break;\n }\n case \"macosx\": {\n switch (arch) {\n case \"x64\":\n return \"micromamba-osx-64\";\n case \"aarch64\":\n return \"micromamba-osx-arm64\";\n default:\n util.assertNever(arch);\n }\n break;\n }\n case \"windows\": {\n switch (arch) {\n case \"x64\":\n return \"micromamba-win-64\";\n case \"aarch64\":\n throw new Error(\"Micromamba does not support ARM64 on Windows\");\n default:\n util.assertNever(arch);\n }\n break;\n }\n default:\n util.assertNever(os);\n }\n throw new Error(\"calm down linter, this code is unreachable\");\n}\n\n/**\n * Downloads a file from URL to local path\n */\nasync function downloadFile(\n logger: winston.Logger,\n url: string,\n outputPath: string,\n): Promise<void> {\n type responseInfo = {\n statusCode: number;\n body: NodeJS.ReadableStream;\n location: string;\n };\n\n let response: responseInfo;\n const maxRedirects = 5;\n const maxAttempts = 3;\n\n let redirCount = 0;\n let attempt = 0;\n for (; attempt <= maxAttempts;) {\n attempt++;\n\n logger.debug(`Trying to download: ${url}`);\n try {\n const requestResult = await undici.request(url, {\n method: \"GET\",\n });\n response = {\n statusCode: requestResult.statusCode,\n location: requestResult.headers[\"location\"]?.toString() ?? \"\",\n body: requestResult.body,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to make request: ${errorMessage}`);\n }\n\n if (response.statusCode === 301 || response.statusCode === 302) {\n if (redirCount >= maxRedirects) {\n throw new Error(`Too many redirects: ${redirCount}, last location: ${response.location}`);\n }\n\n logger.debug(`Processing redirect. New location: ${response.location}`);\n redirCount++;\n url = response.location;\n continue;\n }\n\n if (response.statusCode === 200) {\n break;\n }\n\n logger.error(`Failed to download: ${response.statusCode}, attempt ${attempt}`);\n }\n\n if (response!.statusCode !== 200) {\n throw new Error(`Failed to download: last attempt status code: ${response!.statusCode}`);\n }\n\n const fileStream = fs.createWriteStream(outputPath);\n\n response!.body.pipe(fileStream);\n\n return new Promise((resolve, reject) => {\n fileStream.on(\"finish\", () => {\n fileStream.close();\n resolve();\n });\n\n fileStream.on(\"error\", (err) => {\n fs.unlink(outputPath, () => {}); // Delete the file on error\n reject(err);\n });\n });\n}\n"],"mappings":"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"}
|
|
@@ -3,7 +3,7 @@ let node_fs = require("node:fs");
|
|
|
3
3
|
node_fs = require_runtime.__toESM(node_fs, 1);
|
|
4
4
|
let yaml = require("yaml");
|
|
5
5
|
yaml = require_runtime.__toESM(yaml, 1);
|
|
6
|
-
|
|
6
|
+
// src/core/conda/validate-spec.ts
|
|
7
7
|
/**
|
|
8
8
|
* Channels that are forbidden because they reference the official Anaconda channel.
|
|
9
9
|
* These channels (main, r, msys2, defaults, anaconda) should be avoided in favor of
|
|
@@ -70,7 +70,6 @@ function validateDependencies(dependencies) {
|
|
|
70
70
|
}
|
|
71
71
|
return errors;
|
|
72
72
|
}
|
|
73
|
-
//#endregion
|
|
74
73
|
exports.validateCondaSpec = validateCondaSpec;
|
|
75
74
|
|
|
76
75
|
//# sourceMappingURL=validate-spec.cjs.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import yaml from "yaml";
|
|
3
|
-
|
|
3
|
+
// src/core/conda/validate-spec.ts
|
|
4
4
|
/**
|
|
5
5
|
* Channels that are forbidden because they reference the official Anaconda channel.
|
|
6
6
|
* These channels (main, r, msys2, defaults, anaconda) should be avoided in favor of
|
|
@@ -67,7 +67,6 @@ function validateDependencies(dependencies) {
|
|
|
67
67
|
}
|
|
68
68
|
return errors;
|
|
69
69
|
}
|
|
70
|
-
//#endregion
|
|
71
70
|
export { validateCondaSpec };
|
|
72
71
|
|
|
73
72
|
//# sourceMappingURL=validate-spec.js.map
|
package/dist/core/core.cjs
CHANGED
|
@@ -19,7 +19,7 @@ let node_path = require("node:path");
|
|
|
19
19
|
node_path = require_runtime.__toESM(node_path, 1);
|
|
20
20
|
let yaml = require("yaml");
|
|
21
21
|
yaml = require_runtime.__toESM(yaml, 1);
|
|
22
|
-
|
|
22
|
+
// src/core/core.ts
|
|
23
23
|
var Core = class {
|
|
24
24
|
logger;
|
|
25
25
|
_entrypoints;
|
|
@@ -213,14 +213,12 @@ var Core = class {
|
|
|
213
213
|
return;
|
|
214
214
|
}
|
|
215
215
|
switch (artifact.type) {
|
|
216
|
-
case "conda":
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
else this.logger.debug(`Conda environment build was skipped.`);
|
|
223
|
-
break;
|
|
216
|
+
case "conda": if (options?.condaBuild === void 0 || options.condaBuild) await this.buildCondaPackage({
|
|
217
|
+
artifact,
|
|
218
|
+
platform,
|
|
219
|
+
contentRoot
|
|
220
|
+
});
|
|
221
|
+
else this.logger.debug(`Conda environment build was skipped.`);
|
|
224
222
|
}
|
|
225
223
|
if (!require_util.producesRegistryDescriptor(this.buildMode)) {
|
|
226
224
|
this.logger.info(` no need to build software archive in '${this.buildMode}' mode: archive build was skipped`);
|
|
@@ -376,7 +374,8 @@ var Core = class {
|
|
|
376
374
|
const registry = this.pkgInfo.artifactRegistrySettings(artifact);
|
|
377
375
|
const storageURL = options?.storageURL ?? registry.storageURL;
|
|
378
376
|
const archivePath = options?.archivePath ?? this.archivePath(artifact, os, arch);
|
|
379
|
-
const
|
|
377
|
+
const artInfoPath = this.pkgInfo.artifactInfoLocation(artifact.id, "archive", require_artifacts.isCrossPlatform(artifact.type) ? void 0 : require_util.joinPlatform(os, arch));
|
|
378
|
+
const artInfo = require_sw_json_render.readBuiltArtifactInfo(artInfoPath);
|
|
380
379
|
const dstName = artInfo.uploadPath ?? artInfo.remoteArtifactLocation;
|
|
381
380
|
if (!storageURL) {
|
|
382
381
|
const regNameUpper = registry.name.toUpperCase().replaceAll(/[^A-Z0-9_]/g, "_");
|
|
@@ -424,7 +423,8 @@ var Core = class {
|
|
|
424
423
|
}
|
|
425
424
|
publishDockerImage(artifact, pushTo) {
|
|
426
425
|
if (artifact.type !== "docker") throw require_util.CLIError(`package '${artifact.id}' is not a docker package`);
|
|
427
|
-
const
|
|
426
|
+
const artInfoPath = this.pkgInfo.artifactInfoLocation(artifact.id, "docker", "x64");
|
|
427
|
+
const tag = require_sw_json_render.readBuiltArtifactInfo(artInfoPath).remoteArtifactLocation;
|
|
428
428
|
const pushTag = pushTo ? `${pushTo}:${tag.split(":").slice(-1)[0]}` : tag;
|
|
429
429
|
if (require_docker.remoteImageExists(pushTag)) {
|
|
430
430
|
this.logger.info(`Docker image '${tag}' not exists locally but is already in remote registry. Skipping push...`);
|
|
@@ -453,7 +453,6 @@ var Core = class {
|
|
|
453
453
|
};
|
|
454
454
|
}
|
|
455
455
|
};
|
|
456
|
-
//#endregion
|
|
457
456
|
exports.Core = Core;
|
|
458
457
|
|
|
459
458
|
//# sourceMappingURL=core.cjs.map
|