uloop-cli 0.59.1 → 0.61.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/dist/cli.bundle.cjs +176 -60
- package/dist/cli.bundle.cjs.map +3 -3
- package/package.json +2 -2
- package/src/commands/launch.ts +20 -73
- package/src/default-tools.json +1 -9
- package/src/version.ts +1 -1
package/dist/cli.bundle.cjs
CHANGED
|
@@ -5763,7 +5763,7 @@ var import_path3 = require("path");
|
|
|
5763
5763
|
|
|
5764
5764
|
// src/default-tools.json
|
|
5765
5765
|
var default_tools_default = {
|
|
5766
|
-
version: "0.
|
|
5766
|
+
version: "0.61.0",
|
|
5767
5767
|
tools: [
|
|
5768
5768
|
{
|
|
5769
5769
|
name: "compile",
|
|
@@ -5849,10 +5849,6 @@ var default_tools_default = {
|
|
|
5849
5849
|
FilterValue: {
|
|
5850
5850
|
type: "string",
|
|
5851
5851
|
description: "Filter value"
|
|
5852
|
-
},
|
|
5853
|
-
SaveXml: {
|
|
5854
|
-
type: "boolean",
|
|
5855
|
-
description: "Save test results as XML"
|
|
5856
5852
|
}
|
|
5857
5853
|
}
|
|
5858
5854
|
}
|
|
@@ -6084,10 +6080,6 @@ var default_tools_default = {
|
|
|
6084
6080
|
CompileOnly: {
|
|
6085
6081
|
type: "boolean",
|
|
6086
6082
|
description: "Compile only without execution"
|
|
6087
|
-
},
|
|
6088
|
-
AutoQualifyUnityTypesOnce: {
|
|
6089
|
-
type: "boolean",
|
|
6090
|
-
description: "Auto-qualify Unity types"
|
|
6091
6083
|
}
|
|
6092
6084
|
}
|
|
6093
6085
|
}
|
|
@@ -6215,7 +6207,7 @@ function getCachedServerVersion() {
|
|
|
6215
6207
|
}
|
|
6216
6208
|
|
|
6217
6209
|
// src/version.ts
|
|
6218
|
-
var VERSION = "0.
|
|
6210
|
+
var VERSION = "0.61.0";
|
|
6219
6211
|
|
|
6220
6212
|
// src/spinner.ts
|
|
6221
6213
|
var SPINNER_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
@@ -7472,6 +7464,24 @@ var parseCliArgs = (cliArgsString) => {
|
|
|
7472
7464
|
}
|
|
7473
7465
|
return tokens;
|
|
7474
7466
|
};
|
|
7467
|
+
var groupCliArgs = (args) => {
|
|
7468
|
+
const groups = [];
|
|
7469
|
+
let current = "";
|
|
7470
|
+
for (const arg of args) {
|
|
7471
|
+
if (arg.startsWith("-") && current.length > 0) {
|
|
7472
|
+
groups.push(current);
|
|
7473
|
+
current = arg;
|
|
7474
|
+
} else if (current.length === 0) {
|
|
7475
|
+
current = arg;
|
|
7476
|
+
} else {
|
|
7477
|
+
current += ` ${arg}`;
|
|
7478
|
+
}
|
|
7479
|
+
}
|
|
7480
|
+
if (current.length > 0) {
|
|
7481
|
+
groups.push(current);
|
|
7482
|
+
}
|
|
7483
|
+
return groups;
|
|
7484
|
+
};
|
|
7475
7485
|
var getProjectCliArgs = async (projectPath) => {
|
|
7476
7486
|
(0, import_node_assert.default)(projectPath !== null && projectPath !== void 0, "projectPath must not be null");
|
|
7477
7487
|
const infoFilePath = resolveUnityHubProjectsInfoFile();
|
|
@@ -7777,9 +7787,11 @@ async function handleStaleLockfile(projectPath) {
|
|
|
7777
7787
|
const message = error instanceof Error ? error.message : String(error);
|
|
7778
7788
|
console.warn(`Failed to delete UnityLockfile: ${message}`);
|
|
7779
7789
|
}
|
|
7790
|
+
console.log();
|
|
7780
7791
|
}
|
|
7781
7792
|
var KILL_POLL_INTERVAL_MS = 100;
|
|
7782
7793
|
var KILL_TIMEOUT_MS = 1e4;
|
|
7794
|
+
var GRACEFUL_QUIT_TIMEOUT_MS = 1e4;
|
|
7783
7795
|
function isProcessAlive(pid) {
|
|
7784
7796
|
try {
|
|
7785
7797
|
process.kill(pid, 0);
|
|
@@ -7794,9 +7806,9 @@ function killProcess(pid) {
|
|
|
7794
7806
|
} catch {
|
|
7795
7807
|
}
|
|
7796
7808
|
}
|
|
7797
|
-
async function waitForProcessExit(pid) {
|
|
7809
|
+
async function waitForProcessExit(pid, timeoutMs) {
|
|
7798
7810
|
const start = Date.now();
|
|
7799
|
-
while (Date.now() - start <
|
|
7811
|
+
while (Date.now() - start < timeoutMs) {
|
|
7800
7812
|
if (!isProcessAlive(pid)) {
|
|
7801
7813
|
return true;
|
|
7802
7814
|
}
|
|
@@ -7808,16 +7820,73 @@ async function killRunningUnity(projectPath) {
|
|
|
7808
7820
|
const processInfo = await findRunningUnityProcess(projectPath);
|
|
7809
7821
|
if (!processInfo) {
|
|
7810
7822
|
console.log("No running Unity process found for this project.");
|
|
7823
|
+
console.log();
|
|
7811
7824
|
return;
|
|
7812
7825
|
}
|
|
7813
7826
|
const pid = processInfo.pid;
|
|
7814
7827
|
console.log(`Killing Unity (PID: ${pid})...`);
|
|
7815
7828
|
killProcess(pid);
|
|
7816
|
-
const exited = await waitForProcessExit(pid);
|
|
7829
|
+
const exited = await waitForProcessExit(pid, KILL_TIMEOUT_MS);
|
|
7817
7830
|
if (!exited) {
|
|
7818
7831
|
throw new Error(`Failed to kill Unity (PID: ${pid}) within ${KILL_TIMEOUT_MS / 1e3}s.`);
|
|
7819
7832
|
}
|
|
7820
7833
|
console.log("Unity killed.");
|
|
7834
|
+
console.log();
|
|
7835
|
+
}
|
|
7836
|
+
async function sendGracefulQuitMac(pid) {
|
|
7837
|
+
const script = [
|
|
7838
|
+
'tell application "System Events"',
|
|
7839
|
+
` set frontmost of (first process whose unix id is ${pid}) to true`,
|
|
7840
|
+
' keystroke "q" using {command down}',
|
|
7841
|
+
"end tell"
|
|
7842
|
+
].join("\n");
|
|
7843
|
+
try {
|
|
7844
|
+
await execFileAsync("osascript", ["-e", script]);
|
|
7845
|
+
} catch {
|
|
7846
|
+
}
|
|
7847
|
+
}
|
|
7848
|
+
async function sendGracefulQuitWindows(pid) {
|
|
7849
|
+
const scriptLines = [
|
|
7850
|
+
"$ErrorActionPreference = 'Stop'",
|
|
7851
|
+
`try { $proc = Get-Process -Id ${pid} -ErrorAction Stop; $proc.CloseMainWindow() | Out-Null } catch { }`
|
|
7852
|
+
];
|
|
7853
|
+
try {
|
|
7854
|
+
await execFileAsync(WINDOWS_POWERSHELL, ["-NoProfile", "-Command", scriptLines.join("\n")]);
|
|
7855
|
+
} catch {
|
|
7856
|
+
}
|
|
7857
|
+
}
|
|
7858
|
+
async function sendGracefulQuit(pid) {
|
|
7859
|
+
if (process.platform === "darwin") {
|
|
7860
|
+
await sendGracefulQuitMac(pid);
|
|
7861
|
+
return;
|
|
7862
|
+
}
|
|
7863
|
+
if (process.platform === "win32") {
|
|
7864
|
+
await sendGracefulQuitWindows(pid);
|
|
7865
|
+
return;
|
|
7866
|
+
}
|
|
7867
|
+
}
|
|
7868
|
+
async function quitRunningUnity(projectPath) {
|
|
7869
|
+
const processInfo = await findRunningUnityProcess(projectPath);
|
|
7870
|
+
if (!processInfo) {
|
|
7871
|
+
console.log("No running Unity process found for this project.");
|
|
7872
|
+
return;
|
|
7873
|
+
}
|
|
7874
|
+
const pid = processInfo.pid;
|
|
7875
|
+
console.log(`Quitting Unity (PID: ${pid})...`);
|
|
7876
|
+
await sendGracefulQuit(pid);
|
|
7877
|
+
console.log(`Sent graceful quit signal. Waiting up to ${GRACEFUL_QUIT_TIMEOUT_MS / 1e3}s...`);
|
|
7878
|
+
const exitedGracefully = await waitForProcessExit(pid, GRACEFUL_QUIT_TIMEOUT_MS);
|
|
7879
|
+
if (exitedGracefully) {
|
|
7880
|
+
console.log("Unity quit gracefully.");
|
|
7881
|
+
return;
|
|
7882
|
+
}
|
|
7883
|
+
console.log("Unity did not respond to graceful quit. Force killing...");
|
|
7884
|
+
killProcess(pid);
|
|
7885
|
+
const exitedAfterKill = await waitForProcessExit(pid, KILL_TIMEOUT_MS);
|
|
7886
|
+
if (!exitedAfterKill) {
|
|
7887
|
+
throw new Error(`Failed to kill Unity (PID: ${pid}) within ${KILL_TIMEOUT_MS / 1e3}s.`);
|
|
7888
|
+
}
|
|
7889
|
+
console.log("Unity force killed.");
|
|
7821
7890
|
}
|
|
7822
7891
|
function hasBuildTargetArg(unityArgs) {
|
|
7823
7892
|
for (const arg of unityArgs) {
|
|
@@ -7908,12 +7977,12 @@ function findUnityProjectBfs(rootDir, maxDepth) {
|
|
|
7908
7977
|
async function launch(opts) {
|
|
7909
7978
|
const { projectPath, platform, unityArgs, unityVersion } = opts;
|
|
7910
7979
|
const unityPath = getUnityPath(unityVersion);
|
|
7911
|
-
console.log(`Detected Unity version: ${unityVersion}`);
|
|
7912
7980
|
if (!(0, import_node_fs2.existsSync)(unityPath)) {
|
|
7913
7981
|
throw new Error(`Unity ${unityVersion} not found at ${unityPath}. Please install Unity through Unity Hub.`);
|
|
7914
7982
|
}
|
|
7915
7983
|
console.log("Opening Unity...");
|
|
7916
7984
|
console.log(`Project Path: ${projectPath}`);
|
|
7985
|
+
console.log(`Detected Unity version: ${unityVersion}`);
|
|
7917
7986
|
const args = ["-projectPath", projectPath];
|
|
7918
7987
|
const unityArgsContainBuildTarget = hasBuildTargetArg(unityArgs);
|
|
7919
7988
|
if (platform && platform.length > 0 && !unityArgsContainBuildTarget) {
|
|
@@ -7921,86 +7990,133 @@ async function launch(opts) {
|
|
|
7921
7990
|
}
|
|
7922
7991
|
const hubCliArgs = await getProjectCliArgs(projectPath);
|
|
7923
7992
|
if (hubCliArgs.length > 0) {
|
|
7993
|
+
console.log("Unity Hub launch options:");
|
|
7994
|
+
for (const line of groupCliArgs(hubCliArgs)) {
|
|
7995
|
+
console.log(` ${line}`);
|
|
7996
|
+
}
|
|
7924
7997
|
args.push(...hubCliArgs);
|
|
7998
|
+
} else {
|
|
7999
|
+
console.log("Unity Hub launch options: none");
|
|
7925
8000
|
}
|
|
7926
8001
|
if (unityArgs.length > 0) {
|
|
7927
8002
|
args.push(...unityArgs);
|
|
7928
8003
|
}
|
|
7929
|
-
|
|
7930
|
-
|
|
7931
|
-
|
|
7932
|
-
|
|
7933
|
-
//
|
|
7934
|
-
|
|
7935
|
-
|
|
7936
|
-
|
|
8004
|
+
return new Promise((resolve5, reject) => {
|
|
8005
|
+
const child = (0, import_node_child_process.spawn)(unityPath, args, {
|
|
8006
|
+
stdio: "ignore",
|
|
8007
|
+
detached: true,
|
|
8008
|
+
// Git Bash (MSYS) がWindows パスをUnix 形式に自動変換するのを防ぐ
|
|
8009
|
+
env: {
|
|
8010
|
+
...process.env,
|
|
8011
|
+
MSYS_NO_PATHCONV: "1"
|
|
8012
|
+
}
|
|
8013
|
+
});
|
|
8014
|
+
const handleError = (error) => {
|
|
8015
|
+
child.removeListener("spawn", handleSpawn);
|
|
8016
|
+
reject(new Error(`Failed to launch Unity: ${error.message}`));
|
|
8017
|
+
};
|
|
8018
|
+
const handleSpawn = () => {
|
|
8019
|
+
child.removeListener("error", handleError);
|
|
8020
|
+
child.unref();
|
|
8021
|
+
resolve5();
|
|
8022
|
+
};
|
|
8023
|
+
child.once("error", handleError);
|
|
8024
|
+
child.once("spawn", handleSpawn);
|
|
7937
8025
|
});
|
|
7938
8026
|
}
|
|
7939
|
-
function
|
|
7940
|
-
if (
|
|
7941
|
-
|
|
8027
|
+
async function orchestrateLaunch(options) {
|
|
8028
|
+
if (options.quit && options.restart) {
|
|
8029
|
+
throw new Error("--quit and --restart cannot be used together.");
|
|
7942
8030
|
}
|
|
7943
|
-
|
|
7944
|
-
if (Number.isNaN(parsed)) {
|
|
7945
|
-
console.error(`Error: Invalid --max-depth value: "${value}". Must be an integer.`);
|
|
7946
|
-
process.exit(1);
|
|
7947
|
-
}
|
|
7948
|
-
return parsed;
|
|
7949
|
-
}
|
|
7950
|
-
async function runLaunchCommand(projectPath, options) {
|
|
7951
|
-
const maxDepth = parseMaxDepth(options.maxDepth);
|
|
7952
|
-
let resolvedProjectPath = projectPath ? (0, import_path6.resolve)(projectPath) : void 0;
|
|
8031
|
+
let resolvedProjectPath = options.projectPath;
|
|
7953
8032
|
if (!resolvedProjectPath) {
|
|
7954
|
-
const
|
|
7955
|
-
|
|
7956
|
-
|
|
7957
|
-
`No project-path provided. Searching under ${searchRoot} (max-depth: ${depthInfo})...`
|
|
7958
|
-
);
|
|
7959
|
-
const found = findUnityProjectBfs(searchRoot, maxDepth);
|
|
8033
|
+
const depthInfo = options.searchMaxDepth === -1 ? "unlimited" : String(options.searchMaxDepth);
|
|
8034
|
+
console.log(`Searching for Unity project under ${options.searchRoot} (max-depth: ${depthInfo})...`);
|
|
8035
|
+
const found = findUnityProjectBfs(options.searchRoot, options.searchMaxDepth);
|
|
7960
8036
|
if (!found) {
|
|
7961
|
-
|
|
7962
|
-
process.exit(1);
|
|
8037
|
+
throw new Error(`Unity project not found under ${options.searchRoot}.`);
|
|
7963
8038
|
}
|
|
7964
|
-
console.log(
|
|
8039
|
+
console.log();
|
|
7965
8040
|
resolvedProjectPath = found;
|
|
7966
8041
|
}
|
|
8042
|
+
if (!(0, import_node_fs2.existsSync)(resolvedProjectPath)) {
|
|
8043
|
+
throw new Error(`Project directory not found: ${resolvedProjectPath}`);
|
|
8044
|
+
}
|
|
7967
8045
|
const unityVersion = getUnityVersion(resolvedProjectPath);
|
|
7968
|
-
|
|
7969
|
-
if (unityHubOnlyMode) {
|
|
8046
|
+
if (options.addUnityHub || options.favoriteUnityHub) {
|
|
7970
8047
|
console.log(`Detected Unity version: ${unityVersion}`);
|
|
7971
8048
|
console.log(`Project Path: ${resolvedProjectPath}`);
|
|
7972
8049
|
const now2 = /* @__PURE__ */ new Date();
|
|
7973
|
-
await ensureProjectEntryAndUpdate(
|
|
7974
|
-
resolvedProjectPath,
|
|
7975
|
-
unityVersion,
|
|
7976
|
-
now2,
|
|
7977
|
-
options.favorite === true
|
|
7978
|
-
);
|
|
8050
|
+
await ensureProjectEntryAndUpdate(resolvedProjectPath, unityVersion, now2, options.favoriteUnityHub);
|
|
7979
8051
|
console.log("Unity Hub entry updated.");
|
|
7980
|
-
return;
|
|
8052
|
+
return { action: "hub-updated", projectPath: resolvedProjectPath, unityVersion };
|
|
7981
8053
|
}
|
|
7982
|
-
if (options.
|
|
8054
|
+
if (options.quit) {
|
|
8055
|
+
await quitRunningUnity(resolvedProjectPath);
|
|
8056
|
+
return { action: "quit", projectPath: resolvedProjectPath };
|
|
8057
|
+
}
|
|
8058
|
+
const isRestart = options.restart;
|
|
8059
|
+
if (isRestart) {
|
|
7983
8060
|
await killRunningUnity(resolvedProjectPath);
|
|
7984
8061
|
} else {
|
|
7985
8062
|
const runningProcess = await findRunningUnityProcess(resolvedProjectPath);
|
|
7986
8063
|
if (runningProcess) {
|
|
7987
|
-
console.log(
|
|
7988
|
-
`Unity process already running for project: ${resolvedProjectPath} (PID: ${runningProcess.pid})`
|
|
7989
|
-
);
|
|
8064
|
+
console.log(`Unity process already running for project: ${resolvedProjectPath} (PID: ${runningProcess.pid})`);
|
|
7990
8065
|
await focusUnityProcess(runningProcess.pid);
|
|
7991
|
-
return;
|
|
8066
|
+
return { action: "focused", projectPath: resolvedProjectPath, pid: runningProcess.pid };
|
|
7992
8067
|
}
|
|
7993
8068
|
}
|
|
7994
8069
|
await handleStaleLockfile(resolvedProjectPath);
|
|
7995
8070
|
const resolved = {
|
|
7996
8071
|
projectPath: resolvedProjectPath,
|
|
7997
8072
|
platform: options.platform,
|
|
7998
|
-
unityArgs:
|
|
8073
|
+
unityArgs: options.unityArgs,
|
|
7999
8074
|
unityVersion
|
|
8000
8075
|
};
|
|
8001
8076
|
await launch(resolved);
|
|
8002
8077
|
const now = /* @__PURE__ */ new Date();
|
|
8003
|
-
|
|
8078
|
+
try {
|
|
8079
|
+
await updateLastModifiedIfExists(resolvedProjectPath, now);
|
|
8080
|
+
} catch (error) {
|
|
8081
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
8082
|
+
console.warn(`Failed to update Unity Hub lastModified: ${message}`);
|
|
8083
|
+
}
|
|
8084
|
+
const action = isRestart ? "killed-and-launched" : "launched";
|
|
8085
|
+
return { action, projectPath: resolvedProjectPath, unityVersion };
|
|
8086
|
+
}
|
|
8087
|
+
|
|
8088
|
+
// src/commands/launch.ts
|
|
8089
|
+
function registerLaunchCommand(program3) {
|
|
8090
|
+
program3.command("launch").description(
|
|
8091
|
+
"Open a Unity project with the matching Editor version installed by Unity Hub.\nAuto-detects project path and Unity version from ProjectSettings/ProjectVersion.txt.\nRun 'uloop launch -h' for all options. Details: https://github.com/hatayama/LaunchUnityCommand"
|
|
8092
|
+
).argument("[project-path]", "Path to Unity project").option("-r, --restart", "Kill running Unity and restart").option("-q, --quit", "Gracefully quit running Unity").option("-p, --platform <platform>", "Build target (e.g., Android, iOS)").option("--max-depth <n>", "Search depth when project-path is omitted", "3").option("-a, --add-unity-hub", "Add to Unity Hub (does not launch)").option("-f, --favorite", "Add to Unity Hub as favorite (does not launch)").action(async (projectPath, options) => {
|
|
8093
|
+
await runLaunchCommand(projectPath, options);
|
|
8094
|
+
});
|
|
8095
|
+
}
|
|
8096
|
+
function parseMaxDepth(value) {
|
|
8097
|
+
if (value === void 0) {
|
|
8098
|
+
return 3;
|
|
8099
|
+
}
|
|
8100
|
+
const parsed = parseInt(value, 10);
|
|
8101
|
+
if (Number.isNaN(parsed)) {
|
|
8102
|
+
console.error(`Error: Invalid --max-depth value: "${value}". Must be an integer.`);
|
|
8103
|
+
process.exit(1);
|
|
8104
|
+
}
|
|
8105
|
+
return parsed;
|
|
8106
|
+
}
|
|
8107
|
+
async function runLaunchCommand(projectPath, options) {
|
|
8108
|
+
const maxDepth = parseMaxDepth(options.maxDepth);
|
|
8109
|
+
await orchestrateLaunch({
|
|
8110
|
+
projectPath: projectPath ? (0, import_path6.resolve)(projectPath) : void 0,
|
|
8111
|
+
searchRoot: process.cwd(),
|
|
8112
|
+
searchMaxDepth: maxDepth,
|
|
8113
|
+
platform: options.platform,
|
|
8114
|
+
unityArgs: [],
|
|
8115
|
+
restart: options.restart === true,
|
|
8116
|
+
quit: options.quit === true,
|
|
8117
|
+
addUnityHub: options.addUnityHub === true,
|
|
8118
|
+
favoriteUnityHub: options.favorite === true
|
|
8119
|
+
});
|
|
8004
8120
|
}
|
|
8005
8121
|
|
|
8006
8122
|
// src/commands/focus-window.ts
|