Turn WordPress plugin zip files into git repositories, so that composer version constraints work properly.
composify-ed plugin via composer?composify plugin zip URLs which are password-protected?composify instead of using $ npx?fatal: Could not read from remote repository?composify with Bedrock?Since plugin authors do not usually provide custom composer repositories (e.g: Private Packagist, satis), installing premium WordPress plugins via composer is not easy.
Lots of tutorials teach you: open composer.json and add the following within the repositories array:
// https://kinsta.com/blog/bedrock-trellis/
{
"type": "package",
"package": {
"name": "kinsta/kinsta-mu-plugins",
"type": "wordpress-muplugin",
"version": "2.0.15",
"dist": {
"url": "https://kinsta.com/kinsta-tools/kinsta-mu-plugins.zip",
"type": "zip"
}
}
}
The problems:
- if package.dist.url is version-locked, the repositories array has to be updated whenever a new plugin version is released
- if package.dist.url is not version-locked,$ composer install is not deterministic (even with composer.lock)
* package.dist.url always points to the latest version
* package.version becomes meaningless because the downloaded zip could be a newer version
* running $ composer install (without changing anything) could break the site because a newer plugin version is installed
* when composer caching invoked, there is no way to know which plugin version will be installed
The solution / what composify does:
1. download the plugin zip file
2. unzip it
3. generate composer.json
4. commit plugins files and composer.json
5. $ git tag
5. $ git push --follow-tags
$ npx @itinerisltd/composify just works! No installation required.
$ npx @itinerisltd/composify --help
Turn WordPress plugin zip files into git repositories, so that composer version constraints work properly
USAGE
$ composify
OPTIONS
-b, --branch=branch
the default branch of your remote repository [example: main]
-d, --directory=directory
directory name after unzip [example: kinsta-mu-plugins]
-f, --file=file
main plugin file which containing the plugin header comment [example:
kinsta-mu-plugins.php]
-h, --help
show CLI help
-n, --name=name
(required) package name [example: kinsta-mu-plugins]
-o, --vendor=vendor
(required) vendor / organization name [example: itinerisltd]
-r, --repo=repo
remote url or local path to the gti repository [example:
https://github.com/ItinerisLtd/kinsta-mu-plugins.git]
-t, --type=wordpress-plugin|wordpress-muplugin|wordpress-theme
(required) [default: wordpress-plugin] package type
-u, --[no-]unzip-subdir
unzip file into a sub-directory, only use when default options are breaking
-v, --version
show CLI version
-z, --zip=zip
(required) remote url or local path to the latest zip file [example:
https://kinsta.com/kinsta-tools/kinsta-mu-plugins.zip OR
/User/me/kinsta-mu-plugins.zip]
$ npx @itinerisltd/composify --vendor=itinerisltd --name=gravityforms --zip=<the-signed-s3-url>
Note the flags:
$ wget <the-signed-s3-url>
$ tree .
.
└── gravityforms_x.y.z.zip
$ unzip -o ./gravityforms_2.4.5.zip
$ tree .
.
├── gravityforms <-- `--directory`
│ ├── gravityforms.php <-- `--file`
│ ├── xxx
│ └── yyy.php
└── gravityforms_x.y.z.zip
--directory is omitted because it defaults to ${name}, i.e: gravityforms--file is omitted because it defaults to ${name}.php, i.e: gravityforms.php--repo is omitted because it defaults to https://github.com/${vendor}/${name}.git--unzipDir is omitted because main plugin file is inside --directory$ npx @itinerisltd/composify --vendor=itinerisltd --name=advanced-custom-fields-pro --file=acf.php --zip=https://connect.advancedcustomfields.com/xxx
Note the flags:
$ wget https://connect.advancedcustomfields.com/xxx
$ tree .
.
└── advanced-custom-fields-pro.zip
$ unzip -o ./advanced-custom-fields-pro.zip
$ tree .
.
├── advanced-custom-fields-pro <-- `--directory`
│ ├── acf.php <-- `--file`
│ ├── readme.txt
│ └── xxx
└── advanced-custom-fields-pro.zip
--file is set to acf.php$ npx @itinerisltd/composify --vendor=itinerisltd --name=kinsta-mu-plugins --zip=https://kinsta.com/kinsta-tools/kinsta-mu-plugins.zip --unzip-subdir --type=wordpress-muplugin
Note the flags:
$ wget https://kinsta.com/kinsta-tools/kinsta-mu-plugins.zip
$ tree .
.
└── kinsta-mu-plugins.zip
$ unzip -o ./kinsta-mu-plugins.zip
$ tree .
.
├── kinsta-mu-plugins
│ ├── xxx
│ └── yyy
├── kinsta-mu-plugins.php <-- `--file`
└── kinsta-mu-plugins.zip
--unzip-subdir is set because the unzipped content is not contained inside a --directorycomposify-ed plugin via composer?Open composer.json and add your git remote into repositories:
{
"repositories": [
{
"type": "git",
"url": "https://github.com/<vendor>/<name>"
}
]
}
$ composer require <vendor>/<name>
See: https://getcomposer.org/doc/05-repositories.md#vcs
composify plugin zip URLs which are password-protected?$ composify/bin/run -z /path/to/the-plugin.zip -o itinerisltd -n the-pluginNote: This is a v0.3 feature.
Yes.
These 2 commands are equivalent:
$ COMPOSIFY_VENDOR=itinerisltd COMPOSIFY_NAME=gravityforms COMPOSIFY_ZIP=<the-signed-s3-url> npx @itinerisltd/composify
$ npx @itinerisltd/composify --vendor=itinerisltd --name=gravityforms --zip=<the-signed-s3-url>
composify instead of using $ npx?Yes. However, you are responsible for updating it.
# yarn or npm doesn't matter
$ yarn global add @itinerisltd/composify
$ composify --vendor=itinerisltd --name=gravityforms --zip=<the-signed-s3-url>
Use WordPress Packagist instead.
fatal: Could not read from remote repository?ERROR: Repository not found.
fatal: Could not read from remote repository.
Make sure you have:
composify with Bedrock?No.
Although we prefer and sponsor Bedrock at Itineris, you can composify any plugin zip files into git repositories, and install them via composer.
Bedrock alternatives: - Composer in WordPress - WP Starter
Thanks! Glad you like it. It's important to make my boss know somebody is using this project. Instead of giving reviews on wp.org, consider:
Please provide feedback! We want to make this library useful in as many projects as possible. Please submit an issue and point out what you do and don't like, or fork the project and make suggestions. No issue is too small.
If you discover any security related issues, please email hello@itineris.co.uk instead of using the issue tracker.
Please see CHANGELOG for more information on what has changed recently.
composify is a Itineris Limited project created by Tang Rufus.
Full list of contributors can be found here.
composify is released under the MIT License.
$ claude mcp add composify \
-- python -m otcore.mcp_server <graph>