biaws 0.2.0 → 0.2.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "biaws",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "CLI do Bondia Workspaces para administração, configuração e operação de workspaces",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
package/src/cli/help.js CHANGED
@@ -1,16 +1,38 @@
1
- import { Args, Command, Help } from "@oclif/core";
1
+ import { Args, Help } from "@oclif/core";
2
2
 
3
- const OVERVIEW = `Bondia Workspaces (BIAWS)
3
+ import { LocalInstanceCommand } from "../baseCommands.js";
4
+
5
+ function overview(context) {
6
+ return `Bondia Workspaces (BIAWS)
4
7
 
5
8
  O BIAWS organiza o contexto operacional de aplicações, melhorias, issues,
6
9
  conhecimento e agentes. Este CLI permite administrar uma instalação, configurar
7
10
  o acesso global e trabalhar com o workspace associado à pasta atual.
8
11
 
9
- NÍVEIS
10
- admin instala, diagnostica e opera instâncias da plataforma
12
+ NÍVEIS DE USO
13
+ admin instala, diagnostica e opera instalação e instâncias da plataforma
11
14
  config gerencia URLs, perfis e credenciais globais
12
15
  workspace associa a pasta e acessa os recursos do workspace
13
16
 
17
+ BIAWS CLI
18
+ Raiz da instalação: ${context.repositoryRoot}
19
+ Diretório de instâncias: ${context.instancesDirectory}
20
+ Diretório do CLI: ${context.toolDirectory}
21
+
22
+ Configure caminhos persistentes com as variáveis de ambiente:
23
+
24
+ BIAWS_ROOT raiz da release ou checkout BIAWS; deve conter
25
+ compose.yaml, scripts/ e os demais arquivos da plataforma
26
+ e é normalmente o diretório onde foi feito o git clone
27
+
28
+ BIAWS_INSTANCES_DIR diretório que conterá uma subpasta por instância,
29
+ com seu arquivo .env e dados de configuração, normalmente
30
+ é o uma pasta instances dentro do BIAWS_ROOT
31
+
32
+ Exemplo:
33
+ export BIAWS_ROOT=/opt/biaws
34
+ export BIAWS_INSTANCES_DIR=/var/lib/biaws/instances
35
+
14
36
  PRIMEIROS PASSOS
15
37
  biaws config init
16
38
  biaws workspace init
@@ -22,9 +44,11 @@ AJUDA
22
44
  biaws help workspace issues
23
45
 
24
46
  PROJETO
47
+ Saiba mais sobre o projeto (e contribua se quiser):
25
48
  https://github.com/fbondia/biaws`;
49
+ }
26
50
 
27
- export default class HelpCommand extends Command {
51
+ export default class HelpCommand extends LocalInstanceCommand {
28
52
  static description = "explica o BIAWS ou exibe a ajuda de um comando";
29
53
  static strict = false;
30
54
  static args = {
@@ -38,7 +62,8 @@ export default class HelpCommand extends Command {
38
62
  const { args } = await this.parse(this.constructor);
39
63
  const subject = args.command || [];
40
64
  if (!subject.length) {
41
- this.log(OVERVIEW);
65
+ const context = await this.localContext();
66
+ this.log(overview(context));
42
67
  return;
43
68
  }
44
69
  await new Help(this.config).showHelp(subject);
@@ -65,10 +65,11 @@ export default class InstanceBackup extends LocalInstanceCommand {
65
65
  { secrets: password ? [password] : [], silent: flags.json },
66
66
  ),
67
67
  );
68
- this.output({ json: flags.json }).result(
69
- flags.json
70
- ? { instance: instance.name, operation: "backup", output }
71
- : output,
72
- );
68
+ if (flags.json)
69
+ this.output({ json: true }).result({
70
+ instance: instance.name,
71
+ operation: "backup",
72
+ output,
73
+ });
73
74
  }
74
75
  }
@@ -87,10 +87,11 @@ export default class InstanceRestore extends LocalInstanceCommand {
87
87
  { secrets: password ? [password] : [], silent: flags.json },
88
88
  ),
89
89
  );
90
- this.output({ json: flags.json }).result(
91
- flags.json
92
- ? { instance: instance.name, operation: "restore", output }
93
- : output,
94
- );
90
+ if (flags.json)
91
+ this.output({ json: true }).result({
92
+ instance: instance.name,
93
+ operation: "restore",
94
+ output,
95
+ });
95
96
  }
96
97
  }
@@ -3,13 +3,32 @@ import { spawn as nodeSpawn } from "node:child_process";
3
3
  import { ProcessExecutionError } from "./errors.js";
4
4
  import { redactText } from "./redaction.js";
5
5
 
6
- function attachOutput(stream, target, chunks, shouldBuffer) {
7
- if (!stream) return;
6
+ function attachOutput(stream, target, chunks, options = {}) {
7
+ if (!stream) return () => {};
8
+ const secrets = options.secrets || [];
9
+ let pending = "";
10
+
11
+ const writeSanitizedLines = (value) => {
12
+ pending += value;
13
+ const lastNewline = pending.lastIndexOf("\n");
14
+ if (lastNewline < 0) return;
15
+ target?.write(redactText(pending.slice(0, lastNewline + 1), secrets));
16
+ pending = pending.slice(lastNewline + 1);
17
+ };
18
+
8
19
  stream.on("data", (chunk) => {
9
20
  const value = String(chunk);
10
21
  chunks.push(value);
11
- if (!shouldBuffer && target) target.write(value);
22
+ if (options.silent || !target) return;
23
+ if (secrets.length) writeSanitizedLines(value);
24
+ else target.write(value);
12
25
  });
26
+
27
+ return () => {
28
+ if (!options.silent && target && pending)
29
+ target.write(redactText(pending, secrets));
30
+ pending = "";
31
+ };
13
32
  }
14
33
 
15
34
  export class ProcessRunner {
@@ -25,8 +44,6 @@ export class ProcessRunner {
25
44
  throw new TypeError("ProcessRunner exige comando e array de argumentos.");
26
45
  }
27
46
  const secrets = options.secrets || [];
28
- const shouldBuffer =
29
- Boolean(options.silent) || secrets.some((secret) => String(secret || ""));
30
47
  const stdoutChunks = [];
31
48
  const stderrChunks = [];
32
49
  let child;
@@ -47,8 +64,14 @@ export class ProcessRunner {
47
64
  { cause, command: redactText(command, secrets) },
48
65
  );
49
66
  }
50
- attachOutput(child.stdout, this.stdout, stdoutChunks, shouldBuffer);
51
- attachOutput(child.stderr, this.stderr, stderrChunks, shouldBuffer);
67
+ const flushStdout = attachOutput(child.stdout, this.stdout, stdoutChunks, {
68
+ secrets,
69
+ silent: Boolean(options.silent),
70
+ });
71
+ const flushStderr = attachOutput(child.stderr, this.stderr, stderrChunks, {
72
+ secrets,
73
+ silent: Boolean(options.silent),
74
+ });
52
75
  if (options.input !== undefined) child.stdin.end(options.input);
53
76
 
54
77
  return new Promise((resolve, reject) => {
@@ -73,12 +96,6 @@ export class ProcessRunner {
73
96
  stdout: redactText(stdoutChunks.join(""), secrets),
74
97
  stderr: redactText(stderrChunks.join(""), secrets),
75
98
  });
76
- const flush = (result) => {
77
- if (!shouldBuffer || options.silent) return;
78
- if (result.stdout && this.stdout) this.stdout.write(result.stdout);
79
- if (result.stderr && this.stderr) this.stderr.write(result.stderr);
80
- };
81
-
82
99
  child.once("error", (cause) => {
83
100
  cleanup();
84
101
  reject(
@@ -90,8 +107,9 @@ export class ProcessRunner {
90
107
  });
91
108
  child.once("close", (processExitCode, signal) => {
92
109
  cleanup();
110
+ flushStdout();
111
+ flushStderr();
93
112
  const result = { ...output(), processExitCode, signal: signal || null };
94
- flush(result);
95
113
  if (processExitCode === 0 && !signal) {
96
114
  resolve(result);
97
115
  return;