@microtronics/studio-cli 0.32.3 → 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 CHANGED
@@ -1,4 +1,13 @@
1
+ # Changelog
1
2
 
3
+ ## 0.33.0 (2025-09-01)
4
+
5
+ ### Features
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))
2
11
 
3
12
  ## 0.32.3 (2025-06-11)
4
13
 
@@ -185,7 +194,7 @@
185
194
 
186
195
  ## 0.19.1 (2025-02-20)
187
196
 
188
- # Changelog
197
+
189
198
 
190
199
  ## 0.19.0 (2025-02-19)
191
200
 
@@ -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
- .action((dependencies, opts) => {
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
- .action(opts => {
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
- .action(async (opts) => {
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
@@ -12,6 +12,7 @@ const registryAPI_1 = require("./registryAPI");
12
12
  const preload_1 = __importDefault(require("semver/preload"));
13
13
  const apm_1 = require("./package/apm");
14
14
  var isNumeric = helper_1.Helper.isNumeric;
15
+ const deepmerge_ts_1 = require("deepmerge-ts");
15
16
  const PRODUCT_ID_SUPPORTED = '52v007';
16
17
  const SEMVER_SUPPORTED = '53v001';
17
18
  const ADDON_SUPPORTED = '54v001';
@@ -19,13 +20,17 @@ const ADDON_SUPPORTED = '54v001';
19
20
  const manifestCache = {
20
21
  _manifest: null,
21
22
  _stat: null,
23
+ _overwrites: null,
22
24
  get manifest() {
23
25
  // clone the cached object to prevent any reference changes
24
- return structuredClone(this._manifest);
26
+ return (0, deepmerge_ts_1.deepmerge)(structuredClone(this._manifest), manifestCache._overwrites || {});
25
27
  },
26
28
  set manifest(manifest) {
27
29
  this._manifest = manifest;
28
30
  },
31
+ set overwrites(manifest) {
32
+ this._overwrites = manifest;
33
+ },
29
34
  get stat() {
30
35
  return this._stat;
31
36
  },
@@ -72,6 +77,14 @@ var Manifest;
72
77
  PovLocation["embedded"] = "$embedded";
73
78
  PovLocation["pure"] = "$pure";
74
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;
75
88
  /**
76
89
  * Read the studio.json manifest and parse it
77
90
  * @param cwd
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@microtronics/studio-cli",
3
- "version": "0.32.3",
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",