@microtronics/studio-cli 0.32.2 → 0.33.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/CHANGELOG.md +16 -5
- package/dist/studio-cli.d.ts +3 -0
- package/out/argumentParser.js +64 -0
- package/out/globals.js +1 -1
- package/out/main.js +21 -9
- package/out/manifest.js +14 -30
- package/package.json +3 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,10 +1,21 @@
|
|
|
1
|
+
# Changelog
|
|
1
2
|
|
|
2
|
-
|
|
3
|
-
## 0.32.2 (2025-06-02)
|
|
4
|
-
|
|
3
|
+
## 0.33.0 (2025-09-01)
|
|
5
4
|
|
|
6
|
-
###
|
|
5
|
+
### Features
|
|
7
6
|
|
|
7
|
+
* **cli:** add description to CLI tool usage ([97e8562](https://bitbucket.org/microtronics-core/vscode-studio/commits/97e85625a7c6d11070e2713f3ec3d2c24691854a))
|
|
8
|
+
* **cli:** add support for parsing unknown long options ([fa6523c](https://bitbucket.org/microtronics-core/vscode-studio/commits/fa6523caef791d508b31ed5d563452b616e99ae0))
|
|
9
|
+
* **cli:** support custom ini file in manifest ([5ae2741](https://bitbucket.org/microtronics-core/vscode-studio/commits/5ae2741ad379258fee95311fd28acc8b3dd1bdb6))
|
|
10
|
+
* **cli:** support manifest overwrites with deep merge ([10b69e2](https://bitbucket.org/microtronics-core/vscode-studio/commits/10b69e29c9426bec08022610b66e85b86cee79c9))
|
|
11
|
+
|
|
12
|
+
## 0.32.3 (2025-06-11)
|
|
13
|
+
|
|
14
|
+
## 0.32.2 (2025-06-02)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### Bug Fixes
|
|
18
|
+
|
|
8
19
|
* **studio-cli:** improve semver validation in dependency check ([2238827](https://bitbucket.org/microtronics-core/vscode-studio/commits/2238827380cdbe56fa5798c6de50c284df4da4c7))
|
|
9
20
|
|
|
10
21
|
## 0.32.1 (2025-06-02)
|
|
@@ -183,7 +194,7 @@
|
|
|
183
194
|
|
|
184
195
|
## 0.19.1 (2025-02-20)
|
|
185
196
|
|
|
186
|
-
|
|
197
|
+
|
|
187
198
|
|
|
188
199
|
## 0.19.0 (2025-02-19)
|
|
189
200
|
|
package/dist/studio-cli.d.ts
CHANGED
|
@@ -2196,6 +2196,7 @@ export declare namespace Manifest {
|
|
|
2196
2196
|
dlo?: {
|
|
2197
2197
|
mainFile: string;
|
|
2198
2198
|
compileOptions: string[];
|
|
2199
|
+
iniFile?: string;
|
|
2199
2200
|
};
|
|
2200
2201
|
registry?: {
|
|
2201
2202
|
id?: string;
|
|
@@ -2234,6 +2235,8 @@ export declare namespace Manifest {
|
|
|
2234
2235
|
embedded = "$embedded",
|
|
2235
2236
|
pure = "$pure"
|
|
2236
2237
|
}
|
|
2238
|
+
export function setOverwrites(manifest: Partial<Manifest.Manifest> | null): void;
|
|
2239
|
+
export function clearOverwrites(): void;
|
|
2237
2240
|
/**
|
|
2238
2241
|
* Read the studio.json manifest and parse it
|
|
2239
2242
|
* @param cwd
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseUnknownLongOptions = parseUnknownLongOptions;
|
|
4
|
+
/**
|
|
5
|
+
* Set a nested value in an object by a dot-separated path.
|
|
6
|
+
* Example: setByDotPath(obj, 'dlo.mainFile', 'x') => obj = { dlo: { mainFile: 'x' } }
|
|
7
|
+
*/
|
|
8
|
+
function setByDotPath(target, path, value) {
|
|
9
|
+
const parts = path.split('.').filter(Boolean);
|
|
10
|
+
let cur = target;
|
|
11
|
+
for (let i = 0; i < parts.length; i++) {
|
|
12
|
+
const key = parts[i];
|
|
13
|
+
const isLeaf = i === parts.length - 1;
|
|
14
|
+
if (isLeaf) {
|
|
15
|
+
cur[key] = value;
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
if (typeof cur[key] !== 'object' || cur[key] === null || Array.isArray(cur[key])) {
|
|
19
|
+
cur[key] = {};
|
|
20
|
+
}
|
|
21
|
+
cur = cur[key];
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Parse unknown long options (starting with `--`) into a key/value object.
|
|
27
|
+
* - Supports `--key=value` and `--key value`
|
|
28
|
+
*/
|
|
29
|
+
function parseUnknownLongOptions(command) {
|
|
30
|
+
const argv = command.args;
|
|
31
|
+
const result = {};
|
|
32
|
+
for (let i = 0; i < argv.length; i++) {
|
|
33
|
+
const token = argv[i];
|
|
34
|
+
// Only process long options that start with `--`
|
|
35
|
+
if (!token || !token.startsWith('--')) {
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
// Split inline assignment: --key=value
|
|
39
|
+
const [flag, inlineVal] = token.split('=', 2);
|
|
40
|
+
// Unknown option: collect it
|
|
41
|
+
const key = flag.slice(2); // remove leading '--'
|
|
42
|
+
let value = true;
|
|
43
|
+
if (inlineVal !== undefined) {
|
|
44
|
+
value = inlineVal;
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
// If next token exists and doesn't look like another flag, use it as the value
|
|
48
|
+
const next = argv[i + 1];
|
|
49
|
+
if (next && !next.startsWith('-')) {
|
|
50
|
+
value = next;
|
|
51
|
+
i++; // consume the value
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
// Dot-notation => nested object
|
|
55
|
+
if (key.includes('.')) {
|
|
56
|
+
setByDotPath(result, key, value);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
result[key] = value;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return result;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=argumentParser.js.map
|
package/out/globals.js
CHANGED
|
@@ -71,7 +71,7 @@ var Globals;
|
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
// load the projects main.ini and overwrite existing defines
|
|
74
|
-
const mainIni = vscode_uri_1.Utils.joinPath(cwd, defaultFiles_1.DefaultFiles.filePaths.dlo.mainINI);
|
|
74
|
+
const mainIni = vscode_uri_1.Utils.joinPath(cwd, manifest.dlo?.iniFile || defaultFiles_1.DefaultFiles.filePaths.dlo.mainINI);
|
|
75
75
|
if (await fs.stat(mainIni)) {
|
|
76
76
|
const iniContent = await readIniFile(fs, mainIni);
|
|
77
77
|
Object.assign(allDefines, iniContent);
|
package/out/main.js
CHANGED
|
@@ -12,6 +12,7 @@ const globals_1 = require("./globals");
|
|
|
12
12
|
const update_notifier_1 = __importDefault(require("update-notifier"));
|
|
13
13
|
const api_1 = require("./api");
|
|
14
14
|
const log_1 = require("./log");
|
|
15
|
+
const argumentParser_1 = require("./argumentParser");
|
|
15
16
|
const program = new commander_1.Command();
|
|
16
17
|
const notifier = (0, update_notifier_1.default)({ pkg: package_json_1.default });
|
|
17
18
|
const logger = new log_1.Log.Logger();
|
|
@@ -30,14 +31,21 @@ const devPath = () => {
|
|
|
30
31
|
};
|
|
31
32
|
const cwd = vscode_uri_1.Utils.joinPath(vscode_uri_1.URI.file(process.cwd()), devPath());
|
|
32
33
|
program.version(package_json_1.default.version).usage('<command>');
|
|
34
|
+
program.description('This tool is used to manage the project dependencies, build, package and publish the project.\n' +
|
|
35
|
+
'The manifest options can be overwritten with the --option=value syntax.\n' +
|
|
36
|
+
'Example: "studio build --dlo.mainFile="./dlo/test.dlo" will overwrite the dlo.mainFile option of the manifest.\n' +
|
|
37
|
+
'\nUse "studio --help" for more information.');
|
|
33
38
|
/**
|
|
34
39
|
* Executes a task and ensures that the update available notification is sent after the task completes,
|
|
35
40
|
* regardless of whether it succeeds or fails.
|
|
36
41
|
*
|
|
42
|
+
* @param command
|
|
37
43
|
* @param {Promise<void>} task - A promise representing the task to be executed.
|
|
38
44
|
* @return {void} This function does not return a value.
|
|
39
45
|
*/
|
|
40
|
-
function main(task) {
|
|
46
|
+
function main(command, task) {
|
|
47
|
+
const manifestOptions = (0, argumentParser_1.parseUnknownLongOptions)(command);
|
|
48
|
+
api_1.Manifest.setOverwrites(manifestOptions);
|
|
41
49
|
// todo add task catch handler like: https://github.com/microsoft/vscode-vsce/blob/5518f2f242983d23f1983f6dd0350474f2011543/src/main.ts#L51
|
|
42
50
|
task.finally(() => {
|
|
43
51
|
notifier.notify();
|
|
@@ -94,9 +102,10 @@ program
|
|
|
94
102
|
.allowExcessArguments(true)
|
|
95
103
|
.addOption(optionStudioEnv)
|
|
96
104
|
.addOption(optionStudioToken)
|
|
97
|
-
.
|
|
105
|
+
.allowUnknownOption(true)
|
|
106
|
+
.action((dependencies, opts, command) => {
|
|
98
107
|
const { env, token } = getDefaultOptions(opts);
|
|
99
|
-
main((0, api_1.install)(cwd, cliFS_1.cliFS, env, token, dependencies));
|
|
108
|
+
main(command, (0, api_1.install)(cwd, cliFS_1.cliFS, env, token, dependencies));
|
|
100
109
|
});
|
|
101
110
|
program
|
|
102
111
|
.command('build')
|
|
@@ -104,9 +113,10 @@ program
|
|
|
104
113
|
.allowExcessArguments(true)
|
|
105
114
|
.addOption(optionStudioEnv)
|
|
106
115
|
.addOption(optionStudioToken)
|
|
107
|
-
.
|
|
116
|
+
.allowUnknownOption(true)
|
|
117
|
+
.action((opts, command) => {
|
|
108
118
|
const { env, token } = getDefaultOptions(opts);
|
|
109
|
-
main((0, api_1.build)(cwd, cliFS_1.cliFS, logger, env, token, opts.part));
|
|
119
|
+
main(command, (0, api_1.build)(cwd, cliFS_1.cliFS, logger, env, token, opts.part));
|
|
110
120
|
});
|
|
111
121
|
program
|
|
112
122
|
.command('publish')
|
|
@@ -114,10 +124,11 @@ program
|
|
|
114
124
|
.addOption(optionAllowedBackends)
|
|
115
125
|
.addOption(optionStudioEnv)
|
|
116
126
|
.addOption(optionStudioToken)
|
|
127
|
+
.allowUnknownOption(true)
|
|
117
128
|
.option('-i, --packagePath <path>', 'Publish the provided library or app package. Use "*" for autodetection.')
|
|
118
|
-
.action(async (opts) => {
|
|
129
|
+
.action(async (opts, command) => {
|
|
119
130
|
const { env, token } = getDefaultOptions(opts);
|
|
120
|
-
main((0, api_1.publish)(cwd, cliFS_1.cliFS, logger, env, token, opts.allowedBackends, opts.phase, opts.packagePath));
|
|
131
|
+
main(command, (0, api_1.publish)(cwd, cliFS_1.cliFS, logger, env, token, opts.allowedBackends, opts.phase, opts.packagePath));
|
|
121
132
|
});
|
|
122
133
|
program
|
|
123
134
|
.command('package')
|
|
@@ -126,9 +137,10 @@ program
|
|
|
126
137
|
.addOption(optionReleasePhase)
|
|
127
138
|
.addOption(optionStudioEnv)
|
|
128
139
|
.addOption(optionStudioToken)
|
|
129
|
-
.
|
|
140
|
+
.allowUnknownOption(true)
|
|
141
|
+
.action(async (opts, command) => {
|
|
130
142
|
const { env, token } = getDefaultOptions(opts);
|
|
131
|
-
main((0, api_1.pack)(cwd, cliFS_1.cliFS, logger, env, token, opts.phase));
|
|
143
|
+
main(command, (0, api_1.pack)(cwd, cliFS_1.cliFS, logger, env, token, opts.phase));
|
|
132
144
|
});
|
|
133
145
|
module.exports = function (argv) {
|
|
134
146
|
program.parse(argv);
|
package/out/manifest.js
CHANGED
|
@@ -10,9 +10,9 @@ const image_dimensions_1 = require("image-dimensions");
|
|
|
10
10
|
const file_type_checker_1 = require("file-type-checker");
|
|
11
11
|
const registryAPI_1 = require("./registryAPI");
|
|
12
12
|
const preload_1 = __importDefault(require("semver/preload"));
|
|
13
|
-
const DeviceProfiles_1 = require("./DeviceProfiles");
|
|
14
13
|
const apm_1 = require("./package/apm");
|
|
15
14
|
var isNumeric = helper_1.Helper.isNumeric;
|
|
15
|
+
const deepmerge_ts_1 = require("deepmerge-ts");
|
|
16
16
|
const PRODUCT_ID_SUPPORTED = '52v007';
|
|
17
17
|
const SEMVER_SUPPORTED = '53v001';
|
|
18
18
|
const ADDON_SUPPORTED = '54v001';
|
|
@@ -20,13 +20,17 @@ const ADDON_SUPPORTED = '54v001';
|
|
|
20
20
|
const manifestCache = {
|
|
21
21
|
_manifest: null,
|
|
22
22
|
_stat: null,
|
|
23
|
+
_overwrites: null,
|
|
23
24
|
get manifest() {
|
|
24
25
|
// clone the cached object to prevent any reference changes
|
|
25
|
-
return structuredClone(this._manifest);
|
|
26
|
+
return (0, deepmerge_ts_1.deepmerge)(structuredClone(this._manifest), manifestCache._overwrites || {});
|
|
26
27
|
},
|
|
27
28
|
set manifest(manifest) {
|
|
28
29
|
this._manifest = manifest;
|
|
29
30
|
},
|
|
31
|
+
set overwrites(manifest) {
|
|
32
|
+
this._overwrites = manifest;
|
|
33
|
+
},
|
|
30
34
|
get stat() {
|
|
31
35
|
return this._stat;
|
|
32
36
|
},
|
|
@@ -73,6 +77,14 @@ var Manifest;
|
|
|
73
77
|
PovLocation["embedded"] = "$embedded";
|
|
74
78
|
PovLocation["pure"] = "$pure";
|
|
75
79
|
})(PovLocation = Manifest.PovLocation || (Manifest.PovLocation = {}));
|
|
80
|
+
function setOverwrites(manifest) {
|
|
81
|
+
manifestCache.overwrites = manifest;
|
|
82
|
+
}
|
|
83
|
+
Manifest.setOverwrites = setOverwrites;
|
|
84
|
+
function clearOverwrites() {
|
|
85
|
+
manifestCache.overwrites = null;
|
|
86
|
+
}
|
|
87
|
+
Manifest.clearOverwrites = clearOverwrites;
|
|
76
88
|
/**
|
|
77
89
|
* Read the studio.json manifest and parse it
|
|
78
90
|
* @param cwd
|
|
@@ -112,8 +124,6 @@ var Manifest;
|
|
|
112
124
|
*/
|
|
113
125
|
async function write(cwd, fs, manifest) {
|
|
114
126
|
manifestCache.clear();
|
|
115
|
-
// patch the options if they are not valid for a specific device profile
|
|
116
|
-
patchDloCompileOptionsBasedOnDpid(manifest);
|
|
117
127
|
removeDeprecatedOptions(manifest);
|
|
118
128
|
return fs.writeFile(vscode_uri_1.Utils.joinPath(cwd, Manifest.fileName), JSON.stringify(manifest, null, '\t'));
|
|
119
129
|
}
|
|
@@ -425,32 +435,6 @@ function validateProjectVersion(manifest) {
|
|
|
425
435
|
}
|
|
426
436
|
}
|
|
427
437
|
}
|
|
428
|
-
/**
|
|
429
|
-
* Some devices doesn't support compression. this function does patch the option if it's not supported
|
|
430
|
-
* @param manifest
|
|
431
|
-
*/
|
|
432
|
-
function patchDloCompileOptionsBasedOnDpid(manifest) {
|
|
433
|
-
if (!manifest.dpid) {
|
|
434
|
-
return;
|
|
435
|
-
}
|
|
436
|
-
const deviceProfile = DeviceProfiles_1.DeviceProfiles[manifest.dpid];
|
|
437
|
-
const compileRestrictions = deviceProfile?.dlo?.compileRestrictions || {};
|
|
438
|
-
const { compileOptions } = manifest.dlo || {};
|
|
439
|
-
if (compileOptions) {
|
|
440
|
-
compileOptions.forEach((param, idx) => {
|
|
441
|
-
try {
|
|
442
|
-
const paramType = param.substring(0, 2);
|
|
443
|
-
const paramValue = param.substring(2);
|
|
444
|
-
if (Object.hasOwn(compileRestrictions, paramType) && `${paramValue}` !== `${compileRestrictions[paramType]}`) {
|
|
445
|
-
compileOptions[idx] = `${paramType}${compileRestrictions[paramType]}`;
|
|
446
|
-
}
|
|
447
|
-
}
|
|
448
|
-
catch (e) {
|
|
449
|
-
// todo?
|
|
450
|
-
}
|
|
451
|
-
});
|
|
452
|
-
}
|
|
453
|
-
}
|
|
454
438
|
function removeDeprecatedOptions(manifest) {
|
|
455
439
|
if (manifest.registry) {
|
|
456
440
|
delete manifest.registry.allowedBackends;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@microtronics/studio-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.33.0",
|
|
4
4
|
"description": "Microtronics Studio CLI Tool",
|
|
5
5
|
"main": "./out/api.js",
|
|
6
6
|
"typings": "./dist/studio-cli.d.ts",
|
|
@@ -25,12 +25,14 @@
|
|
|
25
25
|
"author": "Microtronics",
|
|
26
26
|
"license": "ISC",
|
|
27
27
|
"dependencies": {
|
|
28
|
+
"@gera2ld/tarjs": "^0.3.1",
|
|
28
29
|
"ajv": "^8.17.1",
|
|
29
30
|
"ajv-formats": "^3.0.1",
|
|
30
31
|
"ajv-keywords": "^5.1.0",
|
|
31
32
|
"chalk": "^5.4.1",
|
|
32
33
|
"commander": "^12.1.0",
|
|
33
34
|
"cross-fetch": "^4.0.0",
|
|
35
|
+
"deepmerge-ts": "^7.1.5",
|
|
34
36
|
"dotenv": "^16.4.7",
|
|
35
37
|
"file-type-checker": "^1.1.2",
|
|
36
38
|
"glob": "^11.0.1",
|
|
@@ -41,7 +43,6 @@
|
|
|
41
43
|
"openapi-fetch": "^0.13.0",
|
|
42
44
|
"pako": "^2.1.0",
|
|
43
45
|
"semver": "^7.7.2",
|
|
44
|
-
"@gera2ld/tarjs": "^0.3.1",
|
|
45
46
|
"tinytar-fix": "^0.1.1",
|
|
46
47
|
"update-notifier": "^7.3.1",
|
|
47
48
|
"vscode-uri": "^3.0.8",
|