UNPKG

2.9 kBJavaScriptView Raw
1'use strict'
2
3const cli = require('heroku-cli-util')
4const co = require('co')
5const strftime = require('strftime')
6const _ = require('lodash')
7
8const getProcessNum = (s) => parseInt(s.split('.', 2)[1])
9
10function timeAgo (since) {
11 let elapsed = Math.floor((new Date() - since) / 1000)
12 let message = strftime('%Y/%m/%d %H:%M:%S %z', since)
13 if (elapsed < 60) return `${message} (~ ${Math.floor(elapsed)}s ago)`
14 else if (elapsed < 60 * 60) return `${message} (~ ${Math.floor(elapsed / 60)}m ago)`
15 else if (elapsed < 60 * 60 * 25) return `${message} (~ ${Math.floor(elapsed / 60 / 60)}h ago)`
16 else return message
17}
18
19function * run (context, heroku) {
20 const spaceName = context.flags.space || context.args.space
21 if (!spaceName) throw new Error('Space name required.\nUSAGE: heroku spaces:ps my-space')
22
23 const [spaceDynos, space] = yield Promise.all([
24 heroku.get(`/spaces/${spaceName}/dynos`),
25 heroku.get(`/spaces/${spaceName}`)
26 ])
27
28 if (space.shield) {
29 spaceDynos.forEach(spaceDyno => {
30 spaceDyno.dynos.forEach(d => {
31 if (d.size) {
32 d.size = d.size.replace('Private-', 'Shield-')
33 }
34 })
35 })
36 }
37
38 if (context.flags.json) {
39 cli.styledJSON(spaceDynos)
40 } else {
41 render(spaceDynos)
42 }
43}
44
45function render (spaceDynos) {
46 _.forEach(spaceDynos, (spaceDyno) => {
47 printDynos(spaceDyno.app_name, spaceDyno.dynos)
48 })
49}
50
51function printDynos (appName, dynos) {
52 let dynosByCommand = _.reduce(dynos, function (dynosByCommand, dyno) {
53 let since = timeAgo(new Date(dyno.updated_at))
54 let size = dyno.size || '1X'
55
56 if (dyno.type === 'run') {
57 let key = 'run: one-off processes'
58 if (dynosByCommand[key] === undefined) dynosByCommand[key] = []
59 dynosByCommand[key].push(`${dyno.name} (${size}): ${dyno.state} ${since}: ${dyno.command}`)
60 } else {
61 let key = `${cli.color.green(dyno.type)} (${cli.color.cyan(size)}): ${dyno.command}`
62 if (dynosByCommand[key] === undefined) dynosByCommand[key] = []
63 let state = dyno.state === 'up' ? cli.color.green(dyno.state) : cli.color.yellow(dyno.state)
64 let item = `${dyno.name}: ${cli.color.green(state)} ${cli.color.dim(since)}`
65 dynosByCommand[key].push(item)
66 }
67 return dynosByCommand
68 }, {})
69 _.forEach(dynosByCommand, function (dynos, key) {
70 cli.styledHeader(`${appName} ${key} (${cli.color.yellow(dynos.length)})`)
71 dynos = dynos.sort((a, b) => getProcessNum(a) - getProcessNum(b))
72 for (let dyno of dynos) cli.log(dyno)
73 cli.log()
74 })
75}
76
77module.exports = {
78 topic: 'spaces',
79 command: 'ps',
80 description: 'list dynos for a space',
81 needsAuth: true,
82 args: [{ name: 'space', optional: true, hidden: true }],
83 flags: [
84 { name: 'space', char: 's', hasValue: true, description: 'space to get dynos of' },
85 { name: 'json', description: 'output in json format' }
86 ],
87 run: cli.command(co.wrap(run))
88}