diff --git a/.gitignore b/.gitignore index 45530ba..ca5b2b2 100644 --- a/.gitignore +++ b/.gitignore @@ -45,5 +45,8 @@ binaries # VS Code .vs/ .vscode/ -win32/ .nyc_output/ + +# 7-Zip +win32/ +other32/ \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index b047959..050e1bc 100644 --- a/src/index.ts +++ b/src/index.ts @@ -28,26 +28,19 @@ function retry( archive: string ) { // Start the command - return Run('7z', command, options, override) - .progress(function (data: any) { - return progress(onprogress(data)); - }) // When all is done resolve the Promise. - .then(function (args: string[]) { - return resolve(args); - }) // Catch the error and pass it to the reject function of the Promise. - .catch(function () { - console.error(archive + ' failed using `7z`, retying with `7za`.'); - Run('7za', command, options, override) - .progress(function (data: any) { - return progress(onprogress(data)); - }) - .then(function (args: string[]) { - return resolve(args); - }) - .catch(function (err: any) { - return reject(err); - }); + const executables = ['7z', '7za']; // Two or more items + let position = 0; + const runner = () => Run(executables[position], command, options, override) + .progress((data: any) => progress(onprogress(data))) + .then((args: string[]) => resolve(args)) // When all is done resolve the Promise. + .catch((err: any) => { // Catch the error and pass it to the reject function of the Promise. + if (position === executables.length - 1) return reject(err); + console.error(archive + ' failed using `' + executables[position] + + '`, retrying with `' + executables[position + 1] + '`.'); + position++; + runner(); }); + return runner(); } /** @@ -124,24 +117,20 @@ export const deleteArchive = // Convert array of files into a string if needed. files = Files(files); // Create a string that can be parsed by `run`. - let command = 'd "' + filepath + '" ' + files; + let command = `d "${filepath}" ${files}`; // Start the command - Run('7z', command, options, override) // When all is done resolve the Promise. - .then(function (args) { - return resolve(args); - }) // Catch the error and pass it to the reject function of the Promise. - .catch(function () { - console.error( - 'DeleteArchive failed using `7z`, retying with `7za`.' - ); - Run('7za', command, options, override) - .then(function (args) { - return resolve(args); - }) - .catch(function (err) { - return reject(err); - }); + const executables = ['7z', '7za']; // Two or more items + let position = 0; + const runner = () => Run(executables[position], command, options, override) + .then((args: any[]) => resolve(args)) // When all is done resolve the Promise. + .catch((err: any) => { // Catch the error and pass it to the reject function of the Promise. + if (position === executables.length - 1) return reject(err); + console.error('DeleteArchive failed using `' + executables[position] + + '`, retrying with `' + executables[position + 1] + '`.'); + position++; + runner(); }); + return runner(); }); }); @@ -339,32 +328,20 @@ export const listArchive = // Create a string that can be parsed by `run`. let command = 'l "' + filepath + '" '; - Run(isWindows() ? '7z' : '7za', command, options, override) - .progress(function (data: string) { - return progress(onprogress(data)); - }) - .then(function () { - return resolve(spec); - }) - .catch(function (err: any) { - if (isWindows()) { - console.error( - 'ListArchive failed using `7z`, retying with `7za`.' - ); - Run('7za', command, options, override) - .progress(function (data: string) { - return progress(onprogress(data)); - }) - .then(function (args: any) { - return resolve(args); - }) - .catch(function (err: any) { - return reject(err); - }); - } else { - return reject(err); - } + // Start the command + const executables = isWindows() ? ['7z', '7za'] : ['7za']; + let position = 0; + const runner = () => Run(executables[position], command, options, override) + .progress((data: string) => progress(onprogress(data))) + .then((args: any) => resolve(position === 0 ? spec : args)) + .catch((err: any) => { + if (position === executables.length - 1) return reject(err); + console.error('ListArchive failed using `' + executables[position] + + '`, retrying with `' + executables[position + 1] + '`.'); + position++; + runner(); }); + return runner(); }); }); diff --git a/src/utility.ts b/src/utility.ts index 906bbe4..f991804 100644 --- a/src/utility.ts +++ b/src/utility.ts @@ -11,20 +11,15 @@ const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); export const Binary = function (override = false, binary = '7z') { - let path = join( + const path = join( __dirname, '..', 'binaries', - override === true - ? process.platform + sep + 'other32' - : process.platform + `${process.platform}${override === true ? sep + 'other32' : ''}` ); - let filename = isWindows() ? binary + '.exe' : binary; - return { - path: path, - filename: filename, - filepath: join(path, filename), - }; + const filename = `${binary}${isWindows() ? '.exe' : ''}`; + const filepath = join(path, filename); + return { path, filename, filepath }; }; /** @@ -34,22 +29,10 @@ export const Binary = function (override = false, binary = '7z') { * @return {string} */ export const Files = function (files: string | string[]): string { - if (isUndefined(files)) { - return ''; - } - - let toProcess = ''; - - if (Array.isArray(files)) { - files.forEach(function (f) { - toProcess += '"' + f + '" '; - }); - toProcess = toProcess.trim(); - } else { - toProcess = '"' + files + '"'; - } - - return toProcess; + if (isUndefined(files)) return ''; + return (Array.isArray(files) ? files : [files]) + .map((file) => `"${file}"`) + .join(' '); }; /** @@ -57,14 +40,7 @@ export const Files = function (files: string | string[]): string { * @return {string} A path with / for directory separator. */ export const ReplaceNativeSeparator = function (path: string): string { - let result = path, - next; - - while ((next = result.replace(nativeSeparator, '/')) !== result) { - result = next; - } - - return result; + return path.replace(new RegExp(`\\${nativeSeparator}`, 'g'), '/'); }; /** @@ -103,15 +79,10 @@ export function Run( let args = [command.split(' ')[0]]; // Parse and add command (non-switches parameters) to `args`. let regexpCommands = /"((?:\\.|[^"\\])*)"/g; - let commands = command.match(regexpCommands); - - if (commands) { - commands.forEach(function (c) { - c = c.replace(/\//g, sep); - c = c.replace(/\\/g, sep); - c = normalize(c); - args.push(c); - }); + let commands = command.match(regexpCommands) || []; + for (command of commands) { + const arg = command.replace(/(\/|\\)/g, sep); + args.push(normalize(arg)); } // Special treatment for the output switch because it is exposed as a @@ -121,12 +92,8 @@ export function Run( if (output) { args.pop(); - let o = output[0]; - o = o.replace(/\//g, sep); - o = o.replace(/\\/g, sep); - o = o.replace(/"/g, ''); - o = normalize(o); - args.push(o); + const arg = output[0].replace(/(\/|\\|")/g, (match) => match === '"' ? '' : sep); + args.push(normalize(arg)); } if (switches.files) {