@rage-against-the-pixel/unity-cli 3.0.2 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +86 -224
- package/dist/android-sdk.js +8 -1
- package/dist/android-sdk.js.map +1 -1
- package/dist/cli.js +180 -505
- package/dist/cli.js.map +1 -1
- package/dist/failure-markers.d.ts +17 -0
- package/dist/failure-markers.js +46 -0
- package/dist/failure-markers.js.map +1 -0
- package/dist/github-actions-ci.d.ts +1 -0
- package/dist/github-actions-ci.js +17 -3
- package/dist/github-actions-ci.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/license-client.d.ts +113 -2
- package/dist/license-client.js +715 -54
- package/dist/license-client.js.map +1 -1
- package/dist/logger-provider.d.ts +2 -0
- package/dist/logger-provider.js +3 -0
- package/dist/logger-provider.js.map +1 -1
- package/dist/logging.d.ts +5 -0
- package/dist/logging.js +47 -0
- package/dist/logging.js.map +1 -1
- package/dist/process-tracker.d.ts +71 -0
- package/dist/process-tracker.js +213 -0
- package/dist/process-tracker.js.map +1 -0
- package/dist/unity-cli.d.ts +97 -0
- package/dist/unity-cli.js +587 -0
- package/dist/unity-cli.js.map +1 -0
- package/dist/unity-editor.d.ts +25 -16
- package/dist/unity-editor.js +204 -107
- package/dist/unity-editor.js.map +1 -1
- package/dist/unity-installer.d.ts +134 -0
- package/dist/unity-installer.js +963 -0
- package/dist/unity-installer.js.map +1 -0
- package/dist/unity-logging.d.ts +16 -1
- package/dist/unity-logging.js +55 -3
- package/dist/unity-logging.js.map +1 -1
- package/dist/unity-project.d.ts +15 -0
- package/dist/unity-project.js +80 -0
- package/dist/unity-project.js.map +1 -1
- package/dist/upm-cli.d.ts +8 -8
- package/dist/upm-cli.js +8 -8
- package/dist/upm-cli.js.map +1 -1
- package/dist/utilities.d.ts +27 -7
- package/dist/utilities.js +119 -63
- package/dist/utilities.js.map +1 -1
- package/package.json +10 -11
- package/dist/unity-hub.d.ts +0 -140
- package/dist/unity-hub.js +0 -1425
- package/dist/unity-hub.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -40,101 +40,33 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
40
40
|
require("source-map-support/register");
|
|
41
41
|
const fs = __importStar(require("fs"));
|
|
42
42
|
const os = __importStar(require("os"));
|
|
43
|
-
const tar = __importStar(require("tar"));
|
|
44
43
|
const path = __importStar(require("path"));
|
|
45
44
|
const commander_1 = require("commander");
|
|
46
|
-
const unity_hub_1 = require("./unity-hub");
|
|
47
|
-
const unity_editor_1 = require("./unity-editor");
|
|
48
45
|
const update_notifier_1 = __importDefault(require("update-notifier"));
|
|
49
46
|
const logging_1 = require("./logging");
|
|
47
|
+
const unity_cli_1 = require("./unity-cli");
|
|
48
|
+
const unity_editor_1 = require("./unity-editor");
|
|
49
|
+
const unity_installer_1 = require("./unity-installer");
|
|
50
50
|
const unity_version_1 = require("./unity-version");
|
|
51
51
|
const unity_project_1 = require("./unity-project");
|
|
52
|
-
const child_process_1 = require("child_process");
|
|
53
52
|
const android_sdk_1 = require("./android-sdk");
|
|
54
53
|
const license_client_1 = require("./license-client");
|
|
55
54
|
const utilities_1 = require("./utilities");
|
|
56
55
|
const upm_cli_1 = require("./upm-cli");
|
|
56
|
+
const failure_markers_1 = require("./failure-markers");
|
|
57
57
|
const pkgPath = path.join(__dirname, '..', 'package.json');
|
|
58
58
|
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
|
|
59
59
|
(0, update_notifier_1.default)({ pkg }).notify();
|
|
60
60
|
const program = new commander_1.Command();
|
|
61
61
|
program.name('unity-cli')
|
|
62
|
-
.description('
|
|
63
|
-
.version(pkg.version)
|
|
64
|
-
|
|
65
|
-
.
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
.option('--json', 'Print hub path, UPM CLI version, and resolved UPM CLI path as JSON.')
|
|
71
|
-
.action(async (options) => {
|
|
72
|
-
if (options.verbose) {
|
|
73
|
-
logging_1.Logger.instance.logLevel = logging_1.LogLevel.DEBUG;
|
|
74
|
-
}
|
|
75
|
-
logging_1.Logger.instance.debugOptions(options);
|
|
76
|
-
if (options.autoUpdate === true && options.hubVersion) {
|
|
77
|
-
logging_1.Logger.instance.error('Cannot use --auto-update with --hub-version.');
|
|
78
|
-
process.exit(1);
|
|
79
|
-
}
|
|
80
|
-
if (options.autoUpdate === true && options.upmVersion) {
|
|
81
|
-
logging_1.Logger.instance.error('Cannot use --auto-update with --upm-version.');
|
|
82
|
-
process.exit(1);
|
|
83
|
-
}
|
|
84
|
-
try {
|
|
85
|
-
const unityHub = new unity_hub_1.UnityHub();
|
|
86
|
-
const upm = new upm_cli_1.UpmCli();
|
|
87
|
-
let upmRequestedVersion = options.upmVersion?.toString()?.trim();
|
|
88
|
-
if (options.autoUpdate === true) {
|
|
89
|
-
const currentVersion = upm.GetInstalledReleaseTag();
|
|
90
|
-
const latestVersion = await upm.GetLatestReleaseTag();
|
|
91
|
-
if (currentVersion && !upm.IsUpdateAvailable(latestVersion)) {
|
|
92
|
-
logging_1.Logger.instance.info(`Upm cli is already up to date (${currentVersion}).`);
|
|
93
|
-
upmRequestedVersion = currentVersion;
|
|
94
|
-
}
|
|
95
|
-
else {
|
|
96
|
-
if (currentVersion) {
|
|
97
|
-
logging_1.Logger.instance.info(`Updating upm cli ${currentVersion} -> ${latestVersion}...`);
|
|
98
|
-
}
|
|
99
|
-
upmRequestedVersion = latestVersion;
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
const [hubPath, upmVer] = await Promise.all([
|
|
103
|
-
unityHub.Install(options.autoUpdate === true, options.hubVersion),
|
|
104
|
-
upm.Install({
|
|
105
|
-
version: upmRequestedVersion,
|
|
106
|
-
skipIfInstalled: true
|
|
107
|
-
}),
|
|
108
|
-
]);
|
|
109
|
-
logging_1.Logger.instance.CI_setEnvironmentVariable('UNITY_HUB_PATH', hubPath);
|
|
110
|
-
let upmCliPath;
|
|
111
|
-
try {
|
|
112
|
-
await upm.Version(upmVer);
|
|
113
|
-
upmCliPath = upm.executable;
|
|
114
|
-
}
|
|
115
|
-
catch (verifyError) {
|
|
116
|
-
logging_1.Logger.instance.warn(`Upm cli version check failed after install: ${verifyError}`);
|
|
117
|
-
if (process.env.CI === 'true') {
|
|
118
|
-
logging_1.Logger.instance.error('Failing in CI because the installed UPM CLI did not match the expected release.');
|
|
119
|
-
process.exit(1);
|
|
120
|
-
}
|
|
121
|
-
upmCliPath = upm.ResolveManagedPrimaryPath();
|
|
122
|
-
}
|
|
123
|
-
if (options.json) {
|
|
124
|
-
process.stdout.write(`\n${JSON.stringify({
|
|
125
|
-
UNITY_HUB_PATH: hubPath,
|
|
126
|
-
UPM_VERSION: upmVer,
|
|
127
|
-
UPM_CLI_PATH: upmCliPath,
|
|
128
|
-
})}\n`);
|
|
129
|
-
}
|
|
130
|
-
else {
|
|
131
|
-
process.stdout.write(`Unity Hub: ${hubPath}\nUpm cli: ${upmVer}\n${upmCliPath ?? ''}\n`);
|
|
132
|
-
}
|
|
133
|
-
process.exit(0);
|
|
134
|
-
}
|
|
135
|
-
catch (error) {
|
|
136
|
-
logging_1.Logger.instance.error(`${error}`);
|
|
137
|
-
process.exit(1);
|
|
62
|
+
.description('Bridges the gaps in the official Unity CLI (unity) for CI: Unity ID licensing, Unity 4.x and 5.x editors, Android SDK setup and Editor log annotations.')
|
|
63
|
+
.version(pkg.version)
|
|
64
|
+
.option('--unity-cli-version <version>', 'The official Unity CLI version to use (e.g. 1.0.0-beta.14). Defaults to the UNITY_CLI_VERSION environment variable, then the latest release. Commands install it on first use.')
|
|
65
|
+
.hook('preAction', (command) => {
|
|
66
|
+
const version = command.opts().unityCliVersion?.toString()?.trim();
|
|
67
|
+
if (version) {
|
|
68
|
+
// every command resolves the official CLI through UnityCli.Get(), which reads the request from here
|
|
69
|
+
process.env.UNITY_CLI_VERSION = version;
|
|
138
70
|
}
|
|
139
71
|
});
|
|
140
72
|
program.commandsGroup('Auth:');
|
|
@@ -146,51 +78,49 @@ program.command('license-version')
|
|
|
146
78
|
process.exit(0);
|
|
147
79
|
});
|
|
148
80
|
program.command('activate-license')
|
|
149
|
-
.description('Activate a Unity license.')
|
|
81
|
+
.description('Activate a Unity license. Tries the official Unity CLI first, then the Unity Licensing Client with your Unity ID email and password.')
|
|
150
82
|
.option('-l, --license <license>', 'License type (personal, professional, floating). Required.')
|
|
151
|
-
.option('-e, --email <email>', 'Email associated with the Unity account.
|
|
152
|
-
.option('-p, --password <password>', 'Password for the Unity account.
|
|
153
|
-
.option('-s, --serial <serial>', 'License serial number. Required when activating a professional license.')
|
|
83
|
+
.option('-e, --email <email>', 'Email associated with the Unity account. Used when the Unity CLI cannot activate a personal or professional license. Defaults to the UNITY_USERNAME environment variable.')
|
|
84
|
+
.option('-p, --password <password>', 'Password for the Unity account. Used when the Unity CLI cannot activate a personal or professional license. Defaults to the UNITY_PASSWORD environment variable, which keeps it off the command line.')
|
|
85
|
+
.option('-s, --serial <serial>', 'License serial number. Required when activating a professional license. Defaults to the UNITY_SERIAL environment variable.')
|
|
154
86
|
.option('-c, --config <config>', 'Path to the configuration file, raw JSON, or base64 encoded JSON string. Required when activating a floating license.')
|
|
87
|
+
.option('-f, --license-file <licenseFile>', 'A cached license file (Unity_lic.ulf) from an earlier activation on a machine with the same identity: a path, the raw XML, or base64. Defaults to the UNITY_LICENSE environment variable. Falls back to the email and password when it cannot be used.')
|
|
155
88
|
.option('--verbose', 'Enable verbose logging.')
|
|
156
89
|
.option('--json', 'Prints the last line of output as JSON string.')
|
|
157
90
|
.action(async (options) => {
|
|
158
91
|
if (options.verbose) {
|
|
159
92
|
logging_1.Logger.instance.logLevel = logging_1.LogLevel.DEBUG;
|
|
160
93
|
}
|
|
94
|
+
// environment variables keep credentials out of the process command line
|
|
95
|
+
options.email ??= process.env.UNITY_USERNAME || undefined;
|
|
96
|
+
options.password ??= process.env.UNITY_PASSWORD || undefined;
|
|
97
|
+
options.serial ??= process.env.UNITY_SERIAL || undefined;
|
|
98
|
+
// Mask credentials in CI environments before any potential logging
|
|
99
|
+
logging_1.Logger.instance.maskCredential(options.email);
|
|
100
|
+
logging_1.Logger.instance.maskCredential(options.password);
|
|
101
|
+
logging_1.Logger.instance.maskCredential(options.serial);
|
|
161
102
|
logging_1.Logger.instance.debugOptions(options);
|
|
162
|
-
const client = new license_client_1.LicensingClient();
|
|
163
103
|
const licenseStr = options.license?.toString()?.trim();
|
|
164
104
|
if (!licenseStr || licenseStr.length === 0) {
|
|
165
105
|
logging_1.Logger.instance.error('License type is required. Use -l or --license to specify it.');
|
|
166
106
|
process.exit(1);
|
|
167
107
|
}
|
|
168
|
-
const licenseType =
|
|
108
|
+
const licenseType = licenseStr.toLowerCase();
|
|
169
109
|
if (![license_client_1.LicenseType.personal, license_client_1.LicenseType.professional, license_client_1.LicenseType.floating].includes(licenseType)) {
|
|
170
110
|
logging_1.Logger.instance.error(`Invalid license type: ${licenseType}`);
|
|
171
111
|
process.exit(1);
|
|
172
112
|
}
|
|
173
|
-
if (licenseType
|
|
174
|
-
|
|
175
|
-
options.email = await (0, utilities_1.PromptForSecretInput)('Email: ');
|
|
176
|
-
}
|
|
177
|
-
if (!options.password) {
|
|
178
|
-
options.password = await (0, utilities_1.PromptForSecretInput)('Password: ');
|
|
179
|
-
}
|
|
180
|
-
if (licenseType === license_client_1.LicenseType.professional && !options.serial) {
|
|
181
|
-
options.serial = await (0, utilities_1.PromptForSecretInput)('Serial: ');
|
|
182
|
-
}
|
|
183
|
-
// Mask credentials in CI environments before any potential logging
|
|
184
|
-
logging_1.Logger.instance.maskCredential(options.email);
|
|
185
|
-
logging_1.Logger.instance.maskCredential(options.password);
|
|
113
|
+
if (licenseType === license_client_1.LicenseType.professional && !options.serial) {
|
|
114
|
+
options.serial = await (0, utilities_1.PromptForSecretInput)('Serial: ');
|
|
186
115
|
logging_1.Logger.instance.maskCredential(options.serial);
|
|
187
116
|
}
|
|
188
|
-
const token = await
|
|
117
|
+
const token = await (0, license_client_1.ActivateLicense)({
|
|
189
118
|
licenseType,
|
|
190
119
|
servicesConfig: options.config,
|
|
191
120
|
serial: options.serial,
|
|
192
121
|
username: options.email,
|
|
193
|
-
password: options.password
|
|
122
|
+
password: options.password,
|
|
123
|
+
...(options.licenseFile ? { licenseFile: options.licenseFile } : {}),
|
|
194
124
|
});
|
|
195
125
|
if (licenseType === license_client_1.LicenseType.floating && token && options.json) {
|
|
196
126
|
process.stdout.write(`\n${JSON.stringify({ token: token })}\n`);
|
|
@@ -198,16 +128,24 @@ program.command('activate-license')
|
|
|
198
128
|
process.exit(0);
|
|
199
129
|
});
|
|
200
130
|
program.command('return-license')
|
|
201
|
-
.description('Return a Unity license.')
|
|
131
|
+
.description('Return a Unity license. Tries the official Unity CLI first, then the Unity Licensing Client.')
|
|
202
132
|
.option('-l, --license <license>', 'License type (personal, professional, floating)')
|
|
203
|
-
.option('-t, --token <token>', 'Floating license token.
|
|
133
|
+
.option('-t, --token <token>', 'Floating license token from activation. When given, the floating license is returned with the Unity Licensing Client.')
|
|
134
|
+
.option('--when <when>', 'auto, always or never. auto skips returning a personal or professional license on GitHub-hosted macOS and Linux runners, which share one machine identity: a return there revokes the license for every job and repo on that identity. Defaults to auto.', 'auto')
|
|
204
135
|
.option('--verbose', 'Enable verbose logging.')
|
|
205
136
|
.action(async (options) => {
|
|
206
137
|
if (options.verbose) {
|
|
207
138
|
logging_1.Logger.instance.logLevel = logging_1.LogLevel.DEBUG;
|
|
208
139
|
}
|
|
140
|
+
const when = options.when?.toString()?.trim().toLowerCase();
|
|
141
|
+
if (!['auto', 'always', 'never'].includes(when)) {
|
|
142
|
+
logging_1.Logger.instance.error(`Invalid --when value: ${when}. Expected auto, always or never.`);
|
|
143
|
+
process.exit(1);
|
|
144
|
+
}
|
|
145
|
+
const token = options.token?.toString()?.trim() || undefined;
|
|
146
|
+
// Mask token in CI environments before any potential logging
|
|
147
|
+
logging_1.Logger.instance.maskCredential(token);
|
|
209
148
|
logging_1.Logger.instance.debugOptions(options);
|
|
210
|
-
const client = new license_client_1.LicensingClient();
|
|
211
149
|
const licenseStr = options.license?.toString()?.trim();
|
|
212
150
|
if (!licenseStr || licenseStr.length === 0) {
|
|
213
151
|
logging_1.Logger.instance.error('License type is required. Use -l or --license to specify it.');
|
|
@@ -218,26 +156,19 @@ program.command('return-license')
|
|
|
218
156
|
logging_1.Logger.instance.error(`Invalid license type: ${licenseType}`);
|
|
219
157
|
process.exit(1);
|
|
220
158
|
}
|
|
221
|
-
|
|
222
|
-
if (licenseType === license_client_1.LicenseType.floating) {
|
|
223
|
-
if (!token || token.length === 0) {
|
|
224
|
-
token = await (0, utilities_1.PromptForSecretInput)('Token: ');
|
|
225
|
-
}
|
|
226
|
-
if (!token || token.length === 0) {
|
|
227
|
-
logging_1.Logger.instance.error('Token is required when returning a floating license. Use -t or --token to specify it.');
|
|
228
|
-
process.exit(1);
|
|
229
|
-
}
|
|
230
|
-
// Mask token in CI environments before any potential logging
|
|
231
|
-
logging_1.Logger.instance.maskCredential(token);
|
|
232
|
-
}
|
|
233
|
-
await client.Deactivate(licenseType, token);
|
|
159
|
+
await (0, license_client_1.ReturnLicense)(licenseType, token, when);
|
|
234
160
|
process.exit(0);
|
|
235
161
|
});
|
|
236
162
|
program.command('license-context')
|
|
237
|
-
.description('Print the current license
|
|
163
|
+
.description('Print the current license state from the Unity CLI and the Unity Licensing Client.')
|
|
238
164
|
.action(async () => {
|
|
239
|
-
|
|
240
|
-
|
|
165
|
+
await (0, license_client_1.PrintLicenseContext)();
|
|
166
|
+
process.exit(0);
|
|
167
|
+
});
|
|
168
|
+
program.command('license-file-path')
|
|
169
|
+
.description('Prints the path to the machine\'s Unity license file (Unity_lic.ulf).')
|
|
170
|
+
.action(async () => {
|
|
171
|
+
process.stdout.write(`${(0, license_client_1.GetLicenseFilePath)()}\n`);
|
|
241
172
|
process.exit(0);
|
|
242
173
|
});
|
|
243
174
|
program.command('licensing-client-logs')
|
|
@@ -252,94 +183,9 @@ program.command('licensing-audit-logs')
|
|
|
252
183
|
process.stdout.write(`${license_client_1.LicensingClient.ClientAuditLogPath()}\n`);
|
|
253
184
|
process.exit(0);
|
|
254
185
|
});
|
|
255
|
-
program.commandsGroup('Unity
|
|
256
|
-
program.command('hub-version')
|
|
257
|
-
.description('Print the Unity Hub version.')
|
|
258
|
-
.action(async () => {
|
|
259
|
-
const unityHub = new unity_hub_1.UnityHub();
|
|
260
|
-
try {
|
|
261
|
-
const version = await unityHub.Version();
|
|
262
|
-
process.stdout.write(`${version}\n`);
|
|
263
|
-
}
|
|
264
|
-
catch (error) {
|
|
265
|
-
process.stdout.write(`${error}\n`);
|
|
266
|
-
}
|
|
267
|
-
finally {
|
|
268
|
-
process.exit(0);
|
|
269
|
-
}
|
|
270
|
-
});
|
|
271
|
-
program.command('hub-path')
|
|
272
|
-
.description('Print the path to the Unity Hub executable.')
|
|
273
|
-
.option('--json', 'Prints the last line of output as JSON string.')
|
|
274
|
-
.action(async (options) => {
|
|
275
|
-
const hub = new unity_hub_1.UnityHub();
|
|
276
|
-
logging_1.Logger.instance.CI_setEnvironmentVariable('UNITY_HUB_PATH', hub.executable);
|
|
277
|
-
if (options.json) {
|
|
278
|
-
process.stdout.write(`\n${JSON.stringify({ UNITY_HUB_PATH: hub.executable })}\n`);
|
|
279
|
-
}
|
|
280
|
-
else {
|
|
281
|
-
process.stdout.write(`${hub.executable}\n`);
|
|
282
|
-
}
|
|
283
|
-
process.exit(0);
|
|
284
|
-
});
|
|
285
|
-
program.command('hub-logs')
|
|
286
|
-
.description('Prints the path to the Unity Hub log file.')
|
|
287
|
-
.action(async () => {
|
|
288
|
-
process.stdout.write(`${unity_hub_1.UnityHub.LogPath()}\n`);
|
|
289
|
-
process.exit(0);
|
|
290
|
-
});
|
|
291
|
-
program.command('package-manager-logs')
|
|
292
|
-
.description('Prints the path to the Unity Package Manager log file.')
|
|
293
|
-
.action(async () => {
|
|
294
|
-
process.stdout.write(`${unity_hub_1.UnityHub.PackageManagerLogsPath()}\n`);
|
|
295
|
-
process.exit(0);
|
|
296
|
-
});
|
|
297
|
-
program.command('hub-install')
|
|
298
|
-
.description('Install or update the Unity Hub.')
|
|
299
|
-
.option('--verbose', 'Enable verbose logging.')
|
|
300
|
-
.option('--auto-update', 'Automatically updates the Unity Hub if it is already installed. Cannot be used with --hub-version.')
|
|
301
|
-
.option('--hub-version <version>', 'Specify to install a specific version of Unity Hub. Cannot be used with --auto-update.')
|
|
302
|
-
.option('--json', 'Prints the last line of output as JSON string.')
|
|
303
|
-
.action(async (options) => {
|
|
304
|
-
if (options.verbose) {
|
|
305
|
-
logging_1.Logger.instance.logLevel = logging_1.LogLevel.DEBUG;
|
|
306
|
-
}
|
|
307
|
-
logging_1.Logger.instance.debugOptions(options);
|
|
308
|
-
if (options.autoUpdate === true && options.hubVersion) {
|
|
309
|
-
logging_1.Logger.instance.error('Cannot use --auto-update with --hub-version.');
|
|
310
|
-
process.exit(1);
|
|
311
|
-
}
|
|
312
|
-
const unityHub = new unity_hub_1.UnityHub();
|
|
313
|
-
const hubPath = await unityHub.Install(options.autoUpdate === true, options.hubVersion);
|
|
314
|
-
logging_1.Logger.instance.CI_setEnvironmentVariable('UNITY_HUB_PATH', hubPath);
|
|
315
|
-
if (options.json) {
|
|
316
|
-
process.stdout.write(`\n${JSON.stringify({ UNITY_HUB_PATH: hubPath })}\n`);
|
|
317
|
-
}
|
|
318
|
-
else {
|
|
319
|
-
process.stdout.write(`${hubPath}\n`);
|
|
320
|
-
}
|
|
321
|
-
process.exit(0);
|
|
322
|
-
});
|
|
323
|
-
program.command('hub')
|
|
324
|
-
.description('Run commands directly to the Unity Hub. (You need not to pass --headless or -- to this command).')
|
|
325
|
-
.option('--verbose', 'Enable verbose logging.')
|
|
326
|
-
.option('--json', 'Prints the last line of output as a json string, which contains the operation results.')
|
|
327
|
-
.allowUnknownOption(true)
|
|
328
|
-
.argument('<args...>', 'Arguments to pass to the Unity Hub executable.')
|
|
329
|
-
.action(async (args, options) => {
|
|
330
|
-
if (options.verbose) {
|
|
331
|
-
logging_1.Logger.instance.logLevel = logging_1.LogLevel.DEBUG;
|
|
332
|
-
}
|
|
333
|
-
logging_1.Logger.instance.debugOptions({ args, options });
|
|
334
|
-
const unityHub = new unity_hub_1.UnityHub();
|
|
335
|
-
const output = await unityHub.Exec(args, { silent: false, showCommand: logging_1.Logger.instance.logLevel === logging_1.LogLevel.DEBUG });
|
|
336
|
-
if (options.json) {
|
|
337
|
-
process.stdout.write(`\n${JSON.stringify({ output })}\n`);
|
|
338
|
-
}
|
|
339
|
-
process.exit(0);
|
|
340
|
-
});
|
|
186
|
+
program.commandsGroup('Unity Editor:');
|
|
341
187
|
program.command('setup-unity')
|
|
342
|
-
.description('Find or install the Unity Editor for a project or specific version.')
|
|
188
|
+
.description('Find or install the Unity Editor for a project or specific version. 2017.4 and newer install with the official Unity CLI; 4.x and 5.x install from Unity\'s archives.')
|
|
343
189
|
.option('-p, --unity-project <unityProject>', 'The path to a Unity project or "none" to skip project detection.')
|
|
344
190
|
.option('-u, --unity-version <unityVersion>', 'The Unity version to get (e.g. 2020.3.1f1, 2021.x, 2022.1.*, 6000). If specified, it will override the version read from the project.')
|
|
345
191
|
.option('-c, --changeset <changeset>', 'The Unity changeset to get (e.g. 1234567890ab).')
|
|
@@ -347,7 +193,7 @@ program.command('setup-unity')
|
|
|
347
193
|
.option('-a, --arch <arch>', 'The Unity architecture to get (e.g. x86_64, arm64). Defaults to the architecture of the current process.')
|
|
348
194
|
.option('-b, --build-targets <buildTargets>', 'The Unity build target to get/install as comma-separated values (e.g. iOS,Android).')
|
|
349
195
|
.option('-m, --modules <modules>', 'The Unity module to get/install as comma-separated values (e.g. ios,android).')
|
|
350
|
-
.option('-i, --install-path <installPath>', 'The path to install the Unity Editor to. By default, it will be installed to the
|
|
196
|
+
.option('-i, --install-path <installPath>', 'The path to install the Unity Editor to. By default, it will be installed to the Unity CLI install path.')
|
|
351
197
|
.option('--verbose', 'Enable verbose logging.')
|
|
352
198
|
.option('--json', 'Prints the last line of output as JSON string.')
|
|
353
199
|
.action(async (options) => {
|
|
@@ -365,14 +211,23 @@ program.command('setup-unity')
|
|
|
365
211
|
}
|
|
366
212
|
let unityVersion;
|
|
367
213
|
if (options.unityVersion) {
|
|
368
|
-
|
|
214
|
+
const arch = options.arch?.toString()?.trim().toLowerCase();
|
|
215
|
+
const architecture = arch === 'arm64' ? 'ARM64' : arch === 'x86_64' || arch === 'x64' ? 'X86_64' : undefined;
|
|
216
|
+
unityVersion = new unity_version_1.UnityVersion(options.unityVersion, options.changeset, architecture);
|
|
369
217
|
}
|
|
370
218
|
else {
|
|
371
219
|
unityVersion = unityProject.version;
|
|
372
220
|
}
|
|
373
221
|
const modules = options.modules ? options.modules.split(/[ ,]+/).filter(Boolean) : [];
|
|
374
222
|
const buildTargets = options.buildTargets ? options.buildTargets.split(/[ ,]+/).filter(Boolean) : [];
|
|
375
|
-
|
|
223
|
+
// with only a project, its saved build profiles pick the modules; --modules or --build-targets override them
|
|
224
|
+
if (unityProject && modules.length === 0 && buildTargets.length === 0) {
|
|
225
|
+
buildTargets.push(...unityProject.GetBuildProfileTargets());
|
|
226
|
+
if (buildTargets.length > 0) {
|
|
227
|
+
logging_1.Logger.instance.info(`Installing modules for the project's build profiles: ${buildTargets.join(', ')}`);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
const moduleBuildTargetMap = unity_installer_1.UnityInstaller.GetPlatformTargetModuleMap();
|
|
376
231
|
for (const target of buildTargets) {
|
|
377
232
|
const module = moduleBuildTargetMap[target];
|
|
378
233
|
if (module === undefined) {
|
|
@@ -389,7 +244,6 @@ program.command('setup-unity')
|
|
|
389
244
|
modules.includes('None')) {
|
|
390
245
|
modules.length = 0;
|
|
391
246
|
}
|
|
392
|
-
const unityHub = new unity_hub_1.UnityHub();
|
|
393
247
|
const channels = options.channel
|
|
394
248
|
? String(options.channel).split(/[ ,]+/).map((c) => c.trim().toLowerCase()).filter(Boolean)
|
|
395
249
|
: ['f'];
|
|
@@ -400,9 +254,14 @@ program.command('setup-unity')
|
|
|
400
254
|
process.exit(1);
|
|
401
255
|
}
|
|
402
256
|
}
|
|
403
|
-
const
|
|
257
|
+
const unityCli = await unity_cli_1.UnityCli.Get();
|
|
258
|
+
const installer = new unity_installer_1.UnityInstaller(unityCli);
|
|
259
|
+
if (options.installPath) {
|
|
260
|
+
await installer.SetInstallPath(options.installPath);
|
|
261
|
+
}
|
|
262
|
+
const unityEditor = await installer.GetEditor(unityVersion, modules, channels);
|
|
404
263
|
const output = {
|
|
405
|
-
'
|
|
264
|
+
'UNITY_CLI_PATH': unityCli.executable,
|
|
406
265
|
'UNITY_EDITOR_PATH': unityEditor.editorPath,
|
|
407
266
|
'UNITY_EDITOR_VERSION': unityEditor.version.version,
|
|
408
267
|
'UNITY_EDITOR_CHANGESET': unityEditor.version.changeset ?? '',
|
|
@@ -432,56 +291,8 @@ program.command('setup-unity')
|
|
|
432
291
|
}
|
|
433
292
|
process.exit(0);
|
|
434
293
|
});
|
|
435
|
-
program.command('uninstall-unity')
|
|
436
|
-
.description('Uninstall a Unity Editor version.')
|
|
437
|
-
.option('-e, --unity-editor <unityEditor>', 'The path to the Unity Editor executable. If unspecified, -u, --unity-version or the UNITY_EDITOR_PATH environment variable must be set.')
|
|
438
|
-
.option('-u, --unity-version <unityVersion>', 'The Unity version to get (e.g. 2020.3.1f1, 2021.x, 2022.1.*, 6000). If unspecified, then --unity-editor must be specified.')
|
|
439
|
-
.option('-c, --changeset <changeset>', 'The Unity changeset to get (e.g. 1234567890ab).')
|
|
440
|
-
.option('-a, --arch <arch>', 'The Unity architecture to get (e.g. x86_64, arm64). Defaults to the architecture of the current process.')
|
|
441
|
-
.option('--verbose', 'Enable verbose logging.')
|
|
442
|
-
.action(async (options) => {
|
|
443
|
-
if (options.verbose) {
|
|
444
|
-
logging_1.Logger.instance.logLevel = logging_1.LogLevel.DEBUG;
|
|
445
|
-
}
|
|
446
|
-
logging_1.Logger.instance.debugOptions(options);
|
|
447
|
-
let unityEditor;
|
|
448
|
-
const unityVersionStr = options.unityVersion?.toString()?.trim();
|
|
449
|
-
if (unityVersionStr) {
|
|
450
|
-
const unityVersion = new unity_version_1.UnityVersion(unityVersionStr, options.changeset, options.arch);
|
|
451
|
-
const unityHub = new unity_hub_1.UnityHub();
|
|
452
|
-
const installedEditors = await unityHub.ListInstalledEditors();
|
|
453
|
-
if (unityVersion.isLegacy()) {
|
|
454
|
-
const installPath = await unityHub.GetInstallPath();
|
|
455
|
-
unityEditor = new unity_editor_1.UnityEditor(path.join(installPath, `Unity ${unityVersion.toString()}`, 'Unity.exe'));
|
|
456
|
-
}
|
|
457
|
-
else {
|
|
458
|
-
unityEditor = installedEditors.find(e => e.version.equals(unityVersion));
|
|
459
|
-
}
|
|
460
|
-
}
|
|
461
|
-
else {
|
|
462
|
-
const editorPath = options.unityEditor?.toString()?.trim() || process.env.UNITY_EDITOR_PATH || undefined;
|
|
463
|
-
if (!editorPath || editorPath.length === 0) {
|
|
464
|
-
logging_1.Logger.instance.error('You must specify a Unity version or editor path with -u, --unity-version, -e, --unity-editor.');
|
|
465
|
-
process.exit(1);
|
|
466
|
-
}
|
|
467
|
-
try {
|
|
468
|
-
unityEditor = new unity_editor_1.UnityEditor(editorPath);
|
|
469
|
-
}
|
|
470
|
-
catch {
|
|
471
|
-
// ignored
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
if (!unityEditor) {
|
|
475
|
-
logging_1.Logger.instance.info('The specified Unity Editor was not found.');
|
|
476
|
-
}
|
|
477
|
-
else {
|
|
478
|
-
await unityEditor.Uninstall();
|
|
479
|
-
}
|
|
480
|
-
process.exit(0);
|
|
481
|
-
});
|
|
482
|
-
program.commandsGroup('Unity Editor:');
|
|
483
294
|
program.command('run')
|
|
484
|
-
.description('Run Unity Editor command line arguments
|
|
295
|
+
.description('Run Unity Editor command line arguments with live Editor log and UTP annotations. Runs with a project go through the official CLI\'s unity run.')
|
|
485
296
|
.option('--unity-editor <unityEditor>', 'The path to the Unity Editor executable. If unspecified, --unity-project or the UNITY_EDITOR_PATH environment variable must be set.')
|
|
486
297
|
.option('--unity-project <unityProject>', 'The path to a Unity project. If unspecified, the UNITY_PROJECT_PATH environment variable will be used, otherwise no project will be specified.')
|
|
487
298
|
.option('--log-name <logName>', 'The name of the log file.')
|
|
@@ -559,9 +370,8 @@ program.command('run')
|
|
|
559
370
|
process.exit(1);
|
|
560
371
|
}
|
|
561
372
|
if (!unityEditor) {
|
|
562
|
-
const unityHub = new unity_hub_1.UnityHub();
|
|
563
373
|
try {
|
|
564
|
-
unityEditor = await
|
|
374
|
+
unityEditor = await new unity_installer_1.UnityInstaller().GetEditor(unityProject.version);
|
|
565
375
|
}
|
|
566
376
|
catch {
|
|
567
377
|
logging_1.Logger.instance.error(`Could not find Unity Editor version ${unityProject.version.version} installed for project at ${unityProject.projectPath}. Please specify the editor path with --unity-editor or set the UNITY_EDITOR_PATH environment variable.`);
|
|
@@ -583,127 +393,99 @@ program.command('run')
|
|
|
583
393
|
});
|
|
584
394
|
process.exit(0);
|
|
585
395
|
});
|
|
586
|
-
program.command('
|
|
587
|
-
.description('
|
|
588
|
-
.
|
|
396
|
+
program.command('editor-logs')
|
|
397
|
+
.description('Prints the path to the Unity Editor log files.')
|
|
398
|
+
.action(async () => {
|
|
399
|
+
const unityEditorLogsPath = unity_editor_1.UnityEditor.GetEditorLogsDirectory();
|
|
400
|
+
process.stdout.write(`${unityEditorLogsPath}\n`);
|
|
401
|
+
process.exit(0);
|
|
402
|
+
});
|
|
403
|
+
program.commandsGroup('Deprecated, forwarded to the official Unity CLI:');
|
|
404
|
+
program.command('uninstall-unity')
|
|
405
|
+
.description('[Deprecated] Uninstall a Unity Editor version. Forwards to: unity uninstall <version> --yes')
|
|
589
406
|
.option('-e, --unity-editor <unityEditor>', 'The path to the Unity Editor executable. If unspecified, -u, --unity-version or the UNITY_EDITOR_PATH environment variable must be set.')
|
|
407
|
+
.option('-u, --unity-version <unityVersion>', 'The Unity version to uninstall (e.g. 2020.3.1f1, 6000.2). If unspecified, then --unity-editor must be specified.')
|
|
408
|
+
.option('-c, --changeset <changeset>', 'Ignored; the official CLI uninstalls by version.')
|
|
409
|
+
.option('-a, --arch <arch>', 'The Unity architecture to uninstall (x86_64, arm64).')
|
|
590
410
|
.option('--verbose', 'Enable verbose logging.')
|
|
591
|
-
.option('--json', 'Prints the last line of output as JSON string.')
|
|
592
411
|
.action(async (options) => {
|
|
593
412
|
if (options.verbose) {
|
|
594
413
|
logging_1.Logger.instance.logLevel = logging_1.LogLevel.DEBUG;
|
|
595
414
|
}
|
|
596
415
|
logging_1.Logger.instance.debugOptions(options);
|
|
597
|
-
const
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
logging_1.Logger.instance.error('You must specify a Unity version or editor path with -u, --unity-version, -e, --unity-editor, or set UNITY_EDITOR_PATH.');
|
|
416
|
+
const version = await forwardedEditorVersion(options);
|
|
417
|
+
if (!version) {
|
|
418
|
+
logging_1.Logger.instance.error('You must specify the Unity version or editor path with -u, --unity-version, -e, --unity-editor or UNITY_EDITOR_PATH.');
|
|
601
419
|
process.exit(1);
|
|
602
420
|
}
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
}
|
|
608
|
-
else {
|
|
609
|
-
const editorPath = options.unityEditor?.toString()?.trim() || editorFromEnv;
|
|
610
|
-
if (!editorPath || editorPath.length === 0) {
|
|
611
|
-
throw new Error('The Unity Editor path was not specified. Use -e or --unity-editor to specify it, or set the UNITY_EDITOR_PATH environment variable.');
|
|
612
|
-
}
|
|
613
|
-
unityEditor = new unity_editor_1.UnityEditor(editorPath);
|
|
421
|
+
const args = ['uninstall', version, '--yes'];
|
|
422
|
+
const arch = options.arch?.toString()?.trim();
|
|
423
|
+
if (arch) {
|
|
424
|
+
args.push('--architecture', arch);
|
|
614
425
|
}
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
426
|
+
await forwardToUnityCli('uninstall-unity', args);
|
|
427
|
+
});
|
|
428
|
+
program.command('list-project-templates')
|
|
429
|
+
.description('[Deprecated] List available Unity project templates for an editor. Forwards to: unity templates list --editor <version>')
|
|
430
|
+
.option('-u, --unity-version <unityVersion>', 'The Unity version to list templates for (e.g. 2022.3.1f1, 6000.2). If unspecified, then --unity-editor must be specified.')
|
|
431
|
+
.option('-e, --unity-editor <unityEditor>', 'The path to the Unity Editor executable. If unspecified, -u, --unity-version or the UNITY_EDITOR_PATH environment variable must be set.')
|
|
432
|
+
.option('--verbose', 'Enable verbose logging.')
|
|
433
|
+
.option('--json', 'Prints the output as JSON.')
|
|
434
|
+
.action(async (options) => {
|
|
435
|
+
if (options.verbose) {
|
|
436
|
+
logging_1.Logger.instance.logLevel = logging_1.LogLevel.DEBUG;
|
|
626
437
|
}
|
|
627
|
-
|
|
438
|
+
logging_1.Logger.instance.debugOptions(options);
|
|
439
|
+
const version = await forwardedEditorVersion(options, true);
|
|
440
|
+
await forwardToUnityCli('list-project-templates', ['templates', 'list', ...(version ? ['--editor', version] : [])], options.json === true);
|
|
628
441
|
});
|
|
629
442
|
program.command('create-project')
|
|
630
|
-
.description('Create a new Unity project.')
|
|
443
|
+
.description('[Deprecated] Create a new Unity project. Forwards to: unity projects create <name> --path <path> --editor-version <version> --template <id> --no-cloud')
|
|
631
444
|
.option('-n, --name <projectName>', 'The name of the new Unity project. If unspecified, the project will be created in the specified path or the current working directory.')
|
|
632
445
|
.option('-p, --path <projectPath>', 'The path to create the new Unity project. If unspecified, the current working directory will be used.')
|
|
633
|
-
.option('-t, --template <projectTemplate>', 'The
|
|
634
|
-
.option('-u, --unity-version <unityVersion>', 'The Unity version to
|
|
446
|
+
.option('-t, --template <projectTemplate>', 'The template package id to create the project from; an id prefix picks the first matching template.', 'com.unity.template.3d')
|
|
447
|
+
.option('-u, --unity-version <unityVersion>', 'The Unity version to create the project with (e.g. 2022.3.1f1, 6000.2). If unspecified, then --unity-editor must be specified.')
|
|
635
448
|
.option('-e, --unity-editor <unityEditor>', 'The path to the Unity Editor executable. If unspecified, -u, --unity-version, or the UNITY_EDITOR_PATH environment variable must be set.')
|
|
636
449
|
.option('--verbose', 'Enable verbose logging.')
|
|
637
|
-
.option('--json', 'Prints the
|
|
450
|
+
.option('--json', 'Prints the output as JSON.')
|
|
638
451
|
.action(async (options) => {
|
|
639
452
|
if (options.verbose) {
|
|
640
453
|
logging_1.Logger.instance.logLevel = logging_1.LogLevel.DEBUG;
|
|
641
454
|
}
|
|
642
455
|
logging_1.Logger.instance.debugOptions(options);
|
|
643
|
-
const
|
|
644
|
-
const
|
|
645
|
-
|
|
646
|
-
|
|
456
|
+
const version = await forwardedEditorVersion(options, true);
|
|
457
|
+
const target = path.resolve(options.path?.toString()?.trim() || process.cwd());
|
|
458
|
+
const name = options.name?.toString()?.trim();
|
|
459
|
+
const args = ['projects', 'create', name || path.basename(target), '--path', name ? target : path.dirname(target)];
|
|
460
|
+
if (version) {
|
|
461
|
+
args.push('--editor-version', version);
|
|
462
|
+
}
|
|
463
|
+
const template = options.template.toString().trim();
|
|
464
|
+
// v3 took a regex here; a pattern is never compiled from the argument, so its leading literal part
|
|
465
|
+
// (com.unity.template.3d for the v3 default) is matched as an exact id, then as an id prefix
|
|
466
|
+
const prefix = /^[\w.-]+/.exec(template)?.[0];
|
|
467
|
+
if (!prefix) {
|
|
468
|
+
logging_1.Logger.instance.error(`Invalid project template: ${template}. Use a template id such as com.unity.template.3d.`);
|
|
647
469
|
process.exit(1);
|
|
648
470
|
}
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
const unityVersion = new unity_version_1.UnityVersion(unityVersionStr);
|
|
652
|
-
unityEditor = await new unity_hub_1.UnityHub().GetEditor(unityVersion);
|
|
653
|
-
}
|
|
654
|
-
else {
|
|
655
|
-
const editorPath = options.unityEditor?.toString()?.trim() || editorFromEnv;
|
|
656
|
-
if (!editorPath || editorPath.length === 0) {
|
|
657
|
-
logging_1.Logger.instance.error('The Unity Editor path was not specified. Use -e or --unity-editor to specify it, or set the UNITY_EDITOR_PATH environment variable.');
|
|
658
|
-
process.exit(1);
|
|
659
|
-
}
|
|
660
|
-
unityEditor = new unity_editor_1.UnityEditor(editorPath);
|
|
661
|
-
}
|
|
662
|
-
let args = [
|
|
663
|
-
'-quit',
|
|
664
|
-
'-nographics',
|
|
665
|
-
'-batchmode'
|
|
666
|
-
];
|
|
667
|
-
const projectName = options.name?.toString()?.trim();
|
|
668
|
-
let projectPath = options.path?.toString()?.trim() || process.cwd();
|
|
669
|
-
if (projectName && projectName.length > 0) {
|
|
670
|
-
projectPath = path.join(projectPath, projectName);
|
|
671
|
-
}
|
|
672
|
-
args.push('-createProject', projectPath);
|
|
673
|
-
if (options.template && options.template.length > 0) {
|
|
674
|
-
const availableTemplates = unityEditor.GetAvailableTemplates();
|
|
675
|
-
if (availableTemplates.length === 0) {
|
|
676
|
-
if (unityEditor.version.isLessThan('2019.0.0')) {
|
|
677
|
-
logging_1.Logger.instance.info(`Skipping template selection for Unity ${unityEditor.version.toString()} because project templates are not supported.`);
|
|
678
|
-
}
|
|
679
|
-
else {
|
|
680
|
-
throw new Error(`No Unity project templates found for ${unityEditor.version.toString()}`);
|
|
681
|
-
}
|
|
682
|
-
}
|
|
683
|
-
else {
|
|
684
|
-
const templatePath = unityEditor.GetTemplatePath(options.template) ??
|
|
685
|
-
unityEditor.GetTemplatePath('com\\.unity\\.template\\.urp-[\\w-]+') ??
|
|
686
|
-
availableTemplates[0];
|
|
687
|
-
if (!templatePath) {
|
|
688
|
-
throw new Error(`No Unity project template found for ${options.template}`);
|
|
689
|
-
}
|
|
690
|
-
args.push('-cloneFromTemplate', templatePath);
|
|
691
|
-
}
|
|
692
|
-
}
|
|
693
|
-
await unityEditor.Run({ projectPath, args });
|
|
694
|
-
logging_1.Logger.instance.CI_setEnvironmentVariable('UNITY_PROJECT_PATH', projectPath);
|
|
695
|
-
if (options.json) {
|
|
696
|
-
process.stdout.write(`\n${JSON.stringify({ UNITY_PROJECT_PATH: projectPath })}\n`);
|
|
471
|
+
if (prefix !== template) {
|
|
472
|
+
logging_1.Logger.instance.warn(`Template patterns are no longer supported; matching templates that start with ${prefix}.`);
|
|
697
473
|
}
|
|
698
|
-
|
|
699
|
-
|
|
474
|
+
const cli = await unity_cli_1.UnityCli.Get();
|
|
475
|
+
const { envelope } = await cli.RunJson(['templates', 'list', ...(version ? ['--editor', version] : [])]);
|
|
476
|
+
const ids = (envelope?.data ?? []).map(t => t.name || t.id).filter((id) => !!id);
|
|
477
|
+
const templateId = ids.find(id => id === prefix) ?? ids.find(id => id.startsWith(prefix));
|
|
478
|
+
if (!templateId) {
|
|
479
|
+
logging_1.Logger.instance.error(`No project template matches ${prefix}. Available: ${ids.join(', ')}`);
|
|
480
|
+
process.exit(1);
|
|
700
481
|
}
|
|
701
|
-
|
|
482
|
+
args.push('--template', templateId, '--no-cloud');
|
|
483
|
+
await forwardToUnityCli('create-project', args, options.json === true);
|
|
702
484
|
});
|
|
703
485
|
program.command('open-project')
|
|
704
|
-
.description('Open a Unity project in the Unity Editor.')
|
|
486
|
+
.description('[Deprecated] Open a Unity project in the Unity Editor. Forwards to: unity open <project>')
|
|
705
487
|
.option('-p, --unity-project <unityProject>', 'The path to a Unity project. If unspecified, the UNITY_PROJECT_PATH environment variable or the current working directory will be used.')
|
|
706
|
-
.option('-u, --unity-version <unityVersion>', 'The Unity version to
|
|
488
|
+
.option('-u, --unity-version <unityVersion>', 'The Unity version to open the project with. If specified, it will override the version read from the project.')
|
|
707
489
|
.option('-t, --build-target <buildTarget>', 'The Unity build target to switch the project to (e.g. StandaloneWindows64, StandaloneOSX, iOS, Android).')
|
|
708
490
|
.option('--verbose', 'Enable verbose logging.')
|
|
709
491
|
.action(async (options) => {
|
|
@@ -711,47 +493,48 @@ program.command('open-project')
|
|
|
711
493
|
logging_1.Logger.instance.logLevel = logging_1.LogLevel.DEBUG;
|
|
712
494
|
}
|
|
713
495
|
logging_1.Logger.instance.debugOptions(options);
|
|
714
|
-
const projectPath = options.unityProject?.toString()?.trim() ||
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
const unityProject = await unity_project_1.UnityProject.GetProject(projectPath);
|
|
718
|
-
if (!unityProject) {
|
|
719
|
-
logging_1.Logger.instance.error(`The specified path is not a valid Unity project: ${projectPath}`);
|
|
720
|
-
process.exit(1);
|
|
721
|
-
}
|
|
722
|
-
let unityVersion = unityProject?.version;
|
|
723
|
-
if (options.unityVersion) {
|
|
724
|
-
unityVersion = new unity_version_1.UnityVersion(options.unityVersion);
|
|
725
|
-
}
|
|
496
|
+
const projectPath = options.unityProject?.toString()?.trim() || process.env.UNITY_PROJECT_PATH || process.cwd();
|
|
497
|
+
const args = ['open', projectPath];
|
|
498
|
+
const version = options.unityVersion?.toString()?.trim();
|
|
726
499
|
const buildTarget = options.buildTarget?.toString()?.trim();
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
const moduleBuildTargetMap = unity_hub_1.UnityHub.GetPlatformTargetModuleMap();
|
|
730
|
-
module = moduleBuildTargetMap[buildTarget] ? [moduleBuildTargetMap[buildTarget]] : undefined;
|
|
731
|
-
}
|
|
732
|
-
const unityHub = new unity_hub_1.UnityHub();
|
|
733
|
-
const unityEditor = await unityHub.GetEditor(unityVersion, module);
|
|
734
|
-
logging_1.Logger.instance.info(`Opening "${unityProject.projectPath}" with Unity ${unityEditor.version}${buildTarget ? ` - ${buildTarget}` : ''}...`);
|
|
735
|
-
const openArgs = ['-projectPath', unityProject.projectPath];
|
|
736
|
-
if (buildTarget && buildTarget.length > 0) {
|
|
737
|
-
openArgs.push('-buildTarget', buildTarget);
|
|
738
|
-
}
|
|
739
|
-
let child = null;
|
|
740
|
-
try {
|
|
741
|
-
child = (0, child_process_1.spawn)(unityEditor.editorPath, openArgs, { detached: true });
|
|
742
|
-
child.unref();
|
|
500
|
+
if (version) {
|
|
501
|
+
args.push('--editor-version', version);
|
|
743
502
|
}
|
|
744
|
-
|
|
745
|
-
|
|
503
|
+
if (buildTarget) {
|
|
504
|
+
args.push('--build-target', buildTarget);
|
|
746
505
|
}
|
|
506
|
+
await forwardToUnityCli('open-project', args);
|
|
747
507
|
});
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
508
|
+
/**
|
|
509
|
+
* The editor version a forwarded v3 command names, from --unity-version or the editor at --unity-editor / UNITY_EDITOR_PATH.
|
|
510
|
+
* Partial versions such as 2021.3.x become 2021.3, the short form `unity uninstall` accepts; with `exact`, they resolve
|
|
511
|
+
* to the newest matching release instead, because `unity templates list` and `unity projects create` need a full version.
|
|
512
|
+
*/
|
|
513
|
+
async function forwardedEditorVersion(options, exact = false) {
|
|
514
|
+
const version = options.unityVersion?.toString()?.trim();
|
|
515
|
+
if (version) {
|
|
516
|
+
if (!exact) {
|
|
517
|
+
return version.replace(/\.[x*]$/i, '');
|
|
518
|
+
}
|
|
519
|
+
const unityVersion = new unity_version_1.UnityVersion(version);
|
|
520
|
+
if (unityVersion.isFullyQualified()) {
|
|
521
|
+
return unityVersion.version;
|
|
522
|
+
}
|
|
523
|
+
return (await new unity_installer_1.UnityInstaller(await unity_cli_1.UnityCli.Get()).resolveVersion(unityVersion)).version;
|
|
524
|
+
}
|
|
525
|
+
const editorPath = options.unityEditor?.toString()?.trim() || process.env.UNITY_EDITOR_PATH;
|
|
526
|
+
return editorPath ? new unity_editor_1.UnityEditor(editorPath).version.version : undefined;
|
|
527
|
+
}
|
|
528
|
+
/** Warns that a v3 command is deprecated, runs its official Unity CLI replacement and exits with that exit code. */
|
|
529
|
+
async function forwardToUnityCli(command, args, json = false) {
|
|
530
|
+
logging_1.Logger.instance.warn(`unity-cli ${command} is deprecated and will be removed. Use the official Unity CLI instead: unity ${args.join(' ')}`);
|
|
531
|
+
const cli = await unity_cli_1.UnityCli.Get();
|
|
532
|
+
const result = await cli.Run(json ? [...args, '--json'] : args, { stream: !json });
|
|
533
|
+
if (json) {
|
|
534
|
+
process.stdout.write(`${result.stdout.trim()}\n`);
|
|
535
|
+
}
|
|
536
|
+
process.exit(result.exitCode);
|
|
537
|
+
}
|
|
755
538
|
program.commandsGroup("Unity Package Manager:");
|
|
756
539
|
program.command('upm-install')
|
|
757
540
|
.description('Download and install the Unity Package Manager cli (pack/sign).')
|
|
@@ -805,7 +588,7 @@ program.command('upm-install')
|
|
|
805
588
|
process.exit(0);
|
|
806
589
|
}
|
|
807
590
|
catch (error) {
|
|
808
|
-
|
|
591
|
+
(0, failure_markers_1.ReportFailure)(error);
|
|
809
592
|
process.exit(1);
|
|
810
593
|
}
|
|
811
594
|
});
|
|
@@ -819,7 +602,7 @@ program.command('upm-version')
|
|
|
819
602
|
process.exit(0);
|
|
820
603
|
}
|
|
821
604
|
catch (error) {
|
|
822
|
-
|
|
605
|
+
(0, failure_markers_1.ReportFailure)(error);
|
|
823
606
|
process.exit(1);
|
|
824
607
|
}
|
|
825
608
|
});
|
|
@@ -884,120 +667,12 @@ program.command('upm-pack')
|
|
|
884
667
|
process.exit(0);
|
|
885
668
|
}
|
|
886
669
|
catch (error) {
|
|
887
|
-
|
|
670
|
+
(0, failure_markers_1.ReportFailure)(error);
|
|
888
671
|
process.exit(1);
|
|
889
672
|
}
|
|
890
673
|
});
|
|
891
|
-
program.command('sign-package')
|
|
892
|
-
.description('[Deprecated] Sign a Unity package using Unity Editor 6000.3+ batch mode (-upmPack). Use unity-cli upm-pack with organization and service account credentials for new workflows.')
|
|
893
|
-
.option('--package <package>', 'Required. The fully qualified path to the folder that contains the package.json file for the package you want to sign. Note: Don\'t include package.json in this parameter value.')
|
|
894
|
-
.option('--output <output>', 'Optional. The output directory where you want to save the signed tarball file (.tgz). If unspecified, the package contents will be updated in place with the signed .attestation.p7m file.')
|
|
895
|
-
.option('--email <email>', 'Email associated with the Unity account. If unspecified, the UNITY_USERNAME environment variable will be used.')
|
|
896
|
-
.option('--password <password>', 'The password of the Unity account. If unspecified, the UNITY_PASSWORD environment variable will be used.')
|
|
897
|
-
.option('--organization <organization>', 'The Organization ID you copied from the Unity Cloud Dashboard. If unspecified, the UNITY_ORGANIZATION_ID environment variable will be used.')
|
|
898
|
-
.option('--verbose', 'Enable verbose logging.')
|
|
899
|
-
.action(async (options) => {
|
|
900
|
-
logging_1.Logger.instance.warn('The sign-package command is deprecated. Use unity-cli upm-pack --source <path-to-package-folder> --destination <output-path> with UNITY_ORGANIZATION_ID or UNITY_ORG_ID, UPM_SERVICE_ACCOUNT_KEY_ID, and UPM_SERVICE_ACCOUNT_KEY_SECRET (or secure prompts).');
|
|
901
|
-
if (options.verbose) {
|
|
902
|
-
logging_1.Logger.instance.logLevel = logging_1.LogLevel.DEBUG;
|
|
903
|
-
}
|
|
904
|
-
logging_1.Logger.instance.debugOptions(options);
|
|
905
|
-
const packagePath = path.normalize(options.package?.toString()?.trim());
|
|
906
|
-
if (!packagePath || packagePath.length === 0) {
|
|
907
|
-
logging_1.Logger.instance.error('The package path is required. Use --package to specify it.');
|
|
908
|
-
process.exit(1);
|
|
909
|
-
}
|
|
910
|
-
const packageJsonPath = path.join(packagePath, 'package.json');
|
|
911
|
-
try {
|
|
912
|
-
await fs.promises.access(packageJsonPath, fs.constants.R_OK);
|
|
913
|
-
}
|
|
914
|
-
catch {
|
|
915
|
-
logging_1.Logger.instance.error(`Failed to find a valid package.json file at: ${packageJsonPath}`);
|
|
916
|
-
process.exit(1);
|
|
917
|
-
}
|
|
918
|
-
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
|
|
919
|
-
let outputPath = options.output?.toString()?.trim();
|
|
920
|
-
if (outputPath && outputPath.length > 0) {
|
|
921
|
-
outputPath = path.resolve(outputPath);
|
|
922
|
-
if (outputPath.endsWith('.tgz')) {
|
|
923
|
-
// remove .tgz if present
|
|
924
|
-
outputPath = outputPath.substring(0, outputPath.length - 4);
|
|
925
|
-
}
|
|
926
|
-
}
|
|
927
|
-
else {
|
|
928
|
-
outputPath = path.join(path.resolve(packagePath, '..'));
|
|
929
|
-
}
|
|
930
|
-
let username = options.email?.toString()?.trim() || process.env.UNITY_USERNAME || undefined;
|
|
931
|
-
if (!username || username.length === 0) {
|
|
932
|
-
username = await (0, utilities_1.PromptForSecretInput)('Email: ');
|
|
933
|
-
}
|
|
934
|
-
if (!username || username.length === 0) {
|
|
935
|
-
logging_1.Logger.instance.error('The email is required. Use --email to specify it.');
|
|
936
|
-
process.exit(1);
|
|
937
|
-
}
|
|
938
|
-
let password = options.password?.toString()?.trim() || process.env.UNITY_PASSWORD || undefined;
|
|
939
|
-
if (!password || password.length === 0) {
|
|
940
|
-
password = await (0, utilities_1.PromptForSecretInput)('Password: ');
|
|
941
|
-
}
|
|
942
|
-
if (!password || password.length === 0) {
|
|
943
|
-
logging_1.Logger.instance.error('The password is required. Use --password to specify it.');
|
|
944
|
-
process.exit(1);
|
|
945
|
-
}
|
|
946
|
-
let organization = options.organization?.toString()?.trim() || process.env.UNITY_ORGANIZATION_ID || undefined;
|
|
947
|
-
if (!organization || organization.length === 0) {
|
|
948
|
-
organization = await (0, utilities_1.PromptForSecretInput)('Organization ID: ');
|
|
949
|
-
}
|
|
950
|
-
if (!organization || organization.length === 0) {
|
|
951
|
-
logging_1.Logger.instance.error('The organization ID is required. Use --organization to specify it.');
|
|
952
|
-
process.exit(1);
|
|
953
|
-
}
|
|
954
|
-
// Mask credentials in CI environments before any potential logging
|
|
955
|
-
logging_1.Logger.instance.maskCredential(username);
|
|
956
|
-
logging_1.Logger.instance.maskCredential(password);
|
|
957
|
-
logging_1.Logger.instance.maskCredential(organization);
|
|
958
|
-
// must use a unity editor 6000.3 or newer
|
|
959
|
-
const unityVersion = new unity_version_1.UnityVersion('6000.3');
|
|
960
|
-
const unityHub = new unity_hub_1.UnityHub();
|
|
961
|
-
const unityEditor = await unityHub.GetEditor(unityVersion, undefined, ['f', 'b']);
|
|
962
|
-
try {
|
|
963
|
-
await unityEditor.Run({
|
|
964
|
-
args: [
|
|
965
|
-
'-batchmode',
|
|
966
|
-
'-username', username,
|
|
967
|
-
'-password', password,
|
|
968
|
-
'-upmPack', packagePath, path.normalize(outputPath),
|
|
969
|
-
'-cloudOrganization', organization
|
|
970
|
-
]
|
|
971
|
-
});
|
|
972
|
-
}
|
|
973
|
-
catch (error) {
|
|
974
|
-
// currently the editor returns exit code 1 even on success
|
|
975
|
-
}
|
|
976
|
-
finally {
|
|
977
|
-
if (fs.existsSync(outputPath)) {
|
|
978
|
-
const pkg = await (0, utilities_1.ResolveGlobToPath)([outputPath, `${path.basename(packageJson.name)}*.tgz`]);
|
|
979
|
-
logging_1.Logger.instance.info(`Package signed successfully: ${pkg}`);
|
|
980
|
-
// if the output directory was not specified in the command options,
|
|
981
|
-
// then unpack the .tgz file and overwrite the package contents.
|
|
982
|
-
if (!options.output || options.output.length === 0) {
|
|
983
|
-
await tar.x({
|
|
984
|
-
file: pkg,
|
|
985
|
-
cwd: packagePath,
|
|
986
|
-
strip: 1
|
|
987
|
-
});
|
|
988
|
-
logging_1.Logger.instance.info(`Package contents extracted to: ${packagePath}`);
|
|
989
|
-
fs.unlinkSync(pkg);
|
|
990
|
-
}
|
|
991
|
-
process.exit(0);
|
|
992
|
-
}
|
|
993
|
-
else {
|
|
994
|
-
logging_1.Logger.instance.error('Failed to sign the package.');
|
|
995
|
-
process.exit(1);
|
|
996
|
-
}
|
|
997
|
-
}
|
|
998
|
-
});
|
|
999
674
|
void program.parseAsync(process.argv).catch((err) => {
|
|
1000
|
-
|
|
675
|
+
(0, failure_markers_1.ReportFailure)(err);
|
|
1001
676
|
process.exit(1);
|
|
1002
677
|
});
|
|
1003
678
|
//# sourceMappingURL=cli.js.map
|