When using Composer to load a package from a VCS repository, is there a way to specify which folder to install the contents in to (similar to git clone <directory>)?
For example the repo is:
https://github.com/organization/plugin_name.git
And thus composer file reads:
"repositories": [
{
"type": "vcs",
"url": "https://github.com/organization/plugin_name.git"
}]
"require": {
"organization/plugin_name": "dev-master",
}
Whereas the directory I want the contents to be is not "plugin_name" but something like "organization_plugin-title".
I have several repos (custom WP plugins) that have one name, but a different folder name within my WordPress MU setup, and I'd really like to not have to enable each one manually within the admin after updating my composer file.
Naturally answered my own question once I posted...
In the repo's composer.json file, the "name" field should be what you want the directory to be called when installed. I erroneously thought it had to be the name of the repo.
Be sure to then edit the local install's composer.json file so under the "required" section it is the same name as seen in the repo's composer.json file
Related
I've read several questions in SO about how to install 3rd party libraries in another "project". Inevitably, the answer is to use composer and they all say we need a composer.json file in the project root.
I'm confused. I am working on a project, whose "source" build has the following structure
web/
src/
The web folder includes several PHP files that are implemented by the project. This project so far doesn't use composer at all.
The src directory contains c/c++ files for some core engine files.
I now need to add, let's say, php-jwt to this "project" (which is a hybrid PHP+C++ project) in a way that I can include the jwt library in some file inside web/views/myfile.php
I also have the following additional requirements:
The project is quite a large one, and its packaging rules are quite complex. At the end, basically RPM or DEB files are created that users install on their systems. I want to make sure users installing the project, of which jwt-php is a part don't need to install composer.
Given that, where exactly do I download the jwt library using composer? Inside web/ ?
Maybe, we just add a composer.json right next to these two directories:
- web/
- src/
- vendor/---------
composer.json -
composer.lock -
------ autoload.php
------ composer
------ jwt-php
------ other-php-cpp-package-1
------ other-php-cpp-package-2
------ other-php-cpp-package-3
------ other-php-cpp-package-4
-------
Then, our composer.json might look like:
{
"name": "project/cphp",
"type": "library",
"description": "PHP C++ Project X",
"keywords": ["php","c++"],
"copyright": "",
"license": "",
"version": "1.0.0",
"authors": [{
"name": "user1361529",
"role": "Developer"
}],
"require": {
"jwt-php": "*",
},
"require-dev": {},
"autoload": {
"classmap": [],
"psr-0": {},
"psr-4": {}
},
"config": {}
}
If we are using a MacOS for example, we would install the composer:
cd path/to/main/dir
sudo composer install
We can always change the directory later. It might not be so important initially.
As you said, your project is a multi-language hybrid application.
I do not recommend that you install the vendor's vendor directory in the root directory of your project. If your php mainly exists in the web directory, then you can install the vendor in the web directory. The directory structure is as follows:
web/
---vendor/
------autoload.php
------...
---composer.json
---composer.lock
---...
src/
For references to installed libraries, you can use the include '../vendor/autoload.php' in web/views/myfile.php to load the composer auto-registration script (or you might be able to introduce autoload in a unified main entry script). Then call the third-party library through the namespace: new Firebase\JWT\JWT();
Then, submit the vendor to your VCS and package it into RPM or DEB so your customers don't need to install composer.
Answer by Google Translate
Edit:
It is dangerous to place the vendor directory in the directory with open permissions to the web server. Please adjust the specific directory structure according to the actual situation. By the way, the directory named web does not necessarily have the open permission of the web server.
If you do not want to use composer then you can simply download the library and call it in your code.
<?php
require _DIR.'path-to-librayr';
use class;
I am a Composer beginner and I am trying to make one project dependent of another one, while both project only exist on my local machine.
The composer.json in my library project (ProjectA) is:
{
"name" : "project/util",
"type" : "library"
}
I initialized git in the base folder of this project.
My composer.json in the project depending on the first one (ProjectB):
{
"repositories": [
{
"name" : "util",
"type" : "git",
"url" : "/d/workspaces/util"
}
],
"require": {
"project/util" : "*"
},
}
When I run composer install from ProjectB, I get the following error:
[RuntimeException]
Failed to clone , could not read packages from it
fatal: repository '' does not exist
I asume something is wrong with the url of the repository, but I am not sure what else to write there.
Autoload local package using composer (without going to packagist every time you change).
There are many ways to do so, I will be covering 2 of them:
In all cases we have 2 main parties:
- the local package (the code that we do not want to publish on packagist to be able to autoload it in our project composer).
- the main project (the code base that needs to use the local package code, can be another package and or any project).
Method 1: (direct namespace)
Open the main project composer.json file and autoload the local package namespaces using any method (PSR-4, PSR-0, ...).
example:
if in the composer.json of the local package we have:
"autoload": {
"psr-4": {
“Local\\Pack\\": "library"
}
},
"autoload-dev": {
"psr-4": {
"Local\\Pack\\Tests\\": "tests"
}
},
then in the composer.json of the main project we should have:
"autoload": {
"psr-4": {
"Mahmoudz\\Project\\": "src",
"Local\\Pack\\": "../path/to/local/pack/library” << referencing the other local package
}
},
"autoload-dev": {
"psr-4": {
"Mahmoudz\\Project\\Tests\\": "tests"
}
},
Advantages:
- you don’t touche the vendor directory (running composer update by mistake will not override your local changes)
- you don’t need your package to be on packagist to use it
- you work in one place (the local package) and the changes are automatically loaded in the main project
Disadvantages:
- you cannot publish the composer.json on production (needs editing before publishing to require the real package)
Method 2: (local repository)
Download the local package from a local repository.
local package:
1. initialize git in the package (even if you don’t want to use it - no need to commit anything)
2. add composer.json file. In the file make sure you have the following:
"name": "vendor-name/package-name",
"autoload": { … // use whichever method you prefer, but make sure it’s being loaded correctly
"minimum-stability": "dev"
composer dump-autoload
main project:
1. edit your composer.json to contain the following:
"repositories": [
{
"type": "vcs",
"url": "/full/path/to/the/local/package/package-name"
}
],
"require": {
"vendor-name/package-name": "dev-master"
},
composer update vendor-name/package-name
now check your vendor directory you should see the vendor-name/package- name
NOTE: whenever you make change in the local package (not the vendor) you need to git commit then you can composer update the main project, it will get the latest copy of the repo to the main project vendor directory.
Advantage:
- you don’t touch the vendor directory (running composer update by mistake will not override your local changes) - you don’t need your package to be on packagist to use it
Disadvantage:
- you have to keep committing your changes (in the local package) and then running composer update in the main project
- you cannot publish the composer.json on production (needs editing before publishing to require the real package)
I think you've just got the syntax wrong. The type should just be VCS, and then composer figures out what type of VCS it is.
So in your project B, the entry for repositories should be:
"repositories": [
{
"type": "vcs",
"url" : "/d/workspaces/util"
}
],
You don't need to name what library is available in /d/workspaces/util. Composer will scan the composer.json file in that directory and know what project name is available there, and use the project from that directory in preference to a version listed on packagist or other repository.
The easiest way is to use type=path https://getcomposer.org/doc/05-repositories.md#path
{
"repositories": [
{
"type" : "path",
"url" : "/d/workspaces/util"
}
],
"require": {
"project/util" : "*"
},
}
I found this tutorial really useful: https://johannespichler.com/developing-composer-packages-locally/ when I was facing issues with local package production
Note the symlink condition allowing the vendor folder to be a symlink which then means you no longer need to composer update each time you want to see change
"options": {
"symlink": true
}
In addition to Danack's solution: Changing the path from /d/ to d:/ worked for me.
Like this:
"repositories": [
{
"type": "vcs",
"url" : "d:/workspaces/util"
}
],
NOTE: This answer assumes that you have something like a Package Registry or GIT repository where you
can retrieve the releases of your package. If you do not yet have this. https://getcomposer.org/doc/05-repositories.md
Composer enables us to autoload a local development package without contaminating the composer.lock file.
When Composer finds a conflict between two or more packages it wil autoload only one of these packages.
You can use the autoload-dev to autoload a specific folder for development. (https://getcomposer.org/doc/04-schema.md#autoload-dev)
The autoload-dev (and autoload) settings do not touch the composer.lock file
In your projects composer.json file:
"repositories": {
"99999999": {
"type": "composer",
"url": "https://gitlab.com/api/v4/group/99999999/-/packages/composer/packages.json"
}
}
"require": {
"a-vendor-name/test-package": "1.0.*"
},
"autoload-dev": {
"classmap": [
"./../../packages/a-vendor-name/test-package"
],
"exclude-from-classmap": [
"vendor/a-vendor-name/test-package"
]
}
In this example the packages directory lives outside the project root and contains its own package GIT repositories.
autoload-dev because we only want this folder to load when we are developing. (https://getcomposer.org/doc/04-schema.md#autoload-dev)
classmap to load the packages from a local directory. (https://getcomposer.org/doc/04-schema.md#classmap)
exclude-from-classmap to disable loading the package within the vendor directory.
Will also suppress the warning about multiple classes with the same namespace. (https://getcomposer.org/doc/04-schema.md#exclude-files-from-classmaps)
Running DEVELOPMENT (default behaviour):
composer update a-vendor-name/test-package // or any other composer command
Your package will still be downloaded from your Package Registry. This downloaded package is not only ignored in you applications code, its also possible to update it according to the project composer.json file. Which in turn will update the composer.lock file, the right way.
Running DTAP / PRODUCTION by using the --no-dev flag:
composer update a-vendor-name/test-package --no-dev // or any other composer command
In addition to #Glen Solsberry's solutions, if you're running in a docker container like me, you can add a volume to your docker-compose.yml file like:
services:
theservicename:
...
volumes:
- ../:/var/www
- /path/to/src/package:/var/www/vendor/path/to/src/package
...
When you make changes locally they will reflect in the container.
I have a project and there is a Vendor folder under my project and it is not seen by Git. To be clear any change is not detected by Git under Vendor file.
However, I want to commit some files to a branch. How can I do that?
The most optimal thing to do with vendor files is to not add them in git, rather just make an entry in composer.json file.
If you want to edit those files according to your own need then, most of the packages can be published and the files will be available in your project directories for modifications.
Even if that doesn't helps you, the option is to remove the ./vendor entry in .gitignore file.
And the most forceful way is to use git add <filename>.
It is not good idea to commit a folder in vendor directory .
You should find the package repository (github or gitlab , ...) and fork the package .
Then add and commit your changes to your fork .
After that you can use your fork repository address in your composer.json file and get your fork package like this :
"type": "project",
"repositories": [
{
"type": "vcs",
"url": "https://gitlab.com/sample/sampple.git"
}
],
or you can also pull request to main repository and use the main repository.
I have two packages that was pulled to my project with composer.
I don't want to have composer pull updates on these packages from anywhere and don't want composer to try and override my files with any repository.
If I remove the packages from my composer.json file it deletes the packages an removes the autoloaders.
How do I get composer to leave the packages alone and allow me to work on the code without losing the files or autoloaders on update.
I figured out how to do this.
What you want to do is create an artifact directory.
Thus in your main composer.json file you need to do something like this:
"repositories": [
{
"type": "artifact",
"url": "custom/artifact/"
},
..........
the url var should be the file path to the zip files relative to composer.json file.
Now you only need to add a composer.json file with a name and version to a zip file.
If the package already contains a composer.json file you only need to add a version.
example:
vendor-package-1.0.zip needs a composer.json file with:
{
"version": "1.0",
"name": "vendor/package",
"type": "library",
........... etc
}
It is important to define the version in the composer.json file or it will not find it.
Now you call this package by version from your projects composer file:
"require": {
"vendor/package": "1.0",
Now you can create and update files in your package without the worry that some online change or offline server will cause any problems.
As long as the version stays the same it should leave your files alone.
The good thing is that files added or removed will still update the autoloaders as specified in the zip package's composer.json file.
Give a specific version for that package, so it will not be updated when new versions come up
If you don't have too many packages, you can use
composer update package1 package2
I'm trying to run composer using a local SVN repo, I can hit the repo I want but composer keeps adding the /branch to the end of the URL.
How can I override this?
Here are the docs:
http://getcomposer.org/doc/05-repositories.md#vcs
Example of what I have
"repositories": [
{
"type": "vcs",
"url": "http://host.com/externals/project",
"trunk-path": "trunk",
"branches-path": "branches",
"tags-path": "tags",
"reference": "symfony/symfony"
}
],
"require": {
"project/project": "svn-project"
}
Output is something like this:
[RuntimeException]
Repository http://host.com/externals/project/version could not be processed,
svn: URL 'http://host.com/externals/project/version/branches'
non-existent in that revision
Here is my subversion layout:
http://host.com/externals/project/version
Externals are libraries like Symfony
Project is Symfony
version is 2.1.2
So my svn repo is like:
http://host.com/externals/symfony/2.1.2
any thoughts?
this is how the company I work for stores external libraries we are using
UPDATE:
I've changed our repo to this:
http://host.com/externals/symfony/trunk/ <-- empty directory
http://host.com/externals/symfony/branches/ <-- empty directory
http://host.com/externals/symfony/trunk/2.1.2 <-- holds the Symfony 2.1.2 release code
Now I get this message:
Reading composer.json of http://host.com/externals/symfony/ (2.1.2)
Importing tag 2.1.2 (2.1.2.0)
but it then still pulls from the github repo instead of my svn repo.
I've also read on Satis
http://getcomposer.org/doc/articles/handling-private-packages-with-satis.md
but if I do there where do I host this?
Which the project?
On my SVN Repo?
Elsewhere?
Looks like Composer assumes you stick to the common repository layout of /trunk, /branches, and /tags. Plus you must enter the URL to the repository root--not the full project path. You specify the project-specific path with package-path.
See the doc Composer | Subversion Options.
Since Subversion has no native concept of branches and tags, Composer
assumes by default that code is located in $url/trunk, $url/branches
and $url/tags. If your repository has a different layout you can
change those values.