Skip to content

Commit 92612f3

Browse files
committed
feat(cli): ⚡ Integrate release command with core logic
1 parent ce9562d commit 92612f3

File tree

2 files changed

+126
-71
lines changed

2 files changed

+126
-71
lines changed
Lines changed: 125 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,93 +1,148 @@
11
import type { CommandModule } from 'yargs';
22
import chalk from 'chalk';
33
import inquirer from 'inquirer';
4-
import {
5-
detectVersioningStrategy,
6-
getRecommendedBump,
7-
updateAllVersions,
8-
generateChangelog,
9-
MonorepoInfo
10-
} from '@stackcode/core';
114
import semver from 'semver';
125
import fs from 'fs/promises';
136
import path from 'path';
147
import { t } from '@stackcode/i18n';
8+
import {
9+
MonorepoInfo,
10+
PackageBumpInfo,
11+
detectVersioningStrategy,
12+
updateAllVersions,
13+
generateChangelog,
14+
getRecommendedBump,
15+
findChangedPackages,
16+
determinePackageBumps,
17+
updatePackageVersion,
18+
commitAndTagPackage,
19+
} from '@stackcode/core';
1520

1621
async function handleLockedRelease(monorepoInfo: MonorepoInfo) {
17-
const projectRoot = monorepoInfo.rootDir;
18-
const currentVersion = monorepoInfo.rootVersion || '0.0.0';
22+
const projectRoot = monorepoInfo.rootDir;
23+
const currentVersion = monorepoInfo.rootVersion || '0.0.0';
1924

20-
const bumpType = await getRecommendedBump(projectRoot);
21-
const newVersion = semver.inc(currentVersion, bumpType as semver.ReleaseType);
25+
const bumpType = await getRecommendedBump(projectRoot);
26+
const newVersion = semver.inc(currentVersion, bumpType as semver.ReleaseType);
2227

23-
if (!newVersion) {
24-
console.error(chalk.red(t('release.error_calculating_version')));
25-
return;
26-
}
28+
if (!newVersion) {
29+
console.error(chalk.red(t('release.error_calculating_version')));
30+
return;
31+
}
2732

28-
const { confirmRelease } = await inquirer.prompt([{
29-
type: 'confirm',
30-
name: 'confirmRelease',
31-
message: t('release.prompt_confirm_release').replace('{currentVersion}', currentVersion).replace('{newVersion}', newVersion),
32-
default: true,
33-
}]);
33+
const { confirmRelease } = await inquirer.prompt([{
34+
type: 'confirm',
35+
name: 'confirmRelease',
36+
message: t('release.prompt_confirm_release', { currentVersion, newVersion }),
37+
default: true,
38+
}]);
3439

35-
if (!confirmRelease) {
36-
console.log(chalk.yellow(t('common.operation_cancelled')));
37-
return;
38-
}
40+
if (!confirmRelease) {
41+
console.log(chalk.yellow(t('common.operation_cancelled')));
42+
return;
43+
}
44+
45+
console.log(chalk.blue(t('release.step_updating_versions')));
46+
await updateAllVersions(monorepoInfo, newVersion);
47+
48+
console.log(chalk.blue(t('release.step_generating_changelog')));
49+
const changelog = await generateChangelog(monorepoInfo);
50+
const changelogPath = path.join(projectRoot, 'CHANGELOG.md');
51+
52+
let existingChangelog = '';
53+
try {
54+
existingChangelog = await fs.readFile(changelogPath, 'utf-8');
55+
} catch (error) {
56+
// Arquivo não existe, o que é normal.
57+
}
58+
await fs.writeFile(changelogPath, `${changelog}\n${existingChangelog}`);
59+
60+
console.log(chalk.green.bold(`\n${t('release.success_ready_to_commit')}`));
61+
console.log(chalk.yellow(` ${t('release.next_steps_commit')}`));
62+
}
63+
64+
async function handleIndependentRelease(monorepoInfo: MonorepoInfo) {
65+
console.log(chalk.blue(t('release.independent_mode_start')));
66+
67+
const changedPackages = await findChangedPackages(monorepoInfo.packages, monorepoInfo.rootDir);
68+
if (changedPackages.length === 0) {
69+
console.log(chalk.green(t('release.independent_mode_no_changes')));
70+
return;
71+
}
3972

40-
console.log(chalk.blue(t('release.step_updating_versions')));
41-
await updateAllVersions(monorepoInfo, newVersion);
73+
const packagesToUpdate = await determinePackageBumps(changedPackages);
74+
if (packagesToUpdate.length === 0) {
75+
console.log(chalk.yellow(t('release.independent_mode_no_bumps')));
76+
return;
77+
}
78+
79+
console.log(chalk.yellow('Os seguintes pacotes serão atualizados:'));
80+
console.table(
81+
packagesToUpdate.map(info => ({
82+
Package: info.pkg.name,
83+
'Versão Atual': info.pkg.version,
84+
'Tipo de Bump': info.bumpType,
85+
'Nova Versão': info.newVersion,
86+
}))
87+
);
4288

43-
console.log(chalk.blue(t('release.step_generating_changelog')));
44-
const changelog = await generateChangelog(monorepoInfo);
45-
const changelogPath = path.join(projectRoot, 'CHANGELOG.md');
89+
const { confirmRelease } = await inquirer.prompt([{
90+
type: 'confirm',
91+
name: 'confirmRelease',
92+
message: t('release.independent_prompt_confirm'),
93+
default: true,
94+
}]);
95+
96+
if (!confirmRelease) {
97+
console.log(chalk.yellow(t('common.operation_cancelled')));
98+
return;
99+
}
100+
101+
for (const pkgInfo of packagesToUpdate) {
102+
const pkgName = chalk.bold(pkgInfo.pkg.name);
103+
console.log(chalk.cyan(`\nIniciando release para ${pkgName}...`));
46104

105+
process.stdout.write(' -> Atualizando versão... ');
106+
await updatePackageVersion(pkgInfo);
107+
process.stdout.write(chalk.green('✔\n'));
108+
109+
process.stdout.write(' -> Gerando changelog... ');
110+
const changelogContent = await generateChangelog(monorepoInfo, pkgInfo);
111+
const changelogPath = path.join(pkgInfo.pkg.path, 'CHANGELOG.md');
47112
let existingChangelog = '';
48-
try {
49-
existingChangelog = await fs.readFile(changelogPath, 'utf-8');
50-
} catch (error) {
51-
}
52-
await fs.writeFile(changelogPath, changelog + existingChangelog);
113+
try { existingChangelog = await fs.readFile(changelogPath, 'utf-8'); } catch (error) {}
114+
await fs.writeFile(changelogPath, `${changelogContent}\n${existingChangelog}`);
115+
process.stdout.write(chalk.green('✔\n'));
116+
117+
process.stdout.write(' -> Criando commit e tag... ');
118+
await commitAndTagPackage(pkgInfo, monorepoInfo.rootDir);
119+
process.stdout.write(chalk.green('✔\n'));
120+
}
53121

54-
console.log(chalk.green.bold(`\n${t('release.success_ready_to_commit')}`));
55-
console.log(chalk.yellow(` ${t('release.next_steps_commit')}`));
122+
console.log(chalk.green.bold(`\n${t('release.independent_success')}`));
123+
console.log(chalk.yellow(` ${t('release.next_steps_push')}`));
56124
}
57125

58126
export const releaseCommand: CommandModule = {
59-
command: 'release',
60-
describe: t('release.command_description'),
61-
builder: {},
62-
handler: async () => {
63-
console.log(chalk.cyan.bold(t('release.start')));
64-
65-
const monorepoInfo = await detectVersioningStrategy(process.cwd());
66-
67-
if (monorepoInfo.strategy === 'unknown') {
68-
console.error(chalk.red(t('release.error_structure')));
69-
return;
70-
}
71-
72-
const strategyText = chalk.bold(monorepoInfo.strategy);
73-
console.log(chalk.blue(t('release.detected_strategy').replace('{strategy}', strategyText)));
74-
75-
const { proceed } = await inquirer.prompt([{
76-
type: 'confirm',
77-
name: 'proceed',
78-
message: t('release.prompt_continue'),
79-
default: true,
80-
}]);
81-
82-
if (!proceed) {
83-
console.log(chalk.yellow(t('common.operation_cancelled')));
84-
return;
85-
}
86-
87-
if (monorepoInfo.strategy === 'locked') {
88-
await handleLockedRelease(monorepoInfo);
89-
} else if (monorepoInfo.strategy === 'independent') {
90-
console.log(chalk.green(`\n${t('release.independent_mode_start')}`));
91-
}
127+
command: 'release',
128+
describe: t('release.command_description'),
129+
builder: {},
130+
handler: async () => {
131+
console.log(chalk.cyan.bold(t('release.start')));
132+
const monorepoInfo = await detectVersioningStrategy(process.cwd());
133+
134+
if (monorepoInfo.strategy === 'unknown') {
135+
console.error(chalk.red(t('release.error_structure')));
136+
return;
137+
}
138+
139+
const strategyText = chalk.bold(monorepoInfo.strategy);
140+
console.log(chalk.blue(t('release.detected_strategy', { strategy: strategyText })));
141+
142+
if (monorepoInfo.strategy === 'locked') {
143+
await handleLockedRelease(monorepoInfo);
144+
} else if (monorepoInfo.strategy === 'independent') {
145+
await handleIndependentRelease(monorepoInfo);
92146
}
147+
}
93148
};

packages/cli/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { initI18n } from '@stackcode/i18n';
1313

1414
async function main() {
1515
await initI18n();
16-
16+
//teste
1717
yargs(hideBin(process.argv))
1818
.scriptName("stackcode")
1919
.version('1.0.0')

0 commit comments

Comments
 (0)