civicrm / composer-compile-lib
小型编译辅助库
Requires
- civicrm/composer-compile-plugin: ~0.19 || ~1.0
- padaliyajay/php-autoprefixer: ~1.2
- scssphp/scssphp: ^1.8.1
- symfony/filesystem: ~2.8 || ~3.4 || ~4.0 || ~5.0 || ~6.0 || ~7.0
- tubalmartin/cssmin: ^4.1
README
此软件包为与 composer-compile-plugin 一起使用提供了少量小任务和辅助工具。
此软件包的设计指南
- 确保在新/未启动的系统上易于操作
- 使用基本函数和静态方法
- 使用原始数据源(如静态JSON文件)
- 确保编译步骤报告错误
- 每个任务/函数在无法正常工作时必须抛出异常。
- 允许简洁的任务
- 如果任务输出到文件夹,且该文件夹不存在,则应自动创建该文件夹。
这里的主要目的是 示范性的 - 提供示例。因此,它相对最小化/轻量级/松耦合。没有依赖CiviCRM。相反,CiviCRM软件包可能定义了其他不在该库中的任务。
要求库
以下所有示例都需要 civicrm/composer-compile-lib
软件包。通过CLI加载
composer require civicrm/composer-compile-lib:'~0.2'
或通过 composer.json
"require": { "civicrm/composer-compile-lib": "~0.2" }
任务:SCSS
在此示例中,我们通过读取 scss/sandwich.scss
生成一个文件 dist/sandwich.css
。该文件可能从 ./scss/
文件夹导入mixins和变量。
{ "extra": { "compile": [ { "title": "Prepare CSS (<comment>sandwich.css</comment>, <comment>salad.css</comment>)", "run": "@php-method \\CCL\\Tasks::scss", "watch-files": ["scss"], "scss-files": { "dist/sandwich.css": "scss/sandwich.scss", "dist/salad.css": "scss/salad.scss" }, "scss-imports": ["scss"] "scss-import-prefixes": {"LOGICAL_PREFIX/": "physical/folder/"} } ] } }
请注意,“任务”仅仅是调用一个静态PHP方法(@php-method \\CCL\\Tasks::scss
)并将JSON数据作为输入。您也可以在PHP脚本中调用此方法。例如,我们可以根据脚本定义一个任务
{ "extra": { "compile": [ { "title": "Prepare CSS (<comment>sandwich.css</comment>, <comment>salad.css</comment>)", "run": "@php-script bin/compile-scss" } ] } }
以下脚本将之前示例中的示例泛化 - 它将任何SCSS文件(scss/*.scss
)映射到相应的CSS文件(dist/#1.css
)。此文件列表传递给 \CCL\Tasks::scss
以进行处理
\CCL::assertTask(); $files = \CCL::globMap('scss/*.scss', 'dist/#1.css', 1); \CCL\Tasks::scss([ 'scss-files' => $files, 'scss-imports' => ['scss'] 'scss-import-prefixes' => ['LOGICAL_PREFIX/' => 'physical/folder/'] ]);
请注意,此实现中的 \CCL\Tasks::scss()
相当有意见 - 它结合了 scssphp
和 php-autoprefixer
。输出写入两个文件,一个较大的文件(*.css
)和一个较小的文件(*.min.css
)。
任务:PHP模板
在此示例中,我们使用PHP模板生成另一个PHP文件。具体来说,我们使用 Sandwich.json
和 EntityTemplate.php
中的规范创建 Sandwich.php
。
{ "extra": { "compile": [ { "title": "Sandwich (<comment>src/Sandwich.php</comment>)", "run": "@php-method \\CCL\\Tasks::template", "watch-files": ["src/Entity"], "tpl-items": [ "src/Entity/Sandwich.php": "src/Entity/Sandwich.json", "src/Entity/Salad.php": "src/Entity/Salad.json" ], "tpl-file": "src/Entity/EntityTemplate.php" } ] } }
与前面的示例一样,任务只是一个PHP方法(@php-method \\CCL\\Tasks::template
),因此可以从PHP脚本中使用它。以下脚本将扩展模式,将任何JSON文件(src/Entity/*.json
)映射到相应的PHP文件(src/Entity/#1.php
)
$files = \CCL::globMap('src/Entity/*.json', 'src/Entity/#1.php', 1); \CCL\Tasks::template([ "tpl-file" => "src/Entity/EntityTemplate.php", "tpl-items" => $files, ]);
函数
PHP的标准库有很多函数可以用于基本的文件操作(如copy()
、rename()
、chdir()
等)。问题是错误信号——您必须显式检查错误输出,这对于即兴拼凑的粘合代码来说越来越麻烦。更方便的是有默认的 stop-on-error 行为,例如抛出异常。
symfony/filesystem 提供了包装器,它们抛出异常。但它将它们放入一个名为 Filesystem
的类中,这需要更多的模板代码。
大部分情况下,CCL
仅通过在 CCL
类中使用静态方法来镜像 symfony/filesystem
。比较
// PHP Standard Library if (!copy('old', 'new')) { throw new \Exception("..."); } // Symfony Filesystem $fs = new \Symfony\Component\Filesystem\Filesystem(); $fs->copy('old', 'new'); // Composer Compile Library \CCL::copy('old', 'new');
这对于编写单行脚本来说更加方便。例如,以下任务执行简单的文件操作。如果出现任何错误,它们会抛出异常并停止编译过程。
{ "extra": { "compile": [ { "title": "Smorgasboard of random helpers", "run": [ // Create files and folders "@php-eval \\CCL::dumpFile('dist/timestamp.txt', date('Y-m-d H:i:s'));", "@php-eval \\CCL::mkdir('some/other/place');", // Concatenate a few files "@php-eval \\CCL::dumpFile('dist/bundle.js', \\CCL::cat(glob('js/*.js'));", "@php-eval \\CCL::chdir('css'); \\CCL::dumpFile('all.css', ['colors.css', 'layouts.css']);", // If you need reference material from another package... "@export TWBS={{pkg:twbs/bootstrap}}", "@php-eval \\CCL::copy(getenv('TWBS') .'/dist/bootstrap.css', 'web/main.css')" ] } ] } }
完整的功能列表
// CCL wrapper functions function chdir(string $dir); function glob($pat, $flags = null); // CCL distinct functions function cat($files); function mapkv($array, $func); function globMap($globPat, $mapPat, $flip = false); // Symfony wrapper functions function appendToFile($filename, $content); function dumpFile($filename, $content); function mkdir($dirs, $mode = 511); function touch($files, $time = null, $atime = null); function copy($originFile, $targetFile, $overwriteNewerFiles = true); function mirror($originDir, $targetDir, $iterator = null, $options = []); function remove($files); function rename($origin, $target, $overwrite = false); function chgrp($files, $group, $recursive = false); function chmod($files, $mode, $umask = 0, $recursive = false); function chown($files, $user, $recursive = false); function hardlink($originFile, $targetFiles); function readlink($path, $canonicalize = false); function symlink($originDir, $targetDir, $copyOnWindows = false); function exists($files); function tempnam($dir, $prefix);
有关每个函数的更多详细信息,请参阅 CCL\Functions
和 symfony/filesystem。