Skip to content

Commit

Permalink
refactor: remove co
Browse files Browse the repository at this point in the history
Removes [co](https://www.npmjs.com/package/co), the library we
previously needed to achieve an `async/await` like syntax using
generators and `yield`. Our current supported node.js version range is
`^10.0 || ^12.0 || ^14.0`, which allows us to use native `async-await`
built into Node instead of using `co`.

Removing `co` will make debugging
easier and stack traces nicer when testing or when we get error reports
from customers.

I ran the [co-to-async](https://github.com/albinekb/co-to-async) codemod
over the codebase to help achieve this.
  • Loading branch information
fivetanley committed Feb 22, 2021
1 parent cebba02 commit ab57010
Show file tree
Hide file tree
Showing 200 changed files with 1,223 additions and 1,340 deletions.
19 changes: 9 additions & 10 deletions packages/addons-v5/commands/addons/attach.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
'use strict'

let cli = require('heroku-cli-util')
let co = require('co')

function * run (context, heroku) {
async function run(context, heroku) {
const util = require('../../lib/util')

let app = context.app
let addon = yield heroku.get(`/addons/${encodeURIComponent(context.args.addon_name)}`)
let addon = await heroku.get(`/addons/${encodeURIComponent(context.args.addon_name)}`)

function createAttachment (app, as, confirm, credential) {
let body = {
Expand All @@ -30,24 +29,24 @@ function * run (context, heroku) {
}

if (context.flags.credential && context.flags.credential !== 'default') {
let credentialConfig = yield heroku.get(`/addons/${addon.name}/config/credential:${encodeURIComponent(context.flags.credential)}`)
let credentialConfig = await heroku.get(`/addons/${addon.name}/config/credential:${encodeURIComponent(context.flags.credential)}`)
if (credentialConfig.length === 0) {
throw new Error(`Could not find credential ${context.flags.credential} for database ${addon.name}`)
}
}

let attachment = yield util.trapConfirmationRequired(context.app, context.flags.confirm, (confirm) => createAttachment(app, context.flags.as, confirm, context.flags.credential))
let attachment = await util.trapConfirmationRequired(context.app, context.flags.confirm, (confirm) => createAttachment(app, context.flags.as, confirm, context.flags.credential))

yield cli.action(
await cli.action(
`Setting ${cli.color.attachment(attachment.name)} config vars and restarting ${cli.color.app(app)}`,
{ success: false },
co(function * () {
let releases = yield heroku.get(`/apps/${app}/releases`, {
async function () {
let releases = await heroku.get(`/apps/${app}/releases`, {
partial: true,
headers: { 'Range': 'version ..; max=1, order=desc' }
})
cli.action.done(`done, v${releases[0].version}`)
})
}()
)
}

Expand All @@ -63,5 +62,5 @@ module.exports = {
{ name: 'confirm', description: 'overwrite existing add-on attachment with same name', hasValue: true }
],
args: [{ name: 'addon_name' }],
run: cli.command({ preauth: true }, co.wrap(run))
run: cli.command({ preauth: true }, run)
}
9 changes: 4 additions & 5 deletions packages/addons-v5/commands/addons/create.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
'use strict'

const cli = require('heroku-cli-util')
const co = require('co')
const { notify } = require('../../lib/notify')

function parseConfig (args) {
Expand Down Expand Up @@ -31,7 +30,7 @@ function parseConfig (args) {
return config
}

function * run (context, heroku) {
async function run(context, heroku) {
let createAddon = require('../../lib/create_addon')

let { app, flags, args } = context
Expand All @@ -44,7 +43,7 @@ function * run (context, heroku) {
let addon

try {
addon = yield createAddon(heroku, app, args[0], context.flags.confirm, context.flags.wait, { config, name, as })
addon = await createAddon(heroku, app, args[0], context.flags.confirm, context.flags.wait, { config, name, as })
if (context.flags.wait) {
notify(`heroku addons:create ${addon.name}`, 'Add-on successfully provisioned')
}
Expand All @@ -55,7 +54,7 @@ function * run (context, heroku) {
throw error
}

yield context.config.runHook('recache', { type: 'addon', app, addon })
await context.config.runHook('recache', { type: 'addon', app, addon })
cli.log(`Use ${cli.color.cmd('heroku addons:docs ' + addon.addon_service.name)} to view documentation`)
}

Expand All @@ -72,7 +71,7 @@ const cmd = {
{ name: 'confirm', description: 'overwrite existing config vars or existing add-on attachments', hasValue: true },
{ name: 'wait', description: 'watch add-on creation status and exit when complete' }
],
run: cli.command({ preauth: true }, co.wrap(run))
run: cli.command({ preauth: true }, run)
}

module.exports = [
Expand Down
13 changes: 7 additions & 6 deletions packages/addons-v5/commands/addons/destroy.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
'use strict'

const cli = require('heroku-cli-util')
const co = require('co')

function * run (context, heroku) {
async function run(context, heroku) {
const resolve = require('../../lib/resolve')
const { groupBy, toPairs } = require('lodash')

let force = context.flags.force || process.env.HEROKU_FORCE === '1'
if (context.args.length === 0) throw new Error('Missing add-on name')

let addons = yield context.args.map(name => resolve.addon(heroku, context.app, name))
let addons = await Promise.all(
context.args.map(name => resolve.addon(heroku, context.app, name))
)
for (let addon of addons) {
// prevent deletion of app when context.app is set but the addon is attached to a different app
let app = addon.app.name
Expand All @@ -19,10 +20,10 @@ function * run (context, heroku) {
for (let app of toPairs(groupBy(addons, 'app.name'))) {
addons = app[1]
app = app[0]
yield cli.confirmApp(app, context.flags.confirm)
await cli.confirmApp(app, context.flags.confirm)
for (let addon of addons) {
let msg = `Destroying ${cli.color.addon(addon.name)} on ${cli.color.app(addon.app.name)}`
yield cli.action(msg, heroku.request({
await cli.action(msg, heroku.request({
method: 'DELETE',
path: `/apps/${addon.app.id}/addons/${addon.id}`,
headers: { 'Accept-Expansion': 'plan' },
Expand All @@ -43,7 +44,7 @@ let cmd = {
{ name: 'confirm', char: 'c', hasValue: true }
],
variableArgs: true,
run: cli.command({ preauth: true }, co.wrap(run))
run: cli.command({ preauth: true }, run)
}

module.exports = [
Expand Down
17 changes: 8 additions & 9 deletions packages/addons-v5/commands/addons/detach.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,30 @@
'use strict'

let cli = require('heroku-cli-util')
let co = require('co')

function * run (context, heroku) {
async function run(context, heroku) {
let app = context.app
let attachment = yield heroku.get(`/apps/${app}/addon-attachments/${context.args.attachment_name}`)
let attachment = await heroku.get(`/apps/${app}/addon-attachments/${context.args.attachment_name}`)

yield cli.action(
await cli.action(
`Detaching ${cli.color.attachment(attachment.name)} to ${cli.color.addon(attachment.addon.name)} from ${cli.color.app(app)}`,
heroku.request({
path: `/addon-attachments/${attachment.id}`,
method: 'DELETE'
})
)

yield cli.action(
await cli.action(
`Unsetting ${cli.color.attachment(attachment.name)} config vars and restarting ${cli.color.app(app)}`,
{ success: false },
co(function * () {
let releases = yield heroku.request({
async function () {
let releases = await heroku.request({
path: `/apps/${app}/releases`,
partial: true,
headers: { 'Range': 'version ..; max=1, order=desc' }
})
cli.action.done(`done, v${releases[0].version}`)
})
}()
)
}

Expand All @@ -36,5 +35,5 @@ module.exports = {
needsAuth: true,
needsApp: true,
args: [{ name: 'attachment_name' }],
run: cli.command({ preauth: true }, co.wrap(run))
run: cli.command({ preauth: true }, run)
}
11 changes: 5 additions & 6 deletions packages/addons-v5/commands/addons/docs.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
'use strict'

let cli = require('heroku-cli-util')
let co = require('co')

function * run (context, heroku) {
async function run(context, heroku) {
const resolve = require('../../lib/resolve')

let id = context.args.addon.split(':')[0]
let addon = yield heroku.get(`/addon-services/${encodeURIComponent(id)}`).catch(() => null)
if (!addon) addon = (yield resolve.addon(heroku, context.app, id)).addon_service
let addon = await heroku.get(`/addon-services/${encodeURIComponent(id)}`).catch(() => null)
if (!addon) addon = ((await resolve.addon(heroku, context.app, id))).addon_service
let url = `https://devcenter.heroku.com/articles/${addon.name}`

if (context.flags['show-url']) {
cli.log(url)
} else {
cli.log(`Opening ${cli.color.cyan(url)}...`)
yield cli.open(url)
await cli.open(url)
}
}

Expand All @@ -26,6 +25,6 @@ module.exports = {
needsAuth: true,
args: [{ name: 'addon' }],
flags: [{ name: 'show-url', description: 'show URL, do not open browser' }],
run: cli.command({ preauth: true }, co.wrap(run)),
run: cli.command({ preauth: true }, run),
description: "open an add-on's Dev Center documentation in your browser"
}
17 changes: 7 additions & 10 deletions packages/addons-v5/commands/addons/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
'use strict'

const cli = require('heroku-cli-util')
const co = require('co')

function * run (ctx, api) {
async function run(ctx, api) {
const util = require('../../lib/util')
const table = util.table
const style = util.style
Expand All @@ -14,12 +13,10 @@ function * run (ctx, api) {

const { groupBy, some, sortBy, values } = require('lodash')

// Gets *all* attachments and add-ons and filters locally because the API
// returns *owned* items not associated items.
function * addonGetter (api, app) {
async function addonGetter(api, app) {
let attachments, addons

if (app) { // don't disploy attachments globally
if (app) { // don't display attachments globally
addons = api.get(`/apps/${app}/addons`, { headers: {
'Accept-Expansion': 'addon_service,plan'
} })
Expand Down Expand Up @@ -49,7 +46,7 @@ function * run (ctx, api) {
}

// Get addons and attachments in parallel
let items = yield [addons, attachments]
let items = await Promise.all([addons, attachments])

function isRelevantToApp (addon) {
return !app ||
Expand Down Expand Up @@ -247,11 +244,11 @@ function * run (ctx, api) {
}

if (!ctx.flags.all && ctx.app) {
let addons = yield co(addonGetter(api, ctx.app))
let addons = await addonGetter(api, ctx.app)
if (ctx.flags.json) displayJSON(addons)
else displayForApp(ctx.app, addons)
} else {
let addons = yield co(addonGetter(api))
let addons = await addonGetter(api)
if (ctx.flags.json) displayJSON(addons)
else displayAll(addons)
}
Expand All @@ -276,7 +273,7 @@ module.exports = {
}
],

run: cli.command({ preauth: true }, co.wrap(run)),
run: cli.command({ preauth: true }, run),
usage: `${topic} [--all|--app APP]`,
description: 'lists your add-ons and attachments',
help: `The default filter applied depends on whether you are in a Heroku app
Expand Down
17 changes: 7 additions & 10 deletions packages/addons-v5/commands/addons/info.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
'use strict'

let cli = require('heroku-cli-util')
let co = require('co')

let grandfatheredPrice = require('../../lib/util').grandfatheredPrice
let formatPrice = require('../../lib/util').formatPrice
Expand All @@ -10,14 +9,12 @@ let style = require('../../lib/util').style

let run = cli.command({ preauth: true }, function (ctx, api) {
const resolve = require('../../lib/resolve')
return co(function * () {
let addon = yield resolve.addon(api, ctx.app, ctx.args.addon)
let [attachments] = yield [
api.request({
method: 'GET',
path: `/addons/${addon.id}/addon-attachments`
})
]
return async function () {
let addon = await resolve.addon(api, ctx.app, ctx.args.addon)
let attachments = await api.request({
method: 'GET',
path: `/addons/${addon.id}/addon-attachments`
})

addon.plan.price = grandfatheredPrice(addon)
addon.attachments = attachments
Expand All @@ -36,7 +33,7 @@ let run = cli.command({ preauth: true }, function (ctx, api) {
'Installed at': (new Date(addon.created_at)).toString(),
'State': formatState(addon.state)
})
})
}();
})

let topic = 'addons'
Expand Down
23 changes: 11 additions & 12 deletions packages/addons-v5/commands/addons/open.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
'use strict'

let cli = require('heroku-cli-util')
let co = require('co')
let fs = require('fs')
let os = require('os')
let path = require('path')
Expand Down Expand Up @@ -48,28 +47,28 @@ function writeSudoTemplate (ctx, sso, path) {
})
}

let sudo = co.wrap(function * (ctx, api) {
let sso = yield api.request({
let sudo = async function (ctx, api) {
let sso = await api.request({
method: 'GET',
path: `/apps/${ctx.app}/addons/${ctx.args.addon}/sso`,
headers: {
Accept: 'application/vnd.heroku+json; version=3.add-ons-sso'
}
})
if (sso.method === 'get') {
yield open(sso.action)
await open(sso.action)
} else {
yield writeSudoTemplate(ctx, sso, ssoPath)
yield open(`file://${ssoPath}`)
await writeSudoTemplate(ctx, sso, ssoPath)
await open(`file://${ssoPath}`)
}
})
}

function * run (ctx, api) {
async function run(ctx, api) {
const resolve = require('../../lib/resolve')

if (process.env.HEROKU_SUDO) return sudo(ctx, api)

let attachment = yield resolve.attachment(api, ctx.app, ctx.args.addon)
let attachment = await resolve.attachment(api, ctx.app, ctx.args.addon)
.catch(function (err) {
if (err.statusCode !== 404) throw err
})
Expand All @@ -78,14 +77,14 @@ function * run (ctx, api) {
if (attachment) {
webUrl = attachment.web_url
} else {
let addon = yield resolve.addon(api, ctx.app, ctx.args.addon)
let addon = await resolve.addon(api, ctx.app, ctx.args.addon)
webUrl = addon.web_url
}

if (ctx.flags['show-url']) {
cli.log(webUrl)
} else {
yield open(webUrl)
await open(webUrl)
}
}

Expand All @@ -96,6 +95,6 @@ module.exports = {
needsAuth: true,
args: [{ name: 'addon' }],
flags: [{ name: 'show-url', description: 'show URL, do not open browser' }],
run: cli.command({ preauth: true }, co.wrap(run)),
run: cli.command({ preauth: true }, run),
description: "open an add-on's dashboard in your browser"
}
Loading

0 comments on commit ab57010

Please sign in to comment.