Skip to content

refactor: extract deploy command logic into separate functions #1240

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

Merged
merged 3 commits into from
Sep 17, 2020

Conversation

erezrokah
Copy link
Contributor

- Summary

The PR refactors the deploy command code by extracting most of the logic into functions.
Some logic mutates objects so I didn't extract it yet since I wanted the functions to be pure.

- Test plan

Tested manually the different deploy flags, and actually exposed old bugs in the process (which I fixed).

- Description for the changelog

Should not change behaviour

- A picture of a cute animal (not mandatory but encouraged)

🐼

Related to #1236 and #1227 - I initially started looking into those issues and found the code very hard to follow.

@@ -16,20 +16,263 @@ const SitesCreateCommand = require('./sites/create')
const LinkCommand = require('./link')
const { NETLIFYDEV, NETLIFYDEVLOG, NETLIFYDEVERR } = require('../utils/logo')

const triggerDeploy = async ({ api, siteId, siteData, log, error }) => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extracted from

}

const getDeployFolder = async ({ flags, config, site, siteData, log }) => {
let deployFolder
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extracted from

let deployFolder
and
if (!deployFolder) {

return deployFolder
}

const validateDeployFolder = async ({ deployFolder, error }) => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Old version was:

function ensureDirectory(resolvedDeployPath, error) {

Which was broken in multiple places:

  1. Using e.status instead of e.code (fixed in the new version)
    if (e.status === 'ENOENT') {
  2. Referencing stat.isDirectory instead of stat.isDirectory()
    if (!stat.isDirectory) {

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤦‍♂️

return stat
}

const getFunctionsFolder = ({ flags, config, site, siteData }) => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extracted from

let functionsFolder

return functionsFolder
}

const validateFunctionsFolder = async ({ functionsFolder, log, error }) => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extracted from

let functionsFolder
and fixed to reference stat.isDirectory()

const validateFolders = async ({ deployFolder, functionsFolder, error, log }) => {
const deployFolderStat = await validateDeployFolder({ deployFolder, error })
const functionsFolderStat = await validateFunctionsFolder({ functionsFolder, error, log })
return { deployFolderStat, functionsFolderStat }
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need the return value of validateFunctionsFolder. If it's undefined (since the folder doesn't exist) we don't pass functionsFolder to the js-client.
This was done here:

functionsFolder = undefined

return { deployFolderStat, functionsFolderStat }
}

const runDeploy = async ({
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extracted from here:

let results

const deployUrl = get(results, 'deploy.deploy_ssl_url') || get(results, 'deploy.deploy_url')
const logsUrl = `${get(results, 'deploy.admin_url')}/deploys/${get(results, 'deploy.id')}`

return {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This information was used here

const siteUrl = results.deploy.ssl_url || results.deploy.url
and here
name: results.deploy.deployId,

}
}

const printResults = ({ flags, results, deployToProduction, log, logJson, exit }) => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extracted from

const msgData = {

branch: alias,
log(
prettyjson.render({
'Deploy path': deployFolder,
Copy link
Contributor Author

@erezrokah erezrokah Sep 15, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need the conditions here:

pathInfo['Functions path'] = functionsFolder

and here
pathInfo['Configuration path'] = configPath
as prettyjson doesn't print undefined values

}

const deployToProduction = flags.prod
if (deployToProduction && alias) {
this.error(`--prod and --alias flags cannot be used at the same time`)
Copy link
Contributor Author

@erezrokah erezrokah Sep 15, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replaced this with exclusive: ['alias', 'branch'] on the prod flag: https://github.com/netlify/cli/pull/1240/files#diff-e9001bf37e31e33db8a717da3ac59a69R474

@erezrokah erezrokah marked this pull request as ready for review September 15, 2020 17:15
@erezrokah erezrokah added the type: chore work needed to keep the product and development running smoothly label Sep 15, 2020
}

const validateFolders = async ({ deployFolder, functionsFolder, error, log }) => {
const deployFolderStat = await validateDeployFolder({ deployFolder, error })
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we run those two async functions in parallel (Promise.all())?

Copy link
Contributor Author

@erezrokah erezrokah Sep 16, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

validateFunctionsFolder prints a warning message when the folder doesn't exist, while validateDeployFolder exits.
Didn't want to run into a case where we print a warning then exit with another error.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense 👍
This is micro-optimization anyway since those I/O calls are quite fast.

statusCb: flags.json || flags.silent ? () => {} : deployProgressCb(),
draft: !deployToProduction && !alias,
message: flags.message,
deployTimeout: flags.timeout * 1000 || 1.2e6,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we extract that 1.2e6 into a top-level constant variable?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure going to update it

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

@ehmicky ehmicky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @erezrokah, this is much cleaner! 🎉

@erezrokah erezrokah mentioned this pull request Sep 16, 2020
1 task
@erezrokah erezrokah merged commit c9ae248 into master Sep 17, 2020
@erezrokah erezrokah deleted the refactor/cleanup_deploy_command branch September 17, 2020 07:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: chore work needed to keep the product and development running smoothly
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants