Skip to content

Commit 9863de8

Browse files
committed
Merge branch 'main' into feat/process
2 parents 73c1515 + d28e896 commit 9863de8

File tree

74 files changed

+1246
-637
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

74 files changed

+1246
-637
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
All notable changes to this project will be documented in this file.
44

5-
## [1.0.1](https://github.com/tempestphp/tempest-framework/compare/v1.0.0..1.0.1) — 2025-06-27
5+
## [1.0.1](https://github.com/tempestphp/tempest-framework/compare/v1.0.0..v1.0.1) — 2025-06-27
66

77
### 🚀 Features
88

bin/release

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ use Composer\Semver\VersionParser;
1818
use Tempest\Console\Console;
1919
use Tempest\Console\ConsoleApplication;
2020
use Tempest\Console\Exceptions\InterruptException;
21+
use Tempest\Http\Status;
22+
use Tempest\HttpClient\HttpClient;
23+
use Tempest\Support\Json;
2124

2225
use function Tempest\get;
2326
use function Tempest\Support\arr;
@@ -156,11 +159,37 @@ function performPreReleaseChecks(string $remote, string $branch): void
156159
throw new Exception("You must be on the {$remote}/{$branch} branch to release.");
157160
}
158161

162+
if (null === Tempest\env('RELEASE_GITHUB_TOKEN')) {
163+
throw new Exception('`RELEASE_GITHUB_TOKEN` environment variable must be set to release.');
164+
}
165+
159166
if ($behindCount = trim(shell_exec("git rev-list HEAD..{$remote}/{$branch} --count") ?? '0') !== '0') {
160167
throw new Exception("Local branch is behind {$remote}/{$branch} by {$behindCount} commits. Please pull first.");
161168
}
162169
}
163170

171+
/**
172+
* Disables the protection ruleset, so the release branch can be pushed to without a pull request.
173+
*/
174+
function updateBranchProtection(bool $enabled): void
175+
{
176+
// https://github.com/tempestphp/tempest-framework/settings/rules/1879240
177+
$ruleset = '1879240';
178+
$token = Tempest\env('RELEASE_GITHUB_TOKEN');
179+
$url = "https://api.github.com/repos/tempestphp/tempest-framework/rulesets/{$ruleset}";
180+
181+
$httpClient = Tempest\get(HttpClient::class);
182+
$response = $httpClient->put(
183+
uri: $url,
184+
headers: ['Authorization' => "Bearer {$token}"],
185+
body: Json\encode(['enforcement' => $enabled ? 'active' : 'disabled'])
186+
);
187+
188+
if ($response->status !== Status::OK) {
189+
throw new Exception('Failed to update branch ruleset.');
190+
}
191+
}
192+
164193
/**
165194
* Gets the current version.
166195
*/
@@ -338,6 +367,9 @@ try {
338367
handler: fn () => updateChangelog($version),
339368
);
340369

370+
// Disable protection
371+
updateBranchProtection(enabled: false);
372+
341373
// Push tags
342374
$console->task(
343375
label: 'Releasing',
@@ -360,6 +392,9 @@ try {
360392
],
361393
);
362394

395+
// Re-enable protection
396+
updateBranchProtection(enabled: true);
397+
363398
$console->success(sprintf(
364399
'Released <em>%1$s</em>. The <href="https://github.com/tempestphp/tempest-framework/releases/tag/%1$s">GitHub release</href> will be created automatically in a few seconds.',
365400
$tag,

packages/command-bus/src/AsyncCommandRepositories/FileCommandRepository.php

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use Tempest\CommandBus\CommandRepository;
88
use Tempest\CommandBus\Exceptions\PendingCommandCouldNotBeResolved;
9+
use Tempest\Support\Filesystem;
910

1011
use function Tempest\Support\arr;
1112

@@ -15,32 +16,30 @@ public function store(string $uuid, object $command): void
1516
{
1617
$payload = serialize($command);
1718

18-
file_put_contents(__DIR__ . "/../stored-commands/{$uuid}.pending.txt", $payload);
19+
Filesystem\write_file(__DIR__ . "/../stored-commands/{$uuid}.pending.txt", $payload);
1920
}
2021

2122
public function findPendingCommand(string $uuid): object
2223
{
2324
$path = __DIR__ . "/../stored-commands/{$uuid}.pending.txt";
2425

25-
if (! file_exists($path)) {
26+
if (! Filesystem\is_file($path)) {
2627
throw new PendingCommandCouldNotBeResolved($uuid);
2728
}
2829

29-
$payload = file_get_contents($path);
30+
$payload = Filesystem\read_file($path);
3031

3132
return unserialize($payload);
3233
}
3334

3435
public function markAsDone(string $uuid): void
3536
{
36-
$path = __DIR__ . "/../stored-commands/{$uuid}.pending.txt";
37-
38-
unlink($path);
37+
Filesystem\delete_file(__DIR__ . "/../stored-commands/{$uuid}.pending.txt");
3938
}
4039

4140
public function markAsFailed(string $uuid): void
4241
{
43-
if (! is_file(__DIR__ . "/../stored-commands/{$uuid}.pending.txt")) {
42+
if (! Filesystem\is_file(__DIR__ . "/../stored-commands/{$uuid}.pending.txt")) {
4443
return;
4544
}
4645

@@ -55,7 +54,7 @@ public function getPendingCommands(): array
5554
return arr(glob(__DIR__ . '/../stored-commands/*.pending.txt'))
5655
->mapWithKeys(function (string $path) {
5756
$uuid = str_replace('.pending.txt', '', pathinfo($path, PATHINFO_BASENAME));
58-
$payload = file_get_contents($path);
57+
$payload = Filesystem\read_file($path);
5958

6059
yield $uuid => unserialize($payload);
6160
})

packages/console/src/Components/Concerns/OpensInEditor.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use Tempest\Console\CanOpenInEditor;
88
use Tempest\Console\Components\ComponentState;
99
use Tempest\Console\InteractiveConsoleComponent;
10+
use Tempest\Support\Filesystem;
1011

1112
use function Tempest\env;
1213

@@ -39,14 +40,14 @@ public function openInEditor(?string $text): string
3940
$editor = $this->getEditorCommand();
4041
$tempFile = tempnam(sys_get_temp_dir(), '.TEMPEST_INPUT');
4142

42-
file_put_contents($tempFile, $text ?? '');
43+
Filesystem\write_file($tempFile, $text ?? '');
4344

4445
if (passthru(escapeshellcmd("{$editor} " . escapeshellarg($tempFile))) === false) {
4546
// TODO: failed. handle that
4647
return $text;
4748
}
4849

49-
$updatedText = file_get_contents($tempFile);
50+
$updatedText = Filesystem\read_file($tempFile);
5051
unlink($tempFile);
5152

5253
$this->setState($previousState);

packages/console/src/Exceptions/ConsoleExceptionHandler.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use Tempest\Console\Console;
88
use Tempest\Console\ExitCode;
9+
use Tempest\Console\GlobalFlags;
910
use Tempest\Console\HasExitCode;
1011
use Tempest\Console\Input\ConsoleArgumentBag;
1112
use Tempest\Container\Container;
@@ -16,6 +17,7 @@
1617
use Tempest\Core\Kernel;
1718
use Tempest\Highlight\Escape;
1819
use Tempest\Highlight\Highlighter;
20+
use Tempest\Support\Filesystem;
1921
use Throwable;
2022

2123
use function Tempest\Support\str;
@@ -50,7 +52,7 @@ public function handle(Throwable $throwable): void
5052
->writeln($this->getSnippet($throwable->getFile(), $throwable->getLine()))
5153
->writeln();
5254

53-
if ($this->argumentBag->get('-v') !== null) {
55+
if ($this->argumentBag->get(GlobalFlags::VERBOSE_SHORTHAND->value) || $this->argumentBag->get(GlobalFlags::VERBOSE->value)) {
5456
foreach ($throwable->getTrace() as $i => $trace) {
5557
$this->console->writeln("<style='bold fg-blue'>#{$i}</style> " . $this->formatTrace($trace));
5658
}
@@ -76,7 +78,7 @@ public function handle(Throwable $throwable): void
7678
private function getSnippet(string $file, int $lineNumber): string
7779
{
7880
$highlighter = $this->highlighter->withGutter();
79-
$code = Escape::terminal($highlighter->parse(file_get_contents($file), language: 'php'));
81+
$code = Escape::terminal($highlighter->parse(Filesystem\read_file($file), language: 'php'));
8082
$lines = explode(PHP_EOL, $code);
8183

8284
$lines[$lineNumber - 1] = str($lines[$lineNumber - 1])

packages/console/src/GlobalFlags.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ enum GlobalFlags: string
1010

1111
case FORCE = 'force';
1212
case FORCE_SHORTHAND = '-f';
13+
case VERBOSE = 'verbose';
14+
case VERBOSE_SHORTHAND = '-v';
1315
case HELP = 'help';
1416
case HELP_SHORTHAND = '-h';
1517
case INTERACTION = 'interaction';

packages/console/src/Output/LogOutputBuffer.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace Tempest\Console\Output;
66

77
use Tempest\Console\OutputBuffer;
8+
use Tempest\Support\Filesystem;
89

910
final readonly class LogOutputBuffer implements OutputBuffer
1011
{
@@ -14,14 +15,14 @@ public function __construct(
1415

1516
public function clear(): self
1617
{
17-
file_put_contents($this->path, '');
18+
Filesystem\write_file($this->path, '');
1819

1920
return $this;
2021
}
2122

2223
public function read(): string
2324
{
24-
return file_get_contents($this->path);
25+
return Filesystem\read_file($this->path);
2526
}
2627

2728
public function write(string $contents): void

packages/console/src/Scheduler/GenericScheduler.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use Tempest\Console\Input\ConsoleArgumentBag;
99
use Tempest\Console\Scheduler;
1010
use Tempest\Process\ProcessExecutor;
11+
use Tempest\Support\Filesystem;
1112

1213
use function Tempest\event;
1314
use function Tempest\internal_storage_path;
@@ -84,11 +85,11 @@ private function getInvocationsToRun(DateTime $date): array
8485
*/
8586
private function getPreviousRuns(): array
8687
{
87-
if (! file_exists(self::getCachePath())) {
88+
if (! Filesystem\is_file(self::getCachePath())) {
8889
return [];
8990
}
9091

91-
return unserialize(file_get_contents(self::getCachePath()), ['allowed_classes' => false]);
92+
return unserialize(Filesystem\read_file(self::getCachePath()), ['allowed_classes' => false]);
9293
}
9394

9495
/** @param ScheduledInvocation[] $ranInvocations */
@@ -106,6 +107,6 @@ private function markInvocationsAsRun(array $ranInvocations, DateTime $ranAt): v
106107
mkdir(directory: $directory, recursive: true);
107108
}
108109

109-
file_put_contents(self::getCachePath(), serialize($lastRuns));
110+
Filesystem\write_file(self::getCachePath(), serialize($lastRuns));
110111
}
111112
}

packages/core/src/Commands/DiscoveryGenerateCommand.php

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,9 @@ public function __invoke(): void
4343
$this->clearDiscoveryCache();
4444

4545
$this->console->task(
46-
label: "Generating discovery cache using the {$strategy->value} strategy",
46+
label: "Generating discovery cache using the `{$strategy->value}` strategy",
4747
handler: fn (Closure $log) => $this->generateDiscoveryCache($strategy, $log),
4848
);
49-
50-
$this->discoveryCache->storeStrategy($strategy);
5149
}
5250

5351
public function clearDiscoveryCache(): void
@@ -68,16 +66,12 @@ public function generateDiscoveryCache(DiscoveryCacheStrategy $strategy, Closure
6866

6967
$discoveries = $loadDiscoveryClasses->build();
7068

71-
foreach ($discoveries as $discovery) {
72-
$log($discovery::class);
73-
$discoveryItems = $discovery->getItems();
74-
75-
if ($strategy === DiscoveryCacheStrategy::PARTIAL) {
76-
$discoveryItems = $discoveryItems->onlyVendor();
77-
}
78-
79-
$this->discoveryCache->store($discovery, $discoveryItems);
69+
foreach ($this->kernel->discoveryLocations as $location) {
70+
$this->discoveryCache->store($location, $discoveries);
71+
$log($location->path);
8072
}
73+
74+
$this->discoveryCache->storeStrategy($strategy);
8175
}
8276

8377
public function resolveKernel(): Kernel

packages/core/src/Composer.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use Tempest\Process\ProcessExecutor;
88
use Tempest\Support\Arr;
9+
use Tempest\Support\Filesystem;
910
use Tempest\Support\Namespace\Psr4Namespace;
1011
use Tempest\Support\Path;
1112
use Tempest\Support\Str;
@@ -94,7 +95,7 @@ public function addNamespace(string $namespace, string $path): self
9495

9596
public function save(): self
9697
{
97-
file_put_contents($this->composerPath, json_encode($this->composer, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
98+
Filesystem\write_json($this->composerPath, $this->composer, pretty: true);
9899

99100
return $this;
100101
}
@@ -108,10 +109,10 @@ public function executeUpdate(): self
108109

109110
private function loadComposerFile(string $path): array
110111
{
111-
if (! file_exists($path)) {
112+
if (! Filesystem\is_file($path)) {
112113
throw new ComposerJsonCouldNotBeLocated('Could not locate composer.json.');
113114
}
114115

115-
return json_decode(file_get_contents($path), associative: true);
116+
return Filesystem\read_json($path);
116117
}
117118
}

0 commit comments

Comments
 (0)