Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exporting parse function #350

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 5 additions & 43 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,14 @@ import {
stashFiles,
unstashFiles,
degitConfigName,
base
base,
parseSpec
} from './utils.js';

const validModes = new Set(['tar', 'git']);

export { parseSpec };

export default function degit(src, opts) {
return new Degit(src, opts);
}
Expand All @@ -32,7 +35,7 @@ class Degit extends EventEmitter {
this.verbose = opts.verbose;
this.proxy = process.env.https_proxy; // TODO allow setting via --proxy

this.repo = parse(src);
this.repo = parseSpec(src);
this.mode = opts.mode || this.repo.mode;

if (!validModes.has(this.mode)) {
Expand Down Expand Up @@ -322,47 +325,6 @@ class Degit extends EventEmitter {
}
}

const supported = new Set(['github', 'gitlab', 'bitbucket', 'git.sr.ht']);

function parse(src) {
const match = /^(?:(?:https:\/\/)?([^:/]+\.[^:/]+)\/|git@([^:/]+)[:/]|([^/]+):)?([^/\s]+)\/([^/\s#]+)(?:((?:\/[^/\s#]+)+))?(?:\/)?(?:#(.+))?/.exec(
src
);
if (!match) {
throw new DegitError(`could not parse ${src}`, {
code: 'BAD_SRC'
});
}

const site = (match[1] || match[2] || match[3] || 'github').replace(
/\.(com|org)$/,
''
);
if (!supported.has(site)) {
throw new DegitError(
`degit supports GitHub, GitLab, Sourcehut and BitBucket`,
{
code: 'UNSUPPORTED_HOST'
}
);
}

const user = match[4];
const name = match[5].replace(/\.git$/, '');
const subdir = match[6];
const ref = match[7] || 'HEAD';

const domain = `${site}.${
site === 'bitbucket' ? 'org' : site === 'git.sr.ht' ? '' : 'com'
}`;
const url = `https://${domain}/${user}/${name}`;
const ssh = `git@${domain}:${user}/${name}`;

const mode = supported.has(site) ? 'tar' : 'git';

return { site, user, name, ref, url, ssh, subdir, mode };
}

async function untar(file, dest, subdir = null) {
return tar.extract(
{
Expand Down
51 changes: 46 additions & 5 deletions src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,14 @@ export function tryRequire(file, opts) {
}

export function exec(command) {
return new Promise((fulfil, reject) => {
return new Promise((resolve, reject) => {
child_process.exec(command, (err, stdout, stderr) => {
if (err) {
reject(err);
return;
}

fulfil({ stdout, stderr });
resolve({ stdout, stderr });
});
});
}
Expand All @@ -57,7 +57,7 @@ export function mkdirp(dir) {
}

export function fetch(url, dest, proxy) {
return new Promise((fulfil, reject) => {
return new Promise((resolve, reject) => {
let options = url;

if (proxy) {
Expand All @@ -75,11 +75,11 @@ export function fetch(url, dest, proxy) {
if (code >= 400) {
reject({ code, message: response.statusMessage });
} else if (code >= 300) {
fetch(response.headers.location, dest, proxy).then(fulfil, reject);
fetch(response.headers.location, dest, proxy).then(resolve, reject);
} else {
response
.pipe(fs.createWriteStream(dest))
.on('finish', () => fulfil())
.on('finish', () => resolve())
.on('error', reject);
}
})
Expand Down Expand Up @@ -125,3 +125,44 @@ export function unstashFiles(dir, dest) {
}

export const base = path.join(homeOrTmp, '.degit');

const supported = new Set(['github', 'gitlab', 'bitbucket', 'git.sr.ht']);

export function parseSpec(src) {
const match = /^(?:(?:https:\/\/)?([^:/]+\.[^:/]+)\/|git@([^:/]+)[:/]|([^/]+):)?([^/\s]+)\/([^/\s#]+)(?:((?:\/[^/\s#]+)+))?(?:\/)?(?:#(.+))?/.exec(
src
);
if (!match) {
throw new DegitError(`could not parse ${src}`, {
code: 'BAD_SRC'
});
}

const site = (match[1] || match[2] || match[3] || 'github').replace(
/\.(com|org)$/,
''
);
if (!supported.has(site)) {
throw new DegitError(
`degit supports GitHub, GitLab, Sourcehut and BitBucket`,
{
code: 'UNSUPPORTED_HOST'
}
);
}

const user = match[4];
const name = match[5].replace(/\.git$/, '');
const subdir = match[6];
const ref = match[7] || 'HEAD';

const domain = `${site}.${
site === 'bitbucket' ? 'org' : site === 'git.sr.ht' ? '' : 'com'
}`;
const url = `https://${domain}/${user}/${name}`;
const ssh = `git@${domain}:${user}/${name}`;

const mode = supported.has(site) ? 'tar' : 'git';

return { site, user, name, ref, url, ssh, subdir, mode };
}