Skip to content

Commit b9f6226

Browse files
committed
fix: added fix for development snapshots
1 parent ecc6247 commit b9f6226

File tree

3 files changed

+186
-110
lines changed

3 files changed

+186
-110
lines changed

__tests__/installer/windows.test.ts

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,17 +59,37 @@ describe('windows toolchain installation verification', () => {
5959
expect(installer['visualStudio']).toStrictEqual(visualStudio)
6060
})
6161

62-
it('tests unpack', async () => {
62+
it('tests unpack for default toolchains', async () => {
6363
const installer = new WindowsToolchainInstaller(toolchain)
6464
const exe = path.resolve('tool', 'downloaded', 'toolchain.exe')
6565
const extracted = path.resolve('tool', 'extracted', 'path')
6666
process.env.SystemDrive = 'C:'
6767
jest.spyOn(toolCache, 'extractTar').mockResolvedValue(extracted)
6868
jest.spyOn(exec, 'exec').mockResolvedValue(0)
69+
jest.spyOn(fs, 'access').mockRejectedValueOnce(new Error())
70+
jest.spyOn(fs, 'access').mockResolvedValue()
71+
jest.spyOn(fs, 'cp').mockResolvedValue()
6972
const toolPath = path.join(process.env.SystemDrive, 'Library')
7073
await expect(installer['unpack'](exe)).resolves.toBe(toolPath)
7174
})
7275

76+
it('tests unpack for development snapshots', async () => {
77+
const installer = new WindowsToolchainInstaller(toolchain)
78+
const exe = path.resolve('tool', 'downloaded', 'toolchain.exe')
79+
const extracted = path.resolve('tool', 'extracted', 'path')
80+
process.env.SystemDrive = 'C:'
81+
jest.spyOn(toolCache, 'extractTar').mockResolvedValue(extracted)
82+
jest.spyOn(exec, 'exec').mockResolvedValue(0)
83+
jest.spyOn(fs, 'access').mockResolvedValue()
84+
jest.spyOn(fs, 'cp').mockResolvedValue()
85+
const toolPath = path.join(
86+
process.env.SystemDrive,
87+
'Program Files',
88+
'Swift'
89+
)
90+
await expect(installer['unpack'](exe)).resolves.toBe(toolPath)
91+
})
92+
7393
it('tests add to PATH', async () => {
7494
const installer = new WindowsToolchainInstaller(toolchain)
7595
installer['visualStudio'] = visualStudio

dist/index.js

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

src/installer/windows.ts

Lines changed: 92 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -48,90 +48,26 @@ export class WindowsToolchainInstaller extends VerifyingToolchainInstaller<Windo
4848
if (code !== 0) {
4949
throw new Error(`Swift installer failed with exit code: "${code}"`)
5050
}
51-
const installation = path.join(process.env.SystemDrive ?? 'C:', 'Library')
52-
const toolchain = path.join(
53-
installation,
54-
'Developer',
55-
'Toolchains',
56-
'unknown-Asserts-development.xctoolchain'
57-
)
58-
const sdkroot = path.join(
59-
installation,
60-
'Developer',
61-
'Platforms',
62-
'Windows.platform',
63-
'Developer',
64-
'SDKs',
65-
'Windows.sdk'
66-
)
67-
const runtime = path.join(
68-
process.env.SystemDrive ?? 'C:',
69-
'Program Files',
70-
'swift'
71-
)
72-
core.debug(`Toolchain installed at "${toolchain}"`)
73-
core.debug(`SDK installed at "${sdkroot}"`)
74-
try {
75-
await fs.access(runtime)
76-
await fs.cp(runtime, path.join(installation, 'swift'), {recursive: true})
77-
core.debug(`Runtime installed at "${runtime}"`)
78-
} catch (error) {
79-
core.debug('No Swift runtime installed')
80-
}
81-
return installation
51+
const installation = await Installation.detect()
52+
return installation.location
8253
}
8354

84-
protected async add(installation: string) {
85-
const toolchain = path.join(
86-
installation,
87-
'Developer',
88-
'Toolchains',
89-
'unknown-Asserts-development.xctoolchain'
90-
)
91-
const sdkroot = path.join(
92-
installation,
93-
'Developer',
94-
'Platforms',
95-
'Windows.platform',
96-
'Developer',
97-
'SDKs',
98-
'Windows.sdk'
99-
)
100-
core.debug(`Adding toolchain "${toolchain}" to path`)
101-
const swiftPath = path.join(toolchain, 'usr', 'bin')
102-
core.exportVariable('SDKROOT', sdkroot)
103-
const swiftDev = path.join(installation, 'Swift-development', 'bin')
104-
const icu67 = path.join(installation, 'icu-67', 'usr', 'bin')
105-
const runtime = path.join(
106-
installation,
107-
'swift',
108-
'runtime-development',
109-
'usr',
110-
'bin'
111-
)
112-
const requirePaths = [swiftPath, swiftDev, icu67]
113-
try {
114-
await fs.access(runtime)
115-
requirePaths.push(runtime)
116-
} catch (error) {
117-
core.debug('No Swift runtime found, skipping runtime path')
55+
protected async add(installLocation: string) {
56+
const installation = await Installation.get(installLocation)
57+
core.exportVariable('SDKROOT', installation.sdkroot)
58+
if (installation.devdir) {
59+
core.exportVariable('DEVELOPER_DIR', installation.devdir)
11860
}
61+
const swiftPath = path.join(installation.toolchain, 'usr', 'bin')
62+
const swiftDev = path.join(installLocation, 'Swift-development', 'bin')
63+
const icu67 = path.join(installLocation, 'icu-67', 'usr', 'bin')
64+
const runtimePath = path.join(installation.runtime, 'usr', 'bin')
65+
const requirePaths = [swiftPath, swiftDev, icu67, runtimePath]
11966

12067
for (const envPath of requirePaths) {
12168
core.debug(`Adding "${envPath}" to PATH`)
12269
core.addPath(envPath)
12370
}
124-
const pwshScript = `
125-
foreach ($level in "Machine", "User") {
126-
[Environment]::GetEnvironmentVariables($level).GetEnumerator() | % {
127-
# For Path variables, append the new values, if they're not already in there
128-
if ($_.Name -Match 'Path$') {
129-
Write-Output "Env:$($_.Name), value$($_.Value)"
130-
}
131-
}
132-
}
133-
`
134-
await exec ('pwsh', ['--command', pwshScript])
13571
core.debug(`Swift installed at "${swiftPath}"`)
13672
if (!this.visualStudio) {
13773
throw new Error('No supported Visual Studio installation in installer')
@@ -143,3 +79,83 @@ export class WindowsToolchainInstaller extends VerifyingToolchainInstaller<Windo
14379
core.exportVariable('SWIFTFLAGS', swiftFlags)
14480
}
14581
}
82+
83+
class Installation {
84+
readonly location: string
85+
readonly toolchain: string
86+
readonly sdkroot: string
87+
readonly runtime: string
88+
readonly devdir?: string
89+
90+
private constructor(
91+
location: string,
92+
toolchain: string,
93+
sdkroot: string,
94+
runtime: string,
95+
devdir?: string
96+
) {
97+
this.location = location
98+
this.toolchain = toolchain
99+
this.sdkroot = sdkroot
100+
this.runtime = runtime
101+
this.devdir = devdir
102+
}
103+
104+
static async get(location: string, fallback?: string) {
105+
let toolchain: string
106+
let sdkroot: string
107+
let runtime: string
108+
let devdir: string | undefined
109+
110+
try {
111+
core.debug(`Checking for development snapshot installation`)
112+
toolchain = path.join(location, 'Toolchains', '0.0.0+Asserts')
113+
sdkroot = path.join(location, 'Toolchains', '0.0.0+Asserts')
114+
runtime = path.join(location, 'Runtimes', '0.0.0')
115+
await fs.access(toolchain)
116+
} catch (error) {
117+
core.debug(`Switching to default installation due to "${error}"`)
118+
if (fallback) {
119+
location = fallback
120+
}
121+
devdir = path.join(location, 'Developer')
122+
toolchain = path.join(
123+
devdir,
124+
'Toolchains',
125+
'unknown-Asserts-development.xctoolchain'
126+
)
127+
sdkroot = path.join(
128+
devdir,
129+
'Platforms',
130+
'Windows.platform',
131+
'Developer',
132+
'SDKs',
133+
'Windows.sdk'
134+
)
135+
runtime = path.join(location, 'Swift', 'runtime-development')
136+
}
137+
return new Installation(location, toolchain, sdkroot, runtime, devdir)
138+
}
139+
140+
static async detect() {
141+
const systemDrive = process.env.SystemDrive ?? 'C:'
142+
const defaultPath = path.join(systemDrive, 'Library')
143+
const devPath = path.join(systemDrive, 'Program Files', 'Swift')
144+
const installation = await Installation.get(devPath, defaultPath)
145+
if (path.relative(devPath, installation.location)) {
146+
const runtimeRoot = path.join(installation.location, 'Swift')
147+
try {
148+
await fs.access(devPath)
149+
await fs.cp(devPath, runtimeRoot, {recursive: true})
150+
} catch (error) {
151+
core.debug(`Runtime check failed with "${error}"`)
152+
}
153+
}
154+
core.debug(`Installation location at "${installation.location}"`)
155+
core.debug(`Toolchain installed at "${installation.toolchain}"`)
156+
core.debug(`SDK installed at "${installation.sdkroot}"`)
157+
core.debug(`Runtime installed at "${installation.runtime}"`)
158+
core.debug(`Development directory at "${installation.devdir}"`)
159+
return installation
160+
}
161+
}

0 commit comments

Comments
 (0)