甜蜂/composer-suite

生成原始 composer.json 的多个变体

v1.4.0 2024-08-20 09:02 UTC

This package is auto-updated.

Last update: 2024-09-20 09:18:21 UTC


README

CircleCI codecov

生成原始 composer.json 的多个变体

  1. 您必须在 composer.json#/extra/composer-suite 中定义差异,以下为示例。
  2. 下一步是运行以下命令生成替代 composer.json 文件:
    composer -vv suite:generate
  3. 通过设置 COMPOSER 环境变量 激活其中一个替代 composer.json 文件。
    1. export COMPOSER='composer.my-suite-01.json'
    2. composer update --lock

其他好处是,如果 composer.json 中有任何相对路径,例如在 #/repositories/FOO/url#/extra 下的任何位置,那么这些路径也将与替代 composer.*.json 文件一起工作。

示例 composer.json - 多版本依赖

{
    "require": {
        "symfony/console": "^4.0 || ^5.0",
        "symfony/process": "^4.0 || ^5.0"
    },
    "require-dev": {
        "phpunit/phpunit": "^8.0"
    },
    "scripts": {
        "test": "phpunit"
    },
    "extra": {
        "composer-suite": {
            "symfony4": {
                "description": "Make sure Symfony 4.x will be used.",
                "actions": [
                    {
                        "type": "replaceRecursive",
                        "config": {
                            "items": {
                                "require": {
                                    "symfony/console": "^4.0",
                                    "symfony/process": "^4.0"
                                }
                            }
                        }
                    }
                ]
            },
            "symfony5": {
                "description": "Make sure Symfony 5.x will be used.",
                "actions": [
                    {
                        "type": "replaceRecursive",
                        "config": {
                            "items": {
                                "require": {
                                    "symfony/console": "^5.0",
                                    "symfony/process": "^5.0"
                                }
                            }
                        }
                    }
                ]
            }
        }
    }
}

运行: composer suite:generate
生成的文件
composer.symfony4.json

{
    "require": {
        "symfony/console": "^4.0",
        "symfony/process": "^4.0"
    },
    "require-dev": {
        "phpunit/phpunit": "^8.0"
    },
    "scripts": {
        "test": "phpunit"
    },
    "extra": {}
}

composer.symfony5.json

{
    "require": {
        "symfony/console": "^5.0",
        "symfony/process": "^5.0"
    },
    "require-dev": {
        "phpunit/phpunit": "^8.0"
    },
    "scripts": {
        "test": "phpunit"
    },
    "extra": {}
}

然后

unset COMPOSER
composer update --lock
composer suite:generate

export COMPOSER='composer.symfony4.json'
composer update
composer run test

export COMPOSER='composer.symfony5.json'
composer update
composer run test

# Back to normal.
unset COMPOSER
composer update --lock

示例 composer.json - 本地开发

用例

某些第三方服务必须集成到框架中。

Composer 包

  • RestAPI 客户端(类型:库)
  • 框架的模块/插件(类型:库)
  • 框架(类型:项目)
{
    "type": "project",
    "repositories": {},
    "require": {
        "my/module_01": "^1.0"
    },
    "require-dev": {
        "sweetchuck/composer-suite": "^1.0"
    },
    "extra": {
        "composer-suite": {
            "local": {
                "description": "Local development",
                "actions": [
                    {
                        "type": "prepend",
                        "config": {
                            "parents": ["repositories"],
                            "items": {
                                "my/module_01": {
                                    "type": "path",
                                    "url": "../../my/module_01-1.x",
                                    "options": {
                                        "repo-path": {
                                            "url": "https://github.com/my/module_01.git",
                                            "branch": "1.x"
                                        }
                                    }
                                },
                                "my/restapi_client_01": {
                                    "type": "path",
                                    "url": "../../my/restapi_client_01-1.x",
                                    "options": {
                                        "repo-path": {
                                            "url": "https://github.com/my/restapi_client_01.git",
                                            "branch": "1.x"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    {
                        "type": "replaceRecursive",
                        "config": {
                            "parents": ["require"],
                            "items": {
                                "my/module_01": "1.x-dev",
                                "my/restapi_client_01": "1.x-dev"
                            }
                        }
                    }
                ]
            }
        }
    }
}

运行: composer suite:generate
生成的文件
composer.local.json

{
    "type": "project",
    "repositories": {
        "my/module_01": {
            "type": "path",
            "url": "../../my/module_01-1.x",
            "options": {
                "repo-path": {
                    "url": "https://github.com/my/module_01.git",
                    "branch": "1.x"
                }
            }
        },
        "my/restapi_client_01": {
            "type": "path",
            "url": "../../my/restapi_client_01-1.x",
            "options": {
                "repo-path": {
                    "url": "https://github.com/my/restapi_client_01.git",
                    "branch": "1.x"
                }
            }
        }
    },
    "require": {
        "my/module_01": "1.x-dev",
        "my/restapi_client_01": "1.x-dev"
    },
    "require-dev": {
        "sweetchuck/composer-suite": "^1.0"
    },
    "extra": {}
}

然后

unset COMPOSER
composer update --lock
composer suite:generate

cp ./composer.lock ./composer.local.lock
export COMPOSER='composer.local.json'
composer update --lock

# You can work on both libraries (restapi_client_01 and module_01) on-the-fly.

# Back to normal.
unset COMPOSER
composer update --lock

套件

您可以拥有任意多的套件。

如上例所示,套件可以在 composer.json#/extra/composer-suite 中定义,但套件定义也可以存储在外部文件中。
例如 ./.composer-suite/composer-suite.*.json。然后,是否将这些文件跟踪到 VCS 由您决定。

示例 ./.composer-suite/composer-suite.foo.json

{
    "name": "foo",
    "description": "My foo suite.",
    "actions": []
}

name 是可选的。如果省略,则套件名称将从文件名中解析。

如果有两个套件具有相同的名称,则来自外部文件的套件具有最高优先级。

操作

您可以在 extra/composer-suite/<suite-id> 键下定义不同的数组操作。

操作有两个主要属性

  • type (字符串) 操作的标识符。
  • config (混合) 数据类型通常是数组,但取决于 type

操作 - replaceRecursive

官方 PHP 文档: array_replace_recursive()

  • parents: 数组
  • items: 数组
{
    "require": {
        "a/b": "^1.0",
        "symfony/console": "^4.0",
        "symfony/process": "^4.0"
    },
    "extra": {
        "composer-suite": {
            "my-suite-01": {
                "actions": {
                    "type": " replaceRecursive",
                    "config": {
                        "parents": [],
                        "items": {
                            "require": {
                                "symfony/console": "^5.0",
                                "symfony/process": "^5.0"
                            }
                        }
                    }
                }
            }
        }
    }
}

结果

{
    "require": {
        "a/b": "^1.0",
        "symfony/console": "^5.0",
        "symfony/process": "^5.0"
    },
    "extra": {}
}

操作 - unset

删除指定的元素。

  • parents: 数组
{
    "name": "a/b",
    "foo": {
        "bar": "delete me"
    },
    "extra": {
        "composer-suite": {
            "my-suite-01": {
                "actions": {
                    "type": "unset",
                    "config": {
                        "parents": [
                            "foo",
                            "bar"
                        ]
                    }
                }
            }
        }
    }
}

结果

{
    "name": "a/b",
    "foo": {},
    "extra": {}
}

在 "config.parents" 数组中,最后一个项可以是数组

{
    "name": "a/b",
    "foo": {
        "a": "delete me 1",
        "b": "keep me",
        "c": "delete me 2"
    },
    "extra": {
        "composer-suite": {
            "my-suite-01": {
                "actions": {
                    "type": "unset",
                    "config": {
                        "parents": [
                            "foo",
                            [
                                "a",
                                "c"
                            ]
                        ]
                    }
                }
            }
        }
    }
}

结果

{
    "name": "a/b",
    "foo": {
        "b": "keep me"
    },
    "extra": {}
}

操作 - prepend

在数组的开头添加新元素。

  • parents: 数组
  • items: 数组
{
    "repositories": {
        "old/p1": {}
    },
    "extra": {
        "composer-suite": {
            "local": {
                "actions": [
                    {
                        "type": "prepend",
                        "config": {
                            "parents": [
                                "repositories"
                            ],
                            "items": {
                                "new/p1": {},
                                "new/p2": {}
                            }
                        }
                    }
                ]
            }
        }
    }
}

结果

{
    "repositories": {
        "new/p1": {},
        "new/p2": {},
        "old/p1": {}
    },
    "extra": {}
}

操作 - append

在数组的末尾添加新元素。

  • parents: 数组
  • items: 数组

操作 - insertBefore

插入一个或多个 "items"。 "parents" 中的最后一个项是参考点。

  • parents: 数组
  • items: 数组

操作 - insertAfter

插入一个或多个 "items"。 "parents" 中的最后一个项是参考点。

  • parents: 数组
  • items: 数组

命令

此 Composer 插件定义了以下命令

  • composer suite:list
  • composer suite:generate

验证

您可以通过运行官方 COMPOSER='composer.json' composer validate 命令检查自动生成的文件状态。
如果其中一个自动生成的文件 存在且过时,则退出码将不是 0
此命令不会报告关于缺少 composer.*.json 文件的问题。

链接

  1. COMPOSER 环境变量

其他

  1. "$(composer config bin-dir)/codecept" _completion --generate-hook --program codecept | source /dev/stdin