@mikeyt23/node-cli-utils 1.2.6 → 1.3.0

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.
Files changed (3) hide show
  1. package/README.md +6 -1
  2. package/index.js +100 -18
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -6,10 +6,15 @@ Simple node cli utils to:
6
6
  - Copy env template file to env file
7
7
  - Sync new env values from template to "real" env files
8
8
  - Manage all env values in root files that then get copied to other locations
9
+ - Dotnet helper methods:
10
+ - Pack and publish a NuGet package
11
+ - Wrapper commands to install or update dotnet ef tool
12
+ - Wrapper commands to spawn dotnet run and publish
13
+ - Helper methods for DB migration commands (see [mikey-t/db-migrations-dotnet](https://github.com/mikey-t/db-migrations-dotnet))
9
14
 
10
15
  # Env Utility Function Notes
11
16
 
12
- A project can have multiple locations that requires the same env values. For example, you might have a database that needs to be used by a docker project, your main app and also a db migration project. Rather than having to remember where each of the .env files is, we want to use the root directory and overwrite subdirectory env files with the ones in the root. We also want to add new `.env.template` values to the root `.env` files and propagate them to subdirectories - all without having to know about anything about any of the .env files except the ones in the root of the project.
17
+ A project can have multiple locations that require the same env values. For example, you might have a database that needs to be used by a docker project, your main app and also a db migration project. Rather than having to remember where each of the .env files is, we want to use the root directory and overwrite subdirectory env files with the ones in the root. We also want to add new `.env.template` values to the root `.env` files and propagate them to subdirectories - all without having to know about anything about any of the .env files except the ones in the root of the project.
13
18
 
14
19
  # Examples
15
20
 
package/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  const fs = require('fs')
2
2
  const fsp = require('fs').promises
3
3
  const which = require('which')
4
- const { spawn, spawnSync } = require('child_process')
4
+ const {spawn, spawnSync} = require('child_process')
5
5
  const path = require('path')
6
6
  const tar = require('tar')
7
7
 
@@ -9,7 +9,7 @@ const defaultSpawnOptions = {
9
9
  shell: true,
10
10
  stdio: ['ignore', 'inherit', 'inherit']
11
11
  }
12
- const spawnOptionsWithInput = { ...defaultSpawnOptions, stdio: 'inherit' }
12
+ const defaultSpawnOptionsWithInput = {...defaultSpawnOptions, stdio: 'inherit'}
13
13
 
14
14
  function waitForProcess(childProcess) {
15
15
  return new Promise((resolve, reject) => {
@@ -34,13 +34,12 @@ async function overwriteEnvFile(fromPath, toPath) {
34
34
  await copyEnv(fromPath, toPath)
35
35
  }
36
36
 
37
-
38
37
  async function throwIfDockerNotRunning() {
39
38
  if (!which.sync('docker')) {
40
39
  throw Error('docker command not found')
41
40
  }
42
41
 
43
- let childProcess = spawnSync('docker', ['info'], { encoding: 'utf8' })
42
+ let childProcess = spawnSync('docker', ['info'], {encoding: 'utf8'})
44
43
  if (childProcess.error) {
45
44
  throw childProcess.error
46
45
  }
@@ -52,7 +51,7 @@ async function throwIfDockerNotRunning() {
52
51
  async function bashIntoRunningDockerContainer(containerNamePartial, entryPoint = 'bash') {
53
52
  await throwIfDockerNotRunning()
54
53
 
55
- let childProcess = spawnSync('docker', ['container', 'ls'], { encoding: 'utf8' })
54
+ let childProcess = spawnSync('docker', ['container', 'ls'], {encoding: 'utf8'})
56
55
  if (childProcess.error) {
57
56
  throw childProcess.error
58
57
  }
@@ -74,13 +73,13 @@ async function bashIntoRunningDockerContainer(containerNamePartial, entryPoint =
74
73
  console.log('full container name: ' + containerName)
75
74
 
76
75
  const args = ['exec', '-it', containerName, entryPoint]
77
- return waitForProcess(spawn('docker', args, spawnOptionsWithInput))
76
+ return waitForProcess(spawn('docker', args, defaultSpawnOptionsWithInput))
78
77
  }
79
78
 
80
79
  async function dockerContainerIsRunning(containerNamePartial) {
81
80
  await throwIfDockerNotRunning()
82
81
 
83
- let childProcess = spawnSync('docker', ['container', 'ls'], { encoding: 'utf8' })
82
+ let childProcess = spawnSync('docker', ['container', 'ls'], {encoding: 'utf8'})
84
83
  if (childProcess.error) {
85
84
  throw childProcess.error
86
85
  }
@@ -189,7 +188,7 @@ async function createTarball(directoryToTarball, outputDirectory, tarballName, c
189
188
  }
190
189
  }
191
190
 
192
- let options = { gzip: true, file: tarballPath }
191
+ let options = {gzip: true, file: tarballPath}
193
192
  if (!!cwd) {
194
193
  options.cwd = cwd
195
194
  }
@@ -197,12 +196,12 @@ async function createTarball(directoryToTarball, outputDirectory, tarballName, c
197
196
  await tar.c(options, [directoryToTarball])
198
197
  }
199
198
 
200
- async function dockerCompose(command, projectName, dockerRelativeDirectory, detached = false) {
199
+ async function dockerCompose(command, projectName, dockerRelativeDirectory = 'docker', detached = false) {
201
200
  if (!projectName || projectName.length === 0) {
202
201
  throw new Error('projectName is required')
203
202
  }
204
203
 
205
- const dockerRelativeDir = dockerRelativeDirectory || 'docker'
204
+ const dockerRelativeDir = dockerRelativeDirectory || './'
206
205
  const dockerWorkingDir = path.join(process.cwd(), dockerRelativeDir)
207
206
 
208
207
  if (!fs.existsSync(dockerWorkingDir)) {
@@ -211,7 +210,7 @@ async function dockerCompose(command, projectName, dockerRelativeDirectory, deta
211
210
 
212
211
  await throwIfDockerNotRunning()
213
212
 
214
- const dockerSpawnOptions = { ...defaultSpawnOptions, cwd: dockerWorkingDir }
213
+ const dockerSpawnOptions = {...defaultSpawnOptions, cwd: dockerWorkingDir, stdio: 'inherit'}
215
214
 
216
215
  let args = ['--project-name', projectName, command]
217
216
  if (detached) {
@@ -222,19 +221,19 @@ async function dockerCompose(command, projectName, dockerRelativeDirectory, deta
222
221
  }
223
222
 
224
223
  async function dockerDepsUp(projectName, dockerRelativeDirectory) {
225
- return dockerCompose('up', projectName, dockerRelativeDirectory)
224
+ return await dockerCompose('up', projectName, dockerRelativeDirectory)
226
225
  }
227
226
 
228
227
  async function dockerDepsUpDetached(projectName, dockerRelativeDirectory) {
229
- return dockerCompose('up', projectName, dockerRelativeDirectory, true)
228
+ return await dockerCompose('up', projectName, dockerRelativeDirectory, true)
230
229
  }
231
230
 
232
231
  async function dockerDepsDown(projectName, dockerRelativeDirectory) {
233
- return dockerCompose('down', projectName, dockerRelativeDirectory)
232
+ return await dockerCompose('down', projectName, dockerRelativeDirectory)
234
233
  }
235
234
 
236
235
  async function dockerDepsStop(projectName, dockerRelativeDirectory) {
237
- return dockerCompose('stop', projectName, dockerRelativeDirectory)
236
+ return await dockerCompose('stop', projectName, dockerRelativeDirectory)
238
237
  }
239
238
 
240
239
  async function dotnetBuild(release = true) {
@@ -256,7 +255,7 @@ async function dotnetPack(projectDirectoryPath, release = true) {
256
255
  args.push('-c', 'Release')
257
256
  }
258
257
 
259
- const spawnOptions = { ...defaultSpawnOptions, cwd: projectDirectoryPath }
258
+ const spawnOptions = {...defaultSpawnOptions, cwd: projectDirectoryPath}
260
259
  logCommand('dotnet', args, spawnOptions)
261
260
  await waitForProcess(spawn('dotnet', args, spawnOptions))
262
261
  }
@@ -271,7 +270,7 @@ async function dotnetNugetPublish(projectDirectoryPath, csprojFilename, release
271
270
 
272
271
  const packageName = await getPackageName(projectDirectoryPath, csprojFilename)
273
272
  console.log('publishing package ' + packageName)
274
- const spawnOptions = { ...defaultSpawnOptions, cwd: packageDir }
273
+ const spawnOptions = {...defaultSpawnOptions, cwd: packageDir}
275
274
  await waitForProcess(spawn('dotnet', [
276
275
  'nuget',
277
276
  'push',
@@ -294,12 +293,89 @@ async function getPackageName(projectPath, csprojFilename) {
294
293
  return `${namespace}.${version}.nupkg`
295
294
  }
296
295
 
297
- async function logCommand(command, args, spawnOptions) {
296
+ function logCommand(command, args, spawnOptions) {
298
297
  console.log('running command: ' + `${command} ${args.join(' ')}`)
299
298
  console.log('with spawn options: ' + JSON.stringify(spawnOptions))
300
299
  }
301
300
 
301
+ async function dotnetDllCommand(relativeDllPath, argsArray, cwd = null, useStdin = false) {
302
+ throwIfRequiredIsFalsy(relativeDllPath, 'relativeDllPath')
303
+ throwIfRequiredArrayIsFalsyOrEmpty(argsArray, 'argsArray')
304
+
305
+ let args = [relativeDllPath, ...argsArray]
306
+
307
+ let spawnOptions = {...defaultSpawnOptions}
308
+ if (cwd !== null) {
309
+ spawnOptions = {...spawnOptions, cwd: cwd}
310
+ }
311
+ if (useStdin) {
312
+ spawnOptions = {...spawnOptions, stdio: 'inherit'}
313
+ }
314
+
315
+ return waitForProcess(spawn('dotnet', args, spawnOptions))
316
+ }
317
+
318
+ async function dotnetPublish(cwd = null, outputDir = 'publish') {
319
+ let spawnOptions = {...defaultSpawnOptions}
320
+ if (!!cwd) {
321
+ spawnOptions = {...spawnOptions, cwd: cwd}
322
+ }
323
+ if (!outputDir) {
324
+ outputDir = 'publish'
325
+ }
326
+ let args = ['publish', '-o', outputDir]
327
+ return waitForProcess(spawn('dotnet', args, spawnOptions))
328
+ }
329
+
330
+ async function dotnetDbMigrationsList(dbContextName, relativeDbMigratorDirectoryPath) {
331
+ throwIfRequiredIsFalsy(dbContextName, 'dbContextName')
332
+ throwIfRequiredIsFalsy(relativeDbMigratorDirectoryPath, 'relativeDbMigratorDirectoryPath')
333
+ let spawnOptions = {...defaultSpawnOptions, cwd: relativeDbMigratorDirectoryPath}
334
+ return waitForProcess(spawn('dotnet', ['ef', 'migrations', 'list', '--context', dbContextName], spawnOptions))
335
+ }
336
+
337
+ async function dotnetDbMigrate(dbContextName, relativeDbMigratorDirectoryPath, migrationName = '') {
338
+ throwIfRequiredIsFalsy(dbContextName, 'dbContextName')
339
+ throwIfRequiredIsFalsy(relativeDbMigratorDirectoryPath, 'relativeDbMigratorDirectoryPath')
340
+ let args = ['ef', 'database', 'update']
341
+ if (!!migrationName) {
342
+ args.push(migrationName)
343
+ }
344
+ args = [...args, '--context', dbContextName]
345
+ let spawnOptions = {...defaultSpawnOptions, cwd: relativeDbMigratorDirectoryPath}
346
+ return waitForProcess(spawn('dotnet', args, spawnOptions))
347
+ }
348
+
349
+ async function dotnetDbAddMigration(dbContextName, relativeDbMigratorDirectoryPath, migrationName) {
350
+ throwIfRequiredIsFalsy(dbContextName, 'dbContextName')
351
+ throwIfRequiredIsFalsy(relativeDbMigratorDirectoryPath, 'relativeDbMigratorDirectoryPath')
352
+ throwIfRequiredIsFalsy(migrationName, 'migrationName')
353
+ let args = ['ef', 'migrations', 'add', migrationName, '--context', dbContextName, '-o', `Migrations/${dbContextName}Migrations`]
354
+ let spawnOptions = {...defaultSpawnOptions, cwd: relativeDbMigratorDirectoryPath}
355
+ return waitForProcess(spawn('dotnet', args, spawnOptions))
356
+ }
357
+
358
+ async function dotnetDbRemoveMigration(dbContextName, relativeDbMigratorDirectoryPath) {
359
+ throwIfRequiredIsFalsy(dbContextName, 'dbContextName')
360
+ throwIfRequiredIsFalsy(relativeDbMigratorDirectoryPath, 'relativeDbMigratorDirectoryPath')
361
+ let spawnOptions = {...defaultSpawnOptions, cwd: relativeDbMigratorDirectoryPath}
362
+ return waitForProcess(spawn('dotnet', ['ef', 'migrations', 'remove', '--context', dbContextName], spawnOptions))
363
+ }
364
+
365
+ function throwIfRequiredIsFalsy(requiredArg, argName) {
366
+ if (!requiredArg) {
367
+ throw Error(`${argName} is required`)
368
+ }
369
+ }
370
+
371
+ function throwIfRequiredArrayIsFalsyOrEmpty(requiredArrayArg, argName) {
372
+ if (!requiredArrayArg || requiredArrayArg.length === 0 || !Array.isArray(requiredArrayArg)) {
373
+ throw Error(`${argName} array is required`)
374
+ }
375
+ }
376
+
302
377
  exports.defaultSpawnOptions = defaultSpawnOptions
378
+ exports.defaultSpawnOptionsWithInput = defaultSpawnOptionsWithInput
303
379
  exports.waitForProcess = waitForProcess
304
380
  exports.copyNewEnvValues = copyNewEnvValues
305
381
  exports.overwriteEnvFile = overwriteEnvFile
@@ -314,3 +390,9 @@ exports.dockerDepsStop = dockerDepsStop
314
390
  exports.dotnetBuild = dotnetBuild
315
391
  exports.dotnetPack = dotnetPack
316
392
  exports.dotnetNugetPublish = dotnetNugetPublish
393
+ exports.dotnetDllCommand = dotnetDllCommand
394
+ exports.dotnetPublish = dotnetPublish
395
+ exports.dotnetDbMigrationsList = dotnetDbMigrationsList
396
+ exports.dotnetDbMigrate = dotnetDbMigrate
397
+ exports.dotnetDbAddMigration = dotnetDbAddMigration
398
+ exports.dotnetDbRemoveMigration = dotnetDbRemoveMigration
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mikeyt23/node-cli-utils",
3
- "version": "1.2.6",
3
+ "version": "1.3.0",
4
4
  "description": "Some node cli utility functions",
5
5
  "author": "Mike Thompson",
6
6
  "license": "MIT",