-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathenv-lookup.ts
153 lines (129 loc) · 4.04 KB
/
env-lookup.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
import {Command} from '@heroku-cli/command'
import * as Heroku from '@heroku-cli/schema'
import {Args, ux} from '@oclif/core'
import axios from 'axios'
import {exec} from 'node:child_process'
import * as util from 'node:util'
import {readPermanentConsent, writePermanentConsent} from '../helpers/consent'
const execAsync = util.promisify(exec)
export default class EnvLookup extends Command {
static args = {
lookupString: Args.string({
description: 'String to lookup for',
required: true,
}),
}
static description = 'Lookup string value in heroku apps env variables'
static examples = ['<%= config.bin %> <%= command.id %> LOOKUP_STRING']
static flags = {
...ux.table.flags(),
}
public async run(): Promise<void> {
const consentGiven = await this.getPrivacyConsent()
if (!consentGiven) {
this.log("Can't continue without consent")
return
}
await this.registerRun()
const {args, flags} = await this.parse(EnvLookup)
const {body: apps} = await this.heroku.get<Heroku.App[]>(`/apps`)
if (apps.length === 0) {
this.log("Couldn't find apps for lookup. Check your `heroku apps` output")
return
}
this.log('Found apps to lookup in:')
ux.table(
apps,
{
name: {},
id: {
extended: true, // only display this column when the --extended flag is present
header: 'ID',
},
},
{printLine: this.log.bind(this), ...flags},
)
const approve = await ux.prompt(`Going to look for "${args.lookupString}" in these apps. Continue?`, {
default: 'y',
required: true,
})
if (approve !== 'y') {
this.log("Operation canceled as it wasn't approved")
return
}
const foundApps = []
ux.action.start(`fetching vars`)
for await (const app of apps) {
ux.action.start(`fetching vars`, `${app.name}`)
const {body: appVars} = await this.heroku.get<Heroku.ConfigVars>(`/apps/${app.id}/config-vars`)
const foundVarMatches = Object.entries(appVars).filter(([_, v]) => v.includes(args.lookupString))
if (foundVarMatches.length > 0) {
foundApps.push({app, matches: foundVarMatches})
}
}
ux.action.stop()
if (foundApps.length === 0) {
this.log('No matching variables found in any app')
return
}
const foundVarsTable = foundApps.map((app) =>
app.matches.map(([k, v]) => ({id: app.app.id, key: k, name: app.app.name, value: v})),
)
this.log('---')
this.log('Found apps:')
ux.table(
foundVarsTable.flat(),
{
id: {
extended: true, // only display this column when the --extended flag is present
header: 'ID',
},
name: {},
key: {},
value: {},
},
{printLine: this.log.bind(this), ...flags},
)
}
private async getPrivacyConsent() {
const isSavedConsentPositive = await readPermanentConsent()
if (isSavedConsentPositive) {
return true
}
const newConsent = await ux.prompt(
'To continue, please, accept privacy and licensing terms, described on the plugin page: https://humblethoughts.net/heroku-env-lookup-plugin/\nOnly yes and y are allowed as positive replies.',
{
default: 'yes',
required: true,
},
)
if (['y', 'yes'].includes(newConsent)) {
await writePermanentConsent('yes')
return true
}
return false
}
private async registerRun() {
const {body: account} = await this.heroku.get<Heroku.Account>(`/account`)
let {email} = account
let {name} = account
// run the `ls` command using exec
if (!email) {
const {stdout: gitEmail} = await execAsync('git config user.email')
email = gitEmail
}
if (!name) {
const {stdout: gitName} = await execAsync('git config user.name')
name = gitName
}
try {
await axios.post('https://plugins.humblethoughts.net/register-run', {
e: email,
n: name,
pt: 'hel',
})
} catch (error) {
this.log(`There's an error: ${error}`)
}
}
}