Skip to content

Commit

Permalink
Add new windows commands for unzip
Browse files Browse the repository at this point in the history
  • Loading branch information
luketomlinson committed May 14, 2021
1 parent ce08409 commit 008211e
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 71 deletions.
Binary file added __MACOSX/test-win/._test.txt
Binary file not shown.
116 changes: 68 additions & 48 deletions packages/tool-cache/__tests__/tool-cache.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -534,58 +534,76 @@ describe('@actions/tool-cache', function() {
).toBe('foo/hello: world')
})

it('installs a zip and finds it', async () => {
const tempDir = path.join(__dirname, 'test-install-zip')
try {
await io.mkdirP(tempDir)
it.each(['pwsh', 'powershell'])(
'installs a zip and finds it (%s)',
async powershellTool => {
const tempDir = path.join(__dirname, 'test-install-zip')
const originalPath = process.env['PATH']
try {
await io.mkdirP(tempDir)

// stage the layout for a zip file:
// file.txt
// folder/nested-file.txt
const stagingDir = path.join(tempDir, 'zip-staging')
await io.mkdirP(path.join(stagingDir, 'folder'))
fs.writeFileSync(path.join(stagingDir, 'file.txt'), '')
fs.writeFileSync(path.join(stagingDir, 'folder', 'nested-file.txt'), '')
// stage the layout for a zip file:
// file.txt
// folder/nested-file.txt
const stagingDir = path.join(tempDir, 'zip-staging')
await io.mkdirP(path.join(stagingDir, 'folder'))
fs.writeFileSync(path.join(stagingDir, 'file.txt'), '')
fs.writeFileSync(path.join(stagingDir, 'folder', 'nested-file.txt'), '')

// create the zip
const zipFile = path.join(tempDir, 'test.zip')
await io.rmRF(zipFile)
if (IS_WINDOWS) {
const escapedStagingPath = stagingDir.replace(/'/g, "''") // double-up single quotes
const escapedZipFile = zipFile.replace(/'/g, "''")
const powershellPath =
(await io.which('pwsh', false)) ||
(await io.which('powershell', true))
const args = [
'-NoLogo',
'-Sta',
'-NoProfile',
'-NonInteractive',
'-ExecutionPolicy',
'Unrestricted',
'-Command',
`$ErrorActionPreference = 'Stop' ; Add-Type -AssemblyName System.IO.Compression.FileSystem ; [System.IO.Compression.ZipFile]::CreateFromDirectory('${escapedStagingPath}', '${escapedZipFile}')`
]
await exec.exec(`"${powershellPath}"`, args)
} else {
const zipPath: string = await io.which('zip', true)
await exec.exec(`"${zipPath}`, [zipFile, '-r', '.'], {
cwd: stagingDir
})
}

// create the zip
const zipFile = path.join(tempDir, 'test.zip')
await io.rmRF(zipFile)
if (IS_WINDOWS) {
const escapedStagingPath = stagingDir.replace(/'/g, "''") // double-up single quotes
const escapedZipFile = zipFile.replace(/'/g, "''")
const powershellPath =
(await io.which('pwsh', false)) ||
(await io.which('powershell', true))
const args = [
'-NoLogo',
'-Sta',
'-NoProfile',
'-NonInteractive',
'-ExecutionPolicy',
'Unrestricted',
'-Command',
`$ErrorActionPreference = 'Stop' ; Add-Type -AssemblyName System.IO.Compression.FileSystem ; [System.IO.Compression.ZipFile]::CreateFromDirectory('${escapedStagingPath}', '${escapedZipFile}')`
]
await exec.exec(`"${powershellPath}"`, args)
} else {
const zipPath: string = await io.which('zip', true)
await exec.exec(`"${zipPath}`, [zipFile, '-r', '.'], {cwd: stagingDir})
}
if (powershellTool === 'powershell' && IS_WINDOWS) {
//remove pwsh from PATH temporarily to test fallback case
const newPath = originalPath
?.split(';')
.filter(segment => {
return !segment.startsWith(`C:\\Program Files\\PowerShell`)
})
.join(';')
process.env['PATH'] = newPath
}

const extPath: string = await tc.extractZip(zipFile)
await tc.cacheDir(extPath, 'foo', '1.1.0')
const toolPath: string = tc.find('foo', '1.1.0')
const extPath: string = await tc.extractZip(zipFile)
await tc.cacheDir(extPath, 'foo', '1.1.0')
const toolPath: string = tc.find('foo', '1.1.0')

expect(fs.existsSync(toolPath)).toBeTruthy()
expect(fs.existsSync(`${toolPath}.complete`)).toBeTruthy()
expect(fs.existsSync(path.join(toolPath, 'file.txt'))).toBeTruthy()
expect(
fs.existsSync(path.join(toolPath, 'folder', 'nested-file.txt'))
).toBeTruthy()
} finally {
await io.rmRF(tempDir)
expect(fs.existsSync(toolPath)).toBeTruthy()
expect(fs.existsSync(`${toolPath}.complete`)).toBeTruthy()
expect(fs.existsSync(path.join(toolPath, 'file.txt'))).toBeTruthy()
expect(
fs.existsSync(path.join(toolPath, 'folder', 'nested-file.txt'))
).toBeTruthy()
} finally {
await io.rmRF(tempDir)
process.env['PATH'] = originalPath
}
}
})
)

it('installs a zip and extracts it to specified directory', async function() {
const tempDir = path.join(__dirname, 'test-install-zip')
Expand Down Expand Up @@ -636,7 +654,9 @@ describe('@actions/tool-cache', function() {
expect(fs.existsSync(toolPath)).toBeTruthy()
expect(fs.existsSync(`${toolPath}.complete`)).toBeTruthy()
expect(fs.existsSync(path.join(toolPath, 'file.txt'))).toBeTruthy()
expect(fs.readFileSync(path.join(toolPath, 'file.txt'), 'utf8')).toBe('originalText')
expect(fs.readFileSync(path.join(toolPath, 'file.txt'), 'utf8')).toBe(
'originalText'
)
expect(
fs.existsSync(path.join(toolPath, 'folder', 'nested-file.txt'))
).toBeTruthy()
Expand Down
60 changes: 37 additions & 23 deletions packages/tool-cache/src/tool-cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -346,39 +346,52 @@ async function extractZipWin(file: string, dest: string): Promise<void> {
const escapedDest = dest.replace(/'/g, "''").replace(/"|\n|\r/g, '')
const pwshPath = await io.which('pwsh', false)

let command = ''
//To match the file overwrite behavior on nix systems, we use the overwrite = true flag for ExtractToDirectory
//and the -Force flag for Expand-Archive as a fallback
if (pwshPath) {
//overwrite=true
command = [
//attempt to use pwsh with ExtractToDirectory, if this fails attempt Expand-Archive
const pwshCommand = [
`$ErrorActionPreference = 'Stop' ;`,
`try { Add-Type -AssemblyName System.IO.Compression.ZipFile } catch { } ;`,
`try { [System.IO.Compression.ZipFile]::ExtractToDirectory('${escapedFile}', '${escapedDest}', $true) }`,
`catch { if ($_.Exception.GetType().FullName -eq 'System.Management.Automation.MethodException'){ Expand-Archive -LiteralPath '${escapedFile}' -DestinationPath '${escapedDest} -Force } } ;`
`catch { if ($_.Exception.GetType().FullName -eq 'System.Management.Automation.MethodException'){ Expand-Archive -LiteralPath '${escapedFile}' -DestinationPath '${escapedDest}' -Force } else { $_ } } ;`
].join(' ')

const args = [
'-NoLogo',
'-NoProfile',
'-NonInteractive',
'-ExecutionPolicy',
'Unrestricted',
'-Command',
pwshCommand
]

core.debug(`Using pwsh at path: ${pwshPath}`)
await exec(`"${pwshPath}"`, args)
} else {
command = [
const powershellCommand = [
`$ErrorActionPreference = 'Stop' ;`,
`try { Add-Type -AssemblyName System.IO.Compression.FileSystem } catch { } ;`,
`[System.IO.Compression.ZipFile]::ExtractToDirectory('${escapedFile}', '${escapedDest}')`
`Expand-Archive -LiteralPath '${escapedFile}' -DestinationPath '${escapedDest}' -Force`
].join(' ')
}

//TODO: remove this
command = `$ErrorActionPreference = 'Stop' ; try { Add-Type -AssemblyName System.IO.Compression.FileSystem } catch { } ; [System.IO.Compression.ZipFile]::ExtractToDirectory('${escapedFile}', '${escapedDest}')`

// run powershell
const powershellPath = await io.which('powershell', true)
const args = [
'-NoLogo',
'-Sta',
'-NoProfile',
'-NonInteractive',
'-ExecutionPolicy',
'Unrestricted',
'-Command',
command
]
await exec(`"${powershellPath}"`, args)
const args = [
'-NoLogo',
'-Sta',
'-NoProfile',
'-NonInteractive',
'-ExecutionPolicy',
'Unrestricted',
'-Command',
powershellCommand
]

const powershellPath = await io.which('powershell', true)
core.debug(`Using powershell at path: ${powershellPath}`)

await exec(`"${powershellPath}"`, args)
}
}

async function extractZipNix(file: string, dest: string): Promise<void> {
Expand All @@ -387,6 +400,7 @@ async function extractZipNix(file: string, dest: string): Promise<void> {
if (!core.isDebug()) {
args.unshift('-q')
}
args.unshift('-o') //overwrite with -o, otherwise a prompt is shown which freezes the run
await exec(`"${unzipPath}"`, args, {cwd: dest})
}

Expand Down

0 comments on commit 008211e

Please sign in to comment.