Skip to content

Commit 8693612

Browse files
committed
fix(stem): 修复 mac 运行时绝对软链接
1 parent 703d6cf commit 8693612

4 files changed

Lines changed: 97 additions & 6 deletions

File tree

‎scripts/lib/demucs-runtime-portability.mjs‎

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,68 @@ const inspectDarwinBinaryDependencies = ({ binaryPath }) => {
111111
}
112112
}
113113

114+
const inspectDarwinRuntimeSymlinks = ({ runtimeDir }) => {
115+
const issues = []
116+
const visitDir = (currentDir) => {
117+
const entries = fs.readdirSync(currentDir, { withFileTypes: true })
118+
for (const entry of entries) {
119+
const entryPath = path.join(currentDir, entry.name)
120+
const relativePath = path.relative(runtimeDir, entryPath).replace(/\\/g, '/')
121+
const stat = fs.lstatSync(entryPath)
122+
if (stat.isSymbolicLink()) {
123+
let rawTarget = ''
124+
try {
125+
rawTarget = fs.readlinkSync(entryPath)
126+
} catch (error) {
127+
issues.push(
128+
`${relativePath} -> <unreadable> (${toErrorText(
129+
error instanceof Error ? error.message : String(error || 'unknown')
130+
)})`
131+
)
132+
continue
133+
}
134+
const normalizedTarget = String(rawTarget || '').trim()
135+
if (!normalizedTarget) {
136+
issues.push(`${relativePath} -> <empty>`)
137+
continue
138+
}
139+
if (path.isAbsolute(normalizedTarget)) {
140+
issues.push(`${relativePath} -> ${normalizedTarget} (absolute symlink)`)
141+
continue
142+
}
143+
const resolvedTarget = path.resolve(path.dirname(entryPath), normalizedTarget)
144+
if (!isPathInside(runtimeDir, resolvedTarget)) {
145+
issues.push(`${relativePath} -> ${normalizedTarget} (escapes runtime root)`)
146+
continue
147+
}
148+
if (!fs.existsSync(resolvedTarget)) {
149+
issues.push(`${relativePath} -> ${normalizedTarget} (missing target)`)
150+
}
151+
continue
152+
}
153+
if (stat.isDirectory()) {
154+
visitDir(entryPath)
155+
}
156+
}
157+
}
158+
159+
try {
160+
visitDir(runtimeDir)
161+
} catch (error) {
162+
return {
163+
ok: false,
164+
issues: [],
165+
error: toErrorText(error instanceof Error ? error.message : String(error || 'unknown'))
166+
}
167+
}
168+
169+
return {
170+
ok: issues.length === 0,
171+
issues,
172+
error: ''
173+
}
174+
}
175+
114176
const isAllowedDarwinDependency = (runtimeDir, dependencyPath) => {
115177
const normalizedDependency = String(dependencyPath || '').trim()
116178
if (!normalizedDependency) return true
@@ -204,6 +266,21 @@ export const validatePortableDarwinRuntime = ({ runtimeDir, pythonPath, env }) =
204266
}
205267
}
206268

269+
const symlinkCheck = inspectDarwinRuntimeSymlinks({
270+
runtimeDir
271+
})
272+
if (!symlinkCheck.ok) {
273+
const symlinkIssue = symlinkCheck.issues.slice(0, 5).join(' | ')
274+
return {
275+
ok: false,
276+
payload: {
277+
...identity.payload,
278+
dependencies: dependencyCheck.dependencies
279+
},
280+
error: symlinkCheck.error || `runtime symlink issues: ${symlinkIssue}`
281+
}
282+
}
283+
207284
return {
208285
ok: true,
209286
payload: {

‎scripts/lib/demucs-runtime-support.mjs‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ let runtimeDownloadProxyInitialized = false
99
let runtimeDownloadProxyDispatcher
1010
let runtimeDownloadProxySource = ''
1111

12+
const buildPortableRuntimeCopyOptions = () => ({
13+
recursive: true,
14+
force: true,
15+
...(process.platform === 'darwin' ? { verbatimSymlinks: true } : {})
16+
})
17+
1218
const formatErrorWithCause = (error, toShortText) => {
1319
const parts = []
1420
let current = error
@@ -556,7 +562,7 @@ const installRuntimeProfileFromAsset = async ({
556562
throw error
557563
}
558564
fs.rmSync(runtimeDir, { recursive: true, force: true })
559-
fs.cpSync(extractedRuntimeDir, runtimeDir, { recursive: true, force: true })
565+
fs.cpSync(extractedRuntimeDir, runtimeDir, buildPortableRuntimeCopyOptions())
560566
fs.rmSync(extractedRuntimeDir, { recursive: true, force: true })
561567
}
562568
writeRemoteAssetState(runtimeDir, entry)

‎scripts/lib/demucs-standalone-python.mjs‎

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@ const DARWIN_TARGET_TRIPLE_BY_PLATFORM = {
1616
'darwin-x64': 'x86_64-apple-darwin'
1717
}
1818

19+
const buildPortableRuntimeCopyOptions = () => ({
20+
recursive: true,
21+
force: true,
22+
verbatimSymlinks: true
23+
})
24+
1925
const resolveStandaloneArchiveSpec = (platformKey) => {
2026
const targetTriple = DARWIN_TARGET_TRIPLE_BY_PLATFORM[platformKey]
2127
if (!targetTriple) {
@@ -115,10 +121,7 @@ export const bootstrapPortableDarwinPython = async ({
115121
throw error
116122
}
117123
await fs.promises.rm(targetRuntimeDir, { recursive: true, force: true }).catch(() => {})
118-
fs.cpSync(extractedRuntimeDir, targetRuntimeDir, {
119-
recursive: true,
120-
force: true
121-
})
124+
fs.cpSync(extractedRuntimeDir, targetRuntimeDir, buildPortableRuntimeCopyOptions())
122125
await fs.promises.rm(extractedRuntimeDir, { recursive: true, force: true }).catch(() => {})
123126
} finally {
124127
await fs.promises.rm(extractRoot, { recursive: true, force: true }).catch(() => {})

‎scripts/prepare-demucs-runtimes.mjs‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,11 @@ const writeJson = (filePath, data) => {
397397
fs.writeFileSync(filePath, `${JSON.stringify(data, null, 2)}\n`, 'utf8')
398398
}
399399

400+
const buildPortableRuntimeCopyOptions = () => ({
401+
recursive: true,
402+
...(process.platform === 'darwin' ? { verbatimSymlinks: true } : {})
403+
})
404+
400405
for (const [profileName, profileConfig] of selectedProfiles) {
401406
const targetDirName = String(profileConfig.targetDir || `runtime-${profileName}`)
402407
const targetRuntimeDir = path.resolve(runtimeRoot, platformArg, targetDirName)
@@ -435,7 +440,7 @@ for (const [profileName, profileConfig] of selectedProfiles) {
435440
}
436441

437442
if (!fs.existsSync(targetRuntimeDir)) {
438-
fs.cpSync(baseRuntimeDir, targetRuntimeDir, { recursive: true })
443+
fs.cpSync(baseRuntimeDir, targetRuntimeDir, buildPortableRuntimeCopyOptions())
439444
console.log(`[demucs-runtime] Copied base runtime -> ${targetDirName}`)
440445
}
441446

0 commit comments

Comments
 (0)