codger/generate

代码生成器,基础框架

0.10.3 2023-07-06 13:42 UTC

README

CODe GEneratoR, base framework

在任何遵循某种形式标准(无论您自己的还是框架“强制”的)的软件项目中,都会有大量的模板代码。例如,在MVC设置中,您将(实际上)总是为每个在核心上相似的组件拥有模型、视图和控制。一个例子是如果您使用Doctrine - 实体将直接基于您的数据库模式生成。

Codger旨在提供进一步遵循这一原则的代码生成工具,允许您指定所谓的“食谱”进行任意代码生成。

尽管Codger本身使用PHP和Twig,但生成的代码理论上可以是任何语言。例如,包含Chef代码的食谱。

安装

$ composer require --dev codger/generate

通常您会安装一个更具体的包,例如codger/php,它将codger/generate作为依赖项。

用法

$ vendor/bin/codger name-of-recipe some additional arguments --or --options

食谱的名称应该可以解析为PHP类名。这些规则如下:

  • 斜杠或分号被转换为反斜杠(命名空间分隔符);
  • 破折号后面的字符被转换为大写;
  • 其他字符被转换为小写,除了第一个字符,它被转换为大写。

此外,所有食谱都以前缀Codger命名空间。这允许您轻松地将它们分组在常规源代码之外的目录中,例如一个./recipes文件夹。

因此,一个名为monolyth:some-test的食谱将解析为命名空间Codger\\Monolyth\\SomeTest

默认选项

所有Codger食谱都支持由Codger\Generate\DefaultOptions特性定义的2个默认选项

  • --output-dir=/some/path。提供此选项以尝试将生成的文件写入磁盘;默认情况下,将输出到屏幕以供人工检查。
  • --replace。如果设置此标志,将无警告地覆盖现有文件(默认情况下将提示覆盖、输出或跳过)。

是否存在简写标志取决于您的食谱的其他选项。

编写食谱

所有食谱都是扩展Codger\Generate\Recipe的常规PHP类。主要工作应在__invoke方法中完成。Codger食谱扩展了Monolyth\Cliff\Command类,因此(字符串)参数被视为CLI操作数。因此,一个名为Codger\Foo的食谱,其__invoke签名是(string $name),将作为vendor/bin/codger foo myname调用。

如前所述,Composer应该能够自动加载食谱。例如,将autoload-dev属性添加到您的composer.json中,例如"Codger\\MyNamespace\\": "./recipes"

__invoke方法内部,您的食谱应该完成其工作。这取决于您想要发生什么,但通常一个食谱至少应该调用output()来指定它正在生成什么,或调用delegate来指定它需要将任务委托给子食谱。

<?php

namespace Codger\MyNamespace;

use Codger\Generate\Recipe;

class MyRecipe extends Recipe
{
    public function __invoke()
    {
        // Do stuff...
    }
}

设置Twig环境

Codger使用Twig内部将食谱转换为实际代码。这意味着您需要设置您的Twig环境,因为我们无法猜测您的代码是如何组织的。请使用食谱上的setTwigEnvironment方法完成此操作

<?php

// ...
    $this->setTwigEnvironment($twig);
// ...

如果不这样做,Codger在渲染时将退出并返回状态码5。注意,一个只委托内容的“主食谱”不需要调用此方法。

转换参数

使用Codger\Generate\Language类转换各种用途的参数。例如,PHP模块Foo\Bar可能被写入src/Foo/Bar.php。语言辅助类定义了许多方法以简化此过程

<?php

use Codger\Generate\Language;

echo Language::pluralize('city'); // cities
echo Language::singular('cities'); // city
echo Language::convert('Foo\Bar', Language::TYPE_CSS_IDENTIFIER); // foo-bar

以下是一些当前可用的 TYPE_ 常量

  • TYPE_PHP_NAMESPACE: Foo\Bar
  • TYPE_TABLE: foo_bar
  • TYPE_VARIABLE: fooBar
  • TYPE_PATH: Foo/Bar
  • TYPE_URL: foo/bar
  • TYPE_CSS_IDENTIFIER: foo-bar
  • TYPE_ANGULAR_MODULE: foo.bar
  • TYPE_ANGULAR_COMPONENT: fooBar
  • TYPE_ANGULAR_TAG: foo-bar

为了向后兼容,类型 TYPE_NAMESPACE 当前作为 TYPE_PHP_NAMESPACE 的别名使用,但它已被弃用,并且在使用时将引发警告。它将在未来的版本中被删除,因此建议从版本 0.7.0 开始使用 TYPE_PHP_NAMESPACE

委托任务

某些配方可能需要使用其他配方。这样,您可以将配方“链接”起来以构建更复杂的配方。委托是通过调用 Codger\Generate\Recipe::delegate 方法来完成的。

第一个参数是要委托的配方的名称。可选的第二个参数是要传递给委托配方的参数数组,就像从 CLI 调用它一样。

用户反馈

通过 Codger\Generate\InOutTrait,配方提供了 infoerror 方法,可用于提供额外的信息。当配方执行过程中发生错误时,这非常有用,也可以用于无法直接生成到文件中的代码的说明(例如,因为您的配方定义了额外的路由,这些路由不能安全地追加到现有的路由文件中)。

用户输入和条件语句

通常配方会提供各种选项或请求用户输入,这些选项或输入您无法或不想在命令行作为参数指定。配方为此提供了两种便利方法:askoptions

提问

ask 方法旨在用于开放式输入,例如数据库凭据。它的第一个参数是问题字符串,第二个参数是回调。回调将使用单个参数调用:提供的答案字符串。验证答案是在回调内部进行的,由配方作者负责。

<?php

$recipe->ask("What is your name?", function (string $answer) {
    $this->info("Hello, $answer.");
});

请注意,回调绑定到配方,因此在其中您可以简单地使用 $this 来引用它。

提供 options

options 方法旨在为用户提供一个简单的选项列表以进行选择(最简单的情况是 'yes/no')。与 ask 类似,它的第一个参数是问题。第二个参数是选项的数组或哈希表,第三个是回调(与 ask 的工作方式类似)。

ask 不同,options 方法验证提供的答案。它应该是传递的 $options 数组中的键,或者是在其中存在的完整答案。

传递给回调的答案是 始终 数组中的键。

<?php

$recipe->options("Would you like fries with that?", ['Y' => 'Yes', 'n' => 'no'], function (string $answer) {
    if ($answer == 'Y') {
        $this->info('Yummy!');
    } else {
        $this->info('A very healthy choice.');
    }
});