Skip to content

Commit

Permalink
KP-744 Create function for extracting and parsing file paths for CLI …
Browse files Browse the repository at this point in the history
…commands (#6)
  • Loading branch information
xkcm authored May 17, 2022
1 parent f294a80 commit fb3b4b7
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 0 deletions.
23 changes: 23 additions & 0 deletions helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ const parsers = require("./parsers");
const validators = require("./validators");

const CREATE_TEMPORARY_FILE_LINUX_COMMAND = "mktemp --tmpdir kaholo_plugin_library.XXX";
const DEFAULT_PATH_ARGUMENT_REGEX = /(?<=\s|^|\w+=)((?:fileb?:\/\/)?(?:\.\/|\/)(?:[A-Za-z0-9-_]+\/?)*|"(?:fileb?:\/\/)?(?:\.\/|\/)(?:[^"][A-Za-z0-9-_ ]+\/?)*"|'(?:fileb?:\/\/)?(?:\.\/|\/)(?:[^'][A-Za-z0-9-_ ]+\/?)*'|(?:fileb?:\/\/)(?:[A-Za-z0-9-_]+\/?)*|"(?:fileb?:\/\/)(?:[^"][A-Za-z0-9-_ ]+\/?)*"|'(?:fileb?:\/\/)(?:[^'][A-Za-z0-9-_ ]+\/?)*')(?=\s|$)/g;
const QUOTES_REGEX = /((?<!\\)["']$|^(?<!\\)["'])/g;
const FILE_PREFIX_REGEX = /^fileb?:\/\//;

function readActionArguments(action, settings) {
const method = loadMethodFromConfiguration(action.method.name);
Expand Down Expand Up @@ -57,6 +60,25 @@ async function temporaryFileSentinel(fileDataArray, functionToWatch) {
await unlink(temporaryFilePath);
}

function extractPathsFromCommand(commandString, regex = DEFAULT_PATH_ARGUMENT_REGEX) {
const matches = [...commandString.matchAll(regex)];

const mappedMatches = matches.map((match) => ({
path: stripPathArgument(match[0]),
argument: match[0],
startIndex: match.index,
endIndex: match.index + match[0].length - 1,
}));

return mappedMatches;
}

function stripPathArgument(pathArgument) {
return pathArgument
.replace(QUOTES_REGEX, "")
.replace(FILE_PREFIX_REGEX, "");
}

function removeUndefinedAndEmpty(object) {
if (!_.isPlainObject(object)) { return _.clone(object); }
return _.omitBy(object, (value) => value === "" || _.isNil(value) || (_.isObjectLike(value) && _.isEmpty(value)));
Expand Down Expand Up @@ -101,4 +123,5 @@ function loadConfiguration() {
module.exports = {
readActionArguments,
temporaryFileSentinel,
extractPathsFromCommand,
};
80 changes: 80 additions & 0 deletions helpers.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,83 @@ describe("temporaryFileSentinel", () => {
}).rejects.toThrow(`ENOENT: no such file or directory, open '${pathToTempFile}'`);
});
});

describe("extractPathsFromCommand", () => {
it("should extract all paths", () => {
const commandString = "mkdir /tmp/dir /tmp/dir2/";
const extractedPaths = helpers.extractPathsFromCommand(commandString);

expect(extractedPaths[0].path).toMatch("/tmp/dir");
expect(extractedPaths[0].startIndex).toEqual(6);
expect(extractedPaths[0].endIndex).toEqual(13);
expect(extractedPaths[0].argument).toMatch("/tmp/dir");

expect(extractedPaths[1].path).toMatch("/tmp/dir2/");
expect(extractedPaths[1].argument).toMatch("/tmp/dir2/");
});

it("should extract all paths wrapped with \"", () => {
const commandString = "mkdir \"/tmp/dir\" -p=\"/tmp/dir2\"";
const extractedPaths = helpers.extractPathsFromCommand(commandString);

expect(extractedPaths[0].path).toMatch("/tmp/dir");
expect(extractedPaths[0].startIndex).toEqual(6);
expect(extractedPaths[0].endIndex).toEqual(15);
expect(extractedPaths[0].argument).toMatch("\"/tmp/dir\"");

expect(extractedPaths[1].path).toMatch("/tmp/dir2");
expect(extractedPaths[1].argument).toMatch("\"/tmp/dir2\"");
});

it("should extract all paths wrapped with '", () => {
const commandString = "mkdir -p='/tmp/dir' -p='/tmp/dir2'";
const extractedPaths = helpers.extractPathsFromCommand(commandString);

expect(extractedPaths[0].path).toMatch("/tmp/dir");
expect(extractedPaths[0].startIndex).toEqual(9);
expect(extractedPaths[0].endIndex).toEqual(18);
expect(extractedPaths[0].argument).toMatch("'/tmp/dir'");

expect(extractedPaths[1].path).toMatch("/tmp/dir2");
expect(extractedPaths[1].argument).toMatch("'/tmp/dir2'");
});

it("should extract paths starting with file(b)://", () => {
const commandString = "somecmd -p file:///path/to/the/file -r=fileb://some-directory/file";
const extractedPaths = helpers.extractPathsFromCommand(commandString);

expect(extractedPaths[0].path).toMatch("/path/to/the/file");
expect(extractedPaths[0].startIndex).toEqual(11);
expect(extractedPaths[0].endIndex).toEqual(34);
expect(extractedPaths[0].argument).toMatch("file:///path/to/the/file");

expect(extractedPaths[1].path).toMatch("some-directory/file");
expect(extractedPaths[1].argument).toMatch("fileb://some-directory/file");
});

it("should extract paths starting with file(b):// wrapped with \"", () => {
const commandString = "somecmd -p=\"fileb:///path/to the/file\" -r \"file://relative path/to the/file\"";
const extractedPaths = helpers.extractPathsFromCommand(commandString);

expect(extractedPaths[0].path).toMatch("/path/to the/file");
expect(extractedPaths[0].startIndex).toEqual(11);
expect(extractedPaths[0].endIndex).toEqual(37);
expect(extractedPaths[0].argument).toMatch("\"fileb:///path/to the/file\"");

expect(extractedPaths[1].path).toMatch("relative path/to the/file");
expect(extractedPaths[1].argument).toMatch("\"file://relative path/to the/file\"");
});

it("should extract paths starting with file(b):// wrapped with '", () => {
const commandString = "somecmd -p 'fileb:///path/to the/file' -r='file://relative path/to the/file'";
const extractedPaths = helpers.extractPathsFromCommand(commandString);

expect(extractedPaths[0].path).toMatch("/path/to the/file");
expect(extractedPaths[0].argument).toMatch("'fileb:///path/to the/file'");

expect(extractedPaths[1].path).toMatch("relative path/to the/file");
expect(extractedPaths[1].startIndex).toEqual(42);
expect(extractedPaths[1].endIndex).toEqual(75);
expect(extractedPaths[1].argument).toMatch("'file://relative path/to the/file'");
});
});

0 comments on commit fb3b4b7

Please sign in to comment.