pinokiod 3.292.0 → 3.294.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/kernel/bin/xcode-tools.js +93 -89
- package/package.json +1 -1
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
const fs = require('fs')
|
|
2
|
-
const
|
|
2
|
+
const semver = require('semver')
|
|
3
3
|
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const CLT_PACKAGE_IDS = [
|
|
10
|
-
"com.apple.pkg.CLTools_Executables",
|
|
11
|
-
"com.apple.pkg.DeveloperToolsCLI"
|
|
4
|
+
const MIN_CLT_VERSION = '13.0'
|
|
5
|
+
const PACKAGE_MATCHERS = [
|
|
6
|
+
/^com\.apple\.pkg\.CLTools_/,
|
|
7
|
+
/^com\.apple\.pkg\.DeveloperToolsCLI$/,
|
|
8
|
+
/^com\.apple\.pkg\.Xcode$/
|
|
12
9
|
]
|
|
13
10
|
|
|
14
11
|
async function detectCommandLineTools({ exec }) {
|
|
@@ -18,121 +15,128 @@ async function detectCommandLineTools({ exec }) {
|
|
|
18
15
|
|
|
19
16
|
const run = (message) => exec({ message, conda: { skip: true } })
|
|
20
17
|
|
|
21
|
-
|
|
22
|
-
let pathResult
|
|
23
|
-
|
|
18
|
+
let selectResult
|
|
24
19
|
try {
|
|
25
|
-
|
|
20
|
+
selectResult = await run('xcode-select -p')
|
|
26
21
|
} catch (err) {
|
|
27
|
-
|
|
28
|
-
return
|
|
22
|
+
console.log('[CLT] xcode-select -p failed', err)
|
|
23
|
+
return { valid: false, reason: 'xcode-select -p failed' }
|
|
29
24
|
}
|
|
30
25
|
|
|
31
|
-
const developerPath =
|
|
26
|
+
const developerPath = (selectResult && selectResult.stdout ? selectResult.stdout : '')
|
|
27
|
+
.split(/\r?\n/)
|
|
28
|
+
.map((line) => line.trim())
|
|
29
|
+
.find((line) => line.startsWith('/'))
|
|
32
30
|
if (!developerPath) {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
31
|
+
return {
|
|
32
|
+
valid: false,
|
|
33
|
+
reason: 'unable to parse developer path from xcode-select output',
|
|
34
|
+
rawPathOutput: selectResult ? selectResult.stdout : ''
|
|
35
|
+
}
|
|
36
36
|
}
|
|
37
|
-
|
|
37
|
+
console.log('[CLT] developer path:', developerPath)
|
|
38
38
|
|
|
39
39
|
try {
|
|
40
40
|
const stat = await fs.promises.stat(developerPath)
|
|
41
41
|
if (!stat.isDirectory()) {
|
|
42
|
-
|
|
43
|
-
return status
|
|
42
|
+
return { valid: false, reason: `${developerPath} is not a directory` }
|
|
44
43
|
}
|
|
45
44
|
} catch (err) {
|
|
46
|
-
|
|
47
|
-
return
|
|
45
|
+
console.log('[CLT] stat failed for developer path:', err)
|
|
46
|
+
return { valid: false, reason: `developer path ${developerPath} is not accessible` }
|
|
48
47
|
}
|
|
49
48
|
|
|
49
|
+
let clangResult
|
|
50
50
|
try {
|
|
51
|
-
|
|
52
|
-
const binaryPath = path.join(developerPath, ...rel)
|
|
53
|
-
await fs.promises.access(binaryPath, fs.constants.X_OK)
|
|
54
|
-
}
|
|
51
|
+
clangResult = await run('xcrun --find clang')
|
|
55
52
|
} catch (err) {
|
|
56
|
-
|
|
57
|
-
return
|
|
53
|
+
console.log('[CLT] xcrun --find clang failed', err)
|
|
54
|
+
return { valid: false, reason: 'unable to locate clang via xcrun' }
|
|
58
55
|
}
|
|
59
56
|
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
57
|
+
const clangStdout = clangResult && clangResult.stdout ? clangResult.stdout : ''
|
|
58
|
+
const clangPath =
|
|
59
|
+
clangStdout
|
|
60
|
+
.split(/\r?\n/)
|
|
61
|
+
.map((line) => line.trim())
|
|
62
|
+
.filter(Boolean)
|
|
63
|
+
.reverse()
|
|
64
|
+
.find((line) => line.startsWith('/')) || null
|
|
65
|
+
if (!clangPath) {
|
|
66
|
+
console.log('[CLT] xcrun --find clang stdout did not include a path:', clangStdout)
|
|
67
|
+
return { valid: false, reason: 'unable to locate clang via xcrun' }
|
|
64
68
|
}
|
|
65
|
-
|
|
69
|
+
console.log('[CLT] clang path:', clangPath)
|
|
66
70
|
|
|
67
|
-
const
|
|
68
|
-
status.xcodeSelectVersion = selectInfo.version
|
|
69
|
-
if (!selectInfo.valid) {
|
|
70
|
-
status.reason = selectInfo.reason || 'xcode-select version below minimum'
|
|
71
|
-
return status
|
|
72
|
-
}
|
|
71
|
+
const status = { valid: true, path: developerPath, clangPath }
|
|
73
72
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
73
|
+
const pkgInfo = await readPkgInfo(run)
|
|
74
|
+
if (!pkgInfo) {
|
|
75
|
+
console.log('[CLT] pkg info not found for command line tools packages')
|
|
76
|
+
return { ...status, valid: false, reason: 'unable to determine command line tools version' }
|
|
77
|
+
}
|
|
77
78
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
}
|
|
88
|
-
} catch (err) {
|
|
89
|
-
// pkg not installed, try next id
|
|
79
|
+
Object.assign(status, { pkgId: pkgInfo.pkgId, pkgVersion: pkgInfo.version })
|
|
80
|
+
console.log('[CLT] pkg info:', pkgInfo)
|
|
81
|
+
const coercedVersion = pkgInfo.version && semver.coerce(pkgInfo.version)
|
|
82
|
+
const minRequirement = semver.coerce(MIN_CLT_VERSION)
|
|
83
|
+
if (!coercedVersion || !minRequirement || !semver.gte(coercedVersion, minRequirement)) {
|
|
84
|
+
return {
|
|
85
|
+
...status,
|
|
86
|
+
valid: false,
|
|
87
|
+
reason: `command line tools version ${pkgInfo.version} is below required ${MIN_CLT_VERSION}`
|
|
90
88
|
}
|
|
91
89
|
}
|
|
92
|
-
return null
|
|
93
|
-
}
|
|
94
90
|
|
|
95
|
-
async function readXcodeSelectVersion(exec) {
|
|
96
|
-
let result
|
|
97
91
|
try {
|
|
98
|
-
|
|
92
|
+
const versionResult = await run('xcode-select --version')
|
|
93
|
+
const versionStdout = versionResult && versionResult.stdout ? versionResult.stdout : ''
|
|
94
|
+
const match = /xcode-select\s+version\s+([^\s]+)/i.exec(versionStdout)
|
|
95
|
+
const version = (match && match[1] ? match[1] : '')
|
|
96
|
+
.replace(/[^0-9.]+/g, '')
|
|
97
|
+
.replace(/\.+$/, '') || null
|
|
98
|
+
status.xcodeSelectVersion = version
|
|
99
|
+
console.log('[CLT] xcode-select --version parsed:', version)
|
|
99
100
|
} catch (err) {
|
|
100
|
-
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
console.log('xcode-select --version', result)
|
|
104
|
-
|
|
105
|
-
const match = result && result.stdout && /xcode-select version\s+(\d+)/i.exec(result.stdout)
|
|
106
|
-
if (!match) {
|
|
107
|
-
return { valid: false, reason: 'unable to parse xcode-select version' }
|
|
101
|
+
console.log('[CLT] xcode-select --version failed', err)
|
|
108
102
|
}
|
|
109
103
|
|
|
110
|
-
|
|
111
|
-
return {
|
|
112
|
-
valid: numericVersion >= MIN_XCODESELECT_VERSION,
|
|
113
|
-
version: numericVersion
|
|
114
|
-
}
|
|
104
|
+
return status
|
|
115
105
|
}
|
|
116
106
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
107
|
+
async function readPkgInfo(run) {
|
|
108
|
+
let candidates = []
|
|
109
|
+
try {
|
|
110
|
+
const listResult = await run('pkgutil --pkgs')
|
|
111
|
+
const stdout = listResult && listResult.stdout ? listResult.stdout : ''
|
|
112
|
+
candidates = stdout
|
|
113
|
+
.split(/\r?\n/)
|
|
114
|
+
.map((line) => line.trim())
|
|
115
|
+
.filter((id) => PACKAGE_MATCHERS.some((matcher) => matcher.test(id)))
|
|
116
|
+
} catch (err) {
|
|
117
|
+
console.log('[CLT] pkgutil --pkgs failed', err)
|
|
118
|
+
}
|
|
121
119
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
return null
|
|
120
|
+
if (candidates.length === 0) {
|
|
121
|
+
candidates = ['com.apple.pkg.CLTools_Executables']
|
|
125
122
|
}
|
|
123
|
+
console.log('[CLT] pkg candidates:', candidates)
|
|
126
124
|
|
|
127
|
-
const
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
125
|
+
for (const pkgId of candidates) {
|
|
126
|
+
try {
|
|
127
|
+
const result = await run(`pkgutil --pkg-info=${pkgId}`)
|
|
128
|
+
const stdout = result && result.stdout ? result.stdout : ''
|
|
129
|
+
const match = /version:\s*([^\n]+)/i.exec(stdout)
|
|
130
|
+
if (match) {
|
|
131
|
+
return { pkgId, version: match[1].trim() }
|
|
132
|
+
}
|
|
133
|
+
} catch (err) {
|
|
134
|
+
console.log(`[CLT] pkgutil --pkg-info ${pkgId} failed`, err)
|
|
135
135
|
}
|
|
136
136
|
}
|
|
137
137
|
return null
|
|
138
138
|
}
|
|
139
|
+
|
|
140
|
+
module.exports = {
|
|
141
|
+
detectCommandLineTools
|
|
142
|
+
}
|