brianhenryie/strauss

将所有依赖作为WordPress插件内的一个包进行组合

0.19.2 2024-06-10 20:51 UTC

README

PHPUnit PHPStan

Strauss – PHP命名空间重命名工具

一个工具,用于在PHP文件中添加命名空间和类名的前缀,以避免自动加载冲突。

Mozart的一个分支。用于PHP的Composer

主要用例是WordPress插件,在单个WordPress安装中,不同的插件可能包含相同库的不同版本。加载的类版本将是首先注册自动加载器的插件,后续的所有类实例都将使用该版本,可能会导致不可预测的行为和功能缺失。

⚠️ 赞助:我不需要你的钱。 请编写一个单元测试以帮助项目

破坏性变更

  • v0.16.0 – 将不再为polyfill包中看到的PHP内置类添加前缀
  • v0.14.0 – psr/*包默认不再排除
  • v0.12.0 – 默认输出target_directorystrauss更改为vendor-prefixed

请提出可能的破坏性变更问题。我认为我们可能很快就可以升级到1.0.0。

使用

如正常使用Composer

composer require --dev brianhenryie/strauss

并使用vendor/bin/strauss执行。

或者,从发布中下载strauss.phar

curl -o strauss.phar -L -C - https://github.com/BrianHenryIE/strauss/releases/latest/download/strauss.phar

然后在项目文件夹的根目录下使用php strauss.phar运行。

要更新调用前缀类的文件,可以使用--updateCallSites=true,它使用您的自动加载密钥,或者使用--updateCallSites=includes,templates显式指定文件和目录。

应在Composer脚本中自动化使用。

"scripts": {
    "prefix-namespaces": [
        "strauss"
    ],
    "post-install-cmd": [
        "@prefix-namespaces"
    ],
    "post-update-cmd": [
        "@prefix-namespaces"
    ]
}

或者

"scripts": {
    "prefix-namespaces": [
        "@php strauss.phar"
    ]
}

‼️ 如果您将target_directory设置为vendordelete_vendor_packages/delete_vendor_files设置为true,即如果您正在使用require __DIR__ . '/vendor/autoload.php'并且Strauss修改了vendor内的文件,则必须告诉Composer重新构建其自动加载索引,请在scripts/strauss中添加composer dump-autoload

配置

Strauss可能不需要任何配置,但您可能需要稍微自定义一下,通过在您的composer.json中添加一个extra/strauss对象。以下为默认配置,其中namespace_prefixclassmap_prefix由您的composer.json中的autoloadname键确定,packagesrequire键确定

"extra": {
    "strauss": {
        "target_directory": "vendor-prefixed",
        "namespace_prefix": "BrianHenryIE\\My_Project\\",
        "classmap_prefix": "BrianHenryIE_My_Project_",
        "constant_prefix": "BHMP_",
        "packages": [
        ],
        "update_call_sites": false,
        "override_autoload": {
        },
        "exclude_from_copy": {
            "packages": [
            ],
            "namespaces": [
            ],
            "file_patterns": [
            ]
        },
        "exclude_from_prefix": {
            "packages": [
            ],
            "namespaces": [
            ],
            "file_patterns": [
            ]
        },
        "namespace_replacement_patterns" : {
        },
        "delete_vendor_packages": false,
        "delete_vendor_files": false
    }
},

以下配置是推断得出的

  • target_directory定义了文件将复制到的目录,默认为vendor-prefixed
  • namespace_prefix定义了为每个命名空间添加的前缀字符串
  • classmap_prefix定义了为全局命名空间中的类名添加的前缀字符串
  • packages是要处理的包列表。如果不存在,则包括您的composer.jsonrequire键下的所有包
  • classmap_output是一个布尔值,用于决定Strauss是否将创建autoload-classmap.phpautoload.php。如果没有设置,如果target_directory在您的项目的autoload键中,则为false,否则为true

以下配置是默认的

  • delete_vendor_packages: false 一个布尔标志,用于指示在处理之后是否应删除软件包的供应商目录。默认为 false,因此任何具有破坏性的更改都是可选的。

  • delete_vendor_files: false 一个布尔标志,用于指示在处理之后是否应删除从软件包供应商目录中复制来的文件。默认为 false,因此任何具有破坏性的更改都是可选的。这可能已弃用!与 delete_vendor_packages 相比,这个功能还有什么更合适的使用场景吗?

  • include_modified_date 是一个 bool,用于决定 Strauss 是否应在修改后的文件的 (phpdoc) 头部中包含日期。默认为 true

  • include_author 是一个 bool,用于决定 Strauss 是否应在修改后的文件的 (phpdoc) 头部中包含作者名称。默认为 true

  • update_call_sites: false。这可以是 truefalse 或一个目录/文件路径的 array。当设置为 true 时,默认为项目中 autoload 键下的目录和文件。当它们调用带有前缀的类时,将更新 PHP 文件和目录的 PHP 文件。

剩余部分为空

  • constant_prefix 用于 define( "A_CONSTANT", value ); -> define( "MY_PREFIX_A_CONSTANT", value );。如果为空,则常量不会被前缀(这可能将更改为推断值)。
  • override_autoload 是一个字典,键为包名称,包含用于替换原始软件包 composer.json 中的 autoload 属性的自动加载设置。
  • exclude_from_prefix / file_patterns
  • exclude_from_copy
    • packages 包名称数组,要跳过的包
    • namespaces 要跳过的命名空间数组(从包的自动加载键中完全匹配)
    • file_patterns 一个正则表达式模式数组,用于检查文件名(包括供应商相对路径),如果匹配,Strauss 将跳过该文件
  • exclude_from_prefix
    • packages 要排除前缀的包名称数组
    • namespaces 要排除的完全匹配的命名空间数组(即不是子串/父命名空间)
  • namespace_replacement_patterns 一个字典,用于在 preg_replace 中使用,而不是使用 namespace_prefix 前缀。

自动加载

Strauss 使用 Composer 的工具在 target_directory 中生成一个类映射文件,并在其旁边创建一个 autoload.php 文件,因此在许多项目中,自动加载只是

require_once __DIR__ . '/strauss/autoload.php';

如果您希望使用 Composer 的自动加载器,请将您的 target_directory(默认为 vendor-prefixed)添加到您的 autoload classmap 中,当运行 Strauss 时,它将不会创建自己的 autoload.php 文件。然后运行 composer dump-autoload 以将新复制和前缀的文件包含到 Composer 的类映射中。

"autoload": {
    "classmap": [
        "vendor-prefixed/"
    ]
},

动机与 Mozart 的比较

我很高兴为Mozart提交PR来修复bug,但它们没有被审查和合并。在写作的时候,大约50%的Mozart代码是由我编写的(请参阅贡献者列表),另外还有9个未合并的PR,以及大多数问题的解决方案都是由我提供的。这个分支是为了合并我编写的所有未解决的bug修复,并实施我认为更好的问题解决方案的一些更激进的变更。

相对于Mozart的优势

  • 单个输出目录,其结构符合源供应商目录结构(概念上比Mozart的独立的classmap_directorydep_directory)更简单
  • 生成的autoload.php用于在您的项目中include(类似于Composer的vendor/autoload.php
  • 处理files自动加载器 - 以及Composer自身识别的任何自动加载器,因为Strauss使用Composer自带的工具来解析包
  • 零配置 - Strauss从您的composer.json推断出合理的默认值
  • 无破坏性默认值 - delete_vendor_files默认为false,因此任何破坏都是显式选择的结果
  • 许可证文件包含在内,PHP文件头部被编辑以符合修改的许可证要求。我的理解是,重新分发Mozart处理过的代码与大多数开源许可证不符——非法!
  • 经过广泛测试 - 编写了PhpUnit测试来验证Mozart中的许多bug在Strauss中不存在
  • 更多配置选项 - 允许在复制和编辑文件时排除某些内容,并允许特定的/多个命名空间重命名
  • 尊重composer.json中的vendor-dir配置
  • 为常量(define)添加前缀
  • 处理元包和虚拟包

Strauss将从您的composer.json中读取Mozart配置,以实现无缝迁移。

替代方案

我对这些没有强烈的意见。我开始使用Mozart是因为它简单,然后我根据我的感觉进行了调整。我从未使用过这些。

有趣

在v1.0之前的变更

  • 对从Mozart分叉的代码进行全面的归属 - 变更非常剧烈,所以现在git blame已经没有用了,所以我打算添加更多的归属
  • 更一致的命名。我们是添加前缀还是重命名?
  • 更多的单元测试,尤其是与文件系统相关的测试
  • 配置中的正则表达式模式需要验证
  • 更改名称? "Renamespacer"?

在v2.0之前的变更

解决这个问题的正确方法可能是通过PHP-Parser。至少所有的测试都将是有用的。

致谢

Coen Jacobs和所有Mozart的贡献者,尤其是那些编写了优秀问题的贡献者。