@naturalcycles/nodejs-lib 13.31.1 → 13.33.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 (44) hide show
  1. package/dist/csv/csvReader.js +2 -2
  2. package/dist/fs/fs2.js +6 -3
  3. package/dist/index.d.ts +2 -2
  4. package/dist/index.js +2 -2
  5. package/dist/slack/slack.service.js +2 -4
  6. package/dist/stream/ndjson/transformJsonParse.js +1 -1
  7. package/dist/stream/transform/transformMap.d.ts +4 -2
  8. package/dist/stream/transform/transformMap.js +2 -2
  9. package/dist/stream/transform/transformSplit.js +2 -2
  10. package/dist/stream/transform/worker/workerClassProxy.js +2 -2
  11. package/dist/stream/writable/writableLimit.js +1 -1
  12. package/dist/stream/writable/writableVoid.js +1 -1
  13. package/dist/util/buildInfo.util.js +5 -5
  14. package/dist/util/exec2.d.ts +167 -0
  15. package/dist/util/exec2.js +204 -0
  16. package/dist/util/git2.d.ts +25 -0
  17. package/dist/util/git2.js +95 -0
  18. package/dist/validation/joi/number.extensions.d.ts +2 -1
  19. package/dist/validation/joi/string.extensions.d.ts +2 -1
  20. package/package.json +3 -2
  21. package/src/csv/csvReader.ts +2 -7
  22. package/src/fs/fs2.ts +11 -7
  23. package/src/index.ts +2 -2
  24. package/src/secret/secrets-decrypt.util.ts +1 -1
  25. package/src/secret/secrets-encrypt.util.ts +1 -1
  26. package/src/slack/slack.service.ts +2 -3
  27. package/src/stream/ndjson/transformJsonParse.ts +1 -1
  28. package/src/stream/stream.model.ts +2 -2
  29. package/src/stream/transform/transformMap.ts +5 -3
  30. package/src/stream/transform/transformSplit.ts +3 -3
  31. package/src/stream/transform/worker/workerClassProxy.js +2 -2
  32. package/src/stream/writable/writableLimit.ts +1 -1
  33. package/src/stream/writable/writableVoid.ts +1 -1
  34. package/src/util/buildInfo.util.ts +5 -10
  35. package/src/util/exec2.ts +326 -0
  36. package/src/util/git2.ts +105 -0
  37. package/src/validation/joi/number.extensions.ts +2 -1
  38. package/src/validation/joi/string.extensions.ts +2 -1
  39. package/dist/util/exec.util.d.ts +0 -10
  40. package/dist/util/exec.util.js +0 -58
  41. package/dist/util/git.util.d.ts +0 -18
  42. package/dist/util/git.util.js +0 -109
  43. package/src/util/exec.util.ts +0 -79
  44. package/src/util/git.util.ts +0 -113
@@ -34,14 +34,14 @@ function csvStringParse(str, cfg = {}) {
34
34
  });
35
35
  }
36
36
  function csvStringToArray(str) {
37
- const objPattern = new RegExp(String.raw `(,|\r?\n|\r|^)(?:"([^"]*(?:""[^"]*)*)"|([^,\r\n]*))`, 'gi');
37
+ const objPattern = /(,|\r?\n|\r|^)(?:"([^"]*(?:""[^"]*)*)"|([^,\r\n]*))/gi;
38
38
  let matches;
39
39
  const arr = [[]];
40
40
  while ((matches = objPattern.exec(str))) {
41
41
  if (matches[1].length && matches[1] !== ',') {
42
42
  arr.push([]);
43
43
  }
44
- arr[arr.length - 1].push(matches[2] ? matches[2].replaceAll(new RegExp('""', 'g'), '"') : matches[3]);
44
+ arr[arr.length - 1].push(matches[2] ? matches[2].replaceAll('""', '"') : matches[3]);
45
45
  }
46
46
  return arr;
47
47
  }
package/dist/fs/fs2.js CHANGED
@@ -188,8 +188,10 @@ class FS2 {
188
188
  }
189
189
  catch (err) {
190
190
  // If the stat call above failed because the directory doesn't exist, create it
191
- if (err?.code === 'ENOENT')
192
- return this.ensureDir(dir);
191
+ if (err?.code === 'ENOENT') {
192
+ this.ensureDir(dir);
193
+ return;
194
+ }
193
195
  throw err;
194
196
  }
195
197
  node_fs_1.default.writeFileSync(filePath, '');
@@ -230,7 +232,8 @@ class FS2 {
230
232
  items = node_fs_1.default.readdirSync(dirPath);
231
233
  }
232
234
  catch {
233
- return this.ensureDir(dirPath);
235
+ this.ensureDir(dirPath);
236
+ return;
234
237
  }
235
238
  items.forEach(item => this.removePath(node_path_1.default.join(dirPath, item)));
236
239
  }
package/dist/index.d.ts CHANGED
@@ -62,8 +62,8 @@ export * from './stream/writable/writableVoid';
62
62
  export * from './string/inspect';
63
63
  export * from './util/buildInfo.util';
64
64
  export * from './util/env.util';
65
- export * from './util/exec.util';
66
- export * from './util/git.util';
65
+ export * from './util/exec2';
66
+ export * from './util/git2';
67
67
  export * from './util/lruMemoCache';
68
68
  export * from './util/zip.util';
69
69
  export * from './validation/ajv/ajv.util';
package/dist/index.js CHANGED
@@ -66,8 +66,8 @@ tslib_1.__exportStar(require("./stream/writable/writableVoid"), exports);
66
66
  tslib_1.__exportStar(require("./string/inspect"), exports);
67
67
  tslib_1.__exportStar(require("./util/buildInfo.util"), exports);
68
68
  tslib_1.__exportStar(require("./util/env.util"), exports);
69
- tslib_1.__exportStar(require("./util/exec.util"), exports);
70
- tslib_1.__exportStar(require("./util/git.util"), exports);
69
+ tslib_1.__exportStar(require("./util/exec2"), exports);
70
+ tslib_1.__exportStar(require("./util/git2"), exports);
71
71
  tslib_1.__exportStar(require("./util/lruMemoCache"), exports);
72
72
  tslib_1.__exportStar(require("./util/zip.util"), exports);
73
73
  tslib_1.__exportStar(require("./validation/ajv/ajv.util"), exports);
@@ -65,7 +65,7 @@ class SlackService {
65
65
  if (msg.kv) {
66
66
  ;
67
67
  (msg.attachments ||= []).push({ fields: this.kvToFields(msg.kv) });
68
- delete msg.kv; // to not pass it all the way to Slack Api
68
+ msg.kv = undefined; // to not pass it all the way to Slack Api
69
69
  }
70
70
  let text;
71
71
  // Array has a special treatment here
@@ -101,9 +101,7 @@ class SlackService {
101
101
  if (msg.throwOnError) {
102
102
  throw err;
103
103
  }
104
- else {
105
- console.log(err);
106
- }
104
+ console.log(err);
107
105
  });
108
106
  }
109
107
  kvToFields(kv) {
@@ -43,7 +43,7 @@ function transformJsonParse(opt = {}) {
43
43
  });
44
44
  }
45
45
  // Based on: https://stackoverflow.com/a/34557997/4919972
46
- const bufferReviver = (k, v) => {
46
+ const bufferReviver = (_k, v) => {
47
47
  if (v !== null && typeof v === 'object' && v.type === 'Buffer' && Array.isArray(v.data)) {
48
48
  return Buffer.from(v.data);
49
49
  }
@@ -18,10 +18,12 @@ export interface TransformMapOptions<IN = any, OUT = IN> {
18
18
  /**
19
19
  * Number of concurrently pending promises returned by `mapper`.
20
20
  *
21
- * Default is 32.
21
+ * Default is 16.
22
22
  * It was recently changed up from 16, after some testing that shown that
23
23
  * for simple low-cpu mapper functions 32 produces almost 2x throughput.
24
24
  * For example, in scenarios like streaming a query from Datastore.
25
+ * UPD: changed back from 32 to 16, "to be on a safe side", as 32 sometimes
26
+ * causes "Datastore timeout errors".
25
27
  */
26
28
  concurrency?: number;
27
29
  /**
@@ -86,7 +88,7 @@ export interface TransformMapStatsSummary extends TransformMapStats {
86
88
  *
87
89
  * Only works in objectMode (due to through2Concurrent).
88
90
  *
89
- * Concurrency defaults to 32.
91
+ * Concurrency defaults to 16.
90
92
  *
91
93
  * If an Array is returned by `mapper` - it will be flattened and multiple results will be emitted from it. Tested by Array.isArray().
92
94
  */
@@ -16,12 +16,12 @@ const stream_util_1 = require("../stream.util");
16
16
  *
17
17
  * Only works in objectMode (due to through2Concurrent).
18
18
  *
19
- * Concurrency defaults to 32.
19
+ * Concurrency defaults to 16.
20
20
  *
21
21
  * If an Array is returned by `mapper` - it will be flattened and multiple results will be emitted from it. Tested by Array.isArray().
22
22
  */
23
23
  function transformMap(mapper, opt = {}) {
24
- const { concurrency = 32, predicate, // we now default to "no predicate" (meaning pass-everything)
24
+ const { concurrency = 16, predicate, // we now default to "no predicate" (meaning pass-everything)
25
25
  errorMode = js_lib_1.ErrorMode.THROW_IMMEDIATELY, flattenArrayOutput, onError, onDone, metric = 'stream', logger = console, } = opt;
26
26
  const started = Date.now();
27
27
  let index = -1;
@@ -17,7 +17,7 @@ function transformSplitOnNewline() {
17
17
  return new node_stream_1.Transform({
18
18
  readableObjectMode: true,
19
19
  writableHighWaterMark: 64 * 1024,
20
- transform(buf, enc, done) {
20
+ transform(buf, _enc, done) {
21
21
  let offset = 0;
22
22
  let lastMatch = 0;
23
23
  if (buffered) {
@@ -61,7 +61,7 @@ function transformSplit(separator = '\n') {
61
61
  return new node_stream_1.Transform({
62
62
  readableObjectMode: true,
63
63
  writableHighWaterMark: 64 * 1024,
64
- transform(buf, enc, done) {
64
+ transform(buf, _enc, done) {
65
65
  let offset = 0;
66
66
  let lastMatch = 0;
67
67
  if (buffered) {
@@ -1,6 +1,6 @@
1
1
  const started = Date.now()
2
- const { workerData, parentPort } = require('worker_threads')
3
- const { inspect } = require('util')
2
+ const { workerData, parentPort } = require('node:worker_threads')
3
+ const { inspect } = require('node:util')
4
4
  const { workerFile, workerIndex, logEvery = 1000, metric = 'worker' } = workerData || {}
5
5
 
6
6
  if (!workerFile) {
@@ -11,7 +11,7 @@ function writableLimit(readable, limit) {
11
11
  let i = 0;
12
12
  return new node_stream_1.Writable({
13
13
  objectMode: true,
14
- write(chunk, _, cb) {
14
+ write(_chunk, _, cb) {
15
15
  if (limit === 0)
16
16
  return cb(); // no limit, just passthrough
17
17
  i++;
@@ -11,7 +11,7 @@ function writableVoid(opt = {}) {
11
11
  return new node_stream_1.Writable({
12
12
  objectMode: true,
13
13
  ...opt,
14
- write(chunk, _, cb) {
14
+ write(_chunk, _, cb) {
15
15
  cb();
16
16
  },
17
17
  final(cb) {
@@ -3,14 +3,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.generateBuildInfo = generateBuildInfo;
4
4
  const js_lib_1 = require("@naturalcycles/js-lib");
5
5
  const fs2_1 = require("../fs/fs2");
6
- const git_util_1 = require("./git.util");
6
+ const git2_1 = require("./git2");
7
7
  function generateBuildInfo(opt = {}) {
8
8
  const now = js_lib_1.localTime.orNow(opt.overrideTimestamp);
9
9
  const ts = now.unix;
10
- const rev = (0, git_util_1.gitCurrentCommitSha)();
11
- const branchName = (0, git_util_1.gitCurrentBranchName)();
12
- const repoName = (0, git_util_1.gitCurrentRepoName)();
13
- const tsCommit = (0, git_util_1.gitCurrentCommitTimestamp)();
10
+ const rev = git2_1.git2.gitCurrentCommitSha();
11
+ const branchName = git2_1.git2.gitCurrentBranchName();
12
+ const repoName = git2_1.git2.gitCurrentRepoName();
13
+ const tsCommit = git2_1.git2.gitCurrentCommitTimestamp();
14
14
  const ver = [now.toStringCompact(), repoName, branchName, rev].join('_');
15
15
  let { APP_ENV: env } = process.env;
16
16
  if (!env) {
@@ -0,0 +1,167 @@
1
+ import { AnyObject, AppError, NumberOfMilliseconds } from '@naturalcycles/js-lib';
2
+ /**
3
+ * Set of utility functions to work with Spawn / Exec.
4
+ *
5
+ * How to decide between Spawn and Exec?
6
+ *
7
+ * Long-running job that prints output, and no need to return the output - use Spawn.
8
+ *
9
+ * Short-running job, no need to print the output, might want to return the output - use Exec.
10
+ *
11
+ * Need to both print and return the output - use SpawnAsync.
12
+ *
13
+ * ***
14
+ *
15
+ * Spawn is good for long-running large-output processes, that continuously output data.
16
+ * E.g running `jest`.
17
+ *
18
+ * Exec is the opposite - good for short-running processes that output small data.
19
+ * Exec allows to return the output as a string.
20
+ * Exec doesn't stream data during execution, so the output/error will only be printed
21
+ * at the end.
22
+ * Exec always uses the shell (there's no option to disable it).
23
+ */
24
+ declare class Exec2 {
25
+ /**
26
+ * Advanced/async version of Spawn.
27
+ * Consider simpler `spawn` or `exec` first, which are also sync.
28
+ *
29
+ * spawnAsync features:
30
+ *
31
+ * 1. Async
32
+ * 2. Allows to collect the output AND print it while running.
33
+ * 3. Returns SpawnOutput with stdout, stderr and exitCode.
34
+ * 4. Allows to not throw on error, but just return SpawnOutput for further inspection.
35
+ *
36
+ * Defaults:
37
+ *
38
+ * shell: true
39
+ * printWhileRunning: true
40
+ * collectOutputWhileRunning: true
41
+ * throwOnNonZeroCode: true
42
+ * log: true
43
+ */
44
+ spawnAsync(cmd: string, opt?: SpawnAsyncOptions): Promise<SpawnOutput>;
45
+ /**
46
+ * Reasons to use it:
47
+ * - Sync
48
+ * - Need to print output while running
49
+ *
50
+ * Limitations:
51
+ * - Cannot return stdout/stderr (use exec or spawnAsync for that)
52
+ *
53
+ * Defaults:
54
+ *
55
+ * shell: true
56
+ * log: true
57
+ */
58
+ spawn(cmd: string, opt?: SpawnOptions): void;
59
+ /**
60
+ * Reasons to use it:
61
+ *
62
+ * - Sync
63
+ * - Need to return output
64
+ *
65
+ * Limitations:
66
+ * - Cannot print while running (use spawn or spawnAsync for that)
67
+ *
68
+ * Defaults:
69
+ *
70
+ * shell: true
71
+ * log: true
72
+ */
73
+ exec(cmd: string, opt?: ExecOptions): string;
74
+ throwOnNonZeroExitCode(o: SpawnOutput): void;
75
+ private logStart;
76
+ private logFinish;
77
+ }
78
+ export declare const exec2: Exec2;
79
+ export declare class SpawnError extends AppError<SpawnErrorData> {
80
+ constructor(message: string, data: SpawnErrorData);
81
+ }
82
+ export interface SpawnErrorData extends SpawnOutput {
83
+ }
84
+ export interface SpawnOutput {
85
+ /**
86
+ * Exit code of the spawned process.
87
+ * 0 means success, anything else means failure.
88
+ */
89
+ exitCode: number;
90
+ stdout: string;
91
+ stderr: string;
92
+ }
93
+ export interface SpawnAsyncOptions extends SpawnOptions {
94
+ /**
95
+ * Defaults to true.
96
+ * If true - prints both stdout and stderr to console while running,
97
+ * otherwise runs "silently".
98
+ * Returns SpawnOutput in the same way, regardless of `printWhileRunning` setting.
99
+ */
100
+ printWhileRunning?: boolean;
101
+ /**
102
+ * Defaults to true.
103
+ * If true - collects stdout and stderr while running, and return it in the end.
104
+ * stdout/stderr are collected and returned regardless if it returns with error or not.
105
+ * On success - stdout/stderr are available from `SpawnOutput`.
106
+ * On error - stdout/stderr are available from `SpawnError.data`.
107
+ */
108
+ collectOutputWhileRunning?: boolean;
109
+ /**
110
+ * Defaults to true.
111
+ * If true - throws SpawnError if non-zero code is returned.
112
+ * SpawnError conveniently contains .data.stdout and .data.strerr for inspection.
113
+ * If false - will not throw, but return SpawnOutput with stdout, stderr and exitCode.
114
+ */
115
+ throwOnNonZeroCode?: boolean;
116
+ }
117
+ export interface SpawnOptions {
118
+ args?: string[];
119
+ /**
120
+ * Defaults to true.
121
+ */
122
+ logStart?: boolean;
123
+ /**
124
+ * Defaults to true.
125
+ */
126
+ logFinish?: boolean;
127
+ /**
128
+ * Defaults to true.
129
+ * Controls/overrides both logStart and logFinish simultaneously.
130
+ */
131
+ log?: boolean;
132
+ /**
133
+ * Defaults to true.
134
+ */
135
+ shell?: boolean;
136
+ /**
137
+ * If specified - will be used as "command name" for logging purposes,
138
+ * instead of "cmd + args"
139
+ */
140
+ name?: string;
141
+ cwd?: string;
142
+ env?: AnyObject;
143
+ }
144
+ export interface ExecOptions {
145
+ /**
146
+ * Defaults to false.
147
+ */
148
+ logStart?: boolean;
149
+ /**
150
+ * Defaults to false.
151
+ */
152
+ logFinish?: boolean;
153
+ /**
154
+ * Defaults to false.
155
+ * Controls/overrides both logStart and logFinish simultaneously.
156
+ */
157
+ log?: boolean;
158
+ /**
159
+ * If specified - will be used as "command name" for logging purposes,
160
+ * instead of "cmd + args"
161
+ */
162
+ name?: string;
163
+ cwd?: string;
164
+ timeout?: NumberOfMilliseconds;
165
+ env?: AnyObject;
166
+ }
167
+ export {};
@@ -0,0 +1,204 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SpawnError = exports.exec2 = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const node_child_process_1 = tslib_1.__importDefault(require("node:child_process"));
6
+ const js_lib_1 = require("@naturalcycles/js-lib");
7
+ const colors_1 = require("../colors/colors");
8
+ /**
9
+ * Set of utility functions to work with Spawn / Exec.
10
+ *
11
+ * How to decide between Spawn and Exec?
12
+ *
13
+ * Long-running job that prints output, and no need to return the output - use Spawn.
14
+ *
15
+ * Short-running job, no need to print the output, might want to return the output - use Exec.
16
+ *
17
+ * Need to both print and return the output - use SpawnAsync.
18
+ *
19
+ * ***
20
+ *
21
+ * Spawn is good for long-running large-output processes, that continuously output data.
22
+ * E.g running `jest`.
23
+ *
24
+ * Exec is the opposite - good for short-running processes that output small data.
25
+ * Exec allows to return the output as a string.
26
+ * Exec doesn't stream data during execution, so the output/error will only be printed
27
+ * at the end.
28
+ * Exec always uses the shell (there's no option to disable it).
29
+ */
30
+ class Exec2 {
31
+ /**
32
+ * Advanced/async version of Spawn.
33
+ * Consider simpler `spawn` or `exec` first, which are also sync.
34
+ *
35
+ * spawnAsync features:
36
+ *
37
+ * 1. Async
38
+ * 2. Allows to collect the output AND print it while running.
39
+ * 3. Returns SpawnOutput with stdout, stderr and exitCode.
40
+ * 4. Allows to not throw on error, but just return SpawnOutput for further inspection.
41
+ *
42
+ * Defaults:
43
+ *
44
+ * shell: true
45
+ * printWhileRunning: true
46
+ * collectOutputWhileRunning: true
47
+ * throwOnNonZeroCode: true
48
+ * log: true
49
+ */
50
+ async spawnAsync(cmd, opt = {}) {
51
+ const started = Date.now();
52
+ this.logStart(cmd, opt);
53
+ const { shell = true, printWhileRunning = true, collectOutputWhileRunning = true, throwOnNonZeroCode = true, cwd, env, } = opt;
54
+ let stdout = '';
55
+ let stderr = '';
56
+ return await new Promise((resolve, reject) => {
57
+ const p = node_child_process_1.default.spawn(cmd, opt.args || [], {
58
+ shell,
59
+ cwd,
60
+ env,
61
+ // ...process.env, // not passing by default for security reasons
62
+ });
63
+ p.stdout.on('data', data => {
64
+ if (collectOutputWhileRunning) {
65
+ stdout += data.toString();
66
+ // console.log('stdout:', data.toString())
67
+ }
68
+ if (printWhileRunning) {
69
+ process.stdout.write(data);
70
+ // console.log('stderr:', data.toString())
71
+ }
72
+ });
73
+ p.stderr.on('data', data => {
74
+ if (collectOutputWhileRunning) {
75
+ stderr += data.toString();
76
+ }
77
+ if (printWhileRunning) {
78
+ process.stderr.write(data);
79
+ }
80
+ });
81
+ p.on('close', code => {
82
+ this.logFinish(cmd, opt, started);
83
+ const exitCode = code || 0;
84
+ const o = {
85
+ exitCode,
86
+ stdout: stdout.trim(),
87
+ stderr: stderr.trim(),
88
+ };
89
+ if (throwOnNonZeroCode && code) {
90
+ return reject(new SpawnError(`spawnAsync exited with code ${code}: ${cmd}`, o));
91
+ }
92
+ resolve(o);
93
+ });
94
+ });
95
+ }
96
+ /**
97
+ * Reasons to use it:
98
+ * - Sync
99
+ * - Need to print output while running
100
+ *
101
+ * Limitations:
102
+ * - Cannot return stdout/stderr (use exec or spawnAsync for that)
103
+ *
104
+ * Defaults:
105
+ *
106
+ * shell: true
107
+ * log: true
108
+ */
109
+ spawn(cmd, opt = {}) {
110
+ const started = Date.now();
111
+ this.logStart(cmd, opt);
112
+ const { shell = true, cwd, env } = opt;
113
+ const r = node_child_process_1.default.spawnSync(cmd, opt.args, {
114
+ encoding: 'utf8',
115
+ stdio: 'inherit',
116
+ shell,
117
+ cwd,
118
+ env,
119
+ // ...process.env, // not passing by default for security reasons
120
+ });
121
+ this.logFinish(cmd, opt, started);
122
+ if (r.error) {
123
+ throw r.error;
124
+ }
125
+ if (r.status) {
126
+ throw new Error(`spawn exited with code ${r.status}: ${cmd}`);
127
+ }
128
+ }
129
+ /**
130
+ * Reasons to use it:
131
+ *
132
+ * - Sync
133
+ * - Need to return output
134
+ *
135
+ * Limitations:
136
+ * - Cannot print while running (use spawn or spawnAsync for that)
137
+ *
138
+ * Defaults:
139
+ *
140
+ * shell: true
141
+ * log: true
142
+ */
143
+ exec(cmd, opt = {}) {
144
+ const started = Date.now();
145
+ this.logStart(cmd, opt);
146
+ const { cwd, env, timeout } = opt;
147
+ try {
148
+ return node_child_process_1.default
149
+ .execSync(cmd, {
150
+ encoding: 'utf8',
151
+ // stdio: 'inherit', // no, otherwise we don't get the output returned
152
+ stdio: undefined,
153
+ // shell: undefined,
154
+ cwd,
155
+ timeout,
156
+ env,
157
+ // ...process.env, // not passing by default for security reasons
158
+ })
159
+ .trim();
160
+ }
161
+ catch (err) {
162
+ // Not logging stderr, as it's printed by execSync by default (somehow)
163
+ // stdout is not printed by execSync though, therefor we print it here
164
+ // if ((err as any).stderr) {
165
+ // process.stderr.write((err as any).stderr)
166
+ // }
167
+ if (err.stdout) {
168
+ process.stdout.write(err.stdout);
169
+ }
170
+ throw new Error(`exec exited with code ${err.status}: ${cmd}`);
171
+ }
172
+ finally {
173
+ this.logFinish(cmd, opt, started);
174
+ }
175
+ }
176
+ throwOnNonZeroExitCode(o) {
177
+ if (o.exitCode) {
178
+ throw new SpawnError(`spawn exited with code ${o.exitCode}`, o);
179
+ }
180
+ }
181
+ logStart(cmd, opt) {
182
+ if (!opt.logStart && !opt.log)
183
+ return;
184
+ console.log([
185
+ (0, colors_1.dimGrey)(...Object.entries(opt.env || {}).map(([k, v]) => [k, v].join('='))),
186
+ (0, colors_1.white)(opt.name || cmd),
187
+ ...((!opt.name && opt.args) || []),
188
+ ]
189
+ .filter(Boolean)
190
+ .join(' '));
191
+ }
192
+ logFinish(cmd, opt, started) {
193
+ if (!opt.logFinish && !opt.log)
194
+ return;
195
+ console.log([(0, colors_1.white)(opt.name || cmd), (0, colors_1.dimGrey)('took ' + (0, js_lib_1._since)(started))].join(' '));
196
+ }
197
+ }
198
+ exports.exec2 = new Exec2();
199
+ class SpawnError extends js_lib_1.AppError {
200
+ constructor(message, data) {
201
+ super(message, data, { name: 'SpawnError' });
202
+ }
203
+ }
204
+ exports.SpawnError = SpawnError;
@@ -0,0 +1,25 @@
1
+ import type { UnixTimestampNumber } from '@naturalcycles/js-lib';
2
+ /**
3
+ * Set of utility functions to work with git.
4
+ */
5
+ declare class Git2 {
6
+ getLastGitCommitMsg(): string;
7
+ commitMessageToTitleMessage(msg: string): string;
8
+ gitHasUncommittedChanges(): boolean;
9
+ /**
10
+ * Returns true if there were changes
11
+ */
12
+ gitCommitAll(msg: string): boolean;
13
+ /**
14
+ * @returns true if there are not pushed commits.
15
+ */
16
+ gitIsAhead(): boolean;
17
+ gitPull(): void;
18
+ gitPush(): void;
19
+ gitCurrentCommitSha(full?: boolean): string;
20
+ gitCurrentCommitTimestamp(): UnixTimestampNumber;
21
+ gitCurrentBranchName(): string;
22
+ gitCurrentRepoName(): string;
23
+ }
24
+ export declare const git2: Git2;
25
+ export {};