Skip to content

Commit

Permalink
fix: added fix for development snapshots
Browse files Browse the repository at this point in the history
  • Loading branch information
soumyamahunt committed Aug 30, 2023
1 parent ecc6247 commit 0a8cd3e
Show file tree
Hide file tree
Showing 3 changed files with 190 additions and 110 deletions.
22 changes: 21 additions & 1 deletion __tests__/installer/windows.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,17 +59,37 @@ describe('windows toolchain installation verification', () => {
expect(installer['visualStudio']).toStrictEqual(visualStudio)
})

it('tests unpack', async () => {
it('tests unpack for default toolchains', async () => {
const installer = new WindowsToolchainInstaller(toolchain)
const exe = path.resolve('tool', 'downloaded', 'toolchain.exe')
const extracted = path.resolve('tool', 'extracted', 'path')
process.env.SystemDrive = 'C:'
jest.spyOn(toolCache, 'extractTar').mockResolvedValue(extracted)
jest.spyOn(exec, 'exec').mockResolvedValue(0)
jest.spyOn(fs, 'access').mockRejectedValueOnce(new Error())
jest.spyOn(fs, 'access').mockResolvedValue()
jest.spyOn(fs, 'cp').mockResolvedValue()
const toolPath = path.join(process.env.SystemDrive, 'Library')
await expect(installer['unpack'](exe)).resolves.toBe(toolPath)
})

it('tests unpack for development snapshots', async () => {
const installer = new WindowsToolchainInstaller(toolchain)
const exe = path.resolve('tool', 'downloaded', 'toolchain.exe')
const extracted = path.resolve('tool', 'extracted', 'path')
process.env.SystemDrive = 'C:'
jest.spyOn(toolCache, 'extractTar').mockResolvedValue(extracted)
jest.spyOn(exec, 'exec').mockResolvedValue(0)
jest.spyOn(fs, 'access').mockResolvedValue()
jest.spyOn(fs, 'cp').mockResolvedValue()
const toolPath = path.join(
process.env.SystemDrive,
'Program Files',
'Swift'
)
await expect(installer['unpack'](exe)).resolves.toBe(toolPath)
})

it('tests add to PATH', async () => {
const installer = new WindowsToolchainInstaller(toolchain)
installer['visualStudio'] = visualStudio
Expand Down
108 changes: 75 additions & 33 deletions dist/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

170 changes: 94 additions & 76 deletions src/installer/windows.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,90 +48,28 @@ export class WindowsToolchainInstaller extends VerifyingToolchainInstaller<Windo
if (code !== 0) {
throw new Error(`Swift installer failed with exit code: "${code}"`)
}
const installation = path.join(process.env.SystemDrive ?? 'C:', 'Library')
const toolchain = path.join(
installation,
'Developer',
'Toolchains',
'unknown-Asserts-development.xctoolchain'
)
const sdkroot = path.join(
installation,
'Developer',
'Platforms',
'Windows.platform',
'Developer',
'SDKs',
'Windows.sdk'
)
const runtime = path.join(
process.env.SystemDrive ?? 'C:',
'Program Files',
'swift'
)
core.debug(`Toolchain installed at "${toolchain}"`)
core.debug(`SDK installed at "${sdkroot}"`)
try {
await fs.access(runtime)
await fs.cp(runtime, path.join(installation, 'swift'), {recursive: true})
core.debug(`Runtime installed at "${runtime}"`)
} catch (error) {
core.debug('No Swift runtime installed')
}
return installation
const installation = await Installation.detect()
return installation.location
}

protected async add(installation: string) {
const toolchain = path.join(
installation,
'Developer',
'Toolchains',
'unknown-Asserts-development.xctoolchain'
)
const sdkroot = path.join(
installation,
'Developer',
'Platforms',
'Windows.platform',
'Developer',
'SDKs',
'Windows.sdk'
)
core.debug(`Adding toolchain "${toolchain}" to path`)
const swiftPath = path.join(toolchain, 'usr', 'bin')
core.exportVariable('SDKROOT', sdkroot)
const swiftDev = path.join(installation, 'Swift-development', 'bin')
const icu67 = path.join(installation, 'icu-67', 'usr', 'bin')
const runtime = path.join(
installation,
'swift',
'runtime-development',
'usr',
'bin'
)
const requirePaths = [swiftPath, swiftDev, icu67]
try {
await fs.access(runtime)
requirePaths.push(runtime)
} catch (error) {
core.debug('No Swift runtime found, skipping runtime path')
protected async add(installLocation: string) {
const installation = await Installation.get(installLocation)
core.exportVariable('SDKROOT', installation.sdkroot)
if (installation.devdir) {
core.exportVariable('DEVELOPER_DIR', installation.devdir)
}
const location = installation.location
const swiftPath = path.join(installation.toolchain, 'usr', 'bin')
const swiftDev = path.join(location, 'Swift-development', 'bin')
const icu67 = path.join(location, 'icu-67', 'usr', 'bin')
const tools = path.join(location, 'Tools')
const runtimePath = path.join(installation.runtime, 'usr', 'bin')
const requirePaths = [swiftPath, swiftDev, icu67, tools, runtimePath]

for (const envPath of requirePaths) {
core.debug(`Adding "${envPath}" to PATH`)
core.addPath(envPath)
}
const pwshScript = `
foreach ($level in "Machine", "User") {
[Environment]::GetEnvironmentVariables($level).GetEnumerator() | % {
# For Path variables, append the new values, if they're not already in there
if ($_.Name -Match 'Path$') {
Write-Output "Env:$($_.Name), value$($_.Value)"
}
}
}
`
await exec ('pwsh', ['--command', pwshScript])
core.debug(`Swift installed at "${swiftPath}"`)
if (!this.visualStudio) {
throw new Error('No supported Visual Studio installation in installer')
Expand All @@ -143,3 +81,83 @@ export class WindowsToolchainInstaller extends VerifyingToolchainInstaller<Windo
core.exportVariable('SWIFTFLAGS', swiftFlags)
}
}

class Installation {
readonly location: string
readonly toolchain: string
readonly sdkroot: string
readonly runtime: string
readonly devdir?: string

private constructor(
location: string,
toolchain: string,
sdkroot: string,
runtime: string,
devdir?: string
) {
this.location = location
this.toolchain = toolchain
this.sdkroot = sdkroot
this.runtime = runtime
this.devdir = devdir
}

static async get(location: string, fallback?: string) {
let toolchain: string
let sdkroot: string
let runtime: string
let devdir: string | undefined

try {
core.debug(`Checking for development snapshot installation`)
toolchain = path.join(location, 'Toolchains', '0.0.0+Asserts')
sdkroot = path.join(location, 'Toolchains', '0.0.0+Asserts')
runtime = path.join(location, 'Runtimes', '0.0.0')
await fs.access(toolchain)
} catch (error) {
core.debug(`Switching to default installation due to "${error}"`)
if (fallback) {
location = fallback
}
devdir = path.join(location, 'Developer')
toolchain = path.join(
devdir,
'Toolchains',
'unknown-Asserts-development.xctoolchain'
)
sdkroot = path.join(
devdir,
'Platforms',
'Windows.platform',
'Developer',
'SDKs',
'Windows.sdk'
)
runtime = path.join(location, 'Swift', 'runtime-development')
}
return new Installation(location, toolchain, sdkroot, runtime, devdir)
}

static async detect() {
const systemDrive = process.env.SystemDrive ?? 'C:'
const defaultPath = path.join(systemDrive, 'Library')
const devPath = path.join(systemDrive, 'Program Files', 'Swift')
const installation = await Installation.get(devPath, defaultPath)
if (path.relative(devPath, installation.location)) {
const runtimeRoot = path.join(installation.location, 'Swift')
try {
await fs.access(devPath)
await fs.cp(devPath, runtimeRoot, {recursive: true})
} catch (error) {
core.debug(`Runtime check failed with "${error}"`)

Check warning on line 153 in src/installer/windows.ts

View check run for this annotation

Codecov / codecov/patch

src/installer/windows.ts#L153

Added line #L153 was not covered by tests
}
}
core.debug(`Installation location at "${installation.location}"`)
core.debug(`Toolchain installed at "${installation.toolchain}"`)
core.debug(`SDK installed at "${installation.sdkroot}"`)
core.debug(`Runtime installed at "${installation.runtime}"`)
core.debug(`Development directory at "${installation.devdir}"`)
return installation
}
}

0 comments on commit 0a8cd3e

Please sign in to comment.