From 4cef8e78424d3eddd2170ec98713529ed6dea5cf Mon Sep 17 00:00:00 2001 From: zds <49744633+zds-s@users.noreply.github.com> Date: Mon, 7 Oct 2024 22:03:32 +0800 Subject: [PATCH] Initial 3.0 Component --- .gitattributes | 2 + .github/workflows/close-pull-request.yml | 15 ++++ .github/workflows/release.yml | 25 ++++++ .gitignore | 5 ++ Application.php | 42 ++++++++++ Config.php | 49 ++++++++++++ Context.php | 52 +++++++++++++ Entity/ColumnEntity.php | 98 ++++++++++++++++++++++++ Entity/GeneratorEntity.php | 25 ++++++ Entity/TableEntity.php | 58 ++++++++++++++ Enums/TableColumnType.php | 29 +++++++ Event/GeneratorStaringEvent.php | 22 ++++++ Factory.php | 21 +++++ GeneratorInterface.php | 24 ++++++ LICENSE | 21 +++++ Processor/AbstractAstProcessor.php | 61 +++++++++++++++ Processor/AbstractProcessor.php | 44 +++++++++++ Processor/ControllerProcessor.php | 82 ++++++++++++++++++++ Processor/ProcessorInterface.php | 21 +++++ Processor/stubs/controller.blade.php | 26 +++++++ README.md | 3 + composer.json | 26 +++++++ 22 files changed, 751 insertions(+) create mode 100644 .gitattributes create mode 100644 .github/workflows/close-pull-request.yml create mode 100644 .github/workflows/release.yml create mode 100644 .gitignore create mode 100644 Application.php create mode 100644 Config.php create mode 100644 Context.php create mode 100644 Entity/ColumnEntity.php create mode 100644 Entity/GeneratorEntity.php create mode 100644 Entity/TableEntity.php create mode 100644 Enums/TableColumnType.php create mode 100644 Event/GeneratorStaringEvent.php create mode 100644 Factory.php create mode 100644 GeneratorInterface.php create mode 100644 LICENSE create mode 100644 Processor/AbstractAstProcessor.php create mode 100644 Processor/AbstractProcessor.php create mode 100644 Processor/ControllerProcessor.php create mode 100644 Processor/ProcessorInterface.php create mode 100644 Processor/stubs/controller.blade.php create mode 100644 README.md create mode 100644 composer.json diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..ce244ab --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +/tests export-ignore +/.github export-ignore \ No newline at end of file diff --git a/.github/workflows/close-pull-request.yml b/.github/workflows/close-pull-request.yml new file mode 100644 index 0000000..7239c0b --- /dev/null +++ b/.github/workflows/close-pull-request.yml @@ -0,0 +1,15 @@ +name: Close Pull Request + +permissions: write-all + +on: + pull_request_target: + types: [ opened ] + +jobs: + run: + runs-on: ubuntu-latest + steps: + - uses: superbrothers/close-pull-request@v3 + with: + comment: "Hi, this is a READ-ONLY repository, please submit your PR on the https://github.com/mineadmin/components repository.

This Pull Request will close automatically.

Thanks! " \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..ae1823d --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,25 @@ +on: + push: + tags: + - 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10 + +name: Release +permissions: write-all + +jobs: + release: + name: Release + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Create Release + id: create_release + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ github.ref }} + release_name: Release ${{ github.ref }} + draft: false + prerelease: false \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7cb10a6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +composer.lock +.idea +vendor +*.cache +runtime \ No newline at end of file diff --git a/Application.php b/Application.php new file mode 100644 index 0000000..ffe7777 --- /dev/null +++ b/Application.php @@ -0,0 +1,42 @@ +dispatch(new GeneratorStaringEvent($context)); + foreach ($this->config->getProcessors() as $processor) { + $context->getProcessors()->push($processor); + $context->getEntities()->push($processor->process($context)); + } + return $context->getEntities()->all(); + } + + private function dispatch(object $event): void + { + $this->dispatcher->dispatch($event); + } +} diff --git a/Config.php b/Config.php new file mode 100644 index 0000000..efba844 --- /dev/null +++ b/Config.php @@ -0,0 +1,49 @@ +config; + } + + public function isEnable(): bool + { + return (bool) $this->config->get('generator.enable', false); + } + + /** + * @return iterable + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + */ + public function getProcessors(): iterable + { + foreach ($this->config->get('generator.processors', []) as $processor) { + yield $this->container->get($processor); + } + } +} diff --git a/Context.php b/Context.php new file mode 100644 index 0000000..6878e26 --- /dev/null +++ b/Context.php @@ -0,0 +1,52 @@ +config; + } + + public function getTable(): TableEntity + { + return $this->table; + } + + public function getExtra(): Collection + { + return $this->extra; + } + + public function getProcessors(): Collection + { + return $this->processors; + } + + public function getEntities(): Collection + { + return $this->entities; + } +} diff --git a/Entity/ColumnEntity.php b/Entity/ColumnEntity.php new file mode 100644 index 0000000..fde97d2 --- /dev/null +++ b/Entity/ColumnEntity.php @@ -0,0 +1,98 @@ +columnName; + } + + public function setColumnName(string $columnName): void + { + $this->columnName = $columnName; + } + + public function getColumnType(): TableColumnType + { + return $this->columnType; + } + + public function setColumnType(TableColumnType $columnType): void + { + $this->columnType = $columnType; + } + + public function getColumnComment(): string + { + return $this->columnComment; + } + + public function setColumnComment(string $columnComment): void + { + $this->columnComment = $columnComment; + } + + public function isNullable(): bool + { + return $this->isNullable; + } + + public function setIsNullable(bool $isNullable): void + { + $this->isNullable = $isNullable; + } + + public function isPrimary(): bool + { + return $this->isPrimary; + } + + public function setIsPrimary(bool $isPrimary): void + { + $this->isPrimary = $isPrimary; + } + + public function isUnique(): bool + { + return $this->isUnique; + } + + public function setIsUnique(bool $isUnique): void + { + $this->isUnique = $isUnique; + } + + public function isAutoIncrement(): bool + { + return $this->isAutoIncrement; + } + + public function setIsAutoIncrement(bool $isAutoIncrement): void + { + $this->isAutoIncrement = $isAutoIncrement; + } +} diff --git a/Entity/GeneratorEntity.php b/Entity/GeneratorEntity.php new file mode 100644 index 0000000..7fe7c3e --- /dev/null +++ b/Entity/GeneratorEntity.php @@ -0,0 +1,25 @@ +template; + } +} diff --git a/Entity/TableEntity.php b/Entity/TableEntity.php new file mode 100644 index 0000000..b2d3fa4 --- /dev/null +++ b/Entity/TableEntity.php @@ -0,0 +1,58 @@ +tableName; + } + + public function setTableName(string $tableName): void + { + $this->tableName = $tableName; + } + + public function getTableComment(): string + { + return $this->tableComment; + } + + public function setTableComment(string $tableComment): void + { + $this->tableComment = $tableComment; + } + + /** + * @return ColumnEntity[] + */ + public function getColumns(): array + { + return $this->columns; + } + + /** + * @param ColumnEntity[] $columns + */ + public function setColumns(array $columns): void + { + $this->columns = $columns; + } +} diff --git a/Enums/TableColumnType.php b/Enums/TableColumnType.php new file mode 100644 index 0000000..9439b88 --- /dev/null +++ b/Enums/TableColumnType.php @@ -0,0 +1,29 @@ +astParser->parse(file_get_contents($path)); + $originTokens = $this->lexer->getTokens(); + $this->handleAst($c, $traverser, $originStmts, $originTokens, $path, $namespace, $className); + $newStmts = $traverser->traverse($originStmts); + return $this->printer->printFormatPreserving($newStmts, $originStmts, $originTokens); + } + return $this->handleCreate($c, $path, $namespace, $className); + } + + abstract protected function handleAst(Context $c, NodeTraverser $traverser, array $originStmts, array $originTokens, string $path, string $namespace, string $className): void; + + abstract protected function handleCreate(Context $c, string $path, string $namespace, string $className): string; + + private function initialAst(): void + { + $this->lexer = new Emulative([ + 'usedAttributes' => [ + 'comments', + 'startLine', 'endLine', + 'startTokenPos', 'endTokenPos', + ], + ]); + $this->astParser = (new ParserFactory())->create(ParserFactory::ONLY_PHP7, $this->lexer); + $this->printer = new Standard(); + } +} diff --git a/Processor/AbstractProcessor.php b/Processor/AbstractProcessor.php new file mode 100644 index 0000000..1431010 --- /dev/null +++ b/Processor/AbstractProcessor.php @@ -0,0 +1,44 @@ +getClassName($c); + $namespace = $this->getNamespace($c); + $path = $this->getPath($namespace, $className); + return new GeneratorEntity($this->generator($c, $path, $namespace, $className)); + } + + abstract protected function generator(Context $c, string $path, string $namespace, string $className): string; + + protected function getPath(string $namespace, string $className): string + { + return \Hyperf\Support\with(new Project())->path($namespace . '\\' . $className); + } + + abstract protected function getNamespace(Context $c): string; + + abstract protected function getClassName(Context $c): string; +} diff --git a/Processor/ControllerProcessor.php b/Processor/ControllerProcessor.php new file mode 100644 index 0000000..d3f495f --- /dev/null +++ b/Processor/ControllerProcessor.php @@ -0,0 +1,82 @@ +getConfig(), 'commands', []); + $stub = file_get_contents(__DIR__ . '/stubs/controller.stub'); + $stub = str_replace('%namespace%', $namespace, $stub); + $stub = str_replace('%controllerName%', $className, $stub); + $stub = str_replace('%controllerMethods%', $this->handleMethods($c, $commands), $stub); + $stub = str_replace('%controllerExtends%', $this->handleExtends($c, $commands), $stub); + return str_replace('%use%', $this->handleUse($c, $commands), $stub); + } + + protected function handleExtends(Context $c, array $commands): string + { + if (Arr::exists($commands, 'controller.extend')) { + return Arr::get($commands, 'controller.extend'); + } + + return AbstractController::class; + } + + protected function handleMethods(Context $c, array $commands): string + { + $content = ''; + $methods = Arr::get($commands, 'controller.methods', [ + '__construct', 'list', 'create', 'save', 'delete', + ]); + foreach ($methods as $method) { + $content .= file_get_contents(__DIR__ . '/stubs/controller/' . $method . '.stub') . \PHP_EOL; + } + + return $content; + } + + protected function handleUse(Context $c, array $command): string + { + $use = ''; + foreach (Arr::get($command, 'controller.use', []) as $item) { + $use .= 'use ' . $item . ';' . \PHP_EOL; + } + return $use; + } + + protected function getNamespace(Context $c): string + { + if (Arr::has($c->getConfig(), 'controller.namespace')) { + return (string) Arr::get($c->getConfig(), 'controller.namespace'); + } + return 'App\Controller'; + } + + protected function getClassName(Context $c): string + { + if (Arr::has($c->getConfig(), 'controller.name')) { + return Str::ucfirst((string) Arr::get($c->getConfig(), 'controller.name')); + } + return Str::ucfirst($c->getTable()->getTableName()); + } +} diff --git a/Processor/ProcessorInterface.php b/Processor/ProcessorInterface.php new file mode 100644 index 0000000..2a393f6 --- /dev/null +++ b/Processor/ProcessorInterface.php @@ -0,0 +1,21 @@ +