Skip to content

Commit

Permalink
fix extractTar on Windows (actions#264)
Browse files Browse the repository at this point in the history
  • Loading branch information
ericsciple authored Dec 19, 2019
1 parent 81bdf00 commit e7cbd69
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 78 deletions.
Binary file modified packages/tool-cache/__tests__/data/test.tar.gz
Binary file not shown.
144 changes: 68 additions & 76 deletions packages/tool-cache/__tests__/tool-cache.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -268,96 +268,88 @@ describe('@actions/tool-cache', function() {
await io.rmRF(tempDir)
}
})
} else {
it('extract .tar.gz', async () => {
const tempDir = path.join(tempPath, 'test-install-tar.gz')
}

await io.mkdirP(tempDir)
it('extract .tar.gz', async () => {
const tempDir = path.join(tempPath, 'test-install-tar.gz')

// 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)
await io.mkdirP(tempDir)

// extract/cache
const extPath: string = await tc.extractTar(_tgzFile)
await tc.cacheDir(extPath, 'my-tgz-contents', '1.1.0')
const toolPath: string = tc.find('my-tgz-contents', '1.1.0')
// 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)

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')
})
// extract/cache
const extPath: string = await tc.extractTar(_tgzFile)
await tc.cacheDir(extPath, 'my-tgz-contents', '1.1.0')
const toolPath: string = tc.find('my-tgz-contents', '1.1.0')

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')
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')
})

await io.mkdirP(tempDir)
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')

// 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)
await io.mkdirP(tempDir)

// 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')
// 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)

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')
})
// 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')

it('extract .tar.xz', async () => {
const tempDir = path.join(tempPath, 'test-install-tar.xz')
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')
})

await io.mkdirP(tempDir)
it('extract .tar.xz', async () => {
const tempDir = path.join(tempPath, 'test-install-tar.xz')

// copy the .tar.gz file to the test dir
const _txzFile: string = path.join(tempDir, 'test.tar.xz')
await io.cp(path.join(__dirname, 'data', 'test.tar.xz'), _txzFile)
await io.mkdirP(tempDir)

// extract/cache
const extPath: string = await tc.extractTar(_txzFile, undefined, 'x')
await tc.cacheDir(extPath, 'my-txz-contents', '1.1.0')
const toolPath: string = tc.find('my-txz-contents', '1.1.0')
// copy the .tar.gz file to the test dir
const _txzFile: string = path.join(tempDir, 'test.tar.xz')
await io.cp(path.join(__dirname, 'data', 'test.tar.xz'), _txzFile)

expect(fs.existsSync(toolPath)).toBeTruthy()
expect(fs.existsSync(`${toolPath}.complete`)).toBeTruthy()
expect(fs.existsSync(path.join(toolPath, 'bar.txt'))).toBeTruthy()
expect(
fs.existsSync(path.join(toolPath, 'foo', 'hello.txt'))
).toBeTruthy()
expect(
fs.readFileSync(path.join(toolPath, 'foo', 'hello.txt'), 'utf8')
).toBe('foo/hello: world')
})
}
// extract/cache
const extPath: string = await tc.extractTar(_txzFile, undefined, 'x')
await tc.cacheDir(extPath, 'my-txz-contents', '1.1.0')
const toolPath: string = tc.find('my-txz-contents', '1.1.0')

expect(fs.existsSync(toolPath)).toBeTruthy()
expect(fs.existsSync(`${toolPath}.complete`)).toBeTruthy()
expect(fs.existsSync(path.join(toolPath, 'bar.txt'))).toBeTruthy()
expect(fs.existsSync(path.join(toolPath, 'foo', 'hello.txt'))).toBeTruthy()
expect(
fs.readFileSync(path.join(toolPath, 'foo', 'hello.txt'), 'utf8')
).toBe('foo/hello: world')
})

it('installs a zip and finds it', async () => {
const tempDir = path.join(__dirname, 'test-install-zip')
Expand Down
36 changes: 34 additions & 2 deletions packages/tool-cache/src/tool-cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -202,9 +202,41 @@ export async function extractTar(
throw new Error("parameter 'file' is required")
}

// Create dest
dest = await _createExtractFolder(dest)
const tarPath: string = await io.which('tar', true)
await exec(`"${tarPath}"`, [flags, '-C', dest, '-f', file])

// Determine whether GNU tar
let versionOutput = ''
await exec('tar --version', [], {
ignoreReturnCode: true,
listeners: {
stdout: (data: Buffer) => (versionOutput += data.toString()),
stderr: (data: Buffer) => (versionOutput += data.toString())
}
})
const isGnuTar = versionOutput.toUpperCase().includes('GNU TAR')

// Initialize args
const args = [flags]

let destArg = dest
let fileArg = file
if (IS_WINDOWS && isGnuTar) {
args.push('--force-local')
destArg = dest.replace(/\\/g, '/')

// Technically only the dest needs to have `/` but for aesthetic consistency
// convert slashes in the file arg too.
fileArg = file.replace(/\\/g, '/')
}

if (isGnuTar) {
// Suppress warnings when using GNU tar to extract archives created by BSD tar
args.push('--warning=no-unknown-keyword')
}

args.push('-C', destArg, '-f', fileArg)
await exec(`tar`, args)

return dest
}
Expand Down

0 comments on commit e7cbd69

Please sign in to comment.