Skip to content

Commit

Permalink
feat: better log on transform error
Browse files Browse the repository at this point in the history
  • Loading branch information
3cp committed Nov 21, 2019
1 parent 9c771ba commit d38c043
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 93 deletions.
33 changes: 19 additions & 14 deletions lib/write-project/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,26 +20,31 @@ module.exports = function({
prependTransforms = [],
appendTransforms = []
}) {
// Folder "common" is the base template folder
const folders = ['common', ...features].map(f => path.join(skeletonDir, f));
return new Promise((resolve, reject) => {
// Folder "common" is the base template folder
const folders = ['common', ...features].map(f => path.join(skeletonDir, f));

let s = src(folders);
let s = src(folders).on('error', reject);

const params = [properties, features, targetDir, unattended, prompts];
prependTransforms.forEach(t => s = s.pipe(t(...params)));
const params = [properties, features, targetDir, unattended, prompts];
prependTransforms.forEach(t => s = s.pipe(t(...params)).on('error', reject));

s = s.pipe(wrap(_1_markWritePolicy))
.pipe(wrap( _2_filterByFeatures(features)))
.pipe(wrap( _3_preprocess(properties, features)))
.pipe( _4_mergeFiles());
s = s.pipe(wrap(_1_markWritePolicy))
.on('error', reject)
.pipe(wrap( _2_filterByFeatures(features)))
.on('error', reject)
.pipe(wrap( _3_preprocess(properties, features)))
.on('error', reject)
.pipe( _4_mergeFiles())
.on('error', reject);

appendTransforms.forEach(t => s = s.pipe(t(...params)));
appendTransforms.forEach(t => s = s.pipe(t(...params)).on('error', reject));

s = s.pipe(whenFileExists(targetDir, unattended))
.pipe(dest(targetDir));
s = s.pipe(whenFileExists(targetDir, unattended))
.on('error', reject)
.pipe(dest(targetDir))
.on('error', reject);

return new Promise((resolve, reject) => {
s.once('error', reject);
s.once('finish', resolve);
});
};
8 changes: 7 additions & 1 deletion lib/write-project/wrap-transform.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@ module.exports = function(transform) {
objectMode: true,
transform: (file, enc, cb) => {
if (file.isBuffer()) {
file = transform(file);
try {
file = transform(file);
} catch (e) {
e.message = `Error in skeleton file: ${file.path}\n${e.message}`;
cb(e);
return;
}
}
cb(null, file);
}
Expand Down
88 changes: 44 additions & 44 deletions test/write-project/4-merge-files.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,36 @@ import Vinyl from 'vinyl';

test.cb('mergeFiles bypasses unique file', t => {
const merge = mergeFiles();
const files = [];
merge.on('data', file => files.push(file));
merge.once('end', () => {
t.is(files.length, 1);
t.is(files[0].path.replace(/\\/g, '/'), '/test/foo/bar.ext');
t.is(files[0].contents.toString(), 'abc');
t.end();
});

merge.write(new Vinyl({
cwd: '/',
base: '/test',
path: '/test/foo/bar.ext',
contents: Buffer.from('abc')
}));

merge.end();
});

test.cb('mergeFiles by default use last file with same relative path', t => {
const merge = mergeFiles();
const files = [];
merge.on('data', file => files.push(file));

merge.end();
merge.once('end', () => {
t.is(files.length, 1);
t.is(files[0].path.replace(/\\/g, '/'), '/test/foo/bar.ext');
t.is(files[0].contents.toString(), 'abc');
t.is(files[0].path.replace(/\\/g, '/'), '/f2/foo/bar.ext');
t.is(files[0].contents.toString(), 'efg');
t.end();
});
});

test.cb('mergeFiles by default use last file with same relative path', t => {
const merge = mergeFiles();
merge.write(new Vinyl({
cwd: '/',
base: '/test',
Expand All @@ -44,20 +53,22 @@ test.cb('mergeFiles by default use last file with same relative path', t => {
contents: Buffer.from('efg')
}));

merge.end();
});

test.cb('mergeFiles by default merges json files', t => {
const merge = mergeFiles();
const files = [];
merge.on('data', file => files.push(file));

merge.end();
merge.once('end', () => {
t.is(files.length, 1);
t.is(files[0].path.replace(/\\/g, '/'), '/f2/foo/bar.ext');
t.is(files[0].contents.toString(), 'efg');
t.is(files[0].path.replace(/\\/g, '/'), '/test/foo/bar.json');
t.deepEqual(JSON.parse(files[0].contents.toString()), {
a:2, b: [1,2,3]
});
t.end();
});
});

test.cb('mergeFiles by default merges json files', t => {
const merge = mergeFiles();
merge.write(new Vinyl({
cwd: '/',
base: '/test',
Expand All @@ -77,45 +88,43 @@ test.cb('mergeFiles by default merges json files', t => {
contents: Buffer.from('{"b":[2,3]}')
}));

merge.end();
});

test.cb('mergeFiles cleanup single json file', t => {
const merge = mergeFiles();
const files = [];
merge.on('data', file => files.push(file));

merge.end();
merge.once('end', () => {
t.is(files.length, 1);
t.is(files[0].path.replace(/\\/g, '/'), '/test/foo/bar.json');
t.deepEqual(JSON.parse(files[0].contents.toString()), {
a:2, b: [1,2,3]
a:1
});
t.end();
});
});

test.cb('mergeFiles cleanup single json file', t => {
const merge = mergeFiles();
merge.write(new Vinyl({
cwd: '/',
base: '/test',
path: '/test/foo/bar.json',
contents: Buffer.from('{"a":1,}')
}));

merge.end();
});

test.cb('mergeFiles by default appends readme file', t => {
const merge = mergeFiles();
const files = [];
merge.on('data', file => files.push(file));

merge.end();
merge.once('end', () => {
t.is(files.length, 1);
t.is(files[0].path.replace(/\\/g, '/'), '/test/foo/bar.json');
t.deepEqual(JSON.parse(files[0].contents.toString()), {
a:1
});
t.is(files[0].path.replace(/\\/g, '/'), '/test/foo/readme.txt');
t.is(files[0].contents.toString(), 'foo\nbar\nlo');
t.end();
});
});

test.cb('mergeFiles by default appends readme file', t => {
const merge = mergeFiles();
merge.write(new Vinyl({
cwd: '/',
base: '/test',
Expand All @@ -135,20 +144,20 @@ test.cb('mergeFiles by default appends readme file', t => {
contents: Buffer.from('lo')
}));

merge.end();
});

test.cb('mergeFiles by default appends readme file, case2', t => {
const merge = mergeFiles();
const files = [];
merge.on('data', file => files.push(file));

merge.end();
merge.once('end', () => {
t.is(files.length, 1);
t.is(files[0].path.replace(/\\/g, '/'), '/test/foo/readme.txt');
t.is(files[0].path.replace(/\\/g, '/'), '/test/foo/README');
t.is(files[0].contents.toString(), 'foo\nbar\nlo');
t.end();
});
});

test.cb('mergeFiles by default appends readme file, case2', t => {
const merge = mergeFiles();
merge.write(new Vinyl({
cwd: '/',
base: '/test',
Expand All @@ -168,14 +177,5 @@ test.cb('mergeFiles by default appends readme file, case2', t => {
contents: Buffer.from('lo')
}));

const files = [];
merge.on('data', file => files.push(file));

merge.end();
merge.once('end', () => {
t.is(files.length, 1);
t.is(files[0].path.replace(/\\/g, '/'), '/test/foo/README');
t.is(files[0].contents.toString(), 'foo\nbar\nlo');
t.end();
});
});
20 changes: 20 additions & 0 deletions test/write-project/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,3 +150,23 @@ test.serial('writeProject supports prependTransforms and appendTransforms', asyn
'file-b'
);
});

test.serial('writeProject reports error', async t => {
mockfs({
'skeleton/feature1/file.js': '// @if feature2\na\n',
});

try {
await writeProject({
properties: {name: 'app'},
features: ['feature1'],
skeletonDir: 'skeleton',
targetDir: 'here'
});
} catch (e) {
t.is(e.message, 'Error in skeleton file: skeleton/feature1/file.js\nUnbalanced delimiter found in string');
return;
}

t.fail('should not be here');
});

0 comments on commit d38c043

Please sign in to comment.