Skip to content

Commit

Permalink
Extract Files task: add overwrite option (#13595)
Browse files Browse the repository at this point in the history
  • Loading branch information
EzzhevNikita authored Sep 24, 2020
1 parent 32ed379 commit f49f79f
Show file tree
Hide file tree
Showing 8 changed files with 90 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
"loc.input.help.destinationFolder": "Destination folder into which archive files should be extracted. Use [variables](https://go.microsoft.com/fwlink/?LinkID=550988) if files are not in the repo. Example: $(agent.builddirectory)",
"loc.input.label.cleanDestinationFolder": "Clean destination folder before extracting",
"loc.input.help.cleanDestinationFolder": "Select this option to clean the destination directory before archive contents are extracted into it.",
"loc.input.label.overwriteExistingFiles": "Overwrite existing files",
"loc.input.help.overwriteExistingFiles": "Select this option to overwrite existing files in the destination directory.",
"loc.messages.ExtractDirFailedinFindFiles": "Specified archive: %s can not be extracted because it is a directory.",
"loc.messages.ExtractNotFileFailed": "Specified archive: %s can not be extracted because it is not a file.",
"loc.messages.ExtractNotAccessibleFile": "Specified archive: %s can not be extracted because it can not be accessed: %s",
Expand Down
42 changes: 41 additions & 1 deletion Tasks/ExtractFilesV1/Tests/L0.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import path = require('path');
import * as ttm from 'azure-pipelines-task-lib/mock-test';


describe('DeleteFiles Suite', function () {
describe('ExtractFile Suite', function () {
this.timeout(60000);

function runValidations(validator: () => void, tr, done) {
Expand All @@ -21,6 +21,7 @@ describe('DeleteFiles Suite', function () {
it('Successfully extracts a single zip', (done: MochaDone) => {
this.timeout(5000);
process.env['archiveFilePatterns'] = 'zip1.zip';
process.env['overwriteExistingFiles'] = 'true';
delete process.env['cleanDestinationFolder'];

let tp: string = path.join(__dirname, 'L0Extract.js');
Expand All @@ -36,6 +37,7 @@ describe('DeleteFiles Suite', function () {
it('Successfully extracts multiple zips', (done: MochaDone) => {
this.timeout(5000);
process.env['archiveFilePatterns'] = 'zip1.zip\nzip2.zip';
process.env['overwriteExistingFiles'] = 'true';
delete process.env['cleanDestinationFolder'];

let tp: string = path.join(__dirname, 'L0Extract.js');
Expand All @@ -52,6 +54,7 @@ describe('DeleteFiles Suite', function () {
it('Successfully extracts a tar', (done: MochaDone) => {
this.timeout(5000);
process.env['archiveFilePatterns'] = 'tar.tar';
process.env['overwriteExistingFiles'] = 'true';
delete process.env['cleanDestinationFolder'];

let tp: string = path.join(__dirname, 'L0Extract.js');
Expand All @@ -67,6 +70,7 @@ describe('DeleteFiles Suite', function () {
it('Successfully cleans destination', (done: MochaDone) => {
this.timeout(5000);
process.env['archiveFilePatterns'] = 'zip1.zip';
process.env['overwriteExistingFiles'] = 'true';
process.env['cleanDestinationFolder'] = 'true';

let tp: string = path.join(__dirname, 'L0Extract.js');
Expand All @@ -79,4 +83,40 @@ describe('DeleteFiles Suite', function () {
assert(tr.stdout.indexOf('Removing ' + __dirname) > -1);
}, tr, done);
});

it('Successfully overwrites files from zip in output directory', (done: MochaDone) => {
this.timeout(5000);
process.env['archiveFilePatterns'] = 'zip1.zip';
process.env['overwriteExistingFiles'] = 'true';
delete process.env['cleanDestinationFolder'];

let tp: string = path.join(__dirname, 'L0Extract.js');
let tr: ttm.MockTestRunner = new ttm.MockTestRunner(tp);

// run it twice to check files that was created during first run will be overwritten
tr.run();
tr.run();

runValidations(() => {
assert(tr.stdout.indexOf('extracted zip1') > -1);
}, tr, done);
});

it('Successfully overwrites files from tar in output directory', (done: MochaDone) => {
this.timeout(5000);
process.env['archiveFilePatterns'] = 'tar.tar';
process.env['overwriteExistingFiles'] = 'true';
delete process.env['cleanDestinationFolder'];

let tp: string = path.join(__dirname, 'L0Extract.js');
let tr: ttm.MockTestRunner = new ttm.MockTestRunner(tp);

// run it twice to check files that was created during first run will be overwritten
tr.run();
tr.run();

runValidations(() => {
assert(tr.stdout.indexOf('extracted tar') > -1);
}, tr, done);
});
});
13 changes: 7 additions & 6 deletions Tasks/ExtractFilesV1/Tests/L0Extract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ process.env['SYSTEM_DEFAULTWORKINGDIRECTORY'] = __dirname;
tmr.setInput('archiveFilePatterns', process.env['archiveFilePatterns']);
tmr.setInput('destinationFolder', __dirname);
tmr.setInput('cleanDestinationFolder', process.env['cleanDestinationFolder']);
tmr.setInput('overwriteExistingFiles', process.env['overwriteExistingFiles']);
const osType = os.type();
const isWindows = !!osType.match(/^Win/);

Expand Down Expand Up @@ -44,14 +45,14 @@ tlClone.rmRF = function(path) {
tmr.registerMock('azure-pipelines-task-lib/mock-task', tlClone);

let zipExecutable = path.join(__dirname, '..', '7zip', '7z.exe');
let sevenZip1Command: string = `${zipExecutable} x -o${__dirname} ${path.join(__dirname, 'zip1.zip')}`;
let sevenZip2Command: string = `${zipExecutable} x -o${__dirname} ${path.join(__dirname, 'zip2.zip')}`;
let tarCommand = `${zipExecutable} x -o${__dirname} ${path.join(__dirname, 'tar.tar')}`;
let sevenZip1Command: string = `${zipExecutable} -aoa x -o${__dirname} ${path.join(__dirname, 'zip1.zip')}`;
let sevenZip2Command: string = `${zipExecutable} -aoa x -o${__dirname} ${path.join(__dirname, 'zip2.zip')}`;
let tarCommand = `${zipExecutable} -aoa x -o${__dirname} ${path.join(__dirname, 'tar.tar')}`;
if (!isWindows) {
zipExecutable = 'path/to/unzip'
sevenZip1Command = `${zipExecutable} ${path.join(__dirname, 'zip1.zip')} -d ${__dirname}`;
sevenZip2Command = `${zipExecutable} ${path.join(__dirname, 'zip2.zip')} -d ${__dirname}`;
tarCommand = `path/to/tar -xvf ${path.join(__dirname, 'tar.tar')} -C ${__dirname}`;
sevenZip1Command = `${zipExecutable} ${path.join(__dirname, 'zip1.zip')} -o -d ${__dirname}`;
sevenZip2Command = `${zipExecutable} ${path.join(__dirname, 'zip2.zip')} -o -d ${__dirname}`;
tarCommand = `path/to/tar -xvf -k ${path.join(__dirname, 'tar.tar')} -C ${__dirname}`;
}

let a: ma.TaskLibAnswers = <ma.TaskLibAnswers>{
Expand Down
10 changes: 10 additions & 0 deletions Tasks/ExtractFilesV1/extractfilestask.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import os = require('os');
var archiveFilePatterns: string[] = tl.getDelimitedInput('archiveFilePatterns', '\n', true);
var destinationFolder: string = path.normalize(tl.getPathInput('destinationFolder', true, false).trim());
var cleanDestinationFolder: boolean = tl.getBoolInput('cleanDestinationFolder', false);
var overwriteExistingFiles: boolean = tl.getBoolInput('overwriteExistingFiles', false);

var repoRoot: string = tl.getVariable('System.DefaultWorkingDirectory');
tl.debug('repoRoot: ' + repoRoot);
Expand Down Expand Up @@ -191,6 +192,9 @@ function unzipExtract(file, destinationFolder) {
}
var unzip = tl.tool(xpUnzipLocation);
unzip.arg(file);
if (overwriteExistingFiles) {
unzip.arg('-o');
}
unzip.arg('-d');
unzip.arg(destinationFolder);
return handleExecResult(unzip.execSync(), file);
Expand All @@ -199,6 +203,9 @@ function unzipExtract(file, destinationFolder) {
function sevenZipExtract(file, destinationFolder) {
console.log(tl.loc('SevenZipExtractFile', file));
var sevenZip = tl.tool(getSevenZipLocation());
if (overwriteExistingFiles) {
sevenZip.arg('-aoa');
}
sevenZip.arg('x');
sevenZip.arg('-o' + destinationFolder);
sevenZip.arg(file);
Expand All @@ -212,6 +219,9 @@ function tarExtract(file, destinationFolder) {
}
var tar = tl.tool(xpTarLocation);
tar.arg('-xvf'); // tar will correctly handle compression types outlined in isTar()
if (overwriteExistingFiles) {
tar.arg('-k');
}
tar.arg(file);
tar.arg('-C');
tar.arg(destinationFolder);
Expand Down
10 changes: 9 additions & 1 deletion Tasks/ExtractFilesV1/task.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"demands": [],
"version": {
"Major": 1,
"Minor": 175,
"Minor": 176,
"Patch": 0
},
"instanceNameFormat": "Extract files $(message)",
Expand Down Expand Up @@ -50,6 +50,14 @@
"required": true,
"defaultValue": "true",
"helpMarkDown": "Select this option to clean the destination directory before archive contents are extracted into it."
},
{
"name": "overwriteExistingFiles",
"type": "boolean",
"label": "Overwrite existing files",
"required": true,
"defaultValue": "false",
"helpMarkDown": "Select this option to overwrite existing files in the destination directory."
}
],
"execution": {
Expand Down
10 changes: 9 additions & 1 deletion Tasks/ExtractFilesV1/task.loc.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"demands": [],
"version": {
"Major": 1,
"Minor": 175,
"Minor": 176,
"Patch": 0
},
"instanceNameFormat": "ms-resource:loc.instanceNameFormat",
Expand Down Expand Up @@ -50,6 +50,14 @@
"required": true,
"defaultValue": "true",
"helpMarkDown": "ms-resource:loc.input.help.cleanDestinationFolder"
},
{
"name": "overwriteExistingFiles",
"type": "boolean",
"label": "ms-resource:loc.input.label.overwriteExistingFiles",
"required": true,
"defaultValue": "false",
"helpMarkDown": "ms-resource:loc.input.help.overwriteExistingFiles"
}
],
"execution": {
Expand Down
8 changes: 4 additions & 4 deletions Tests-Legacy/L0/ExtractFiles/extractFilesLinux.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
"output": true
},
"exec": {
"/usr/bin/unzip mockedBuildSources/foo.zip -d output": {
"/usr/bin/unzip -o mockedBuildSources/foo.zip -d output": {
"code": 0,
"stdout": "extracted mockedBuildSources/foo.zip",
"stderr": ""
Expand All @@ -60,17 +60,17 @@
"stdout": "extracted mockedBuildSources/foo.tar.gz",
"stderr": ""
},
"/usr/bin/unzip mockedBuildSources/subdir/foo.jar -d output": {
"/usr/bin/unzip -o mockedBuildSources/subdir/foo.jar -d output": {
"code": 0,
"stdout": "extracted mockedBuildSources/subdir/foo.jar",
"stderr": ""
},
"/usr/bin/7z x -ooutput mockedBuildSources/subdir/subdir/foo.7z": {
"/usr/bin/7z x -aoa -ooutput mockedBuildSources/subdir/subdir/foo.7z": {
"code": 0,
"stdout": "extracted mockedBuildSources/subdir/subdir/foo.7z",
"stderr": ""
},
"/usr/bin/unzip mockedBuildSources/subdir/foo.zip -d output": {
"/usr/bin/unzip -o mockedBuildSources/subdir/foo.zip -d output": {
"code": 0,
"stdout": "extracted mockedBuildSources/subdir/foo.zip",
"stderr": ""
Expand Down
16 changes: 8 additions & 8 deletions Tests-Legacy/L0/ExtractFiles/extractFilesWin.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,42 +40,42 @@
"output": true
},
"exec": {
"/ExtractFiles/7zip/7z.exe x -ooutput mockedBuildSources/foo.zip": {
"/ExtractFiles/7zip/7z.exe x -aoa -ooutput mockedBuildSources/foo.zip": {
"code": 0,
"stdout": "extracted mockedBuildSources/foo.zip",
"stderr": ""
},
"/ExtractFiles/7zip/7z.exe x -ooutput mockedBuildSources/foo.tar": {
"/ExtractFiles/7zip/7z.exe x -aoa -ooutput mockedBuildSources/foo.tar": {
"code": 0,
"stdout": "extracted mockedBuildSources/foo.tar",
"stderr": ""
},
"/ExtractFiles/7zip/7z.exe x -ooutput/_foo.tar.gz_ mockedBuildSources/foo.tar.gz": {
"/ExtractFiles/7zip/7z.exe x -aoa -ooutput/_foo.tar.gz_ mockedBuildSources/foo.tar.gz": {
"code": 0,
"stdout": "extracted mockedBuildSources/foo.tar.gz",
"stderr": ""
},
"/ExtractFiles/7zip/7z.exe x -ooutput output/_foo.tar.gz_/foo.tar": {
"/ExtractFiles/7zip/7z.exe x -aoa -ooutput output/_foo.tar.gz_/foo.tar": {
"code": 0,
"stdout": "extracted output/_foo.tar.gz_/foo.tar",
"stderr": ""
},
"/ExtractFiles/7zip/7z.exe x -ooutput/ output/_foo.tar.gz_/foo.tar": {
"/ExtractFiles/7zip/7z.exe x -aoa -ooutput/ output/_foo.tar.gz_/foo.tar": {
"code": 0,
"stdout": "extractedoutput/_foo.tar.gz_/foo.tar",
"stderr": ""
},
"/ExtractFiles/7zip/7z.exe x -ooutput mockedBuildSources/subdir/foo.jar": {
"/ExtractFiles/7zip/7z.exe x -aoa -ooutput mockedBuildSources/subdir/foo.jar": {
"code": 0,
"stdout": "extracted mockedBuildSources/subdir/foo.jar",
"stderr": ""
},
"/ExtractFiles/7zip/7z.exe x -ooutput mockedBuildSources/subdir/subdir/foo.7z": {
"/ExtractFiles/7zip/7z.exe x -aoa -ooutput mockedBuildSources/subdir/subdir/foo.7z": {
"code": 0,
"stdout": "extracted mockedBuildSources/subdir/subdir/foo.7z",
"stderr": ""
},
"/ExtractFiles/7zip/7z.exe x -ooutput mockedBuildSources/subdir/foo.zip": {
"/ExtractFiles/7zip/7z.exe x -aoa -ooutput mockedBuildSources/subdir/foo.zip": {
"code": 0,
"stdout": "extracted mockedBuildSources/subdir/foo.zip",
"stderr": ""
Expand Down

0 comments on commit f49f79f

Please sign in to comment.