Skip to content

Commit

Permalink
fix: allow . in default name regex, fix bitbucket tarball check
Browse files Browse the repository at this point in the history
Bitbucket tarball url now returns 503 on HEAD request, so we cannot use HEAD
to check. Just try GET request directly, then fallback to git clone.

closes #13
  • Loading branch information
3cp committed Mar 25, 2021
1 parent b97bfa5 commit 5b746c6
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 64 deletions.
4 changes: 2 additions & 2 deletions lib/skeleton-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ const defaultNamePrompt = {
name: 'name',
message: 'Please name this new project:',
default: 'my-app',
validate: value => value.match(/^[a-zA-Z0-9_-]+$/) ? null :
'Please only use letters, numbers, dash(-) and underscore(_).'
validate: value => value.match(/^[.a-zA-Z0-9_-]+$/) ? null :
'Please only use letters, numbers, dot(.), dash(-) and underscore(_).'
};

function defaultRequire(modulePath) {
Expand Down
48 changes: 6 additions & 42 deletions lib/skeleton-dir.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,39 +25,6 @@ function resolveRepo(supplier) {
};
}

function getHash(tarball) {
const url = new URL(tarball);
return new Promise((resolve, reject) => {
const req = https.request({
host: url.hostname,
path: url.pathname + url.search,
method: 'HEAD',
agent
}, res => {
if (res.statusCode === 200) {
let hash;
if (res.headers.etag) {
hash = res.headers.etag;
} else if (res.headers['content-disposition']) {
const m = res.headers['content-disposition'].match(/filename=(.+)$/);
if (m) hash = m[1];
}

if (hash) {
// remove quotes
resolve(hash.replace(/^("|')|("|')$/g, ''));
} else {
reject(new SoftError('Unable to get unique file name for ' + tarball));
}
} else {
reject(new SoftError('Unable to get ' + tarball));
}
});
req.on('error', reject);
req.end();
});
}

async function finalFolder(target, generate) {
await generate(target);

Expand Down Expand Up @@ -104,15 +71,7 @@ module.exports = async function(supplier, {
_tmpFolder = tmp.dirSync({unsafeCleanup: true}).name;
}

try {
await getHash(result.tarball);
} catch (e) {
warn(e.message);
warn('Maybe this is a private skeleton.');
return await _useGitRepo(_tmpFolder, result);
}

return await finalFolder(
return finalFolder(
_tmpFolder,
target => {
info('Fetching tarball ' + result.tarball);
Expand All @@ -132,9 +91,14 @@ module.exports = async function(supplier, {
.once('finish', resolve);
} else {
reject(new SoftError(`Unable to download ${result.tarball}\n${res.statusCode} ${res.statusMessage}`));

}
}
).on('error', reject);
}).catch(e => {
warn(e.message);
warn('Maybe this is a private skeleton.');
return _useGitRepo(_tmpFolder, result);
});
}
);
Expand Down
4 changes: 2 additions & 2 deletions test/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ test.serial('makes checks target folder', async t => {
name: 'name',
message: 'Name:',
validate: value => value.match(/^[a-zA-Z0-9_-]+$/) ? null :
'Please only use letters, numbers, dash(-) and underscore(_).'
'Please only use letters, numbers, dot(.), dash(-) and underscore(_).'
},
questions: [
{
Expand Down Expand Up @@ -83,7 +83,7 @@ test.serial('makes rejects invalid folder name', async t => {
name: 'name',
message: 'Name:',
validate: value => value.match(/^[a-zA-Z0-9_-]+$/) ? null :
'Please only use letters, numbers, dash(-) and underscore(_).'
'Please only use letters, numbers, dot(.), dash(-) and underscore(_).'
},
questions: []
}),
Expand Down
36 changes: 18 additions & 18 deletions test/skeleton-config.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ test.serial('skeletonConfig runs npm install when required', async t => {
delete result.nameQuestion.validate;

t.is(validate('ab-1_2'), null);
t.is(validate(' a'), 'Please only use letters, numbers, dash(-) and underscore(_).');
t.is(validate('@a'), 'Please only use letters, numbers, dash(-) and underscore(_).');
t.is(validate(' a'), 'Please only use letters, numbers, dot(.), dash(-) and underscore(_).');
t.is(validate('@a'), 'Please only use letters, numbers, dot(.), dash(-) and underscore(_).');
t.deepEqual(result, {
nameQuestion: {
name: 'name',
Expand Down Expand Up @@ -57,8 +57,8 @@ test.serial('skeletonConfig does not run npm install when node_modules exists',
delete result.nameQuestion.validate;

t.is(validate('ab-1_2'), null);
t.is(validate(' a'), 'Please only use letters, numbers, dash(-) and underscore(_).');
t.is(validate('@a'), 'Please only use letters, numbers, dash(-) and underscore(_).');
t.is(validate(' a'), 'Please only use letters, numbers, dot(.), dash(-) and underscore(_).');
t.is(validate('@a'), 'Please only use letters, numbers, dot(.), dash(-) and underscore(_).');
t.deepEqual(result, {
nameQuestion: {
name: 'name',
Expand Down Expand Up @@ -90,8 +90,8 @@ test.serial('skeletonConfig does not run npm install for devDependencies', async
delete result.nameQuestion.validate;

t.is(validate('ab-1_2'), null);
t.is(validate(' a'), 'Please only use letters, numbers, dash(-) and underscore(_).');
t.is(validate('@a'), 'Please only use letters, numbers, dash(-) and underscore(_).');
t.is(validate(' a'), 'Please only use letters, numbers, dot(.), dash(-) and underscore(_).');
t.is(validate('@a'), 'Please only use letters, numbers, dot(.), dash(-) and underscore(_).');
t.deepEqual(result, {
nameQuestion: {
name: 'name',
Expand Down Expand Up @@ -123,8 +123,8 @@ test.serial('skeletonConfig skip npm install when not required', async t => {
delete result.nameQuestion.validate;

t.is(validate('ab-1_2'), null);
t.is(validate(' a'), 'Please only use letters, numbers, dash(-) and underscore(_).');
t.is(validate('@a'), 'Please only use letters, numbers, dash(-) and underscore(_).');
t.is(validate(' a'), 'Please only use letters, numbers, dot(.), dash(-) and underscore(_).');
t.is(validate('@a'), 'Please only use letters, numbers, dot(.), dash(-) and underscore(_).');
t.deepEqual(result, {
nameQuestion: {
name: 'name',
Expand Down Expand Up @@ -156,8 +156,8 @@ test.serial('skeletonConfig skip npm install when no packge.json', async t => {
delete result.nameQuestion.validate;

t.is(validate('ab-1_2'), null);
t.is(validate(' a'), 'Please only use letters, numbers, dash(-) and underscore(_).');
t.is(validate('@a'), 'Please only use letters, numbers, dash(-) and underscore(_).');
t.is(validate(' a'), 'Please only use letters, numbers, dot(.), dash(-) and underscore(_).');
t.is(validate('@a'), 'Please only use letters, numbers, dot(.), dash(-) and underscore(_).');
t.deepEqual(result, {
nameQuestion: {
name: 'name',
Expand Down Expand Up @@ -200,8 +200,8 @@ test.serial('skeletonConfig reads questions, and transforms', async t => {
delete result.nameQuestion.validate;

t.is(validate('ab-1_2'), null);
t.is(validate(' a'), 'Please only use letters, numbers, dash(-) and underscore(_).');
t.is(validate('@a'), 'Please only use letters, numbers, dash(-) and underscore(_).');
t.is(validate(' a'), 'Please only use letters, numbers, dot(.), dash(-) and underscore(_).');
t.is(validate('@a'), 'Please only use letters, numbers, dot(.), dash(-) and underscore(_).');
t.deepEqual(result, {
nameQuestion: {
name: 'name',
Expand Down Expand Up @@ -245,8 +245,8 @@ test.serial('skeletonConfig does not inject question for project name if user pr
delete result.nameQuestion.validate;

t.is(validate('ab-1_2'), null);
t.is(validate(' a'), 'Please only use letters, numbers, dash(-) and underscore(_).');
t.is(validate('@a'), 'Please only use letters, numbers, dash(-) and underscore(_).');
t.is(validate(' a'), 'Please only use letters, numbers, dot(.), dash(-) and underscore(_).');
t.is(validate('@a'), 'Please only use letters, numbers, dot(.), dash(-) and underscore(_).');
t.deepEqual(result, {
nameQuestion: {name: 'name', message: 'Name', default: 'my-app'},
questions: [
Expand Down Expand Up @@ -282,8 +282,8 @@ test.serial('skeletonConfig reads before and after tasks', async t => {
delete result.nameQuestion.validate;

t.is(validate('ab-1_2'), null);
t.is(validate(' a'), 'Please only use letters, numbers, dash(-) and underscore(_).');
t.is(validate('@a'), 'Please only use letters, numbers, dash(-) and underscore(_).');
t.is(validate(' a'), 'Please only use letters, numbers, dot(.), dash(-) and underscore(_).');
t.is(validate('@a'), 'Please only use letters, numbers, dot(.), dash(-) and underscore(_).');
t.deepEqual(result, {
nameQuestion: {
name: 'name',
Expand All @@ -309,8 +309,8 @@ test.serial('skeletonConfig reads banner', async t => {
delete result.nameQuestion.validate;

t.is(validate('ab-1_2'), null);
t.is(validate(' a'), 'Please only use letters, numbers, dash(-) and underscore(_).');
t.is(validate('@a'), 'Please only use letters, numbers, dash(-) and underscore(_).');
t.is(validate(' a'), 'Please only use letters, numbers, dot(.), dash(-) and underscore(_).');
t.is(validate('@a'), 'Please only use letters, numbers, dot(.), dash(-) and underscore(_).');
t.deepEqual(result, {
nameQuestion: {
name: 'name',
Expand Down

0 comments on commit 5b746c6

Please sign in to comment.