Skip to content

Commit f2d46ea

Browse files
Peter Wangmeta-codesync[bot]
authored andcommitted
check Mse cli version for the mini version -v14 stop glxf export if lower than the mini version
Summary: - Add MSE version check before GLXF generation that stops if version is outdated Reviewed By: felixtrz Differential Revision: D95651564 fbshipit-source-id: 9e17e39320a54e85a260fa192cc1d34b35aeb947
1 parent fffef0b commit f2d46ea

3 files changed

Lines changed: 171 additions & 81 deletions

File tree

packages/vite-plugin-metaspatial/src/generate-glxf/index.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import fs from 'fs-extra';
1111
import type { Plugin, ViteDevServer } from 'vite';
1212
import { resolveMetaSpatialCliPath } from './cli-path-resolver.js';
1313
import { regenerateGLXF, createFileWatcher, cleanup } from './file-watcher.js';
14+
import { verifyMSEVersion } from './mse-version-check.js';
1415
import type { GLXFGenerationOptions, ProcessedGLXFOptions } from './types.js';
1516

1617
// Export types
@@ -54,6 +55,9 @@ async function generateInitialGLXF(
5455

5556
console.log('🚀 Generating initial GLXF files for dev server...');
5657

58+
// Check MSE version — throws if outdated
59+
verifyMSEVersion();
60+
5761
try {
5862
// Find all .metaspatial files
5963
if (await fs.pathExists(watchDir)) {
@@ -103,6 +107,9 @@ async function generateBuildGLXF(
103107
console.log('🚀 Starting GLXF generation build phase...');
104108
}
105109

110+
// Check MSE version — throws if outdated
111+
verifyMSEVersion();
112+
106113
try {
107114
const metaSpatialDir = path.resolve(
108115
process.cwd(),
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
import { execSync } from 'child_process';
9+
import * as path from 'path';
10+
import fs from 'fs-extra';
11+
import { getHighestVersion } from './cli-path-resolver.js';
12+
13+
type Platform = 'darwin' | 'win32' | 'linux';
14+
15+
const MSE_MIN_VERSION = '14.0.0';
16+
17+
const MSE_DOWNLOAD_URLS = {
18+
darwin:
19+
'https://developers.meta.com/horizon/downloads/package/meta-spatial-editor-for-mac',
20+
win32:
21+
'https://developers.meta.com/horizon/downloads/package/meta-spatial-editor-for-windows',
22+
linux:
23+
'https://developers.meta.com/horizon/downloads/package/meta-spatial-editor-for-linux',
24+
default: 'https://developers.meta.com/horizon/downloads/spatial-sdk/',
25+
} as const;
26+
27+
const MSE_INSTALL_PATHS = {
28+
darwin: '/Applications/Meta Spatial Editor.app',
29+
win32: 'C:\\Program Files\\Meta Spatial Editor',
30+
linux: `${process.env.HOME}/.local/lib/meta-spatial-editor-cli`,
31+
} as const;
32+
33+
const MSE_LINUX_CLI_NAME = 'MetaSpatialEditorCLI';
34+
35+
function detectPlatform(): Platform {
36+
const p = process.platform;
37+
return p === 'darwin' || p === 'win32' ? p : 'linux';
38+
}
39+
40+
function getDownloadUrl(platform?: Platform): string {
41+
const p = platform || detectPlatform();
42+
return MSE_DOWNLOAD_URLS[p] || MSE_DOWNLOAD_URLS.default;
43+
}
44+
45+
/** Normalize version to major.minor.patch */
46+
function normalizeVersion(v: string): string {
47+
const parts = v.split('.');
48+
while (parts.length < 3) parts.push('0');
49+
return parts.slice(0, 3).join('.');
50+
}
51+
52+
/** Compare two semver-like version strings. Returns true if installed >= required. */
53+
function isVersionSufficient(installed: string, required: string): boolean {
54+
const iParts = normalizeVersion(installed).split('.').map(Number);
55+
const rParts = normalizeVersion(required).split('.').map(Number);
56+
for (let i = 0; i < 3; i++) {
57+
if (iParts[i] > rParts[i]) return true;
58+
if (iParts[i] < rParts[i]) return false;
59+
}
60+
return true; // equal
61+
}
62+
63+
function getMacOSAppVersion(appPath: string): string | null {
64+
const plistPath = path.join(appPath, 'Contents', 'Info.plist');
65+
try {
66+
const output = execSync(
67+
`plutil -extract CFBundleShortVersionString raw "${plistPath}"`,
68+
{ encoding: 'utf-8', timeout: 5000 },
69+
);
70+
return output.trim();
71+
} catch {
72+
return null;
73+
}
74+
}
75+
76+
function getWindowsAppVersion(basePath: string): string | null {
77+
const highestVersion = getHighestVersion(basePath);
78+
if (!highestVersion) return null;
79+
const vNum = parseInt(highestVersion.substring(1), 10);
80+
return `${vNum}.0.0`;
81+
}
82+
83+
function parseVersionFromOutput(output: string): string | null {
84+
const match = output.match(/v?(\d+\.\d+\.\d+)/);
85+
return match ? match[1] : null;
86+
}
87+
88+
function detectMSEVersion(platform: Platform): string | null {
89+
if (platform === 'linux') {
90+
const cliPath = path.join(MSE_INSTALL_PATHS.linux, MSE_LINUX_CLI_NAME);
91+
92+
if (fs.existsSync(cliPath)) {
93+
try {
94+
const output = execSync(`"${cliPath}" --version`, {
95+
encoding: 'utf-8',
96+
timeout: 5000,
97+
});
98+
return parseVersionFromOutput(output);
99+
} catch {
100+
return null;
101+
}
102+
}
103+
104+
try {
105+
const output = execSync('MetaSpatialEditorCLI --version', {
106+
encoding: 'utf-8',
107+
timeout: 5000,
108+
});
109+
return parseVersionFromOutput(output);
110+
} catch {
111+
return null;
112+
}
113+
}
114+
115+
const installPath = MSE_INSTALL_PATHS[platform];
116+
if (!installPath || !fs.existsSync(installPath)) return null;
117+
118+
return platform === 'darwin'
119+
? getMacOSAppVersion(installPath)
120+
: getWindowsAppVersion(installPath);
121+
}
122+
123+
/**
124+
* Verify MSE version before GLXF generation.
125+
* Throws if the installed version is below MSE_MIN_VERSION.
126+
*/
127+
export function verifyMSEVersion(): void {
128+
const platform = detectPlatform();
129+
const downloadUrl = getDownloadUrl(platform);
130+
const version = detectMSEVersion(platform);
131+
132+
if (version === null) {
133+
// Can't detect version -- skip check silently (CLI path validation will catch missing installs)
134+
return;
135+
}
136+
137+
if (!isVersionSufficient(version, MSE_MIN_VERSION)) {
138+
throw new Error(
139+
[
140+
'',
141+
`❌ Meta Spatial Editor version ${version} is outdated.`,
142+
` Minimum required version: ${MSE_MIN_VERSION}`,
143+
'',
144+
' GLXF generation cannot proceed with an outdated version.',
145+
'',
146+
'📥 Please update Meta Spatial Editor:',
147+
` ${downloadUrl}`,
148+
'',
149+
].join('\n'),
150+
);
151+
}
152+
153+
console.log(
154+
`✅ Meta Spatial Editor version ${version} (minimum: ${MSE_MIN_VERSION})`,
155+
);
156+
}

pnpm-lock.yaml

Lines changed: 8 additions & 81 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)