1
0
mirror of https://github.com/laurent22/joplin.git synced 2024-12-24 10:27:10 +02:00

Cli: Fixes #5341: Ignore newline between quotes while spliting batch (#5540)

This commit is contained in:
Kingsley Yung 2021-10-16 19:19:53 +08:00 committed by GitHub
parent 1d46d9f657
commit 5e6e1bf913
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 80 additions and 3 deletions

View File

@ -9,7 +9,7 @@ const Tag = require('@joplin/lib/models/Tag').default;
const Setting = require('@joplin/lib/models/Setting').default;
const { reg } = require('@joplin/lib/registry.js');
const { fileExtension } = require('@joplin/lib/path-utils');
const { splitCommandString } = require('@joplin/lib/string-utils');
const { splitCommandString, splitCommandBatch } = require('@joplin/lib/string-utils');
const { _ } = require('@joplin/lib/locale');
const fs = require('fs-extra');
const { cliUtils } = require('./cli-utils.js');
@ -390,7 +390,8 @@ class Application extends BaseApplication {
async commandList(argv) {
if (argv.length && argv[0] === 'batch') {
const commands = [];
const commandLines = (await fs.readFile(argv[1], 'utf-8')).split('\n');
const commandLines = splitCommandBatch(await fs.readFile(argv[1], 'utf-8'));
for (const commandLine of commandLines) {
if (!commandLine.trim()) continue;
const splitted = splitCommandString(commandLine.trim());

View File

@ -1,5 +1,6 @@
/* eslint-disable no-unused-vars */
const { splitCommandBatch } = require('./string-utils');
const StringUtils = require('./string-utils');
describe('StringUtils', function() {
@ -53,4 +54,26 @@ describe('StringUtils', function() {
});
}));
it('should split the command batch by newlines not inside quotes', (async () => {
const eol = '\n';
const testCases = [
['',
['']],
['command1',
['command1']],
['command1 arg1 arg2 arg3',
['command1 arg1 arg2 arg3']],
[`command1 arg1 'arg2${eol}continue' arg3`,
[`command1 arg1 'arg2${eol}continue' arg3`]],
[`command1 arg1 'arg2${eol}continue'${eol}command2${eol}command3 'arg1${eol}continue${eol}continue' arg2 arg3`,
[`command1 arg1 'arg2${eol}continue'`, 'command2', `command3 'arg1${eol}continue${eol}continue' arg2 arg3`]],
[`command1 arg\\1 'arg2${eol}continue\\'continue' arg3`,
[`command1 arg\\1 'arg2${eol}continue\\'continue' arg3`]],
];
testCases.forEach((t) => {
expect(splitCommandBatch(t[0])).toEqual(t[1]);
});
}));
});

View File

@ -210,6 +210,59 @@ function splitCommandString(command, options = null) {
return args;
}
function splitCommandBatch(commandBatch) {
const commandLines = [];
const eol = '\n';
let state = 'command';
let current = '';
let quote = '';
for (let i = 0; i < commandBatch.length; i++) {
const c = commandBatch[i];
if (state === 'command') {
if (c === eol) {
commandLines.push(current);
current = '';
} else if (c === '"' || c === '\'') {
quote = c;
current += c;
state = 'quoted';
} else if (c === '\\') {
current += c;
if (i + 1 < commandBatch.length) {
current += commandBatch[i + 1];
i++;
}
} else {
current += c;
}
} else if (state === 'quoted') {
if (c === quote) {
quote = '';
current += c;
state = 'command';
} else if (c === '\\') {
current += c;
if (i + 1 < commandBatch.length) {
current += commandBatch[i + 1];
i++;
}
} else {
current += c;
}
}
}
if (current.length > 0) {
commandLines.push(current);
}
if (commandLines.length === 0) {
commandLines.push('');
}
return commandLines;
}
function padLeft(string, length, padString) {
if (!string) return '';
@ -307,4 +360,4 @@ function scriptType(s) {
return 'en';
}
module.exports = Object.assign({ formatCssSize, camelCaseToDash, removeDiacritics, substrWithEllipsis, nextWhitespaceIndex, escapeFilename, wrap, splitCommandString, padLeft, toTitleCase, urlDecode, escapeHtml, surroundKeywords, scriptType, commandArgumentsToString }, stringUtilsCommon);
module.exports = Object.assign({ formatCssSize, camelCaseToDash, removeDiacritics, substrWithEllipsis, nextWhitespaceIndex, escapeFilename, wrap, splitCommandString, splitCommandBatch, padLeft, toTitleCase, urlDecode, escapeHtml, surroundKeywords, scriptType, commandArgumentsToString }, stringUtilsCommon);