@brunoluizdesiqueira/bbuilder-cli 1.0.10 → 1.0.11

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/README.md CHANGED
@@ -162,6 +162,8 @@ bbuilder build --type FAST --project faturamento\BimerFaturamento
162
162
  bbuilder build --type RELEASE --project Bimer --version 11.3.1
163
163
  ```
164
164
 
165
+ Durante o build, o CLI exibe feedback visual por etapas com spinner, barra indeterminada e tempo decorrido. Essa barra representa atividade do pipeline, não percentual real do `dcc64`.
166
+
165
167
  ### Atalhos diretos por modo
166
168
  ```bash
167
169
  bbuilder fast # interativo para projeto/versão
@@ -122,7 +122,6 @@ async function runCgrc(opts, projectName) {
122
122
  const vrcFile = path.join(tempDir, `${projectName}.vrc`);
123
123
  const resFile = path.join(tempDir, `${projectName}.res`);
124
124
  const delphiEnv = await getDelphiEnvironment(opts.delphiDir);
125
- (0, output_1.step)('Compilando recursos e embutindo ícone...');
126
125
  try {
127
126
  await (0, execa_1.default)(path.win32.join(opts.delphiDir, 'bin', 'cgrc.exe'), [vrcFile, `-fo${resFile}`], {
128
127
  env: delphiEnv,
@@ -144,7 +143,6 @@ async function runDcc64(opts, projectName, workspaceDir) {
144
143
  fs.mkdirSync(exeOut, { recursive: true });
145
144
  if (!fs.existsSync(dcuOut))
146
145
  fs.mkdirSync(dcuOut, { recursive: true });
147
- (0, output_1.step)(`Iniciando compilação do código fonte (${opts.type})...`);
148
146
  const nsValue = 'Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;System;Xml;Data;Datasnap;Web;Soap;Winapi;FireDAC.VCLUI;System.Win;';
149
147
  const aliasValue = 'Generics.Collections=System.Generics.Collections;Generics.Defaults=System.Generics.Defaults;WinTypes=Winapi.Windows;WinProcs=Winapi.Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE';
150
148
  const dcc64 = path.win32.join(opts.delphiDir, 'bin', 'dcc64.exe');
@@ -41,16 +41,21 @@ const compiler_1 = require("./compiler");
41
41
  const project_1 = require("./project");
42
42
  const resources_1 = require("./resources");
43
43
  async function executeBuild(opts) {
44
+ const totalStages = 4;
44
45
  (0, output_1.banner)();
45
46
  const { workspaceDir, projectName } = (0, project_1.resolveProject)(opts.project, opts.repoBase);
46
47
  (0, output_1.printBuildHeader)(opts, projectName, workspaceDir);
47
- (0, resources_1.prepareProjectResources)(opts, projectName, workspaceDir);
48
+ await (0, output_1.withProgress)(1, totalStages, 'Preparando versao, manifesto e recursos', () => {
49
+ (0, resources_1.prepareProjectResources)(opts, projectName, workspaceDir);
50
+ });
48
51
  const oldRes = path.win32.join(workspaceDir, `${projectName}.res`);
49
52
  if (fs.existsSync(oldRes))
50
53
  fs.unlinkSync(oldRes);
51
- const resFile = await (0, compiler_1.runCgrc)(opts, projectName);
52
- fs.copyFileSync(resFile, path.win32.join(workspaceDir, `${projectName}.res`));
53
- await (0, compiler_1.runDcc64)(opts, projectName, workspaceDir);
54
+ const resFile = await (0, output_1.withProgress)(2, totalStages, 'Compilando recursos nativos', () => (0, compiler_1.runCgrc)(opts, projectName));
55
+ await (0, output_1.withProgress)(3, totalStages, 'Sincronizando recurso final no projeto', () => {
56
+ fs.copyFileSync(resFile, path.win32.join(workspaceDir, `${projectName}.res`));
57
+ });
58
+ await (0, output_1.withProgress)(4, totalStages, `Compilando projeto Delphi (${opts.type})`, () => (0, compiler_1.runDcc64)(opts, projectName, workspaceDir));
54
59
  (0, output_1.printSuccess)(opts.type);
55
60
  const { runAfter } = (0, compiler_1.buildCompilerFlags)(opts.type);
56
61
  if (runAfter) {
@@ -151,12 +151,6 @@ function prepareProjectResources(opts, projectName, workspaceDir) {
151
151
  if (!fs.existsSync(dproj)) {
152
152
  (0, output_1.fatal)(`Arquivo de projeto não encontrado: ${dproj}`);
153
153
  }
154
- if (opts.version) {
155
- (0, output_1.step)(`Injetando versão ${opts.version} no projeto...`);
156
- }
157
- else {
158
- (0, output_1.step)('Nenhuma versão informada. Lendo atual do projeto...');
159
- }
160
154
  try {
161
155
  const projectContent = fs.readFileSync(dproj, 'utf-8');
162
156
  const { content: updatedContent, fullVersion, parts } = resolveVersionInfo(projectContent, opts.version);
package/dist/ui/output.js CHANGED
@@ -7,8 +7,12 @@ exports.banner = banner;
7
7
  exports.printBuildHeader = printBuildHeader;
8
8
  exports.printSuccess = printSuccess;
9
9
  exports.step = step;
10
+ exports.withProgress = withProgress;
10
11
  exports.fatal = fatal;
11
12
  const chalk_1 = __importDefault(require("chalk"));
13
+ const SPINNER_FRAMES = ['|', '/', '-', '\\'];
14
+ const BAR_WIDTH = 18;
15
+ const BAR_SEGMENT = 6;
12
16
  function banner() {
13
17
  console.log('');
14
18
  console.log(chalk_1.default.blue(' ══════════════════════════════════════════════════════════════'));
@@ -57,6 +61,59 @@ function printSuccess(buildType) {
57
61
  function step(msg) {
58
62
  console.log(chalk_1.default.cyan(' [*]') + ' ' + chalk_1.default.white(msg));
59
63
  }
64
+ function formatElapsed(startTime) {
65
+ const totalSeconds = Math.max(0, Math.floor((Date.now() - startTime) / 1000));
66
+ const minutes = Math.floor(totalSeconds / 60)
67
+ .toString()
68
+ .padStart(2, '0');
69
+ const seconds = (totalSeconds % 60).toString().padStart(2, '0');
70
+ return `${minutes}:${seconds}`;
71
+ }
72
+ function buildIndeterminateBar(frameIndex) {
73
+ const chars = new Array(BAR_WIDTH).fill('░');
74
+ const start = frameIndex % (BAR_WIDTH + BAR_SEGMENT);
75
+ for (let offset = 0; offset < BAR_SEGMENT; offset++) {
76
+ const position = start - offset;
77
+ if (position >= 0 && position < BAR_WIDTH) {
78
+ chars[position] = '█';
79
+ }
80
+ }
81
+ return chars.join('');
82
+ }
83
+ function renderProgressLine(stage, total, label, startTime, frameIndex) {
84
+ const spinner = SPINNER_FRAMES[frameIndex % SPINNER_FRAMES.length];
85
+ const bar = buildIndeterminateBar(frameIndex);
86
+ const elapsed = formatElapsed(startTime);
87
+ return ` ${chalk_1.default.cyan(`[${stage}/${total}]`)} ${chalk_1.default.yellow(spinner)} ${chalk_1.default.white(label)} ${chalk_1.default.blue(`[${bar}]`)} ${chalk_1.default.gray(elapsed)}`;
88
+ }
89
+ async function withProgress(stage, total, label, task) {
90
+ const startTime = Date.now();
91
+ if (!process.stdout.isTTY) {
92
+ step(`[${stage}/${total}] ${label}`);
93
+ const result = await task();
94
+ console.log(` ${chalk_1.default.green('OK')} ${chalk_1.default.white(label)} ${chalk_1.default.gray(`(${formatElapsed(startTime)})`)}`);
95
+ return result;
96
+ }
97
+ let frameIndex = 0;
98
+ process.stdout.write(`${renderProgressLine(stage, total, label, startTime, frameIndex)}`);
99
+ const timer = setInterval(() => {
100
+ frameIndex += 1;
101
+ process.stdout.write(`\r${renderProgressLine(stage, total, label, startTime, frameIndex)}`);
102
+ }, 120);
103
+ try {
104
+ const result = await task();
105
+ clearInterval(timer);
106
+ process.stdout.write(`\r${' '.repeat(120)}\r`);
107
+ console.log(` ${chalk_1.default.green('OK')} ${chalk_1.default.white(label)} ${chalk_1.default.gray(`(${formatElapsed(startTime)})`)}`);
108
+ return result;
109
+ }
110
+ catch (error) {
111
+ clearInterval(timer);
112
+ process.stdout.write(`\r${' '.repeat(120)}\r`);
113
+ console.log(` ${chalk_1.default.red('FAIL')} ${chalk_1.default.white(label)} ${chalk_1.default.gray(`(${formatElapsed(startTime)})`)}`);
114
+ throw error;
115
+ }
116
+ }
60
117
  function fatal(msg) {
61
118
  console.error('');
62
119
  console.error(chalk_1.default.red(' [ERRO FATAL] ') + msg);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brunoluizdesiqueira/bbuilder-cli",
3
- "version": "1.0.10",
3
+ "version": "1.0.11",
4
4
  "description": "CLI de build local para projetos Delphi do Bimer",
5
5
  "license": "ISC",
6
6
  "repository": {