@leverege/build-tools 2.124.1 → 2.126.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +9 -9
- package/src/Utils.mjs +2 -2
- package/src/chart-compass.mjs +1 -1
- package/src/close-dependabot-prs.mjs +121 -15
- package/src/refresh-npm-token.mjs +20 -9
- package/src/repo-panopticon.mjs +10 -8
- package/src/send-to-slack.mjs +3 -3
- package/src/service-man/config/Config.mjs +2 -2
- package/src/service-man/gcloud-k8s/SecretsManager.mjs +1 -2
- package/src/dashboard/json/pitcrew/pitcrew-ingestor.json +0 -1613
- package/src/dashboard/json/pitcrew/pitcrew-ui-service.json +0 -637
- package/src/dashboard/json/pitcrew/pitcrew-vision-logic-server.json +0 -1137
- package/src/dashboard/json/pitcrew/pubsub-repeater.json +0 -1243
- package/src/dashboard/json/pitcrew/triton-interface.json +0 -1201
- package/src/dashboard/json/pitcrew/vms-server.json +0 -1882
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@leverege/build-tools",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.126.1",
|
|
4
4
|
"description": "A collection of build / support tools for Leverege developers",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"repository": {
|
|
@@ -102,21 +102,21 @@
|
|
|
102
102
|
"execa": "^10.0.1",
|
|
103
103
|
"find-yarn-workspace-root": "^2.0.0",
|
|
104
104
|
"glob": "^13.0.6",
|
|
105
|
-
"googleapis": "^
|
|
105
|
+
"googleapis": "^182.0.0",
|
|
106
106
|
"handlebars": "^4.7.9",
|
|
107
|
-
"ignore": "^7.0.
|
|
107
|
+
"ignore": "^7.0.10",
|
|
108
108
|
"inquirer": "^14.2.2",
|
|
109
109
|
"js-yaml": "^4.3.2",
|
|
110
110
|
"jsdoc": "^4.0.5",
|
|
111
111
|
"ms": "^2.1.3",
|
|
112
112
|
"npm-registry-fetch": "^20.0.1",
|
|
113
113
|
"ora": "^9.4.1",
|
|
114
|
-
"p-limit": "^7.3.
|
|
114
|
+
"p-limit": "^7.3.3",
|
|
115
115
|
"package-up": "^5.0.0",
|
|
116
116
|
"readline-sync": "^1.4.10",
|
|
117
117
|
"semver": "^7.8.5",
|
|
118
118
|
"shell-quote": "^1.10.0",
|
|
119
|
-
"simple-git": "^
|
|
119
|
+
"simple-git": "^4.0.2",
|
|
120
120
|
"sloc": "^0.3.2",
|
|
121
121
|
"superstruct": "^2.0.2",
|
|
122
122
|
"tmp": "^0.2.7",
|
|
@@ -125,11 +125,11 @@
|
|
|
125
125
|
"zx": "^8.8.5"
|
|
126
126
|
},
|
|
127
127
|
"devDependencies": {
|
|
128
|
-
"@leverege/eslint-config-leverege": "^
|
|
128
|
+
"@leverege/eslint-config-leverege": "^10",
|
|
129
129
|
"chai": "^6.2.2",
|
|
130
|
-
"eslint": "^
|
|
131
|
-
"mocha": "^12.0.
|
|
132
|
-
"npm": "^12.0
|
|
130
|
+
"eslint": "^10",
|
|
131
|
+
"mocha": "^12.0.2",
|
|
132
|
+
"npm": "^12.1.0"
|
|
133
133
|
},
|
|
134
134
|
"allowScripts": {
|
|
135
135
|
"unrs-resolver@1.12.2": true
|
package/src/Utils.mjs
CHANGED
|
@@ -322,7 +322,7 @@ export const parseYamlFile = async ( filePath ) => {
|
|
|
322
322
|
const fileContent = await fs.promises.readFile( filePath, 'utf8' ) /* eslint-disable-line security/detect-non-literal-fs-filename */
|
|
323
323
|
return YAML.load( fileContent )
|
|
324
324
|
} catch ( error ) {
|
|
325
|
-
throw new Error( `Failed to parse YAML file ${filePath}: ${error.message}
|
|
325
|
+
throw new Error( `Failed to parse YAML file ${filePath}: ${error.message}`, { cause : error } )
|
|
326
326
|
}
|
|
327
327
|
}
|
|
328
328
|
|
|
@@ -334,7 +334,7 @@ export const parseJsonFile = async ( jsonFile ) => {
|
|
|
334
334
|
const json = JSON.parse( fs.readFileSync( jsonFile, 'utf8' ) )
|
|
335
335
|
return json
|
|
336
336
|
} catch ( error ) {
|
|
337
|
-
throw new Error( `${error} in ${jsonFile}
|
|
337
|
+
throw new Error( `${error} in ${jsonFile}`, { cause : error } )
|
|
338
338
|
}
|
|
339
339
|
}
|
|
340
340
|
|
package/src/chart-compass.mjs
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { $ } from 'zx'
|
|
4
4
|
import { program } from 'commander'
|
|
5
5
|
import chalk from 'chalk'
|
|
6
|
+
import semver from 'semver'
|
|
6
7
|
|
|
7
8
|
import { enableDebug, errorExit, log } from './Utils.mjs'
|
|
8
9
|
|
|
@@ -10,14 +11,21 @@ $.verbose = false
|
|
|
10
11
|
|
|
11
12
|
const DEFAULT_OWNER = 'Leverege'
|
|
12
13
|
|
|
13
|
-
const
|
|
14
|
+
const GROUPED_COMMENT = (
|
|
14
15
|
'Closing in favor of the new grouped Dependabot config (patch/minor ' +
|
|
15
16
|
'updates now batch into a single PR). Not a rejection of this specific ' +
|
|
16
17
|
'bump - Dependabot will re-propose it as part of a grouped PR on its ' +
|
|
17
18
|
'next scan.'
|
|
18
19
|
)
|
|
19
20
|
|
|
21
|
+
const SATISFIED_COMMENT = (
|
|
22
|
+
'Closing because the target branch already declares a version that ' +
|
|
23
|
+
'satisfies this bump (it was applied through a different PR). Not a ' +
|
|
24
|
+
'rejection of this specific bump.'
|
|
25
|
+
)
|
|
26
|
+
|
|
20
27
|
const TITLE_RE = /^Bump (\S+) from (\S+) to (\S+)$/
|
|
28
|
+
const DEP_SECTIONS = [ 'dependencies', 'devDependencies', 'peerDependencies', 'optionalDependencies' ]
|
|
21
29
|
|
|
22
30
|
program
|
|
23
31
|
.name( 'close-dependabot-prs' )
|
|
@@ -25,12 +33,20 @@ program
|
|
|
25
33
|
.argument( '<repos...>', 'repo names - bare name uses --owner, or pass owner/repo to override' )
|
|
26
34
|
.option( '--owner <name>', 'GitHub org/owner for bare repo names', DEFAULT_OWNER )
|
|
27
35
|
.option( '--dry-run', 'show what would be closed without closing anything' )
|
|
36
|
+
.option(
|
|
37
|
+
'--close-satisfied',
|
|
38
|
+
'also CLOSE PRs (any bump type, including major) whose proposed version is ' +
|
|
39
|
+
'already satisfied by the target branch\'s package.json - e.g. a manual bump ' +
|
|
40
|
+
'landed through a different PR while this one sat stale. Without this flag, ' +
|
|
41
|
+
'such PRs are only reported as a "hint" line, never closed'
|
|
42
|
+
)
|
|
28
43
|
.option( '--debug', 'Enable debug logging' )
|
|
29
44
|
.addHelpText( 'after', `
|
|
30
45
|
${chalk.yellow( 'Examples:' )}
|
|
31
46
|
${chalk.green( 'close-dependabot-prs array-util base62-util' )}
|
|
32
47
|
${chalk.green( 'close-dependabot-prs --dry-run cache' )}
|
|
33
48
|
${chalk.green( 'close-dependabot-prs --owner SomeOtherOrg some-repo' )}
|
|
49
|
+
${chalk.green( 'close-dependabot-prs --close-satisfied --dry-run overdose' )}
|
|
34
50
|
|
|
35
51
|
${chalk.yellow( 'Notes:' )}
|
|
36
52
|
Closes open Dependabot PRs that are superseded by a newly-added groups:
|
|
@@ -39,7 +55,21 @@ ${chalk.yellow( 'Notes:' )}
|
|
|
39
55
|
closing them risks Dependabot never re-proposing that exact version.
|
|
40
56
|
|
|
41
57
|
Skips any repo whose dependabot.yml has no groups: block at all - closing
|
|
42
|
-
PRs there would lose them rather than get them re-proposed
|
|
58
|
+
PRs there would lose them rather than get them re-proposed - unless
|
|
59
|
+
--close-satisfied finds a reason to close a specific PR anyway.
|
|
60
|
+
|
|
61
|
+
--close-satisfied handles a different, unrelated situation: a PR (of any
|
|
62
|
+
bump type) that Dependabot never auto-closed as superseded because it sat
|
|
63
|
+
idle past GitHub's 30-day auto-rebase cutoff, even though the dependency
|
|
64
|
+
was already bumped to (or past) the PR's target version through a separate
|
|
65
|
+
PR. This is checked with real semver comparison against the target
|
|
66
|
+
branch's declared range, so it is safe for major bumps too - if the base
|
|
67
|
+
branch's range doesn't already guarantee the proposed version, the PR is
|
|
68
|
+
left alone. Always sanity-check with --dry-run first.
|
|
69
|
+
|
|
70
|
+
This "already satisfied" check always runs, even without --close-satisfied
|
|
71
|
+
- a plain run will surface a "hint" line for any PR it finds satisfied, so
|
|
72
|
+
you know --close-satisfied is worth trying instead of guessing.
|
|
43
73
|
|
|
44
74
|
Requires the gh CLI, authenticated.
|
|
45
75
|
` )
|
|
@@ -90,20 +120,51 @@ async function openDependabotPrs( repo ) {
|
|
|
90
120
|
return JSON.parse( stdout )
|
|
91
121
|
}
|
|
92
122
|
|
|
93
|
-
async function
|
|
123
|
+
async function fetchPackageJson( repo ) {
|
|
124
|
+
let stdout
|
|
125
|
+
try {
|
|
126
|
+
( { stdout } = await $`gh api repos/${repo}/contents/package.json --jq .content` )
|
|
127
|
+
} catch {
|
|
128
|
+
return null // couldn't fetch - treat as unknown, caller should skip
|
|
129
|
+
}
|
|
130
|
+
try {
|
|
131
|
+
return JSON.parse( Buffer.from( stdout.trim(), 'base64' ).toString( 'utf8' ) )
|
|
132
|
+
} catch {
|
|
133
|
+
return null // unparseable - treat as unknown, caller should skip
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Returns true if the target branch's package.json already declares a range for
|
|
138
|
+
// depName whose minimum version satisfies-or-exceeds toV. Returns false if it
|
|
139
|
+
// definitely doesn't. Returns null if this can't be determined safely (dependency
|
|
140
|
+
// missing, range unparseable, etc) - callers should treat null as "don't know".
|
|
141
|
+
function isAlreadySatisfied( pkgJson, depName, toV ) {
|
|
142
|
+
const toVersion = semver.valid( toV )
|
|
143
|
+
if ( toVersion == null ) return null
|
|
144
|
+
|
|
145
|
+
const declaredRange = DEP_SECTIONS
|
|
146
|
+
.map( section => pkgJson[section] && pkgJson[section][depName] )
|
|
147
|
+
.find( range => range != null )
|
|
148
|
+
if ( declaredRange == null ) return null
|
|
149
|
+
|
|
150
|
+
let minCurrent
|
|
151
|
+
try {
|
|
152
|
+
minCurrent = semver.minVersion( declaredRange )
|
|
153
|
+
} catch {
|
|
154
|
+
return null
|
|
155
|
+
}
|
|
156
|
+
if ( minCurrent == null ) return null
|
|
157
|
+
|
|
158
|
+
return semver.gte( minCurrent, toVersion )
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
async function processRepo( repo, opts ) {
|
|
94
162
|
log( `\n=== ${repo} ===` )
|
|
95
163
|
const grouped = await hasGroupingConfigured( repo )
|
|
96
164
|
if ( grouped === null ) {
|
|
97
165
|
log( ' ! could not read .github/dependabot.yml - skipping' )
|
|
98
166
|
return
|
|
99
167
|
}
|
|
100
|
-
if ( !grouped ) {
|
|
101
|
-
log(
|
|
102
|
-
' ! no `groups:` block found in dependabot.yml - skipping ' +
|
|
103
|
-
'(closing PRs here would lose them, not get them re-proposed)'
|
|
104
|
-
)
|
|
105
|
-
return
|
|
106
|
-
}
|
|
107
168
|
|
|
108
169
|
const prs = await openDependabotPrs( repo )
|
|
109
170
|
if ( prs.length === 0 ) {
|
|
@@ -111,7 +172,25 @@ async function processRepo( repo, dryRun ) {
|
|
|
111
172
|
return
|
|
112
173
|
}
|
|
113
174
|
|
|
175
|
+
// Always check for already-satisfied PRs (cheap - one extra API call) so we can
|
|
176
|
+
// at least *report* them even when --close-satisfied wasn't passed. Acting on
|
|
177
|
+
// them still requires the flag; finding them shouldn't.
|
|
178
|
+
const pkgJson = await fetchPackageJson( repo )
|
|
179
|
+
if ( pkgJson == null ) {
|
|
180
|
+
log( ' ! package.json could not be read/parsed - the "already satisfied" check will be skipped' )
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
if ( !grouped && pkgJson == null ) {
|
|
184
|
+
log(
|
|
185
|
+
' ! no `groups:` block found in dependabot.yml - skipping ' +
|
|
186
|
+
'(closing PRs here would lose them, not get them re-proposed)'
|
|
187
|
+
)
|
|
188
|
+
return
|
|
189
|
+
}
|
|
190
|
+
|
|
114
191
|
let closedCount = 0
|
|
192
|
+
let closedSatisfiedCount = 0
|
|
193
|
+
let hintCount = 0
|
|
115
194
|
let keptCount = 0
|
|
116
195
|
let skippedCount = 0
|
|
117
196
|
|
|
@@ -122,14 +201,37 @@ async function processRepo( repo, dryRun ) {
|
|
|
122
201
|
log( ` skip #${pr.number} (title didn't match expected pattern) ${pr.title}` )
|
|
123
202
|
continue
|
|
124
203
|
}
|
|
125
|
-
const [ , ,
|
|
204
|
+
const [ , depName, , toV ] = m
|
|
205
|
+
|
|
206
|
+
if ( pkgJson != null && isAlreadySatisfied( pkgJson, depName, toV ) === true ) {
|
|
207
|
+
if ( opts.closeSatisfied ) {
|
|
208
|
+
closedSatisfiedCount++
|
|
209
|
+
log( ` close #${String( pr.number ).padEnd( 4 )} satisfied ${pr.title}` )
|
|
210
|
+
if ( !opts.dryRun ) {
|
|
211
|
+
// eslint-disable-next-line no-await-in-loop
|
|
212
|
+
await $`gh pr close ${pr.number} --repo ${repo} --comment ${SATISFIED_COMMENT}`
|
|
213
|
+
}
|
|
214
|
+
} else {
|
|
215
|
+
hintCount++
|
|
216
|
+
log( ` hint #${String( pr.number ).padEnd( 4 )} satisfied ${pr.title} (rerun with --close-satisfied to close)` )
|
|
217
|
+
}
|
|
218
|
+
continue
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
if ( !grouped ) {
|
|
222
|
+
keptCount++
|
|
223
|
+
log( ` keep #${String( pr.number ).padEnd( 4 )} ungrouped ${pr.title}` )
|
|
224
|
+
continue
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
const [ , , fromV ] = m
|
|
126
228
|
const bumpType = classifyBump( fromV, toV )
|
|
127
229
|
if ( bumpType === 'patch' || bumpType === 'minor' ) {
|
|
128
230
|
closedCount++
|
|
129
231
|
log( ` close #${String( pr.number ).padEnd( 4 )} ${bumpType.padEnd( 7 )} ${pr.title}` )
|
|
130
|
-
if ( !dryRun ) {
|
|
232
|
+
if ( !opts.dryRun ) {
|
|
131
233
|
// eslint-disable-next-line no-await-in-loop
|
|
132
|
-
await $`gh pr close ${pr.number} --repo ${repo} --comment ${
|
|
234
|
+
await $`gh pr close ${pr.number} --repo ${repo} --comment ${GROUPED_COMMENT}`
|
|
133
235
|
}
|
|
134
236
|
} else {
|
|
135
237
|
keptCount++
|
|
@@ -137,12 +239,16 @@ async function processRepo( repo, dryRun ) {
|
|
|
137
239
|
}
|
|
138
240
|
}
|
|
139
241
|
|
|
140
|
-
log(
|
|
242
|
+
log(
|
|
243
|
+
` -> ${closedCount} closed (grouped), ${closedSatisfiedCount} closed (satisfied), ` +
|
|
244
|
+
`${hintCount} satisfied but not closed (see --close-satisfied), ` +
|
|
245
|
+
`${keptCount} left open, ${skippedCount} skipped`
|
|
246
|
+
)
|
|
141
247
|
}
|
|
142
248
|
|
|
143
249
|
// ---------- Run ----------
|
|
144
250
|
|
|
145
251
|
for ( const repo of repos ) {
|
|
146
252
|
// eslint-disable-next-line no-await-in-loop
|
|
147
|
-
await processRepo( repo, opts
|
|
253
|
+
await processRepo( repo, opts )
|
|
148
254
|
}
|
|
@@ -76,18 +76,29 @@ ${chalk.bold( 'Environment Variables (optional)' )}
|
|
|
76
76
|
|
|
77
77
|
${chalk.bold( 'REFRESH_NPM_PROJECT' )} ${chalk.green( 'may be used in lieu of --project' )}
|
|
78
78
|
|
|
79
|
-
${chalk.bold( 'Manually
|
|
79
|
+
${chalk.bold( 'Manually Bootstrapping the Token' )}
|
|
80
80
|
${chalk.green( `
|
|
81
|
-
There may be times when a token is expired, lost or a new developer needs
|
|
82
|
-
to seed their ~/.npmrc
|
|
83
|
-
|
|
84
|
-
|
|
81
|
+
There may be times when a token is expired, lost, or a new developer needs
|
|
82
|
+
to seed their ~/.npmrc for the first time. Because the REFRESH_NPM_NPMRC
|
|
83
|
+
secret is a template (not a rendered file), you must fetch the token and
|
|
84
|
+
substitute it in one step. Run the following — requires only gcloud and a
|
|
85
|
+
valid gcloud auth login:
|
|
86
|
+
|
|
87
|
+
TOKEN=$(gcloud secrets versions access latest \\
|
|
88
|
+
--secret=REFRESH_NPM_TOKEN \\
|
|
89
|
+
--project=leverege-registry) && \\
|
|
85
90
|
gcloud secrets versions access latest \\
|
|
86
|
-
--secret=REFRESH_NPM_NPMRC
|
|
87
|
-
--project=leverege-registry
|
|
91
|
+
--secret=REFRESH_NPM_NPMRC \\
|
|
92
|
+
--project=leverege-registry | \\
|
|
93
|
+
sed "s/\\\${REFRESH_NPM_TOKEN}/\${TOKEN}/g" > ~/.npmrc
|
|
94
|
+
|
|
95
|
+
Once ~/.npmrc is seeded with a valid token, install build-tools and let it
|
|
96
|
+
manage the rc files going forward:
|
|
97
|
+
|
|
98
|
+
npm install -g @leverege/build-tools
|
|
99
|
+
refresh-npm-token --force
|
|
88
100
|
|
|
89
|
-
Note
|
|
90
|
-
developers.` )}
|
|
101
|
+
Note: the --project flag above may differ for non-leverege environments.` )}
|
|
91
102
|
` )
|
|
92
103
|
.parse()
|
|
93
104
|
|
package/src/repo-panopticon.mjs
CHANGED
|
@@ -8,7 +8,7 @@ import chalk from 'chalk'
|
|
|
8
8
|
import { glob } from 'glob'
|
|
9
9
|
import ora from 'ora'
|
|
10
10
|
import pLimit from 'p-limit'
|
|
11
|
-
import simpleGit from 'simple-git'
|
|
11
|
+
import { simpleGit } from 'simple-git'
|
|
12
12
|
import { $ } from 'zx'
|
|
13
13
|
|
|
14
14
|
import { clear, enableDebug, log, parseJsonFile } from './Utils.mjs'
|
|
@@ -23,6 +23,7 @@ const SYM_BAD = chalk.red( '✘' )
|
|
|
23
23
|
// Add new checks here — the table expands automatically.
|
|
24
24
|
|
|
25
25
|
let latestOrbVersion = null
|
|
26
|
+
const pulledRoots = new Set()
|
|
26
27
|
|
|
27
28
|
const CHECKS = [
|
|
28
29
|
{
|
|
@@ -194,18 +195,19 @@ async function checkRepo( dir, { pull } ) {
|
|
|
194
195
|
const pkgVer = parseVersion( pkg?.version )
|
|
195
196
|
|
|
196
197
|
let syncOk = true
|
|
197
|
-
if (
|
|
198
|
+
if ( pull && !pulledRoots.has( gitRoot ) ) {
|
|
199
|
+
pulledRoots.add( gitRoot )
|
|
198
200
|
try {
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
syncOk = status.files.length === 0
|
|
201
|
+
await git.pull()
|
|
202
|
+
await git.fetch( [ '--tags' ] )
|
|
202
203
|
} catch {
|
|
203
204
|
syncOk = false
|
|
204
205
|
}
|
|
205
|
-
} else if (
|
|
206
|
+
} else if ( isWorkspace ) {
|
|
206
207
|
try {
|
|
207
|
-
|
|
208
|
-
await git.
|
|
208
|
+
const relDir = path.relative( gitRoot, dir )
|
|
209
|
+
const status = await git.status( [ '--', relDir ] )
|
|
210
|
+
syncOk = status.files.length === 0
|
|
209
211
|
} catch {
|
|
210
212
|
syncOk = false
|
|
211
213
|
}
|
package/src/send-to-slack.mjs
CHANGED
|
@@ -70,8 +70,8 @@ if ( args._unknown ) {
|
|
|
70
70
|
}
|
|
71
71
|
/* eslint-enable no-underscore-dangle */
|
|
72
72
|
|
|
73
|
-
if ( semverLt( process.version, '
|
|
74
|
-
log( chalk.red( '\n\n***ERROR: must be running at least node
|
|
73
|
+
if ( semverLt( process.version, '24.0.0' ) ) {
|
|
74
|
+
log( chalk.red( '\n\n***ERROR: must be running at least node 24\n' ) )
|
|
75
75
|
process.exit( 1 )
|
|
76
76
|
}
|
|
77
77
|
|
|
@@ -104,7 +104,7 @@ const slackData = {
|
|
|
104
104
|
channel : slackConfig.channel,
|
|
105
105
|
}
|
|
106
106
|
|
|
107
|
-
if ( process.env.BUILD_TOOLS_DEBUG || args.dryRun ) {
|
|
107
|
+
if ( process.env.BUILD_TOOLS_DEBUG || args.dryRun ) { // || process.env.SKIP_SEND_TO_SLACK ) {
|
|
108
108
|
const account = await shellCmd( 'gcloud config get account' )
|
|
109
109
|
log( { account, slackConfig, slackData }, '<==Slack skipped' )
|
|
110
110
|
} else {
|
|
@@ -4,7 +4,7 @@ import fs from 'node:fs/promises' /* eslint-disable security/detect-non-literal-
|
|
|
4
4
|
import chalk from 'chalk'
|
|
5
5
|
import { execa } from 'execa'
|
|
6
6
|
import inquirer from 'inquirer'
|
|
7
|
-
import SimpleGit from 'simple-git'
|
|
7
|
+
import { simpleGit as SimpleGit } from 'simple-git'
|
|
8
8
|
|
|
9
9
|
import { log, } from '../../Utils.mjs'
|
|
10
10
|
|
|
@@ -12,7 +12,7 @@ export default class Config {
|
|
|
12
12
|
constructor( options ) {
|
|
13
13
|
// we cannot async in the constructor - so use init to do the rest
|
|
14
14
|
this.configRoot = `${options.sourceTop}/config`
|
|
15
|
-
this.git =
|
|
15
|
+
this.git = SimpleGit()
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
// expects a directory name containing text files with a .json extension
|