Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,19 +31,19 @@ unity-cli [command] [options]
- `unity-cli hub-install`: Install Unity Hub
- `unity-cli hub-version`: Print Unity Hub version
- `unity-cli hub-path`: Print Unity Hub executable path
- `unity-cli hub [args...]`: Run Unity Hub commands directly
- `unity-cli activate-license`: Activate a Unity license
- `unity-cli return-license`: Return a Unity license
- `unity-cli hub [options] <args...>`: Run [Unity Hub command line arguments](https://docs.unity3d.com/hub/manual/HubCLI.html)
- `unity-cli activate-license [options]`: Activate a Unity license
- `unity-cli return-license [options]`: Return a Unity license
- `unity-cli license-version`: Print Unity License Client version
- `unity-cli setup-unity`: Find or install Unity Editor for a project/version
- `unity-cli create-project`: Create a new Unity project from a template
- `unity-cli run [args...]`: Run commands in [Unity Editor Command Line Arguments](https://docs.unity3d.com/Manual/EditorCommandLineArguments.html)
- `unity-cli setup-unity [options]`: Find or install Unity Editor for a project/version
- `unity-cli create-project [options]`: Create a new Unity project from a [template](https://docs.unity3d.com/hub/manual/Templates.html)
- `unity-cli run [options] <args...>`: Run [Unity Editor Command Line Arguments](https://docs.unity3d.com/Manual/EditorCommandLineArguments.html)

#### Install Unity Hub and Editor

```bash
unity-cli hub-install
unity-cli setup-unity --unity-version 2022.3.x --modules android,ios --json
unity-cli setup-unity --unity-version 2022.3.x --modules android,ios
```

#### Activate a Unity License
Expand All @@ -61,5 +61,5 @@ unity-cli create-project --name "MyGame" --template com.unity.template.3d --unit
#### Build a Project

```bash
unity-cli run --unity-editor <path-to-editor> --unity-project <path-to-project> -quit -batchmode -executeMethod Utilities.Editor.BuildPipeline.UnityPlayerBuildTools.StartCommandLineBuild
unity-cli run --unity-editor <path-to-editor> --unity-project <path-to-project> -quit -batchmode -executeMethod StartCommandLineBuild
```
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@rage-against-the-pixel/unity-cli",
"version": "1.0.4",
"version": "1.0.5",
"description": "A command line utility for the Unity Game Engine.",
"author": "RageAgainstThePixel",
"license": "MIT",
Expand Down
6 changes: 3 additions & 3 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -214,17 +214,17 @@ program.command('setup-unity')
}

const unityHub = new UnityHub();
const editorPath = await unityHub.GetEditor(unityVersion, modules);
const unityEditor = await unityHub.GetEditor(unityVersion, modules);
const output: { [key: string]: string } = {
'UNITY_HUB_PATH': unityHub.executable,
'UNITY_EDITOR': editorPath
'UNITY_EDITOR': unityEditor.editorPath
};

if (unityProject) {
output['UNITY_PROJECT_PATH'] = unityProject.projectPath;

if (modules.includes('android')) {
await CheckAndroidSdkInstalled(editorPath, unityProject.projectPath);
await CheckAndroidSdkInstalled(unityEditor.editorPath, unityProject.projectPath);
}
}

Expand Down
28 changes: 19 additions & 9 deletions src/unity-editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
spawn,
ChildProcessByStdio,
} from 'child_process';
import { UnityVersion } from './unity-version';

export interface EditorCommand {
args: string[];
Expand All @@ -31,27 +32,36 @@ export class UnityEditor {
* @param editorPath The path to the Unity Editor installation.
* @throws Will throw an error if the editor path is invalid or not executable.
*/
constructor(public readonly editorPath: string) {
constructor(
public readonly editorPath: string,
public readonly version: UnityVersion | undefined = undefined
) {
if (!fs.existsSync(editorPath)) {
throw new Error(`The Unity Editor path does not exist: ${editorPath}`);
}

fs.accessSync(editorPath, fs.constants.X_OK);
this.editorRootPath = UnityEditor.GetEditorRootPath(editorPath);

const match = editorPath.match(/(?<major>\d+)\.(?<minor>\d+)\.(?<patch>\d+)/);
if (!version) {
const match = editorPath.match(/(?<major>\d+)\.(?<minor>\d+)\.(?<patch>\w+)/);

if (!match) {
throw Error(`Invalid Unity Editor Path: ${editorPath}`);
}
if (!match || !match.groups) {
throw Error(`Invalid Unity Editor Path: ${editorPath}`);
}

const unityMajorVersion = match.groups?.major;
const unityMajorVersion = match.groups!.major;

if (!unityMajorVersion) {
throw Error(`Invalid Unity Major Version: ${editorPath}`);
if (!unityMajorVersion) {
throw Error(`Invalid Unity Major Version: ${editorPath}`);
}

this.version = new UnityVersion(`${match.groups!.major}.${match.groups!.minor}.${match.groups!.patch}`);
} else {
this.version = version;
}

this.autoAddNoGraphics = parseInt(unityMajorVersion, 10) > 2018;
this.autoAddNoGraphics = this.version.satisfies('>2018.0.0');
}

/**
Expand Down
15 changes: 9 additions & 6 deletions src/unity-hub.ts
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ chmod -R 777 "$hubPath"`]);
* @param modules The modules to install alongside the editor.
* @returns The path to the Unity Editor executable.
*/
public async GetEditor(unityVersion: UnityVersion, modules: string[]): Promise<string> {
public async GetEditor(unityVersion: UnityVersion, modules: string[]): Promise<UnityEditor> {
const retryErrorMessages = [
'Editor already installed in this location',
'failed to download. Error given: Request timeout'
Expand Down Expand Up @@ -442,6 +442,7 @@ chmod -R 777 "$hubPath"`]);
if (installPath) {
await DeleteDirectory(installPath);
}

installPath = await this.installUnity(unityVersion, modules);
} else {
throw error;
Expand All @@ -459,7 +460,7 @@ chmod -R 777 "$hubPath"`]);
await this.patchBeeBackend(editorPath);

if (unityVersion.isLegacy() || modules.length === 0) {
return editorPath;
return new UnityEditor(path.normalize(editorPath), unityVersion);
}

try {
Expand Down Expand Up @@ -487,7 +488,7 @@ chmod -R 777 "$hubPath"`]);
}
}

return path.normalize(editorPath);
return new UnityEditor(path.normalize(editorPath), unityVersion);
}

/**
Expand All @@ -503,6 +504,7 @@ chmod -R 777 "$hubPath"`]);

private async checkInstalledEditors(unityVersion: UnityVersion, failOnEmpty: boolean, installPath: string | undefined = undefined): Promise<string | undefined> {
let editorPath = undefined;

if (!installPath) {
const paths: string[] = await this.ListInstalledEditors();

Expand Down Expand Up @@ -578,7 +580,7 @@ chmod -R 777 "$hubPath"`]);
throw new Error(`Failed to find installed Unity Editor: ${unityVersion.toString()}\n > ${error}`);
}

this.logger.ci(`Found installed Unity Editor: ${editorPath}`);
this.logger.debug(`Found installed editor: "${editorPath}"`);
return editorPath;
}

Expand Down Expand Up @@ -799,6 +801,8 @@ done
}

private async installUnity(unityVersion: UnityVersion, modules: string[]): Promise<string | undefined> {
this.logger.ci(`Installing Unity ${unityVersion.toString()}...`);

if (unityVersion.isLegacy()) {
return await this.installUnity4x(unityVersion);
}
Expand Down Expand Up @@ -848,7 +852,6 @@ done
args.push('--cm');
}

this.logger.info(`Installing Unity ${unityVersion.toString()}...`);
const output = await this.Exec(args, { showCommand: true, silent: false });

if (output.includes(`Error while installing an editor or a module from changeset`)) {
Expand All @@ -871,7 +874,7 @@ done
this.logger.info(`Running Unity ${unityVersion.toString()} installer...`);

try {
await Exec(installerPath, ['/S', `/D=${installPath}`, '-Wait', '-NoNewWindow'], { silent: true, showCommand: true });
await Exec('powershell', ['-Command', `Start-Process -FilePath \"${installerPath}\" -ArgumentList \"/S /D=${installPath}\" -Wait -NoNewWindow`], { silent: true, showCommand: true });
} catch (error) {
this.logger.error(`Failed to install Unity ${unityVersion.toString()}: ${error}`);
} finally {
Expand Down
8 changes: 4 additions & 4 deletions src/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ export async function TryKillProcess(procInfo: ProcInfo): Promise<number | undef

try {
pid = procInfo.pid;
logger.ci(`Killing process '${procInfo.name}' with pid: ${pid}`);
logger.ci(`Killing process "${procInfo.name}" with pid: ${pid}`);
process.kill(pid);
} catch (error) {
const nodeJsException = error as NodeJS.ErrnoException;
Expand Down Expand Up @@ -295,10 +295,10 @@ export async function KillChildProcesses(procInfo: ProcInfo): Promise<void> {
logger.debug(`Killing child processes of ${procInfo.name} with pid: ${procInfo.pid}...`);
try {
if (process.platform === 'win32') {
const pwshCommand = 'powershell -Command "Get-CimInstance Win32_Process -Filter \'ParentProcessId=' + procInfo.pid + '\' | ForEach-Object { Stop-Process -Id $_.ProcessId -Force }"';
await Exec('cmd', ['/c', pwshCommand], { silent: true });
const command = `Get-CimInstance Win32_Process -Filter "ParentProcessId=${procInfo.pid}" | ForEach-Object { Stop-Process -Id $_.ProcessId -Force }`;
await Exec('powershell', ['-Command', command], { silent: true, showCommand: true });
} else { // linux and macos
const psOutput = await Exec('ps', ['-eo', 'pid,ppid,comm'], { silent: true });
const psOutput = await Exec('ps', ['-eo', 'pid,ppid,comm'], { silent: true, showCommand: false });
const lines = psOutput.split('\n').slice(1); // Skip header line

for (const line of lines) {
Expand Down