drupal / drupal-scaffold
用于在使用 drupal/core 时更新 Drupal 脚本文件的 Composer 插件
Requires
- php: >=5.4.5
- composer-plugin-api: ^1.0.0
- composer/semver: ^1.4
Requires (Dev)
- composer/composer: dev-master
- g1a/composer-test-scenarios: ^2.1.0
- phpunit/phpunit: ^6
- squizlabs/php_codesniffer: ^2.8
README
这是一个演示,将不会维护。请勿使用。
composer-scaffold
这是一个演示,将不会维护。请勿使用。
此项目提供了一个 composer 插件,用于将 drupal/core
项目的脚本文件(如 index.php
,update.php
等)放置到 Web 根目录下期望的位置。仅可以使用此插件生成单个文件。
生成文件的目的在于允许 Drupal 站点完全由 Composer 管理,同时仍允许将单个资源文件放置在任意位置。这样做是为了使配置良好的 composer 模板能够生成与 Drupal 8.7.x 及更早版本 tarball 发布包完全匹配的文件布局。也可能提供其他文件布局;例如,一个与当前 drupal-composer/drupal-project 模板非常相似的项目布局也将被提供。当使用这些项目之一时,用户应该在解压缩下载的存档后立即使用 composer require
和 composer update
在 Drupal 站点上进行操作。
注意,Drupal 站点的依赖关系只有在顶级 composer.json 文件中明确授予此权限的情况下才能生成文件。请参阅下面的 允许的包。
使用方法
Composer-scaffold 通过在您的项目中的 composer.json 文件的 extra
部分中提供配置设置,通过在项目中要求 drupal/core-composer-scaffold
来使用。也会咨询项目依赖关系的 composer.json 文件以生成项目需要的文件。还可以在脚本文件的开头或结尾添加额外信息,正如通常对 .htaccess
和 robots.txt
文件所做的那样。有关更多信息,请参阅 修改脚本文件。
允许的包
脚本文件存储在主项目 composer.json 文件中要求的项目内部,如同通常一样。生成操作发生在 composer install
之后,涉及将所需的资源复制或创建符号链接到目标位置。为了防止任意依赖通过脚本机制复制文件,只有那些由顶级项目明确允许的项目才会用于生成文件。
示例:允许从项目 drupal/core
中生成脚本
"name": "my/project",
...
"extra": {
"composer-scaffold": {
"allowed-packages": [
"drupal/core",
],
...
}
}
允许一个包生成文件也允许它将生成权限委派给它所要求的任何项目。这允许一个包按照其认为合适的方式组织其脚本资源。例如,项目 drupal/core
可能选择将资源存储在子项目 drupal/assets
中。
一个项目可以从多个项目中获取生成文件。例如,一个使用发布包的 Drupal 项目,在特定的网络托管服务提供商上安装时,可能从以下项目中获取生成文件:
- Drupal 核心
- 它的发布包
- 托管提供商提供的项目
- 项目本身
每个允许由顶级项目构建的项目将依次使用,位于allowed-packages
列表中较晚声明的项目将优先于之前命名的项目。顶级composer.json文件本身始终隐式允许构建文件,其构建文件具有最高优先级。
定义项目位置
顶级项目必须定义网站根目录的位置。它通过以下所示的locations
映射来完成
"name": "my/project",
...
"extra": {
"composer-scaffold": {
"locations": {
"web-root": "./docroot"
},
...
}
}
这使得可以配置具有不同文件布局的项目;例如,可以使用drupal/drupal
文件布局或drupal-composer/drupal-project
文件布局来设置项目。
如果没有明确定义网站根目录,则默认为./
。
修改构建文件
有时,一个项目可能希望使用依赖项提供的构建文件,但对其进行某种修改。支持两种修改形式:追加和修补。
以下示例显示了一个项目,它将额外的条目追加到由drupal/core
提供的robots.txt
文件末尾
"name": "my/project",
...
"extra": {
"composer-scaffold": {
"file-mapping": {
"[web-root]/robots.txt": {
"append": "assets/my-robots-additions.txt",
}
}
}
}
也可以通过包含一个提供要追加到构建文件中的文件的相对路径的"prepend"条目来在构建文件之前追加,而不是追加,或者追加和预处理。
以下示例演示了使用post-composer-scaffold-cmd
钩子使用修补程序修补.htaccess
文件
"name": "my/project",
...
"scripts": {
"post-composer-scaffold-cmd": [
"cd docroot && patch -p1 <../patches/htaccess-ssl.patch"
]
}
定义构建文件
构建资产的位置由提供它们的该项目控制,但位置始终相对于由根项目定义的某个目录(通常是网站根目录)。例如,以下代码片段中的构建文件robots.txt
从其源位置assets/robots.txt
复制到网站根目录。
{
"name": "drupal/assets",
...
"extra": {
"composer-scaffold": {
"file-mapping": {
"[web-root]/robots.txt": "assets/robots.txt",
...
}
}
}
}
排除构建文件
有时,一个项目可能希望完全替换由依赖项提供的构建文件,并不再接收任何更新。可以通过将构建文件的排除值设置为false
来完成此操作
"name": "my/project",
...
"extra": {
"composer-scaffold": {
"file-mapping": {
"[web-root]/robots.txt": false
}
}
}
尽可能使用上述修改构建文件中解释的append
和prepend
指令。排除文件意味着项目将不会获得任何本地修改的文件的错误修复或其他更新。
覆盖
默认情况下,构建文件会覆盖目标位置存在的任何内容。有时,一个项目可能希望为在后续更新中不会更改的文件提供初始内容。这可以通过将overwrite
标志设置为false
来完成,如下面的示例所示
{
"name": "service-provider/d8-scaffold-files",
"extra": {
"composer-scaffold": {
"file-mapping": {
"[web-root]/sites/default/settings.php": {
"mode": "replace",
"path": "assets/sites/default/settings.php",
"overwrite": false
}
}
}
}
}
请注意,overwrite
指令旨在由启动包、服务提供商等使用。单个Drupal站点应通过将值设置为false来排除文件。
自动加载文件
构建工具在构建操作过程中自动在Drupal根目录中创建所需的autoload.php
文件。此文件不应以任何方式进行修改或定制。如果已将其提交到存储库,则构建工具将停止管理它。如果由于任何原因更改了vendor
目录的位置,并且已将autoload.php
文件提交到存储库,请手动删除它,然后运行composer install
以更新它。
规范
以下是关于“composer.json”文件“extra”部分“composer-scaffold”节配置指令的参考部分。
allowed-packages
allowed-packages
配置设置包含一个有序列表的包名,这些包名将在脚手架阶段使用。
"allowed-packages": [
"drupal/core",
],
file-mapping
file-mapping
配置设置由一个映射组成,该映射从要脚手架的文件的目标路径到一组控制如何脚手架文件的属性。
可用的属性如下
- mode: "replace","append"或"skip"之一。
- path: 要写入目标文件的源文件的路径。
- prepend: 要添加到目标文件的前面的源文件的路径,这必须是其他项目提供的脚手架文件。
- append: 与
prepend
类似,但追加内容而不是添加到前面。 - overwrite: 如果
false
,则防止在目标文件已存在时发生replace
。
模式可能可以从其他属性推断。如果没有指定模式,则将提供以下默认值
- replace: 如果存在
path
属性,或者条目的值是字符串而不是属性集,则选择。 - append: 如果存在
prepend
或append
属性,则选择。 - skip: 如果条目的值是布尔值
false
,则选择。
示例
"file-mapping": {
"[web-root]/sites/default/default.settings.php": {
"mode": "replace",
"path": "assets/sites/default/default.settings.php",
"overwrite": true
},
"[web-root]/sites/default/settings.php": {
"mode": "replace",
"path": "assets/sites/default/settings.php",
"overwrite": false
},
"[web-root]/robots.txt": {
"mode": "append",
"prepend": "assets/robots-prequel.txt",
"append": "assets/robots-append.txt"
},
"[web-root]/.htaccess": {
"mode": "skip",
}
}
上述示例的简写形式将是
"file-mapping": {
"[web-root]/sites/default/default.settings.php": "assets/sites/default/default.settings.php",
"[web-root]/sites/default/settings.php": {
"path": "assets/sites/default/settings.php",
"overwrite": false
},
"[web-root]/robots.txt": {
"prepend": "assets/robots-prequel.txt",
"append": "assets/robots-append.txt"
},
"[web-root]/.htaccess": false
}
请注意,没有独立的“prepend”模式;“append”模式用于向脚手架文件添加和预添加。这样做的原因是,脚手架文件条目在文件映射部分按其目标路径标识,并且不可能有多个条目具有相同的键。如果“prepend”是一个单独的模式,那么就无法同时向同一文件添加和预添加。
gitignore
gitignore
配置设置控制此插件是否将管理在脚手架操作期间写入的文件的.gitignore
文件。
- true: 当写入脚手架文件时,将更新
.gitignore
文件。 - false: 从不修改
.gitignore
文件。 - 未设置:如果目标目录是git存储库的本地工作副本,并且该存储库中没有提交
vendor
目录,则将更新.gitignore
文件。
locations
locations
配置设置包含一个命名位置列表,可以在放置脚手架文件时使用。唯一必需的位置是web-root
。如果需要,也可以定义其他位置。
"locations": {
"web-root": "./docroot"
},
symlink
symlink
属性会使replace
操作创建指向源文件的符号链接,而不是复制它。这对于核心开发很有用,因为符号链接文件本身不应被编辑。请注意,append
操作会覆盖symlink
选项,以防止更改原始脚手架资产。
"symlink": true,
管理脚手架文件
脚手架文件应该像处理 vendor
目录一样对待。如果您需要提交 vendor
(例如,为了部署您的网站),那么您也应该提交您的脚手架文件。除非必要,否则您不应该提交您的 vendor
目录或脚手架文件。
如果某个依赖项提供了一个设置 overwrite
为 false
的脚手架文件,则该文件应提交到您的仓库。
默认情况下,如果需要,当脚手架文件写入时,.gitignore
文件将自动更新。请参阅上方规范部分中的 gitignore
设置。
示例
以下是一些完整的示例。
依赖 composer-scaffold 的项目的 composer.json 示例
{
"name": "my/project",
"require": {
"drupal/composer-scaffold": "*",
"composer/installers": "^1.2",
"cweagans/composer-patches": "^1.6.5",
"drupal/core": "^8.8.x-dev",
"service-provider/d8-scaffold-files": "^1"
},
"config": {
"optimize-autoloader": true,
"sort-packages": true
},
"extra": {
"composer-scaffold": {
"allowed-packages": [
"drupal/core",
],
"locations": {
"web-root": "./docroot"
},
"symlink": true,
"overwrite": true,
"file-mapping": {
"[web-root]/.htaccess": false,
"[web-root]/robots.txt": "assets/robots-default.txt"
}
}
}
}
将资产放在不同项目的 drupal/core 的 composer.json 示例
{
"name": "drupal/core",
"extra": {
"composer-scaffold": {
"allowed-packages": [
"drupal/assets",
]
}
}
}
drupal/assets 中 composer-scaffold 文件的 composer.json 示例
{
"name": "drupal/assets",
"extra": {
"composer-scaffold": {
"file-mapping": {
"[web-root]/.csslintrc": "assets/.csslintrc",
"[web-root]/.editorconfig": "assets/.editorconfig",
"[web-root]/.eslintignore": "assets/.eslintignore",
"[web-root]/.eslintrc.json": "assets/.eslintrc.json",
"[web-root]/.gitattributes": "assets/.gitattributes",
"[web-root]/.ht.router.php": "assets/.ht.router.php",
"[web-root]/.htaccess": "assets/.htaccess",
"[web-root]/sites/default/default.services.yml": "assets/default.services.yml",
"[web-root]/sites/default/default.settings.php": "assets/default.settings.php",
"[web-root]/sites/example.settings.local.php": "assets/example.settings.local.php",
"[web-root]/sites/example.sites.php": "assets/example.sites.php",
"[web-root]/index.php": "assets/index.php",
"[web-root]/robots.txt": "assets/robots.txt",
"[web-root]/update.php": "assets/update.php",
"[web-root]/web.config": "assets/web.config"
}
}
}
}
实现 composer-scaffold 的库的 composer.json 示例
{
"name": "service-provider/d8-scaffold-files",
"extra": {
"composer-scaffold": {
"file-mapping": {
"[web-root]/sites/default/settings.php": "assets/sites/default/settings.php"
}
}
}
}
追加到 robots.txt
{
"name": "service-provider/d8-scaffold-files",
"extra": {
"composer-scaffold": {
"file-mapping": {
"[web-root]/robots.txt": {
"append": "assets/my-robots-additions.txt",
}
}
}
}
}
在复制文件后修复文件
"post-composer-scaffold-cmd": [
"cd docroot && patch -p1 <../patches/htaccess-ssl.patch"
]
相关插件
drupal-composer/drupal-scaffold
drupal-scaffold 的早期版本(请参阅社区项目,drupal-composer/drupal-scaffold)直接从其分发服务器(例如 https://cgit.drupalcode.org
)到目标目录下载每个脚手架文件。这是必要的,因为没有可用的脚手架文件子树分割。从已由 Composer 下载的项目复制脚手架资产更为有效,因为下载和解压缩归档文件比逐个下载每个脚手架文件更高效。
composer/installers
composer/installers 插件与这个插件类似,因为它允许依赖项安装在其他位置,而不是 vendor
目录。然而,Composer 和 composer/installers
插件有一个限制,即一个项目不能移动到另一个项目中。因此,如果您使用 composer/installers
将 Drupal 模块放置在 web/modules/contrib
目录中,那么您也不能使用 composer/installers
将文件(如 index.php
和 robots.txt
)放置到 web
目录中。drupal-scaffold 插件是为了解决这个问题而创建的。