-
-
Notifications
You must be signed in to change notification settings - Fork 144
chore: subsplit wip — Enzo will have to change this title :) #1908
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 3.x
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| <?php | ||
|
|
||
| namespace App\Git; | ||
|
|
||
| final class FakeGit implements Git | ||
| { | ||
| public array $commands = []; | ||
| private string $branch = 'test'; | ||
|
|
||
| public function __construct( | ||
| private readonly string $path, | ||
| ) {} | ||
|
|
||
| public function isInitialized(): bool | ||
| { | ||
| return true; | ||
| } | ||
|
|
||
| public function tryInit(string $remote): void | ||
| { | ||
| $this->commands[] = 'git init'; | ||
| } | ||
|
|
||
| public function checkoutBranch(string $branch): void | ||
| { | ||
| $this->branch = $branch; | ||
| $this->commands[] = 'git checkout -b ' . $branch; | ||
| } | ||
|
|
||
| public function pull(): void | ||
| { | ||
| $this->commands[] = 'git pull origin ' . $this->getCurrentBranch(); | ||
| } | ||
|
|
||
| public function push(): void | ||
| { | ||
| $this->commands[] = 'git push origin ' . $this->getCurrentBranch(); | ||
| } | ||
|
|
||
| public function getCurrentBranch(): string | ||
| { | ||
| return 'test'; | ||
| } | ||
|
|
||
| public function status(): string | ||
| { | ||
| return ''; | ||
| } | ||
|
|
||
| public function commit(string $message): void | ||
| { | ||
| $this->commands[] = 'git add . && git commit -m "' . $message . '"'; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,101 @@ | ||
| <?php | ||
|
|
||
| namespace App\Git; | ||
|
|
||
| use Tempest\Container\Autowire; | ||
| use function Tempest\Support\path; | ||
| use Tempest\Support\Filesystem; | ||
|
|
||
| #[Autowire] | ||
| final readonly class GenericGit implements Git | ||
| { | ||
| public function __construct( | ||
| private string $path, | ||
| ) {} | ||
|
|
||
| public function isInitialized(): bool | ||
| { | ||
| return Filesystem\exists(path($this->path . '/.git/')); | ||
| } | ||
|
|
||
| public function tryInit(string $remote): void | ||
| { | ||
| if ($this->isInitialized()) { | ||
| return; | ||
| } | ||
|
|
||
| exec("cd {$this->path}; git init && git remote add origin {$remote};", result_code: $result); | ||
|
|
||
| if ($result !== 0) { | ||
| throw new GitOperationFailed('Failed to initialize git repository.'); | ||
| } | ||
| } | ||
|
|
||
| public function checkoutBranch(string $branch): void | ||
| { | ||
| exec("cd {$this->path}; git checkout -b {$branch} &> /dev/null", result_code: $result); | ||
|
|
||
| if ($result === 0) { | ||
| return; | ||
| } | ||
|
|
||
| exec("cd {$this->path}; git checkout &> {$branch}", result_code: $result); | ||
|
|
||
| if ($result !== 0) { | ||
| throw new GitOperationFailed('Failed to checkout branch.'); | ||
| } | ||
| } | ||
|
|
||
| public function pull(): void | ||
| { | ||
| exec("cd {$this->path}; git pull origin {$this->getCurrentBranch()} &> /dev/null", result_code: $result); | ||
|
|
||
| if ($result !== 0) { | ||
| throw new GitOperationFailed('Failed to pull changes from remote.'); | ||
| } | ||
| } | ||
|
|
||
| public function push(): void | ||
| { | ||
| exec("cd {$this->path}; git push origin {$this->getCurrentBranch()} &> /dev/null", result_code: $result); | ||
|
|
||
| if ($result !== 0) { | ||
| throw new GitOperationFailed('Failed to push changes to remote.'); | ||
| } | ||
| } | ||
|
|
||
| public function getCurrentBranch(): string | ||
| { | ||
| exec("cd {$this->path}; git branch --show-current", output: $output, result_code: $result); | ||
|
|
||
| if ($result !== 0 || $output === []) { | ||
| throw new GitOperationFailed('Failed get current branch.'); | ||
| } | ||
|
|
||
| return $output[0]; | ||
| } | ||
|
|
||
| public function status(): string | ||
| { | ||
| exec("cd {$this->path}; git status" , output: $output, result_code: $result); | ||
|
|
||
| if ($result !== 0) { | ||
| throw new GitOperationFailed('Failed to get git status.'); | ||
| } | ||
|
|
||
| return implode(PHP_EOL, $output); | ||
| } | ||
|
|
||
| public function commit(string $message): void | ||
| { | ||
| if (str_contains($this->status(), 'nothing to commit')) { | ||
| return; | ||
| } | ||
|
|
||
| exec("cd {$this->path}; git add . && git commit -m \"{$message}\"" , result_code: $result); | ||
|
|
||
| if ($result !== 0) { | ||
| throw new GitOperationFailed('Failed to commit changes.'); | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| <?php | ||
|
|
||
| namespace App\Git; | ||
|
|
||
| interface Git | ||
| { | ||
| public function isInitialized(): bool; | ||
|
|
||
| public function tryInit(string $remote): void; | ||
|
|
||
| public function checkoutBranch(string $branch): void; | ||
|
|
||
| public function pull(): void; | ||
|
|
||
| public function push(): void; | ||
|
|
||
| public function getCurrentBranch(): string; | ||
|
|
||
| public function status(): string; | ||
|
|
||
| public function commit(string $message): void; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| <?php | ||
|
|
||
| namespace App\Git; | ||
|
|
||
| use Exception; | ||
|
|
||
| final class GitOperationFailed extends Exception | ||
| { | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| <?php | ||
|
|
||
| namespace App\Subsplit; | ||
|
|
||
| use Tempest\Support\Arr\ImmutableArray; | ||
| use function Tempest\Support\arr; | ||
|
|
||
| final class Package | ||
| { | ||
| public function __construct( | ||
| public readonly string $path, | ||
| public readonly string $name, | ||
| ) {} | ||
|
|
||
| public string $remote { | ||
| get => "git@github.com:tempestphp/tempest-{$this->name}.git"; | ||
| } | ||
|
|
||
| public string $buildPath { | ||
| get => __DIR__ . '/../../build/packages/' . $this->name . '/'; | ||
| } | ||
|
|
||
| public string $sourcePath { | ||
| get => __DIR__ . '/../../packages/' . $this->name . '/'; | ||
| } | ||
|
|
||
| /** @return ImmutableArray<array-key, self> */ | ||
| public static function all(): ImmutableArray | ||
| { | ||
| return arr(glob(__DIR__ . '/../../packages/*')) | ||
| ->map(fn (string $path) => self::fromPath($path)); | ||
| } | ||
|
|
||
| public static function fromPath(string $path): self | ||
| { | ||
| return new self( | ||
| path: $path, | ||
| name: pathinfo($path, PATHINFO_FILENAME), | ||
| ); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,86 @@ | ||
| <?php | ||
|
|
||
| namespace App\Subsplit; | ||
|
|
||
| use App\Git\Git; | ||
| use App\Git\GitOperationFailed; | ||
| use Tempest\Console\ConsoleCommand; | ||
| use Tempest\Console\HasConsole; | ||
| use Tempest\Console\Middleware\ForceMiddleware; | ||
| use Tempest\Container\Container; | ||
| use Tempest\Support\Filesystem; | ||
| use App\Git\GenericGit; | ||
| use function Tempest\root_path; | ||
|
|
||
| final class TempestSubsplitCommand | ||
| { | ||
| use HasConsole; | ||
|
|
||
| public function __construct( | ||
| private Container $container, | ||
| ) {} | ||
|
|
||
| #[ConsoleCommand(middleware: [ForceMiddleware::class])] | ||
| public function __invoke(?string $package = null): void | ||
| { | ||
| $packages = Package::all(); | ||
|
|
||
| if ($package) { | ||
| $packages = $packages->filter(fn (Package $search) => $search->name === $package)->values(); | ||
| } | ||
|
|
||
| if ($packages->isEmpty()) { | ||
| $this->error('No packages found'); | ||
| return; | ||
| } | ||
|
|
||
| $total = $packages->count(); | ||
|
|
||
| $currentBranch = $this->container->get(Git::class, path: root_path())->getCurrentBranch(); | ||
|
|
||
| $this->confirm("Subsplitting on `{$currentBranch}`, continue?"); | ||
|
|
||
| foreach ($packages as $i => $package) { | ||
| $this->info("{$i}/{$total} <em>tempest/{$package->name}</em>"); | ||
|
|
||
| try { | ||
| $git = $this->container->get(Git::class, path: $package->buildPath); | ||
|
|
||
| Filesystem\ensure_directory_exists($package->buildPath); | ||
|
|
||
| if ( ! $git->isInitialized()) { | ||
| $git->tryInit($package->remote); | ||
| $this->writeln(' - New remote initialized'); | ||
| } | ||
|
|
||
| $this->writeln(" - Checking out <em>{$currentBranch}</em> branch"); | ||
| $git->checkoutBranch($currentBranch); | ||
|
|
||
| $this->writeln(' - Pulling latest changes'); | ||
|
|
||
| try { | ||
| $git->pull(); | ||
| } catch (GitOperationFailed) { | ||
| // Remote branch does not exist yet | ||
| } | ||
|
|
||
| // Don't we have a recursive directory copy function somewhere?? | ||
| exec("cp -R {$package->sourcePath} {$package->buildPath}"); | ||
| $this->writeln(" - Copied updated contents from <em>{$package->sourcePath}</em> to <em>{$package->buildPath}</em>"); | ||
|
|
||
| // TODO: Validate composer, LICENSE, README, and what else? | ||
| $this->writeln(" - Committing changes"); | ||
| $git->commit("chore: subsplit"); | ||
|
|
||
| $this->writeln(" - Pushing changes"); | ||
| $git->push(); | ||
|
|
||
| $this->success('Done'); | ||
| } catch (GitOperationFailed $e) { | ||
| $this->error($e->getMessage()); | ||
| continue; | ||
| } | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| <?php | ||
|
|
||
| namespace App; | ||
|
|
||
| use Tempest\Console\ConsoleCommand; | ||
| use Tempest\Console\HasConsole; | ||
|
|
||
| final class TempestReleaseCommand | ||
| { | ||
| use HasConsole; | ||
|
|
||
| #[ConsoleCommand] | ||
| public function __invoke(): void | ||
| { | ||
| // Move all logic of the `bin/release` script into here | ||
|
|
||
| $this->info('Todo'); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -202,6 +202,7 @@ | |
| }, | ||
| "autoload-dev": { | ||
| "psr-4": { | ||
| "App\\": "app/", | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We definitely need to use another directory than Something like
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agree, I used app as a placeholder. Any preferences? |
||
| "Tempest\\Auth\\Tests\\": "packages/auth/tests", | ||
| "Tempest\\Cache\\Tests\\": "packages/cache/tests", | ||
| "Tempest\\Clock\\Tests\\": "packages/clock/tests", | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We do now: #1909
However, this is not the right approach. We need to use actual
git subtree split(or an equivalent alternative) to keep the history and tags in sync with the main monorepo.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I was under the impression the release script took care of keeping tags in sync, actually, but that was probably a wrong assumption
When it comes to history: I really don't care about keeping it in sync. However, tags are important indeed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You need to care about history. This will break Packagist if you don't.