@heroku-cli/plugin-pg-v5
Version:
Heroku CLI plugin to manage Postgres.
129 lines (113 loc) • 4.56 kB
JavaScript
const co = require('co')
const cli = require('heroku-cli-util')
function * run (context, heroku) {
if (context.args.length > 0) {
// backwards compatible for executing commands like
// `heroku pg:backups info` instead of `heroku pg:backups:info`
let pgbackupCommand = `backups:${context.args[0]}`
const commands = require('../..').commands
const cmd = commands.find(c => c.topic === 'pg' && c.command === pgbackupCommand)
if (!cmd) {
throw new Error(`Unknown pg:backups command: ${context.args[0]}`)
}
let args = {}
context.args.slice(1).forEach(function (arg, index) {
if (cmd.args[index]) {
args[cmd.args[index].name] = arg
} else {
throw new Error(`Unexpected argument: ${arg}`)
}
})
context = Object.assign(context, { args })
yield cmd.run(context, heroku)
} else {
yield list(context, heroku)
}
}
function * list (context, heroku) {
const pgbackups = require('../../lib/pgbackups')(context, heroku)
const { sortBy } = require('lodash')
const host = require('../../lib/host')()
const app = context.app
function displayBackups (backups) {
cli.styledHeader('Backups')
if (!backups.length) {
cli.log(`No backups. Capture one with ${cli.color.cmd('heroku pg:backups:capture')}`)
} else {
cli.table(backups, {
columns: [
{ label: 'ID', format: (_, t) => cli.color.cyan(pgbackups.transfer.name(t)) },
{ label: 'Created at', key: 'created_at' },
{ label: 'Status', format: (_, t) => pgbackups.transfer.status(t) },
{ label: 'Size', key: 'processed_bytes', format: b => pgbackups.filesize(b) },
{ label: 'Database', key: 'from_name', format: d => cli.color.configVar(d) || 'UNKNOWN' }
]
})
}
cli.log()
}
function displayRestores (restores) {
cli.styledHeader('Restores')
restores = restores.slice(0, 10)
if (!restores.length) {
cli.log(`No restores found. Use ${cli.color.cmd('heroku pg:backups:restore')} to restore a backup`)
} else {
cli.table(restores, {
columns: [
{ label: 'ID', format: (_, t) => cli.color.cyan(pgbackups.transfer.name(t)) },
{ label: 'Started at', key: 'created_at' },
{ label: 'Status', format: (_, t) => pgbackups.transfer.status(t) },
{ label: 'Size', key: 'processed_bytes', format: b => pgbackups.filesize(b) },
{ label: 'Database', key: 'to_name', format: d => cli.color.configVar(d) || 'UNKNOWN' }
]
})
}
cli.log()
}
function displayCopies (copies) {
cli.styledHeader('Copies')
copies = copies.slice(0, 10)
if (!copies.length) {
cli.log(`No copies found. Use ${cli.color.cmd('heroku pg:copy')} to copy a database to another`)
} else {
cli.table(copies, {
columns: [
{ label: 'ID', format: (_, t) => cli.color.cyan(pgbackups.transfer.name(t)) },
{ label: 'Started at', key: 'created_at' },
{ label: 'Status', format: (_, t) => pgbackups.transfer.status(t) },
{ label: 'Size', key: 'processed_bytes', format: b => pgbackups.filesize(b) },
{ label: 'From', key: 'from_name', format: d => cli.color.configVar(d) || 'UNKNOWN' },
{ label: 'To', key: 'to_name', format: d => cli.color.configVar(d) || 'UNKNOWN' }
]
})
}
cli.log()
}
let transfers = yield heroku.get(`/client/v11/apps/${app}/transfers`, { host })
transfers = sortBy(transfers, 'created_at').reverse()
let backups = transfers.filter(t => t.from_type === 'pg_dump' && t.to_type === 'gof3r')
let restores = transfers.filter(t => t.from_type !== 'pg_dump' && t.to_type === 'pg_restore')
let copies = transfers.filter(t => t.from_type === 'pg_dump' && t.to_type === 'pg_restore')
displayBackups(backups)
displayRestores(restores)
displayCopies(copies)
}
module.exports = {
topic: 'pg',
command: 'backups',
description: 'list database backups',
needsApp: true,
needsAuth: true,
variableArgs: true,
flags: [
// for backwards compatibility with `pg:backups command` invocation
{ name: 'verbose', char: 'v', hidden: true },
{ name: 'confirm', char: 'c', hasValue: true, hidden: true },
{ name: 'output', char: 'o', hasValue: true, hidden: true },
{ name: 'wait-interval', hasValue: true, hidden: true },
{ name: 'at', hasValue: true, hidden: true },
{ name: 'quiet', char: 'q', hidden: true }
],
run: cli.command({ preauth: true }, co.wrap(run))
}