diff --git a/packages/tool-cache/__tests__/tool-cache.test.ts b/packages/tool-cache/__tests__/tool-cache.test.ts index ff85a200..d316fe43 100644 --- a/packages/tool-cache/__tests__/tool-cache.test.ts +++ b/packages/tool-cache/__tests__/tool-cache.test.ts @@ -142,6 +142,36 @@ describe('@actions/tool-cache', function() { } }) + it('extracts a 7z to a directory that does not exist', async () => { + const tempDir = path.join(__dirname, 'test-install-7z') + const destDir = path.join(tempDir, 'not-exist') + try { + await io.mkdirP(tempDir) + + // copy the 7z file to the test dir + const _7zFile: string = path.join(tempDir, 'test.7z') + await io.cp(path.join(__dirname, 'data', 'test.7z'), _7zFile) + + // extract/cache + const extPath: string = await tc.extract7z(_7zFile, destDir) + await tc.cacheDir(extPath, 'my-7z-contents', '1.1.0') + const toolPath: string = tc.find('my-7z-contents', '1.1.0') + + expect(extPath).toContain('not-exist') + 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, 'file-with-ç-character.txt')) + ).toBeTruthy() + expect( + fs.existsSync(path.join(toolPath, 'folder', 'nested-file.txt')) + ).toBeTruthy() + } finally { + await io.rmRF(tempDir) + } + }) + it('extract 7z using custom 7z tool', async function() { const tempDir = path.join( __dirname, @@ -229,6 +259,39 @@ describe('@actions/tool-cache', function() { ).toBe('folder/nested-file.txt contents') }) + it('extract .tar.gz to a directory that does not exist', async () => { + const tempDir = path.join(tempPath, 'test-install-tar.gz') + const destDir = path.join(tempDir, 'not-exist') + + await io.mkdirP(tempDir) + + // copy the .tar.gz file to the test dir + const _tgzFile: string = path.join(tempDir, 'test.tar.gz') + await io.cp(path.join(__dirname, 'data', 'test.tar.gz'), _tgzFile) + + // extract/cache + const extPath: string = await tc.extractTar(_tgzFile, destDir) + await tc.cacheDir(extPath, 'my-tgz-contents', '1.1.0') + const toolPath: string = tc.find('my-tgz-contents', '1.1.0') + + expect(extPath).toContain('not-exist') + 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, 'file-with-ç-character.txt')) + ).toBeTruthy() + expect( + fs.existsSync(path.join(toolPath, 'folder', 'nested-file.txt')) + ).toBeTruthy() + expect( + fs.readFileSync( + path.join(toolPath, 'folder', 'nested-file.txt'), + 'utf8' + ) + ).toBe('folder/nested-file.txt contents') + }) + it('extract .tar.xz', async () => { const tempDir = path.join(tempPath, 'test-install-tar.xz') @@ -363,6 +426,60 @@ describe('@actions/tool-cache', function() { } }) + it('extract zip to a directory that does not exist', async function() { + const tempDir = path.join(__dirname, 'test-install-zip') + 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'), '') + + // 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('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') + await exec.exec(zipPath, [zipFile, '-r', '.'], {cwd: stagingDir}) + } + + const destDir = path.join(tempDir, 'not-exist') + + const extPath: string = await tc.extractZip(zipFile, destDir) + await tc.cacheDir(extPath, 'foo', '1.1.0') + const toolPath: string = tc.find('foo', '1.1.0') + + expect(extPath).toContain('not-exist') + 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) + } + }) + it('works with a 502 temporary failure', async function() { nock('http://example.com') .get('/temp502') diff --git a/packages/tool-cache/src/tool-cache.ts b/packages/tool-cache/src/tool-cache.ts index c932ab77..b0b695d7 100644 --- a/packages/tool-cache/src/tool-cache.ts +++ b/packages/tool-cache/src/tool-cache.ts @@ -130,7 +130,7 @@ export async function extract7z( ok(IS_WINDOWS, 'extract7z() not supported on current OS') ok(file, 'parameter "file" is required') - dest = dest || (await _createExtractFolder(dest)) + dest = await _createExtractFolder(dest) const originalCwd = process.cwd() process.chdir(dest) @@ -199,7 +199,7 @@ export async function extractTar( throw new Error("parameter 'file' is required") } - dest = dest || (await _createExtractFolder(dest)) + dest = await _createExtractFolder(dest) const tarPath: string = await io.which('tar', true) await exec(`"${tarPath}"`, [flags, '-C', dest, '-f', file]) @@ -218,7 +218,7 @@ export async function extractZip(file: string, dest?: string): Promise { throw new Error("parameter 'file' is required") } - dest = dest || (await _createExtractFolder(dest)) + dest = await _createExtractFolder(dest) if (IS_WINDOWS) { await extractZipWin(file, dest)