I've read other questions about this topic and I just can't seem to get this to work. I'm trying to get a download of cforms as a custom package to install into wp-content/plugins/cforms. I've gotten this to work for the other packages that wpackagist supplies, and even some custom plugins developed in-house.
Here's what I have:
{
"name": "mycompany/wordpress-install",
"description": "Themes and plugins for our wordpress install.",
"authors": [
{
"name": "Me",
"email": "example#example.net"
}
],
"require": {
"deliciousdays/cforms": "14.5.2"
},
"repositories": [
{
"type": "package",
"package": {
"name": "deliciousdays/cforms",
"version": "14.5.2",
"dist": {
"url": "http://www.deliciousdays.com/download/cforms-v14.5.zip",
"type": "zip"
}
}
}
],
"extra": {
"installer-paths": {
"wp-content/plugins/cforms": ["deliciousdays/cforms"]
}
}
}
It's downloading cforms fine, but it's still putting it into vendor/deliciousdays/cforms when I want it in (obviously) wp-content/plugins/cforms. What am I doing wrong?
Try using this composer.json, it includes Wordpress (v3.9 as of right now).
It uses fancyguy/webroot-installer to install to certain directories.
This file is meant to be in the root wordpress directory. The extra section shows the "webroot-dir" to be "."; This will install into current directory, (Do not use "/" or "./"), if you would like it to install into a specific directory simply change "." to the name of the directory you'd like to install to.
"extra": {
"webroot-dir": ".",
"webroot-package": "wordpress"
}
So after running this file you should have the normal wordpress structure with cforms placed in the wp-content/plugins directory, to install a theme, you can copy the cforms section and change the type to "wordpress-theme" to have it installed into the themes directory.
I'm by no means an expert with composer, but I was able to get this working correctly.
{
"name": "mycompany/wordpress-install",
"description": "Themes and plugins for our wordpress install.",
"authors": [
{
"name": "Me",
"email": "example#example.net"
}
],
"repositories": [
{
"type": "composer",
"url": "http://wpackagist.org"
},
{
"type": "package",
"package": {
"name": "wordpress",
"type": "webroot",
"version": "3.9",
"dist": {
"type": "zip",
"url": "https://github.com/WordPress/WordPress/archive/3.9.zip"
}
}
},
{
"type": "package",
"package": {
"name": "cforms",
"type": "wordpress-plugin",
"version": "14.5.2",
"dist": {
"url": "http://www.deliciousdays.com/download/cforms-v14.5.zip",
"type": "zip"
}
}
}
],
"require": {
"php": ">=5.3.0",
"composer/installers": "~1.0",
"wordpress": "3.9",
"fancyguy/webroot-installer": "1.0.0",
"wpackagist/wordpress-seo": "*",
"cforms": "14.5.2"
},
"extra": {
"webroot-dir": ".",
"webroot-package": "wordpress"
}
}
Note that using wpackagist, you can view a list of installable plugins/themes at these links:
http://plugins.svn.wordpress.org/
http://themes.svn.wordpress.org/
If you would like to include plugins from the Wordpress Plugin Respository, you can add them in easily. For instance, if you wanted to add the Yoast Wordpress SEO plugin, you would add the following to require (Note that you need to know the slug of the plugin to add it):
"require": {
"php": ">=5.3.0",
"composer/installers": "~1.0",
"wordpress": "3.9",
"fancyguy/webroot-installer": "1.0.0",
"wpackagist/wordpress-seo": "*",
"cforms": "14.5.2"
}
Finally figured it out after trying lots of different things. I think I was missing two things:
In the package declaration I changed it to have the "type": "wordpress-plugin", and then in the requires I had to add "composers/installers": "~1.0" like so (also note that the extra was removed entirely):
{
"name": "mycompany/wordpress-install",
"description": "Themes and plugins for our wordpress install.",
"authors": [
{
"name": "Me",
"email": "example#example.net"
}
],
"require": {
"composer/installers": "~1.0.0",
"deliciousdays/cforms": "14.5.2"
},
"repositories": [
{
"type": "package",
"package": {
"name": "deliciousdays/cforms",
"version": "14.5.2",
"type": "wordpress-plugin",
"dist": {
"url": "http://www.deliciousdays.com/download/cforms-v14.5.zip",
"type": "zip"
}
}
}
]
}
I still have been unable to figure out how to get a custom package to install to a directory of my choosing even with the composer/installers require in there. It just seems to ignore everything until I've added a type to the object, and then it forces it to download into the location defined by that type, based on how composer/installers decided to map it.
But I think this will work for now... If anyone knows how to make it download into, say, "myfolder/something/cforms" I'll accept your answer.
it happens I have got an answer for you, because I ran into the same problem. Clearly, there is a big demand now to custom install packages.
The composer/installers ONLY work on defined frameworks and CMS(s), but doesn't work for normal composer packages.
I have implemented this composer plugin to install packages into user (custom) defined folders you can just include it in your composer.json, follow the example and tell me if you have more questions :)
https://github.com/mnsami/composer-custom-directory-installer
composer-custom-directory-installer
A composer plugin, to install differenty types of composer packages in custom directories outside the default composer default installation path which is in the vendor folder.
This is not another composer-installer library for supporting non-composer package types i.e. application .. etc. This is only to add the flexability of installing composer packages outside the vendor folder. This package only supports composer package types,
https://getcomposer.org/doc/04-schema.md#type
The type of the package. It defaults to library.
Package types are used for custom installation logic. If you have a package that needs some special logic, you can define a custom type. This could be a symfony-bundle, a wordpress-plugin or a typo3-module. These types will all be specific to certain projects, and they will need to provide an installer capable of installing packages of that type.
How to use
Include the composer plugin into your composer.json require section::
"require":{
"php": ">=5.3",
"mnsami/composer-custom-directory-installer": "1.1.*",
"monolog/monolog": "*"
}
In the extra section define the custom directory you want to the package to be installed in::
"extra":{
"installer-paths":{
"./monolog/": ["monolog/monolog"]
}
by adding the installer-paths part, you are telling composer to install the monolog package inside the monolog folder in your root directory.
As an added new feature, we have added more flexibility in defining your download directory same like the composer/installers, in other words you can use variables like {$vendor} and {$name} in your installer-path section:
"extra": {
"installer-paths": {
"./customlibs/{$vendor}/db/{$name}": ["doctrine/orm"]
}
}
the above will manage to install the doctrine/orm package in the root folder of your project, under customlibs.
Note
Composer type: project is not supported in this installer, as packages with type project only make sense to be used with application shells like symfony/framework-standard-edition, to be required by another package.
Related
Since composer merge plugin is deprecated and the alternative is use of composer path repositories I found a problem transitioning to the later.
My structure is:
/composer.json
/local/composer.json
Where /composer.json is main composer with all setup and /local/composer.json is a file managing only private repositories.
Contents of each file are:
#/composer.json
{
"name": "main/project",
"type": "project",
"repositories": [
{
"type": "path",
"url": "local"
}
],
"require": {
"sub/project": "dev-main"
},
"extra": {
"installer-paths": {
"web/modules/custom/{$name}": [
"type:drupal-custom-module"
]
}
}
}
#/local/composer.json
{
"name": "sub/project",
"autoload": {},
"repositories": {
"test_repo": {
"type": "git",
"url": "git#github.com:rotari/test_repo.git"
}
},
"require": {
"rotari/test_repo": "dev-main"
}
}
As you can see the plan is simple: main composer requires sub/project and sub/project requires rotari/test_repo. However on install I'm prompted with error
sub/project dev-main requires rotari/test_repo dev-main -> could not be found in any version
Running composer install in /local is a success so there is no problem accessing rotari/test_repo.
Any idea or suggestions how this issue could be solved?
This part from documentation answers my quetion:
https://getcomposer.org/doc/faqs/why-cant-composer-load-repositories-recursively.md
Composer in not able to load repositories recursively.
I am trying to setup a composer project that will enable me to setup my own framework and pulling out any given dependency stored in github private repos.
First some prerequisites:
I don't want to add code to packagist.
I want to make sure my vendor folder is as clean as possible.
Framework composer.json
{
"name": "mycompany/myframework",
"description": "YET another Framework",
"type": "project",
"repositories": [
{
"type": "package",
"package": {
"name": "mycompany/system",
"version": "0.0.2",
"type": "library",
"source": {
"url": "https://github.com/mycompany/system.git",
"type": "git",
"reference": "master"
}
}
}
],
"require": {
"mycompany/system": "0.0.2",
"mnsami/composer-custom-directory-installer": "1.1.*"
},
"license": "proprietary",
"authors": [...],
"extra":{
"installer-paths":{}
}
}
mycompany/system composer.json
{
"name": "mycompany/system",
"type": "library",
"description": "utility belt xD"
}
The code for the class in PHP ( from mycompany/sytem ) has the following structure:
namespace MYCOMPANY;
//this file name is called utils.php
//adherence to PSR-4 is assumed
class utils {
}
My goal is:
I want to tell composer that it should create the following structure :
vendor \ MYCOMPANY \ utils.php ( not vendor \ mycompany \system \utils.php )
Later on, I want to be able to add more repositories like this and store them under MYCOMPANY as well. The framwework will work around this setup.
Custom installation is handled by mnsami/composer-custom-directory-installer
I'm guessing I should keep, by rule of thumb, the different packages in their own directories, but, since there is no risk of overwriting because other files will have a different naming convention.
Edit
Can this be done?
If so, how?
Thank you in advance
After some hours of work and following on #NicoHaase's reply in the comments, I gave up on this issue.
I was trying to make a clean folder where I would put all the different classes from different repos, but composer just doesn't work that way.
I hope this will help others that want the same thing.
Here is the scenario:
I have two projects driven by composer. The first one looks like this:
{
"name": "myusername/composer_test",
"description": "Composer project for CircleK Drupal 8",
"type": "project",
"license": "GPL-2.0-or-later",
"authors": [
{
"name": "Name Surname",
"role": "webdeveloper"
}
],
"repositories": [
{
"type": "composer",
"url": "https://packages.drupal.org/8"
}
],
"require": {
"php": ">=5.6",
"composer/installers": "^1.2",
"drupal-composer/drupal-scaffold": "^2.5",
"drupal/core": "^8.7.0",
"vlucas/phpdotenv": "^2.4",
"webflo/drupal-finder": "^1.0.0",
"webmozart/path-util": "^2.3",
"zaporylie/composer-drupal-optimizations": "^1.0"
},
"minimum-stability": "dev",
"prefer-stable": true,
"extra": {
"installer-paths": {
"web/core": ["type:drupal-core"]
}
}
}
Second one requires the first one and it's pretty straight forward:
{
"name": "user/site",
"description": "Composer for Site",
"type": "project",
"license": "GPL-2.0-or-later",
"authors": [
{
"name": "Name Surname",
"role": "webdeveloper"
}
],
"repositories": [
{
"type": "git",
"url": "git#github.com:myusername/composer_test.git"
},
{
"type": "composer",
"url": "https://packages.drupal.org/8"
}
],
"require": {
"myusername/composer_test": "dev-drupal_only"
},
"minimum-stability": "dev",
"prefer-stable": true
}
As you can see the first one defines where drupal core should be placed at by defining installer-paths. It turns out that when I run composer install just for the first composer.json file drupal core ends up in ./web directory as should, however when I run composer install for second file it does download every package from first composer.json just fine, but drupal core ends up in main directory instead of ./web. I know I can put installer-paths into the last composer file and overwrite it, but that's not the point. I want first file to define where stuff should be place at.
The extra settings only work for the root package. Consider user/site requiring 2 different packages that both specifiy different installer paths. Which one should composer use and how should it know? By ignoring those settings, unless they are specified in your root composer.json, composer circumvents any surprises/problems.
There is a way around this, you can create a post-install script that determines the correct path for you, e.g. by checking if myusername/composer_test is installed and the variable is set. This is a bit similar to how Symfony's Install-Script in the SensioDistributionBundle used to do it. It provides a fallback to determine the right directory to use based on configs and folder structure (due to changes in how the default directory structure looks at ~2.8, e.g. moving app/console to bin/console).
You could write your own install script that inspects the installed composer packages. The downside is, that just like you now have to specify the extra config in your second composer.json, you will have to specify the install scripts, plus you have to write the install script itself. So it might be a lot of extra work without gaining a lot from it.
This is my composer.json, I want to use Nodge's fork of lessphp project on Github
"repositories": [{
"type": "package",
"package": {
"version": "dev-master",
"name": "nodge/lessphp",
"source": {
"url": "https://github.com/Nodge/lessphp.git",
"type": "git",
"reference": "master"
},
"autoload": {
"classmap": ["lessc.inc.php"]
}
}
}],
"require": {
"php": ">=5.3.3",
"nodge/lessphp": "dev-master"
},
But I get this error when I run composer update:
nodge/lessphp dev-master -> no matching package found.
I don't know how to require correctly this fork.
The most common (and easiest) way of doing it is using a VCS repository.
All you have to do is add your fork as a repository and update the
version constraint to point to your custom branch. Your custom branch
name must be prefixed with dev-.
Assuming you forked monolog/monolog and created a branch called bugfix, you would update your composer.json like this:
{
"repositories": [
{
"type": "vcs",
"url": "https://github.com/igorw/monolog"
}
],
"require": {
"monolog/monolog": "dev-bugfix"
}
}
Note that you don't change the require statement except to specify your bugfix branch. You still reference the upstream package (monolog/monolog), not your personal fork (igorw/monolog), and the branch name is prefixed with dev-. You can read details in the docs
Using VCS works:
"name": "test/test",
"repositories": [{
"type": "vcs",
"url": "http://github.com/Nodge/lessphp"
}],
"require": {
"leafo/lessphp": "dev-master"
},
But if I require a module that has this composer.json, it doesn't work. It installs the original project, not the fork.
Example
"name": "example/example",
"require": {
"test/test": "dev-master"
},
I should mention again the repository. Is that normal?
If you can't get #Neilime answer to work for you, make sure your fork uses a different branch.
For example push your changes to a branch on your fork called my-bugfix, do not added dev- prefix in your branch name but in your composer.json you have to add it. Your composer file will look like:
"repositories":
[
{
"type": "vcs",
"url": "http://github.com/yourname/packageName"
}
],
"require": {
"owner/packageName": "dev-my-bugfix"
},
I have tried many options but After I got this post I saw the light and it just worked perfect.
This is what you have to do:
1- Fork The repository
2- Create a branch and make the required modifications.
3- Add the repository label to your composer.json
"repositories": [
{
"type": "vcs",
"url": "https://github.com/user/yourforkname"
}
]
4- In the command line inside your project require your fork like this:
composer require vendor/packagename:dev-branchname
And Voilá!!
You have your fork version working
According to the Composer documentation
http://getcomposer.org/doc/05-repositories.md#vcs, it's enough to
specify the original repository (not the fork) in the require ("nodge/lessphp" in your case). Composer will then install YOUR fork (look at the code in the vendors)
So, this is 2019, and most of the answers here are already correct.
If you find yourself however, in a situation where you need to require a particular branch of your fork (that you created), have composer list the available versions/tags first.
This saved me a lot of time.
A full example with spatie/laravel-backup package.
First, add repositories key to composer.json. With the url of your fork
"repositories": [{
"type": "vcs",
"url": "https://github.com/holymp2006/laravel-backup"
}]
Get available versions/tags
composer show "spatie/laravel-backup" --all
Choose the version you want from versions in the terminal output, then require that version
composer require spatie/laravel-backup:v5.x-dev
I usually add a "dist" node to the package definition.
I never had a problem using it this way.
I can't remember where I got this trick from, though, for any further explanations.
{
"repositories": [
{
"type": "package",
"package": {
"version": "dev-master",
"name": "nodge/lessphp",
"source": {
"url": "https://github.com/Nodge/lessphp.git",
"type": "git",
"reference": "master"
},
"autoload": {
"classmap": ["lessc.inc.php"]
},
"dist": {
"url": "https://github.com/Nodge/lessphp/archive/master.zip",
"type": "zip"
}
}
}
],
"require": {
"nodge/lessphp": "*"
}
}
The accepted answer and clarifying answers all worked well for me when I had ex. an application, which needed a dependency I had forked and modified. I’d still use the accepted answer in this case.
However, when I had a package I wanted to distribute myself on Packagist, which also contained a forked and modified dependency, this approach no longer worked.
If someone were to try and install with this config, they’ll still get that same -> no matching package found. error message.
This answer and the linked Composer docs suggest that the repo settings have to be at the top-level composer.json. That means, someone installing this package would have to add that config to their composer.json file too—which adds a lot of unnecessary confusion to the install process.
Instead, I published my fork to Packagist. My understanding is that while forks are frowned upon, this would be considered a maintained fork, since I am using it for this new package.
Hopefully that’s helpful for anyone who has this problem with a package or library they’d like to distribute.
I'm try using CakePHP for the first time with composer, but I have some problems.
I have this composer.json:
{
"name": "example.com.br",
"repositories": [
{
"type": "pear",
"url": "http://pear.cakephp.org"
}
],
"config": {
"vendor-dir": "Vendor/"
},
"require": {
"php": ">=5.4",
"pear-cakephp/cakephp": ">=2.4.3",
"cakephp/debug_kit": "2.2.*",
"smottt/wideimage": "dev-master"
},
"extra": {
"installer-paths": {
"app/Plugin/DebugKit": ["cakephp/debug_kit"],
"app/Vendor/Wideimage": ["smottt/wideimage"]
}
}
}
When I run composer install (or update) --prefer-dist, everything works except smottt/wideimage.
This package is being installed in the /Vendor folder instead /app/Vendor, so, installer-paths was ignored.
Of course, what Danack has said is true: the composer-installers plugin only supports a select list of package types.
In response to that, I have written an extension for the composer-installers plugin which allows any arbitrary package type to be handled by the "installer-paths" directive.
Simply require oomphinc/composer-installers-extender in your composer.json and add support for any additional arbitrary package types:
"extra": {
"installer-types": ["library"],
"installer-paths": {
"special/package/": ["my/package"],
"path/to/libraries/{$name}/": ["type:library"]
}
}
For packages that don't specify a type, use the default type library.
From the documentation.
You cannot use this to change the path of any package. This is only
applicable to packages that require composer/installers and use a
custom type that it handles.
From one of the packages you're installing:
{
"name": "smottt/wideimage",
"description": "An open-source PHP library for image manipulation. (With namespaces, PHP 5.3+)",
"homepage": "http://wideimage.sourceforge.net",
"type": "library",
"license": ["GPL-2.0","LGPL-2.1"],
"version": "11.02.19",
"autoload": {
"psr-0" : {
"WideImage" : "lib/"
}
}
}
So basically the package you're trying to install doesn't support custom install paths.
Use option "script" of composer (work only with linux) :
"scripts": {
"post-install-cmd": [
"php -r \"system('mv '.getcwd().'/Vendor/smottt/wideimage '.getcwd().'/Vendor/Wideimage');\""
]
}
Add your custom types to the installer-types:
{
"installer-types": ["library", "myttype-1", "mytype-2"]
}
https://packagist.org/packages/oomphinc/composer-installers-extender