generated from actions/typescript-action
-
Notifications
You must be signed in to change notification settings - Fork 260
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Provide
shell
and escape
options when formatting matching files
- Loading branch information
Showing
7 changed files
with
124 additions
and
47 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,57 @@ | ||
import shellEscape from '../src/shell-escape' | ||
import {escape, shellEscape} from '../src/shell-escape' | ||
|
||
test('simple filename should not be modified', () => { | ||
expect(shellEscape('file.txt')).toBe('file.txt') | ||
}) | ||
describe('escape() backslash escapes every character except subset of definitely safe characters', () => { | ||
test('simple filename should not be modified', () => { | ||
expect(escape('file.txt')).toBe('file.txt') | ||
}) | ||
|
||
test('directory separator should be preserved and not escaped', () => { | ||
expect(shellEscape('path/to/file.txt')).toBe('path/to/file.txt') | ||
}) | ||
test('directory separator should be preserved and not escaped', () => { | ||
expect(escape('path/to/file.txt')).toBe('path/to/file.txt') | ||
}) | ||
|
||
test('spaces should be escaped with backslash', () => { | ||
expect(shellEscape('file with space')).toBe('file\\ with\\ space') | ||
}) | ||
test('spaces should be escaped with backslash', () => { | ||
expect(escape('file with space')).toBe('file\\ with\\ space') | ||
}) | ||
|
||
test('quotes should be escaped with backslash', () => { | ||
expect(shellEscape('file\'with quote"')).toBe('file\\\'with\\ quote\\"') | ||
test('quotes should be escaped with backslash', () => { | ||
expect(escape('file\'with quote"')).toBe('file\\\'with\\ quote\\"') | ||
}) | ||
|
||
test('$variables should be escaped', () => { | ||
expect(escape('$var')).toBe('\\$var') | ||
}) | ||
}) | ||
|
||
test('$variables sould be escaped', () => { | ||
expect(shellEscape('$var')).toBe('\\$var') | ||
describe('shellEscape() returns human readable filenames with as few escaping applied as possible', () => { | ||
test('simple filename should not be modified', () => { | ||
expect(shellEscape('file.txt')).toBe('file.txt') | ||
}) | ||
|
||
test('directory separator should be preserved and not escaped', () => { | ||
expect(shellEscape('path/to/file.txt')).toBe('path/to/file.txt') | ||
}) | ||
|
||
test('filename with spaces should be quoted', () => { | ||
expect(shellEscape('file with space')).toBe("'file with space'") | ||
}) | ||
|
||
test('filename with spaces should be quoted', () => { | ||
expect(shellEscape('file with space')).toBe("'file with space'") | ||
}) | ||
|
||
test('filename with $ should be quoted', () => { | ||
expect(shellEscape('$var')).toBe("'$var'") | ||
}) | ||
|
||
test('filename with " should be quoted', () => { | ||
expect(shellEscape('file"name')).toBe("'file\"name'") | ||
}) | ||
|
||
test('filename with single quote should be wrapped in double quotes', () => { | ||
expect(shellEscape("file'with quote")).toBe('"file\'with quote"') | ||
}) | ||
|
||
test('filename with single quote and special characters is split and quoted/escaped as needed', () => { | ||
expect(shellEscape("file'with $quote")).toBe("file\\''with $quote'") | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,28 @@ | ||
// Uses easy safe set of characters which can be left unescaped to keep it readable. | ||
// Every other character will be backslash-escaped | ||
export default function shellEscape(value: string): string { | ||
// Backslash escape every character except small subset of definitely safe characters | ||
export function escape(value: string): string { | ||
return value.replace(/([^a-zA-Z0-9,._+:@%/-])/gm, '\\$1') | ||
} | ||
|
||
// Returns filename escaped for usage as shell argument. | ||
// Applies "human readable" approach with as few escaping applied as possible | ||
export function shellEscape(value: string): string { | ||
if (value === '') return value | ||
|
||
// Only safe characters | ||
if (/^[a-zA-Z0-9,._+:@%/-]+$/m.test(value)) { | ||
return value | ||
} | ||
|
||
if (value.includes("'")) { | ||
// Only safe characters, single quotes and white-spaces | ||
if (/^[a-zA-Z0-9,._+:@%/'\s-]+$/m.test(value)) { | ||
return `"${value}"` | ||
} | ||
|
||
// Split by single quote and apply escaping recursively | ||
return value.split("'").map(shellEscape).join("\\'") | ||
} | ||
|
||
// Contains some unsafe characters but no single quote | ||
return `'${value}'` | ||
} |