Skip to content

Commit

Permalink
few more updates for bard
Browse files Browse the repository at this point in the history
  • Loading branch information
JoshuaEstes committed Oct 1, 2024
1 parent 018afa5 commit 1f69d6b
Show file tree
Hide file tree
Showing 3 changed files with 152 additions and 84 deletions.
5 changes: 4 additions & 1 deletion src/SonsOfPHP/Bard/src/Console/Command/PushCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
['git', 'subtree', 'push', '-P', $pkg['path'], $pkg['repository'], $input->getOption('branch')],
];

$io->text(sprintf('Pushing <info>%s</>', $pkgName));
$output->writeln($this->getHelper('formatter')->formatSection($pkgName, 'Pushing...'));
foreach ($commands as $cmd) {
$process = new Process($cmd);
$io->text($process->getCommandLine());
Expand All @@ -60,6 +60,9 @@ protected function execute(InputInterface $input, OutputInterface $output): int
->wait();
}
}

$output->writeln($this->getHelper('formatter')->formatSection($pkgName, '...Done'));
$io->newLine();
}

$io->success('All Packages have been published.');
Expand Down
222 changes: 140 additions & 82 deletions src/SonsOfPHP/Bard/src/Console/Command/ReleaseCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@
use RuntimeException;
use SonsOfPHP\Bard\JsonFile;
use SonsOfPHP\Bard\Worker\File\Bard\UpdateVersion;
use SonsOfPHP\Bard\Worker\File\Composer\Package\BranchAlias;
use SonsOfPHP\Bard\Worker\File\Composer\Root\UpdateReplaceSection;
use SonsOfPHP\Component\Version\Version;
use SonsOfPHP\Component\Version\VersionInterface;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
Expand All @@ -26,10 +28,14 @@ final class ReleaseCommand extends AbstractCommand
{
private JsonFile $bardConfig;

private VersionInterface|Version|null $releaseVersion = null;
private VersionInterface|null $releaseVersion = null;

private bool $isDryRun = true;

private JsonFile $rootComposerJsonFile;

private SymfonyStyle $io;

protected function configure(): void
{
$this
Expand All @@ -40,14 +46,14 @@ protected function configure(): void
->addArgument('release', InputArgument::REQUIRED, 'Next Release you want to start? Use format <major>.<minor>.<patch>-<PreRelease>+<BuildMetadata> or "major", "minor", "patch"')
->setHelp(
<<<'EOT'
This command allows you to create a new release and will update the various
repos that have been configured. The current version can be found in the
`bard.json` file. This will will update the version based on the type of release
that you are doing.
This command allows you to create a new release and will update the various
repos that have been configured. The current version can be found in the
`bard.json` file. This will will update the version based on the type of release
that you are doing.
<comment>%command.full_name%</comment>
<comment>%command.full_name%</comment>
Read more at https://docs.SonsOfPHP.com
Read more at https://docs.SonsOfPHP.com
EOT
);
}
Expand Down Expand Up @@ -83,62 +89,87 @@ protected function initialize(InputInterface $input, OutputInterface $output): v
}

$this->isDryRun = $input->getOption('dry-run');
$this->io = new SymfonyStyle($input, $output);

$this->rootComposerJsonFile = new JsonFile($input->getOption('working-dir') . '/composer.json');
}

protected function execute(InputInterface $input, OutputInterface $output): int
{
$formatter = $this->getHelper('formatter');
$io = new SymfonyStyle($input, $output);
if ($this->isDryRun) {
$io->note('dry-run enabled no changes will be made');
$this->io->note('dry-run enabled no changes will be made');
}

$io->text([
sprintf('Bumping release from <info>%s</> to <info>%s</>', $this->bardConfig->getSection('version'), $this->releaseVersion->toString()),
]);
$this->io->text(sprintf('Bumping release from <info>%s</> to <info>%s</>', $this->bardConfig->getSection('version'), $this->releaseVersion->toString()));

// 0. Make sure we have the latest changes
$this->pullLatestChanges($input, $output);

// 1. Update "replace" in main composer.json with the Package Names
// "package/name": "self.version"
$this->updateReplace($input, $output);

// @todo
// 2. Update Changelog
// Changes the "Unreleased" headline to the version we are releaseing
// Adds new headline at top for unreleased features

// 3. Tag Release and push
$this->tagReleaseAndPushMonorepo($input, $output);

// 4. Subtree Split for each package
$this->tagReleaseAndPushPackages($input, $output);

// 5. Update branch alias in all composer.json files
$this->updateBranchAliasForPackages($input, $output);

// 6. Update bard.json with current version
$this->updateBardConfigVersion();

// Make sure we have the latest changes
// 7. Commit and push updates
$this->commitAndPushNewChanges($input, $output);

$this->io->success('Congrations on your new release');
if ($this->isDryRun) {
$this->io->note([
'dry-run was enabled so no files were changed and no code was pushed',
]);
}

return self::SUCCESS;
}

private function pullLatestChanges(InputInterface $input, OutputInterface $output): void
{
$this->io->section('Making sure branch is up to date with latest changes');
$process = new Process(['git', 'pull', 'origin', $input->getOption('branch')]);
$io->text($process->getCommandLine());
$this->io->text($process->getCommandLine());
if (!$this->isDryRun) {
$this->getHelper('process')->mustRun($output, $process, sprintf('There was and error running command: %s', $process->getCommandLine()));
}

$rootComposerJsonFile = new JsonFile($input->getOption('working-dir') . '/composer.json');
$this->io->success('Done');
}

// 1. Update "replace" in main composer.json with the Package Names
// "package/name": "self.version"
$io->section('updating root composer.json "replace" section with package information');
private function updateReplace(InputInterface $input, OutputInterface $output): void
{
$this->io->section('updating root composer.json "replace" section with package information');
foreach ($this->bardConfig->getSection('packages') as $pkg) {
$pkgComposerJsonFile = new JsonFile(realpath($input->getOption('working-dir') . '/' . $pkg['path'] . '/composer.json'));
$output->writeln([
$formatter->formatSection($pkgComposerJsonFile->getSection('name'), 'Updating root <info>composer.json</info>'),
]);
$rootComposerJsonFile = $rootComposerJsonFile->with(new UpdateReplaceSection($pkgComposerJsonFile));
$output->writeln($this->getHelper('formatter')->formatSection($pkgComposerJsonFile->getSection('name'), 'Updating root <info>composer.json</info>'));
$this->rootComposerJsonFile = $this->rootComposerJsonFile->with(new UpdateReplaceSection($pkgComposerJsonFile));
}

$output->writeln([
'saving root composer.json',
]);
if (!$this->isDryRun) {
file_put_contents($rootComposerJsonFile->getFilename(), $rootComposerJsonFile->toJson());
$this->rootComposerJsonFile->save();
}

$output->writeln([
'root composer.json file saved',
]);
$io->newLine();
$io->success('root "composer.json" update complete');

// @todo
// 2. Update Changelog
// Changes the "Unreleased" headline to the version we are releaseing
// Adds new headline at top for unreleased features

// 3. Tag Release and push
$io->newLine();
$io->section(sprintf('updating mother repo for release %s', $this->releaseVersion->toString()));
$this->io->success('Done');
}

private function tagReleaseAndPushMonorepo(InputInterface $input, OutputInterface $output): void
{
$this->io->section(sprintf('updating mother repo for release %s', $this->releaseVersion->toString()));
$processCommands = [
['git', 'add', '.'],
['git', 'commit', '--allow-empty', '-m', sprintf('"Preparing for Release v%s"', $this->releaseVersion->toString())],
Expand All @@ -148,22 +179,22 @@ protected function execute(InputInterface $input, OutputInterface $output): int
];
foreach ($processCommands as $cmd) {
$process = new Process($cmd);
$io->text($process->getCommandLine());
$this->io->text($process->getCommandLine());
if (!$this->isDryRun) {
$this->getHelper('process')->mustRun($output, $process, sprintf('There was and error running command: %s', $process->getCommandLine()));
}
}

$io->success('Mother Repository Released');
$this->io->success('Mother Repository Released');
}

// 4. Subtree Split for each package
// @todo run split command
$io->newLine();
$io->title(sprintf('updating package repos with release %s', $this->releaseVersion->toString()));
private function tagReleaseAndPushPackages(InputInterface $input, OutputInterface $output): void
{
$this->io->section(sprintf('updating package repos with release %s', $this->releaseVersion->toString()));
foreach ($this->bardConfig->getSection('packages') as $pkg) {
$pkgComposerJsonFile = new JsonFile(realpath($input->getOption('working-dir') . '/' . $pkg['path'] . '/composer.json'));
$pkgName = $pkgComposerJsonFile->getSection('name');
$io->text(sprintf('Package <info>%s</> is being released', $pkgName));
$output->writeln($this->getHelper('formatter')->formatSection($pkgName, 'Releasing...'));
$processCommands = [
['git', 'subtree', 'split', '-P', $pkg['path'], '-b', $pkgName],
['git', 'checkout', $pkgName],
Expand All @@ -176,56 +207,83 @@ protected function execute(InputInterface $input, OutputInterface $output): int
];
foreach ($processCommands as $cmd) {
$process = new Process($cmd);
$io->text($process->getCommandLine());
$this->io->text($process->getCommandLine());
if (!$this->isDryRun) {
$this->getHelper('process')->mustRun($output, $process, sprintf('There was and error running command: %s', $process->getCommandLine()));
}
}

$io->newLine();
$output->writeln($this->getHelper('formatter')->formatSection($pkgName, '...Done'));
$this->io->newLine();
}

$io->text('All Packages have been Released');
// $io->success('All Packages have been Released');
$this->io->success('All Packages have been Released');
}

// 5. Update branch alias in all composer.json files
// - Only if update is major or minor
// $io->section('Updating Branch Alias in root and packages');
/**
* Foreach package, this will update the extra.branch-alias to the same
* value as the root composer.json value
*/
private function updateBranchAliasForPackages(InputInterface $input, OutputInterface $output): void
{
$this->io->section('Updating the Branch Alias for root and packages');
$extra = $this->rootComposerJsonFile->getSection('extra');
$branchAlias = explode('.', $this->releaseVersion->toString());
$branchAlias[2] = 'x-dev';
$branchAlias = implode('.', $branchAlias);
$extra['branch-alias'] = $branchAlias;
$this->rootComposerJsonFile->setSection('extra', $extra);
$this->io->text('root composer.json updated to ' . $branchAlias);
if (!$this->isDryRun) {
$this->rootComposerJsonFile->save();
}

// 6. Update bard.json with current version
$io->section('Updating version in bard.json');
foreach ($this->bardConfig->getSection('packages') as $pkg) {
$pkgComposerJsonFile = new JsonFile(realpath($input->getOption('working-dir') . '/' . $pkg['path'] . '/composer.json'));
$pkgComposerJsonFile = $pkgComposerJsonFile->with(new BranchAlias($this->rootComposerJsonFile));
$output->writeln($this->getHelper('formatter')->formatSection($pkgComposerJsonFile->getSection('name'), 'Updated branch alias to "' . $branchAlias . '"'));
if (!$this->isDryRun) {
$pkgComposerJsonFile->save();
}
}

$this->io->success('Done');
}

private function updateBardConfigVersion(): void
{
$this->io->section('Updating version in bard.json');
$this->bardConfig = $this->bardConfig->with(new UpdateVersion($this->releaseVersion));
if (!$this->isDryRun) {
file_put_contents($this->bardConfig->getFilename(), $this->bardConfig->toJson());
$this->bardConfig->save();
}

$io->text('bard.json updated with new version');
$this->io->success('bard.json updated with new version');
}

// 7. Commit and push updates
// $io->section('Updating mother repo');
// $processCommands = [
// ['git', 'add', '.'],
// ['git', 'commit', '-m', '"starting release"'],
// ['git', 'push', 'origin', $input->getOption('branch')],
// ];
// foreach ($processCommands as $cmd) {
// $process = new Process($cmd);
// $io->text($process->getCommandLine());
// if (!$this->isDryRun) {
// $this->getHelper('process')->mustRun($output, $process, sprintf('There was and error running command: %s', $process->getCommandLine()));
// }
// }
// $io->text('done');

$io->newLine();
$io->success('Congrations on your new release');
if ($this->isDryRun) {
$io->note([
'dry-run was enabled so no files were changed and no code was pushed',
]);
private function commitAndPushNewChanges(InputInterface $input, OutputInterface $output): void
{
$this->io->section('Commiting and new Pushing Changes');
$processCommands = [
['git', 'add', '.'],
['git', 'commit', '-m', '"starting next release"'],
['git', 'push', 'origin', $input->getOption('branch')],
];
foreach ($processCommands as $cmd) {
$process = new Process($cmd);
$this->io->text($process->getCommandLine());
if (!$this->isDryRun) {
$this->getHelper('process')->mustRun($output, $process, sprintf('There was and error running command: %s', $process->getCommandLine()));
}
}

return self::SUCCESS;
$cmdInput = new ArrayInput([
'command' => 'push',
'--dry-run' => $this->isDryRun,
'--branch' => $input->getOption('branch'),
]);
$this->getApplication()->doRun($cmdInput, $output);

$this->io->success('Done');
}
}
9 changes: 8 additions & 1 deletion src/SonsOfPHP/Bard/src/JsonFile.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ final class JsonFile

public function __construct(
private string $filename,
) {}
) {
$this->load();
}

private function load(): void
{
Expand Down Expand Up @@ -67,4 +69,9 @@ public function with($operator): self
{
return $operator->apply($this);
}

public function save(): void
{
file_put_contents($this->filename, $this->toJson());
}
}

0 comments on commit 1f69d6b

Please sign in to comment.