launch-unity 0.3.0 → 0.5.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/launch.js CHANGED
@@ -8,6 +8,7 @@ import { existsSync, readFileSync, readdirSync, lstatSync, realpathSync } from "
8
8
  import { rm } from "node:fs/promises";
9
9
  import { join, resolve } from "node:path";
10
10
  import { promisify } from "node:util";
11
+ import { updateLastModifiedIfExists } from "./unityHub.js";
11
12
  const execFileAsync = promisify(execFile);
12
13
  const UNITY_EXECUTABLE_PATTERN_MAC = /Unity\.app\/Contents\/MacOS\/Unity/i;
13
14
  const UNITY_EXECUTABLE_PATTERN_WINDOWS = /Unity\.exe/i;
@@ -195,6 +196,13 @@ function extractProjectPath(command) {
195
196
  }
196
197
  return trimmed;
197
198
  }
199
+ const isUnityAuxiliaryProcess = (command) => {
200
+ const normalizedCommand = command.toLowerCase();
201
+ if (normalizedCommand.includes("-batchmode")) {
202
+ return true;
203
+ }
204
+ return normalizedCommand.includes("assetimportworker");
205
+ };
198
206
  async function listUnityProcessesMac() {
199
207
  let stdout = "";
200
208
  try {
@@ -224,6 +232,9 @@ async function listUnityProcessesMac() {
224
232
  if (!UNITY_EXECUTABLE_PATTERN_MAC.test(command)) {
225
233
  continue;
226
234
  }
235
+ if (isUnityAuxiliaryProcess(command)) {
236
+ continue;
237
+ }
227
238
  const projectArgument = extractProjectPath(command);
228
239
  if (!projectArgument) {
229
240
  continue;
@@ -273,6 +284,9 @@ async function listUnityProcessesWindows() {
273
284
  if (!UNITY_EXECUTABLE_PATTERN_WINDOWS.test(command)) {
274
285
  continue;
275
286
  }
287
+ if (isUnityAuxiliaryProcess(command)) {
288
+ continue;
289
+ }
276
290
  const projectArgument = extractProjectPath(command);
277
291
  if (!projectArgument) {
278
292
  continue;
@@ -526,6 +540,14 @@ async function main() {
526
540
  unityArgs: options.unityArgs,
527
541
  };
528
542
  launch(resolved);
543
+ // Best-effort update of Unity Hub's lastModified timestamp.
544
+ try {
545
+ await updateLastModifiedIfExists(resolvedProjectPath, new Date());
546
+ }
547
+ catch (error) {
548
+ const message = error instanceof Error ? error.message : String(error);
549
+ console.warn(`Failed to update Unity Hub lastModified: ${message}`);
550
+ }
529
551
  }
530
552
  main().catch((error) => {
531
553
  console.error(error);
@@ -0,0 +1,90 @@
1
+ import { readFile, writeFile } from "node:fs/promises";
2
+ import { join, resolve } from "node:path";
3
+ const resolveUnityHubProjectFiles = () => {
4
+ if (process.platform === "darwin") {
5
+ const home = process.env.HOME;
6
+ if (!home) {
7
+ return [];
8
+ }
9
+ const base = join(home, "Library", "Application Support", "UnityHub");
10
+ return [join(base, "projects-v1.json"), join(base, "projects.json")];
11
+ }
12
+ if (process.platform === "win32") {
13
+ const appData = process.env.APPDATA;
14
+ if (!appData) {
15
+ return [];
16
+ }
17
+ const base = join(appData, "UnityHub");
18
+ return [join(base, "projects-v1.json"), join(base, "projects.json")];
19
+ }
20
+ return [];
21
+ };
22
+ const removeTrailingSeparators = (target) => {
23
+ let trimmed = target;
24
+ while (trimmed.length > 1 && (trimmed.endsWith("/") || trimmed.endsWith("\\"))) {
25
+ trimmed = trimmed.slice(0, -1);
26
+ }
27
+ return trimmed;
28
+ };
29
+ const normalizePath = (target) => {
30
+ const resolvedPath = resolve(target);
31
+ return removeTrailingSeparators(resolvedPath);
32
+ };
33
+ const toComparablePath = (value) => {
34
+ return value.replace(/\\/g, "/").toLocaleLowerCase();
35
+ };
36
+ const pathsEqual = (left, right) => {
37
+ return toComparablePath(normalizePath(left)) === toComparablePath(normalizePath(right));
38
+ };
39
+ export const updateLastModifiedIfExists = async (projectPath, when) => {
40
+ const candidates = resolveUnityHubProjectFiles();
41
+ if (candidates.length === 0) {
42
+ return;
43
+ }
44
+ // Try primary then fallback only if read/parse fails
45
+ for (const path of candidates) {
46
+ let content;
47
+ let json;
48
+ try {
49
+ content = await readFile(path, "utf8");
50
+ }
51
+ catch {
52
+ // Try next candidate on read error
53
+ continue;
54
+ }
55
+ try {
56
+ json = JSON.parse(content);
57
+ }
58
+ catch {
59
+ // Try next candidate on parse error
60
+ continue;
61
+ }
62
+ if (!json.data) {
63
+ // If file is readable but has no data, do not attempt fallback
64
+ return;
65
+ }
66
+ const projectKey = Object.keys(json.data).find((key) => {
67
+ const entryPath = json.data?.[key]?.path;
68
+ return entryPath ? pathsEqual(entryPath, projectPath) : false;
69
+ });
70
+ if (!projectKey) {
71
+ // Project not registered in Hub; do nothing
72
+ return;
73
+ }
74
+ const original = json.data[projectKey];
75
+ if (!original) {
76
+ return;
77
+ }
78
+ json.data[projectKey] = {
79
+ ...original,
80
+ lastModified: when.getTime(),
81
+ };
82
+ try {
83
+ await writeFile(path, JSON.stringify(json, undefined, 2), "utf8");
84
+ }
85
+ catch {
86
+ // Swallow write errors per requirement to not crash CLI
87
+ }
88
+ return;
89
+ }
90
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "launch-unity",
3
- "version": "0.3.0",
3
+ "version": "0.5.0",
4
4
  "description": "Open a Unity project with the matching Editor version (macOS/Windows)",
5
5
  "type": "module",
6
6
  "main": "dist/launch.js",