Skip to content

Commit

Permalink
Use GNU tar on macOS if available (#701)
Browse files Browse the repository at this point in the history
* use GNU tar on macOS

* remove unnecessary code

* formatting fix

* fix tests

* fix more tests

* typo fix

* fix test
  • Loading branch information
Cyberbeni committed Feb 2, 2021
1 parent 8252049 commit ccd1dd2
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 22 deletions.
20 changes: 9 additions & 11 deletions packages/cache/__tests__/tar.test.ts
Expand Up @@ -12,6 +12,8 @@ jest.mock('@actions/io')

const IS_WINDOWS = process.platform === 'win32'

const defaultTarPath = process.platform === 'darwin' ? 'gtar' : 'tar'

function getTempDir(): string {
return path.join(__dirname, '_temp', 'tar')
}
Expand All @@ -38,14 +40,13 @@ test('zstd extract tar', async () => {
? `${process.env['windir']}\\fakepath\\cache.tar`
: 'cache.tar'
const workspace = process.env['GITHUB_WORKSPACE']
const tarPath = 'tar'

await tar.extractTar(archivePath, CompressionMethod.Zstd)

expect(mkdirMock).toHaveBeenCalledWith(workspace)
expect(execMock).toHaveBeenCalledTimes(1)
expect(execMock).toHaveBeenCalledWith(
`"${tarPath}"`,
`"${defaultTarPath}"`,
[
'--use-compress-program',
'zstd -d --long=30',
Expand All @@ -72,7 +73,7 @@ test('gzip extract tar', async () => {
expect(mkdirMock).toHaveBeenCalledWith(workspace)
const tarPath = IS_WINDOWS
? `${process.env['windir']}\\System32\\tar.exe`
: 'tar'
: defaultTarPath
expect(execMock).toHaveBeenCalledTimes(1)
expect(execMock).toHaveBeenCalledWith(
`"${tarPath}"`,
Expand Down Expand Up @@ -125,15 +126,14 @@ test('zstd create tar', async () => {
const archiveFolder = getTempDir()
const workspace = process.env['GITHUB_WORKSPACE']
const sourceDirectories = ['~/.npm/cache', `${workspace}/dist`]
const tarPath = 'tar'

await fs.promises.mkdir(archiveFolder, {recursive: true})

await tar.createTar(archiveFolder, sourceDirectories, CompressionMethod.Zstd)

expect(execMock).toHaveBeenCalledTimes(1)
expect(execMock).toHaveBeenCalledWith(
`"${tarPath}"`,
`"${defaultTarPath}"`,
[
'--posix',
'--use-compress-program',
Expand Down Expand Up @@ -165,7 +165,7 @@ test('gzip create tar', async () => {

const tarPath = IS_WINDOWS
? `${process.env['windir']}\\System32\\tar.exe`
: 'tar'
: defaultTarPath

expect(execMock).toHaveBeenCalledTimes(1)
expect(execMock).toHaveBeenCalledWith(
Expand Down Expand Up @@ -193,13 +193,12 @@ test('zstd list tar', async () => {
const archivePath = IS_WINDOWS
? `${process.env['windir']}\\fakepath\\cache.tar`
: 'cache.tar'
const tarPath = 'tar'

await tar.listTar(archivePath, CompressionMethod.Zstd)

expect(execMock).toHaveBeenCalledTimes(1)
expect(execMock).toHaveBeenCalledWith(
`"${tarPath}"`,
`"${defaultTarPath}"`,
[
'--use-compress-program',
'zstd -d --long=30',
Expand All @@ -217,13 +216,12 @@ test('zstdWithoutLong list tar', async () => {
const archivePath = IS_WINDOWS
? `${process.env['windir']}\\fakepath\\cache.tar`
: 'cache.tar'
const tarPath = 'tar'

await tar.listTar(archivePath, CompressionMethod.ZstdWithoutLong)

expect(execMock).toHaveBeenCalledTimes(1)
expect(execMock).toHaveBeenCalledWith(
`"${tarPath}"`,
`"${defaultTarPath}"`,
[
'--use-compress-program',
'zstd -d',
Expand All @@ -245,7 +243,7 @@ test('gzip list tar', async () => {

const tarPath = IS_WINDOWS
? `${process.env['windir']}\\System32\\tar.exe`
: 'tar'
: defaultTarPath
expect(execMock).toHaveBeenCalledTimes(1)
expect(execMock).toHaveBeenCalledWith(
`"${tarPath}"`,
Expand Down
33 changes: 22 additions & 11 deletions packages/cache/src/internal/tar.ts
Expand Up @@ -9,18 +9,29 @@ async function getTarPath(
args: string[],
compressionMethod: CompressionMethod
): Promise<string> {
const IS_WINDOWS = process.platform === 'win32'
if (IS_WINDOWS) {
const systemTar = `${process.env['windir']}\\System32\\tar.exe`
if (compressionMethod !== CompressionMethod.Gzip) {
// We only use zstandard compression on windows when gnu tar is installed due to
// a bug with compressing large files with bsdtar + zstd
args.push('--force-local')
} else if (existsSync(systemTar)) {
return systemTar
} else if (await utils.isGnuTarInstalled()) {
args.push('--force-local')
switch (process.platform) {
case 'win32': {
const systemTar = `${process.env['windir']}\\System32\\tar.exe`
if (compressionMethod !== CompressionMethod.Gzip) {
// We only use zstandard compression on windows when gnu tar is installed due to
// a bug with compressing large files with bsdtar + zstd
args.push('--force-local')
} else if (existsSync(systemTar)) {
return systemTar
} else if (await utils.isGnuTarInstalled()) {
args.push('--force-local')
}
break
}
case 'darwin': {
const gnuTar = await io.which('gtar', false)
if (gnuTar) {
return gnuTar
}
break
}
default:
break
}
return await io.which('tar', true)
}
Expand Down

0 comments on commit ccd1dd2

Please sign in to comment.