Skip to content

Commit

Permalink
fix(command-init): remove code duplication with sites:create and ad…
Browse files Browse the repository at this point in the history
…d error handling (#1619)
  • Loading branch information
erezrokah authored Dec 3, 2020
1 parent bd59e01 commit 7090638
Show file tree
Hide file tree
Showing 10 changed files with 515 additions and 428 deletions.
55 changes: 6 additions & 49 deletions src/commands/init.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@ const inquirer = require('inquirer')
const isEmpty = require('lodash/isEmpty')

const Command = require('../utils/command')
const getRepoData = require('../utils/get-repo-data')
const { getRepoData } = require('../utils/get-repo-data')
const { ensureNetlifyIgnore } = require('../utils/gitignore')
const configGithub = require('../utils/init/config-github')
const configManual = require('../utils/init/config-manual')
const { configureRepo } = require('../utils/init/config')
const { track } = require('../utils/telemetry')

const LinkCommand = require('./link')
Expand Down Expand Up @@ -168,46 +167,6 @@ const logExistingRepoSetupAndExit = ({ log, exit, siteName, repoUrl }) => {
exit()
}

const configureGitHub = async ({ context, siteInfo, repo }) => {
try {
await configGithub(context, siteInfo, repo)
} catch (error) {
context.warn(`GitHub error: ${error.status}`)
if (error.status === 404) {
context.error(
`Does the repository ${repo.repo_path} exist and do you have the correct permissions to set up deploy keys?`,
)
} else {
throw error
}
}
}

const configureProvider = async ({ context, siteInfo, repo }) => {
switch (repo.provider) {
case 'github': {
await configureGitHub({ context, siteInfo, repo })
break
}
default: {
context.error('No configurator found for the git hosting service')
}
}
}

const logSuccess = ({ log, repo }) => {
log()
log(chalk.greenBright.bold.underline(`Success! Netlify CI/CD Configured!`))
log()
log(`This site is now configured to automatically deploy from ${repo.provider} branches & pull requests`)
log()
log(`Next steps:
${chalk.cyanBright.bold('git push')} Push to your git repository to trigger new site builds
${chalk.cyanBright.bold('netlify open')} Open the Netlify admin URL of your site
`)
}

class InitCommand extends Command {
async run() {
const { flags } = this.parse(InitCommand)
Expand All @@ -229,9 +188,9 @@ class InitCommand extends Command {
}

// Look for local repo
const repo = await getRepoData(flags.gitRemoteName)
if (repo.error) {
await handleNoGitRemoteAndExit({ log, exit, error: repo.error, state })
const repoData = await getRepoData({ log, remoteName: flags.gitRemoteName })
if (repoData.error) {
await handleNoGitRemoteAndExit({ log, exit, error: repoData.error, state })
}

if (isEmpty(siteInfo)) {
Expand All @@ -246,9 +205,7 @@ class InitCommand extends Command {

persistState({ state, siteInfo })

await (flags.manual ? configManual(this, siteInfo, repo) : configureProvider({ context: this, siteInfo, repo }))

logSuccess({ log, repo })
await configureRepo({ context: this, siteId: siteInfo.id, repoData, manual: flags.manual })

return siteInfo
}
Expand Down
48 changes: 4 additions & 44 deletions src/commands/sites/create.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@ const chalk = require('chalk')
const inquirer = require('inquirer')
const pick = require('lodash/pick')
const sample = require('lodash/sample')
const parseGitRemote = require('parse-github-url')
const prettyjson = require('prettyjson')

const Command = require('../../utils/command')
const configGithub = require('../../utils/init/config-github')
const configManual = require('../../utils/init/config-manual')
const { getRepoData } = require('../../utils/get-repo-data')
const { configureRepo } = require('../../utils/init/config')
const { track } = require('../../utils/telemetry')

class SitesCreateCommand extends Command {
Expand Down Expand Up @@ -118,47 +117,8 @@ class SitesCreateCommand extends Command {

if (flags['with-ci']) {
this.log('Configuring CI')
const { url } = await inquirer.prompt([
{
type: 'input',
name: 'url',
message: 'Git SSH remote URL to enable CI with:',
validate: (input) => (parseGitRemote(input) ? true : `Could not parse Git remote ${input}`),
},
])
console.log(url)
const repoData = parseGitRemote(url)
const repo = {
repoData,
repo_path: url,
}

switch (true) {
case flags.manual: {
await configManual(this, site, repo)
break
}
case repoData.host === 'github.com': {
try {
await configGithub(this, site, repo)
} catch (error) {
this.warn(`Github error: ${error.status}`)
if (error.status === 404) {
this.error(
`Does the repository ${repo.repo_path} exist and do you have the correct permissions to set up deploy keys?`,
)
} else {
throw error
}
}
break
}
default: {
this.log('No configurator found for the provided git remote. Configuring manually...')
await configManual(this, site, repo)
break
}
}
const repoData = await getRepoData({ log: this.log })
await configureRepo({ context: this, siteId: site.id, repoData, manual: flags.manual })
}

if (flags.json) {
Expand Down
59 changes: 26 additions & 33 deletions src/utils/get-repo-data.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const path = require('path')
const { dirname } = require('path')
const process = require('process')
const util = require('util')

Expand All @@ -8,63 +8,56 @@ const gitconfiglocal = require('gitconfiglocal')
const isEmpty = require('lodash/isEmpty')
const parseGitRemote = require('parse-github-url')

const getRepoData = async function (remote) {
const cwd = process.cwd()
let repo = {}
const getRepoData = async function ({ log, remoteName }) {
try {
const gitConfig = await util.promisify(gitconfiglocal)(cwd)
const gitDirectory = findUp.sync(['.git'], { cwd, type: 'directory' })
const baseGitPath = path.dirname(gitDirectory)
const cwd = process.cwd()
const [gitConfig, gitDirectory] = await Promise.all([
util.promisify(gitconfiglocal)(cwd),
findUp('.git', { cwd, type: 'directory' }),
])
const baseGitPath = dirname(gitDirectory)

if (cwd !== baseGitPath) {
console.log(`Git directory located in ${baseGitPath}`)
// TODO prompt for "is this the correct git remote"?
// If folder gitignored inside another git repo it could link to wrong repo.
log(`Git directory located in ${baseGitPath}`)
}

if (isEmpty(gitConfig) || isEmpty(gitConfig.remote)) {
throw new Error('No Git remote found')
}

if (!remote) {
remote = Object.prototype.hasOwnProperty.call(gitConfig, 'origin')
? 'origin'
: Object.keys(gitConfig.remote).shift()
if (!remoteName) {
const remotes = Object.keys(gitConfig.remote)
remoteName = remotes.find((remote) => remote === 'origin') || remotes[0]
}

if (!Object.prototype.hasOwnProperty.call(gitConfig.remote, remote) || isEmpty(gitConfig.remote[remote])) {
if (!Object.prototype.hasOwnProperty.call(gitConfig.remote, remoteName) || isEmpty(gitConfig.remote[remoteName])) {
throw new Error(
`The specified remote "${remote}" is not defined in Git repo. Please use --gitRemoteName flag to specify a remote.`,
`The specified remote "${remoteName}" is not defined in Git repo. Please use --gitRemoteName flag to specify a remote.`,
)
}

const remoteData = parseGitRemote(gitConfig.remote[remote].url)
const repoData = gitRepoInfo()

// TODO refactor shape
repo = {
gitDirectoryPath: gitDirectory,
remoteData,
repoData,
repo_path: remoteData.path,
repo_branch: repoData.branch,
allowed_branches: [repoData.branch],
host: remoteData.host,
provider: PROVIDERS[remoteData.host],
const { url } = gitConfig.remote[remoteName]
const { name, owner, host, repo } = parseGitRemote(url)
const { branch } = gitRepoInfo()
return {
name,
owner,
repo,
url,
branch,
provider: PROVIDERS[host] || host,
httpsUrl: `https://${host}/${repo}`,
}
} catch (error) {
// console.log('error', error)
return {
error: error.message,
}
}

return repo
}

const PROVIDERS = {
'github.com': 'github',
'gitlab.com': 'gitlab',
}

module.exports = getRepoData
module.exports = { getRepoData }
Loading

0 comments on commit 7090638

Please sign in to comment.