From cf935c741cfd57a585ceda7c0404d1049528cc50 Mon Sep 17 00:00:00 2001 From: Matt Travi Date: Thu, 11 Apr 2019 00:12:40 -0500 Subject: [PATCH] feat(repo-creation): prevented creation without an auth-ed octokit client closes #1 --- src/github-client-factory.js | 19 ++++++++++++++-- src/scaffolder.js | 4 ++-- test/unit/github-client-factory-test.js | 6 +++++ test/unit/scaffolder-test.js | 29 ++++++++++++++++++++----- 4 files changed, 48 insertions(+), 10 deletions(-) diff --git a/src/github-client-factory.js b/src/github-client-factory.js index c8a774af..60352e00 100644 --- a/src/github-client-factory.js +++ b/src/github-client-factory.js @@ -1,8 +1,23 @@ +import chalk from 'chalk'; import Octokit from '../third-party-wrappers/octokit'; import netrc from '../third-party-wrappers/netrc'; +function getPersonalAccessTokenFromNetRc() { + console.error(chalk.grey('Getting GitHub Personal Access Token from ~/.netrc')); // eslint-disable-line no-console + + const githubNetrcElement = netrc()['github.com']; + + if (githubNetrcElement) return githubNetrcElement.login; + + console.error(chalk.grey('No GitHub Personal Access Token available in ~/.netrc')); // eslint-disable-line no-console + + return undefined; +} + export function factory() { - const personalAccessToken = netrc()['github.com'].login; + const personalAccessToken = getPersonalAccessTokenFromNetRc(); + + if (personalAccessToken) return new Octokit({auth: `token ${personalAccessToken}`}); - return new Octokit({auth: `token ${personalAccessToken}`}); + return undefined; } diff --git a/src/scaffolder.js b/src/scaffolder.js index ba08fb96..b296ff3e 100644 --- a/src/scaffolder.js +++ b/src/scaffolder.js @@ -10,8 +10,8 @@ export async function scaffold({name, owner, projectRoot, projectType, descripti const [, creationResult] = await Promise.all([ scaffoldSettings(projectRoot, name, description, homepage, visibility, projectType), - create(name, owner, visibility, octokit) + ...octokit ? [create(name, owner, visibility, octokit)] : [] ]); - return creationResult; + return {...creationResult}; } diff --git a/test/unit/github-client-factory-test.js b/test/unit/github-client-factory-test.js index d389b3a8..cb25beda 100644 --- a/test/unit/github-client-factory-test.js +++ b/test/unit/github-client-factory-test.js @@ -26,4 +26,10 @@ suite('github client factory', () => { assert.equal(factory(), instance); assert.calledWithNew(octokit.default); }); + + test('that no client is returned if no token is available in the netrc', () => { + netrc.default.returns({}); + + assert.isUndefined(factory()); + }); }); diff --git a/test/unit/scaffolder-test.js b/test/unit/scaffolder-test.js index bf56045f..58efcccb 100644 --- a/test/unit/scaffolder-test.js +++ b/test/unit/scaffolder-test.js @@ -10,6 +10,11 @@ suite('github', () => { let sandbox; const projectRoot = any.string(); const projectName = any.string(); + const description = any.sentence(); + const homepage = any.url(); + const projectType = any.word(); + const projectOwner = any.word(); + const visibility = any.word(); setup(() => { sandbox = sinon.createSandbox(); @@ -22,18 +27,13 @@ suite('github', () => { teardown(() => sandbox.restore()); test('that the settings file is produced and the repository is created', async () => { - const description = any.sentence(); - const homepage = any.url(); - const projectType = any.word(); - const projectOwner = any.word(); - const visibility = any.word(); const creationResult = any.simpleObject(); const octokitClient = any.simpleObject(); settingsScaffolder.default.resolves(); creator.default.withArgs(projectName, projectOwner, visibility, octokitClient).resolves(creationResult); clientFactory.factory.returns(octokitClient); - assert.equal( + assert.deepEqual( await scaffold({ projectRoot, name: projectName, @@ -56,4 +56,21 @@ suite('github', () => { projectType ); }); + + test('that the repo is not created if an octokit client is not available', async () => { + clientFactory.factory.returns(undefined); + + assert.deepEqual( + await scaffold({ + projectRoot, + name: projectName, + owner: projectOwner, + description, + homepage, + projectType, + visibility + }), + {} + ); + }); });