Skip to content

Commit 0f1cc95

Browse files
authored
Merge pull request #12 from byjg/5.0
Update to the new base library (5.0 and PHP 8.x) / Fix Break Compatibility
2 parents 6ef104f + e3bde08 commit 0f1cc95

Some content is hidden

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

53 files changed

+844
-652
lines changed

.github/workflows/build-app-image.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,18 +57,18 @@ jobs:
5757

5858
steps:
5959
- name: Checkout repository
60-
uses: actions/checkout@v3
60+
uses: actions/checkout@v4
6161

6262
- name: Set up QEMU
63-
uses: docker/setup-qemu-action@v2
63+
uses: docker/setup-qemu-action@v3
6464

6565
- name: Set up Docker Buildx
66-
uses: docker/setup-buildx-action@v2
66+
uses: docker/setup-buildx-action@v3
6767

6868
# Login against a Docker registry to pull the GHCR image
6969
# https://github.com/docker/login-action
7070
- name: Log into registry
71-
uses: docker/login-action@v2
71+
uses: docker/login-action@v3
7272
with:
7373
registry: ${{ env.REGISTRY }}
7474
username: ${{ github.actor }}
@@ -85,7 +85,7 @@ jobs:
8585
# Build image locally to enable to run the test
8686
# https://github.com/docker/build-push-action
8787
- name: Build Docker image
88-
uses: docker/build-push-action@v4
88+
uses: docker/build-push-action@v5
8989
with:
9090
context: .
9191
file: docker/Dockerfile

builder/BaseScripts.php

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

1515
class BaseScripts
1616
{
17-
protected $workdir;
17+
protected string|false $workdir;
1818
protected string $systemOs;
1919

2020
public function __construct()
@@ -47,9 +47,9 @@ public function fixDir($command)
4747
/**
4848
* Execute the given command by displaying console output live to the user.
4949
*
50-
* @param string|array $cmd : command to be executed
51-
* @return array exit_status : exit status of the executed command
52-
* output : console output of the executed command
50+
* @param array|string $cmd : command to be executed
51+
* @return array|null exit_status : exit status of the executed command
52+
* output : console output of the executed command
5353
* @throws ConfigException
5454
* @throws ConfigNotFoundException
5555
* @throws DependencyInjectionException
@@ -58,7 +58,7 @@ public function fixDir($command)
5858
* @throws KeyNotFoundException
5959
* @throws ReflectionException
6060
*/
61-
protected function liveExecuteCommand($cmd): ?array
61+
protected function liveExecuteCommand(array|string $cmd): ?array
6262
{
6363
// while (@ ob_end_flush()); // end all output buffers if any
6464

@@ -122,7 +122,7 @@ protected function replaceVariables($variableValue)
122122
foreach ($args[0] as $arg) {
123123
$variableValue = str_replace(
124124
$arg,
125-
Psr11::container()->get(substr($arg,1, -1)),
125+
Psr11::get(substr($arg,1, -1)),
126126
$variableValue
127127
);
128128
}

builder/PostCreateScript.php

Lines changed: 65 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,21 @@
22

33
namespace Builder;
44

5-
use ByJG\Util\JwtWrapper;
5+
use ByJG\AnyDataset\Db\Factory;
6+
use ByJG\JwtWrapper\JwtWrapper;
67
use ByJG\Util\Uri;
78
use Composer\Script\Event;
9+
use Exception;
810
use RecursiveCallbackFilterIterator;
911
use RecursiveDirectoryIterator;
1012
use RecursiveIteratorIterator;
1113

1214
class PostCreateScript
1315
{
14-
public function execute($workdir, $namespace, $composerName, $phpVersion, $mysqlConnection, $timezone)
16+
public function execute($workdir, $namespace, $composerName, $phpVersion, $mysqlConnection, $timezone): void
1517
{
1618
// ------------------------------------------------
17-
// Defining function to interatively walking through the directories
19+
// Defining function to interactively walking through the directories
1820
$directory = new RecursiveDirectoryIterator($workdir);
1921
$filter = new RecursiveCallbackFilterIterator($directory, function ($current/*, $key, $iterator*/) {
2022
// Skip hidden files and directories.
@@ -50,8 +52,8 @@ public function execute($workdir, $namespace, $composerName, $phpVersion, $mysql
5052
foreach ($files as $file) {
5153
$contents = file_get_contents("$workdir/$file");
5254
$contents = str_replace('ENV TZ=UTC', "ENV TZ=$timezone", $contents);
53-
$contents = str_replace('php:8.1-fpm', "php:$phpVersion-fpm", $contents);
54-
$contents = str_replace('php81', "php$phpVersionMSimple", $contents);
55+
$contents = str_replace('php:8.3-fpm', "php:$phpVersion-fpm", $contents);
56+
$contents = str_replace('php83', "php$phpVersionMSimple", $contents);
5557
file_put_contents(
5658
"$workdir/$file",
5759
$contents
@@ -66,7 +68,6 @@ public function execute($workdir, $namespace, $composerName, $phpVersion, $mysql
6668
'config/config-prod.php',
6769
'config/config-test.php',
6870
'docker-compose-dev.yml',
69-
'docker-compose-image.yml'
7071
];
7172
$uri = new Uri($mysqlConnection);
7273
foreach ($files as $file) {
@@ -87,12 +88,12 @@ public function execute($workdir, $namespace, $composerName, $phpVersion, $mysql
8788
$objects = new RecursiveIteratorIterator($filter);
8889
foreach ($objects as $name => $object) {
8990
$contents = file_get_contents($name);
90-
if (strpos($contents, 'RestReferenceArchitecture') !== false) {
91+
if (str_contains($contents, 'RestReferenceArchitecture')) {
9192
echo "$name\n";
9293

9394
// Replace inside Quotes
9495
$contents = preg_replace(
95-
"/([\'\"])RestReferenceArchitecture(.*?[\'\"])/",
96+
"/(['\"])RestReferenceArchitecture(.*?['\"])/",
9697
'$1' . str_replace('\\', '\\\\\\\\', $namespace) . '$2',
9798
$contents
9899
);
@@ -114,26 +115,77 @@ public function execute($workdir, $namespace, $composerName, $phpVersion, $mysql
114115
);
115116
}
116117
}
118+
119+
shell_exec("composer update");
120+
shell_exec("git init");
121+
shell_exec("git branch -m main");
122+
shell_exec("git add .");
123+
shell_exec("git commit -m 'Initial commit'");
117124
}
118125

126+
/**
127+
* @param Event $event
128+
* @return void
129+
* @throws Exception
130+
*/
119131
public static function run(Event $event)
120132
{
121133
$workdir = realpath(__DIR__ . '/..');
122134
$stdIo = $event->getIO();
123135

124136
$currentPhpVersion = PHP_MAJOR_VERSION . "." .PHP_MINOR_VERSION;
125137

138+
$validatePHPVersion = function ($arg) {
139+
$validPHPVersions = ['8.1', '8.2', '8.3'];
140+
if (in_array($arg, $validPHPVersions)) {
141+
return $arg;
142+
}
143+
throw new Exception('Only the PHP versions ' . implode(', ', $validPHPVersions) . ' are supported');
144+
};
145+
146+
$validateNamespace = function ($arg) {
147+
if (empty($arg) || !preg_match('/^[A-Z][a-zA-Z0-9]*$/', $arg)) {
148+
throw new Exception('Namespace must be one word in CamelCase');
149+
}
150+
return $arg;
151+
};
152+
153+
$validateComposer = function ($arg) {
154+
if (empty($arg) || !preg_match('/^[a-z0-9-]+\/[a-z0-9-]+$/', $arg)) {
155+
throw new Exception('Invalid Composer name');
156+
}
157+
return $arg;
158+
};
159+
160+
$validateURI = function ($arg) {
161+
$uri = new Uri($arg);
162+
if (empty($uri->getScheme())) {
163+
throw new Exception('Invalid URI');
164+
}
165+
Factory::getRegisteredDrivers($uri->getScheme());
166+
return $arg;
167+
};
168+
169+
$validateTimeZone = function ($arg) {
170+
if (empty($arg) || !in_array($arg, timezone_identifiers_list())) {
171+
throw new Exception('Invalid Timezone');
172+
}
173+
return $arg;
174+
};
175+
176+
$maxRetries = 5;
177+
126178
$stdIo->write("========================================================");
127179
$stdIo->write(" Setup Project");
128180
$stdIo->write(" Answer the questions below");
129181
$stdIo->write("========================================================");
130182
$stdIo->write("");
131183
$stdIo->write("Project Directory: " . $workdir);
132-
$phpVersion = $stdIo->ask("PHP Version [$currentPhpVersion]: ", $currentPhpVersion);
133-
$namespace = $stdIo->ask('Project namespace [MyRest]: ', 'MyRest');
134-
$composerName = $stdIo->ask('Composer name [me/myrest]: ', 'me/myrest');
135-
$mysqlConnection = $stdIo->ask('MySQL connection DEV [mysql://root:mysqlp455w0rd@mysql-container/mydb]: ', 'mysql://root:mysqlp455w0rd@mysql-container/mydb');
136-
$timezone = $stdIo->ask('Timezone [UTC]: ', 'UTC');
184+
$phpVersion = $stdIo->askAndValidate("PHP Version [$currentPhpVersion]: ", $validatePHPVersion, $maxRetries, $currentPhpVersion);
185+
$namespace = $stdIo->askAndValidate('Project namespace [MyRest]: ', $validateNamespace, $maxRetries, 'MyRest');
186+
$composerName = $stdIo->askAndValidate('Composer name [me/myrest]: ', $validateComposer, $maxRetries, 'me/myrest');
187+
$mysqlConnection = $stdIo->askAndValidate('MySQL connection DEV [mysql://root:mysqlp455w0rd@mysql-container/mydb]: ', $validateURI, $maxRetries, 'mysql://root:mysqlp455w0rd@mysql-container/mydb');
188+
$timezone = $stdIo->askAndValidate('Timezone [UTC]: ', $validateTimeZone, $maxRetries, 'UTC');
137189
$stdIo->ask('Press <ENTER> to continue');
138190

139191
$script = new PostCreateScript();

builder/Scripts.php

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use ByJG\DbMigration\Database\MySqlDatabase;
1212
use ByJG\DbMigration\Exception\InvalidMigrationFile;
1313
use ByJG\DbMigration\Migration;
14+
use ByJG\JinjaPhp\Exception\TemplateParseException;
1415
use ByJG\JinjaPhp\Loader\FileSystemLoader;
1516
use ByJG\Util\Uri;
1617
use Composer\Script\Event;
@@ -39,7 +40,7 @@ public function __construct()
3940
* @throws KeyNotFoundException
4041
* @throws ReflectionException
4142
*/
42-
public static function migrate(Event $event)
43+
public static function migrate(Event $event): void
4344
{
4445
$migrate = new Scripts();
4546
$migrate->runMigrate($event->getArguments());
@@ -53,7 +54,7 @@ public static function migrate(Event $event)
5354
* @throws KeyNotFoundException
5455
* @throws ReflectionException
5556
*/
56-
public static function genOpenApiDocs(Event $event)
57+
public static function genOpenApiDocs(Event $event): void
5758
{
5859
$build = new Scripts();
5960
$build->runGenOpenApiDocs($event->getArguments());
@@ -62,14 +63,16 @@ public static function genOpenApiDocs(Event $event)
6263
/**
6364
* @param Event $event
6465
* @return void
66+
* @throws ConfigException
6567
* @throws ConfigNotFoundException
6668
* @throws DependencyInjectionException
6769
* @throws InvalidArgumentException
70+
* @throws InvalidDateException
6871
* @throws KeyNotFoundException
6972
* @throws ReflectionException
70-
* @throws \ByJG\Serializer\Exception\InvalidArgumentException
73+
* @throws TemplateParseException
7174
*/
72-
public static function codeGenerator(Event $event)
75+
public static function codeGenerator(Event $event): void
7376
{
7477
$build = new Scripts();
7578
$build->runCodeGenerator($event->getArguments());
@@ -86,8 +89,9 @@ public static function codeGenerator(Event $event)
8689
* @throws ReflectionException
8790
* @throws ConfigException
8891
* @throws InvalidDateException
92+
* @throws Exception
8993
*/
90-
public function runMigrate($arguments)
94+
public function runMigrate($arguments): void
9195
{
9296
$argumentList = $this->extractArguments($arguments);
9397
if (isset($argumentList["command"])) {
@@ -160,7 +164,7 @@ protected function extractArguments(array $arguments, bool $hasCmd = true): arra
160164
* @param array $arguments
161165
* @return void
162166
*/
163-
public function runGenOpenApiDocs(array $arguments)
167+
public function runGenOpenApiDocs(array $arguments): void
164168
{
165169
$docPath = $this->workdir . '/public/docs/';
166170

@@ -179,15 +183,17 @@ public function runGenOpenApiDocs(array $arguments)
179183
/**
180184
* @param array $arguments
181185
* @return void
186+
* @throws ConfigException
182187
* @throws ConfigNotFoundException
183188
* @throws DependencyInjectionException
184189
* @throws InvalidArgumentException
190+
* @throws InvalidDateException
185191
* @throws KeyNotFoundException
186192
* @throws ReflectionException
187-
* @throws \ByJG\Serializer\Exception\InvalidArgumentException
193+
* @throws TemplateParseException
188194
* @throws Exception
189195
*/
190-
public function runCodeGenerator(array $arguments)
196+
public function runCodeGenerator(array $arguments): void
191197
{
192198
// Get Table Name
193199
$table = null;
@@ -217,10 +223,11 @@ public function runCodeGenerator(array $arguments)
217223
$save = in_array("--save", $arguments);
218224

219225
/** @var DbDriverInterface $dbDriver */
220-
$dbDriver = Psr11::container()->get(DbDriverInterface::class);
226+
$dbDriver = Psr11::get(DbDriverInterface::class);
221227

222228
$tableDefinition = $dbDriver->getIterator("EXPLAIN " . strtolower($table))->toArray();
223229
$tableIndexes = $dbDriver->getIterator("SHOW INDEX FROM " . strtolower($table))->toArray();
230+
$autoIncrement = false;
224231

225232
// Convert DB Types to PHP Types
226233
foreach ($tableDefinition as $key => $field) {
@@ -230,6 +237,10 @@ public function runCodeGenerator(array $arguments)
230237
return strtoupper($matches[1]);
231238
}, $field['field']);
232239

240+
if ($field['extra'] == 'auto_increment') {
241+
$autoIncrement = true;
242+
}
243+
233244
switch ($type) {
234245
case 'int':
235246
case 'tinyint':
@@ -292,15 +303,15 @@ public function runCodeGenerator(array $arguments)
292303
}
293304
}
294305

295-
// Create an array with non nullable fields but primary keys
306+
// Create an array with non-nullable fields but primary keys
296307
$nonNullableFields = [];
297308
foreach ($tableDefinition as $field) {
298309
if ($field['null'] == 'NO' && $field['key'] != 'PRI') {
299310
$nonNullableFields[] = $field["property"];
300311
}
301312
}
302313

303-
// Create an array with non nullable fields but primary keys
314+
// Create an array with non-nullable fields but primary keys
304315
foreach ($tableIndexes as $key => $field) {
305316
$tableIndexes[$key]['camelColumnName'] = preg_replace_callback('/_(.?)/', function($match) {
306317
return strtoupper($match[1]);
@@ -309,6 +320,7 @@ public function runCodeGenerator(array $arguments)
309320

310321
$data = [
311322
'namespace' => 'RestReferenceArchitecture',
323+
'autoIncrement' => $autoIncrement ? 'yes' : 'no',
312324
'restTag' => ucwords(explode('_', strtolower($table))[0]),
313325
'restPath' => str_replace('_', '/', strtolower($table)),
314326
'className' => preg_replace_callback('/(?:^|_)(.?)/', function($match) {
@@ -373,7 +385,7 @@ public function runCodeGenerator(array $arguments)
373385
echo "Processing Test for table $table...\n";
374386
$template = $loader->getTemplate('test.php');
375387
if ($save) {
376-
$file = __DIR__ . '/../tests/Functional/Rest/' . $data['className'] . 'Test.php';
388+
$file = __DIR__ . '/../tests/Rest/' . $data['className'] . 'Test.php';
377389
file_put_contents($file, $template->render($data));
378390
echo "File saved in $file\n";
379391
} else {

0 commit comments

Comments
 (0)