pantheon-systems / composer-scaffold
一个灵活的Composer项目脚手架构建器。
Requires
- php: >=7.3.0
- composer-plugin-api: ^1 || ^2
Requires (Dev)
- composer/composer: ^1.8@stable
Conflicts
README
不再维护
此仓库已被弃用,并由 WordPress Composer Managed 取代。WordPress脚手架处理在 composer.json
文件 中。
此项目提供了一个Composer插件,可以将来自 drupal/core
项目的脚手架文件(如 index.php
、update.php
等)放置在网站根目录的期望位置。只能使用此插件来构建单个文件。
构建文件的目的允许Drupal站点由Composer完全管理,同时仍允许将单个资产文件放置在任意位置。这样做的目的是使配置正确的Composer模板生成与Drupal 8.7.x及更早版本tarball分发完全一致的文件布局。其他文件布局也将成为可能;例如,将提供一个与当前 drupal-composer/drupal-project 模板非常相似的项目布局。当使用这些项目之一时,用户应能够在解压下载的归档文件后立即在Drupal站点上使用 composer require
和 composer update
。
请注意,Drupal站点的依赖项只有在顶级composer.json文件中明确授予该权限时才能构建文件。请参阅下面的 允许的包。
用法
Composer Scaffold通过在项目的composer.json文件的extra部分提供配置设置,并在项目中要求pantheon-systems/composer-scaffold
来使用。还咨询了项目依赖项的composer.json文件中的附加配置,以构建项目所需的文件。还可以将附加信息添加到脚手架文件的开始或结尾,如通常对.htaccess
和robots.txt
文件所做的那样。有关更多信息,请参阅修改脚手架文件。
通常,脚手架操作在需要时自动运行,例如在composer install
之后,因此一旦在项目的composer.json文件中设置了配置,通常不需要执行任何不同的操作来构建项目,如下所述。要直接构建文件,请运行
composer composer:scaffold
允许的包
脚手架文件存储在主项目的composer.json文件中要求的项目内。构建操作在composer install
之后发生,涉及将所需的资产复制或链接到目标位置。为了防止任意依赖通过脚手架机制复制文件,只有那些由顶级项目明确允许的项目才会用于构建文件。
示例:允许从项目 upstream/project
进行脚手架
"name": "my/project",
...
"extra": {
"composer-scaffold": {
"allowed-packages": [
"upstream/project"
],
...
}
}
允许一个软件包构建文件也允许它将构建权限委派给它所需的任何项目。这允许软件包根据需要组织其构建资源。例如,如果 upstream/project
将其资源存储在子项目 upstream/assets
中,则 upstream/assets
将隐式允许构建文件。
项目可以从多个项目中获取构建文件。例如,一个使用发行版的 Drupal 项目,并在特定的网络托管服务提供商上安装,可能从以下来源获取其构建文件:
- Drupal 核心库
- 它的发行版
- 由托管提供商提供的项目
- 项目本身
允许顶级项目构建的每个项目将依次使用,其中在 allowed-packages
列表中声明较晚的项目将优先于先前命名的项目。drupal/core
是隐式允许的,并将位于列表顶部。顶级 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": [
"example/assets",
],
文件映射
file-mapping
配置设置由脚手架文件的目标路径到控制如何脚手架文件的属性集的映射组成。
以下为可用的属性
- 模式:以下之一“replace”,“append”或“skip”。
- 路径:写入目标文件的源文件路径。
- 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 到脚手架文件。这样做的原因是,脚手架文件条目在文件映射部分中按其目标路径标识,并且不可能有多个条目具有相同的键。如果“prepend”是一个单独的模式,那么将无法同时对同一文件进行 prepend 和 append。
默认情况下,追加操作只能应用于由先前评估的项目脚手架的文件。但是,如果向append
操作添加了force-append
属性,则只有在追加文本尚未出现在文件中时,才会将追加应用于非脚手架文件。在使用此模式时,还可能提供在目标文件完全缺失时使用的默认内容。
以下示例演示了脚手架一个settings-custom.php文件,并将其包含在现有的settings.php
文件中。
"file-mapping": {
"[web-root]/sites/default/settings-custom.php": "assets/settings-custom.php",
"[web-root]/sites/default/settings.php": {
"append": "assets/include-settings-custom.txt",
"force-append": true,
"default": "assets/initial-default-settings.txt"
}
}
请注意,如果与脚手架settings.php文件的项目的示例仍有效。
gitignore
配置设置 gitignore
控制此插件是否在构建操作期间管理 .gitignore
文件。
- true:当写入构建文件时,将更新
.gitignore
文件。 - false:永远不会修改
.gitignore
文件。 - 未设置:如果目标目录是 git 仓库的本地工作副本,并且该仓库忽略了
vendor
目录,则将更新.gitignore
文件。
位置
locations
配置设置包含一个命名位置的列表,这些位置可以用于放置构建文件。唯一必需的位置是 web-root
。如果需要,也可以定义其他位置。
"locations": {
"web-root": "./docroot"
},
符号链接
symlink
属性会导致 replace
操作为源文件创建一个符号链接而不是复制它。在进行核心开发时,这很有用,因为符号链接文件本身不应该被编辑。请注意,append
操作会覆盖 symlink
选项,以防止原始构建资产被更改。
"symlink": true,
管理构建文件
构建文件应该像处理 vendor
目录一样对待。如果您需要提交 vendor
(例如,为了部署您的站点),那么您也应该提交您的构建文件。除非必要,您不应提交 vendor
目录或构建文件。
如果依赖项提供了一个设置为 false
的 overwrite
的构建文件,则应将该文件提交到您的仓库。
默认情况下,如果需要,当写入构建文件时,将自动更新 .gitignore
文件。请参阅上面规格部分中的 gitignore
设置。
示例
以下是一些完整的示例。
依赖使用 composer-scaffold 的项目的示例 composer.json
{
"name": "my/project",
"require": {
"pantheon-systems/composer-scaffold": "*",
"composer/installers": "^1.9",
"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": {
"locations": {
"web-root": "./docroot"
},
"symlink": 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
Composer Scaffold 的早期版本(请参阅社区项目,drupal-composer/drupal-scaffold)直接从其分发服务器(例如 https://git.drupalcode.org
)将每个构建文件下载到目标目录。这是必要的,因为没有可用的构建文件子树拆分。从已经由 Composer 下载的项目复制构建资产更为有效,因为下载和解压归档文件比单独下载每个构建文件更高效。
composer/installers
composer/installers 插件与这个插件类似,它允许依赖项安装在除了 vendor
目录之外的其它位置。然而,Composer 和 composer/installers
插件有一个限制,即一个项目不能被移动到另一个项目内部。因此,如果您使用 composer/installers
将 Drupal 模块放置在 web/modules/contrib
目录中,那么您就不能再使用 composer/installers
将如 index.php
和 robots.txt
等文件放入 web
目录。composer-scaffold 插件正是为了解决这个问题而创建的。