Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use GNU tar on macOS if available #701

Merged
merged 7 commits into from Feb 2, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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