Skip to content

Commit

Permalink
fix(preProcessPatterns): support glob context paths with special char…
Browse files Browse the repository at this point in the history
…acters (#208)
  • Loading branch information
clydin authored and michael-ciniawsky committed Jan 26, 2018
1 parent f6c1ba7 commit ea0c05f
Show file tree
Hide file tree
Showing 6 changed files with 142 additions and 4 deletions.
7 changes: 5 additions & 2 deletions src/preProcessPattern.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import fs from 'fs';
import pify from 'pify';
import path from 'path';
import isGlob from 'is-glob';
import escape from './utils/escape';
import isObject from './utils/isObject';

// https://www.debuggex.com/r/VH2yS2mvJOitiyr3
Expand Down Expand Up @@ -46,7 +47,7 @@ export default function preProcessPattern(globalRef, pattern) {
delete fromArgs.glob;

pattern.fromArgs = fromArgs;
pattern.absoluteFrom = path.resolve(pattern.context, pattern.from.glob);
pattern.absoluteFrom = escape(pattern.context, pattern.from.glob);
return Promise.resolve(pattern);
}

Expand All @@ -63,6 +64,7 @@ export default function preProcessPattern(globalRef, pattern) {
// If from doesn't appear to be a glob, then log a warning
if (isGlob(pattern.from) || pattern.from.indexOf('*') !== -1) {
pattern.fromType = 'glob';
pattern.absoluteFrom = escape(pattern.context, pattern.from);
} else {
const msg = `unable to locate '${pattern.from}' at '${pattern.absoluteFrom}'`;
warning(msg);
Expand All @@ -79,13 +81,14 @@ export default function preProcessPattern(globalRef, pattern) {
pattern.fromType = 'dir';
pattern.context = pattern.absoluteFrom;
contextDependencies.push(pattern.absoluteFrom);
pattern.absoluteFrom = path.join(pattern.absoluteFrom, '**/*');
pattern.absoluteFrom = escape(pattern.absoluteFrom, '**/*');
pattern.fromArgs = {
dot: true
};
} else if(stat.isFile()) {
pattern.fromType = 'file';
pattern.context = path.dirname(pattern.absoluteFrom);
pattern.absoluteFrom = escape(pattern.absoluteFrom);
pattern.fromArgs = {
dot: true
};
Expand Down
24 changes: 24 additions & 0 deletions src/utils/escape.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import path from 'path';

export default function escape(context, from) {
if (from && path.isAbsolute(from)) {
return from;
} else {
// Ensure context is escaped before globbing
// Handles special characters in paths
const absoluteContext = path.resolve(context)
.replace(/\\/, '/')
.replace(/[\*|\?|\!|\(|\)|\[|\]|\{|\}]/g, (substring) => `\\${substring}`);

if (!from) {
return absoluteContext;
}

// Cannot use path.join/resolve as it "fixes" the path separators
if (absoluteContext.endsWith('/')) {
return `${absoluteContext}${from}`;
} else {
return `${absoluteContext}/${from}`;
}
}
}
1 change: 1 addition & 0 deletions tests/helpers/[special?directory]/(special-*file).txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
special
1 change: 1 addition & 0 deletions tests/helpers/[special?directory]/directoryfile.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
new
Empty file.
113 changes: 111 additions & 2 deletions tests/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,9 @@ describe('apply function', () => {
'file.txt.gz',
'directory/directoryfile.txt',
'directory/nested/nestedfile.txt',
'[special?directory]/directoryfile.txt',
'[special?directory]/(special-*file).txt',
'[special?directory]/nested/nestedfile.txt',
'noextension'
],
patterns: [{
Expand All @@ -287,6 +290,9 @@ describe('apply function', () => {
'nested/file.txt.gz',
'nested/directory/directoryfile.txt',
'nested/directory/nested/nestedfile.txt',
'nested/[special?directory]/directoryfile.txt',
'nested/[special?directory]/(special-*file).txt',
'nested/[special?directory]/nested/nestedfile.txt',
'nested/noextension'
],
patterns: [{
Expand Down Expand Up @@ -314,6 +320,38 @@ describe('apply function', () => {
.catch(done);
});

it('can use a direct glob to move multiple files in a different relative context with special characters', (done) => {
runEmit({
expectedAssetKeys: [
'directoryfile.txt',
'(special-*file).txt',
'nested/nestedfile.txt'
],
patterns: [{
context: '[special?directory]',
from: { glob: '**/*' }
}]
})
.then(done)
.catch(done);
});

it('can use a glob to move multiple files in a different relative context with special characters', (done) => {
runEmit({
expectedAssetKeys: [
'directoryfile.txt',
'(special-*file).txt',
'nested/nestedfile.txt'
],
patterns: [{
context: '[special?directory]',
from: '**/*'
}]
})
.then(done)
.catch(done);
});

it('can use a glob to flatten multiple files in a relative context to a non-root directory', (done) => {
runEmit({
expectedAssetKeys: [
Expand Down Expand Up @@ -365,7 +403,10 @@ describe('apply function', () => {
expectedAssetKeys: [
'file.txt',
'directory/directoryfile.txt',
'directory/nested/nestedfile.txt'
'directory/nested/nestedfile.txt',
'[special?directory]/directoryfile.txt',
'[special?directory]/(special-*file).txt',
'[special?directory]/nested/nestedfile.txt'
],
patterns: [{
from: path.join(HELPER_DIR, '**/*.txt')
Expand All @@ -383,6 +424,9 @@ describe('apply function', () => {
'nested/file.txt-5b311c.gz',
'nested/directory/directoryfile-22af64.txt',
'nested/directory/nested/nestedfile-d41d8c.txt',
'nested/[special?directory]/(special-*file)-0bd650.txt',
'nested/[special?directory]/directoryfile-22af64.txt',
'nested/[special?directory]/nested/nestedfile-d41d8c.txt',
'nested/noextension-d41d8c'
],
patterns: [{
Expand Down Expand Up @@ -586,6 +630,34 @@ describe('apply function', () => {
.catch(done);
});

it('can move a file with a context containing special characters', (done) => {
runEmit({
expectedAssetKeys: [
'directoryfile.txt'
],
patterns: [{
from: 'directoryfile.txt',
context: '[special?directory]'
}]
})
.then(done)
.catch(done);
});

it('can move a file with special characters with a context containing special characters', (done) => {
runEmit({
expectedAssetKeys: [
'(special-*file).txt'
],
patterns: [{
from: '(special-*file).txt',
context: '[special?directory]'
}]
})
.then(done)
.catch(done);
});

it('can move a file to a new directory with an extension', (done) => {
runEmit({
expectedAssetKeys: [
Expand Down Expand Up @@ -797,6 +869,9 @@ describe('apply function', () => {
'binextension.bin',
'directory/directoryfile.txt',
'directory/nested/nestedfile.txt',
'[special?directory]/directoryfile.txt',
'[special?directory]/(special-*file).txt',
'[special?directory]/nested/nestedfile.txt',
'noextension'
],
patterns: [{
Expand Down Expand Up @@ -880,6 +955,37 @@ describe('apply function', () => {
.catch(done);
});

it('can move a directory\'s contents to the root directory using from with special characters', (done) => {
runEmit({
expectedAssetKeys: [
'directoryfile.txt',
'(special-*file).txt',
'nested/nestedfile.txt'
],
patterns: [{
from: '[special?directory]'
}]
})
.then(done)
.catch(done);
});

it('can move a directory\'s contents to the root directory using context with special characters', (done) => {
runEmit({
expectedAssetKeys: [
'directoryfile.txt',
'(special-*file).txt',
'nested/nestedfile.txt'
],
patterns: [{
from: '.',
context: '[special?directory]'
}]
})
.then(done)
.catch(done);
});

it('warns when directory not found', (done) => {
runEmit({
expectedAssetKeys: [],
Expand Down Expand Up @@ -1202,6 +1308,9 @@ describe('apply function', () => {
'file.txt.gz',
'directory/directoryfile.txt',
'directory/nested/nestedfile.txt',
'[special?directory]/directoryfile.txt',
'[special?directory]/(special-*file).txt',
'[special?directory]/nested/nestedfile.txt',
'noextension'
],
options: {
Expand Down Expand Up @@ -1260,7 +1369,7 @@ describe('apply function', () => {
'noextension'
],
options: {
ignore: ['directory/**/*']
ignore: ['directory/**/*', '\\[special\\?directory\\]/**/*']
},
patterns: [{
from: '.'
Expand Down

0 comments on commit ea0c05f

Please sign in to comment.