Composer with local SVN repo - php

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.

Related

Use a non-namespace composer package in a custom Laravel package [duplicate]

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.

Installing A Custom Composer Package from GitLab

I've created a simple test wordpress plugin. The plugin consists of a single php file (kreplach.php) and a composer.json:
kreplach.php
<?php
/*
Plugin Name: kreplach
Plugin URI: http://gitlab.example.com/sales/kreplach
Description: just a test
Author: Foo Bartok
Version: 1.0
Author URI: http://example.com
*/
?>
composer.json
{
"license": "MIT",
"name": "sales/kreplach",
"type": "wordpress-plugin",
"description": "just a test",
"authors": [
{
"name": "Foo Bartok",
"email": "foo#example.com",
"homepage": "example.com"
}
],
"require": {
"composer/installers": "*"
}
}
On my dev server I have the following composer.json
Server's composer.json
{
"repositories": [
{
"type": "composer",
"url": "https://wpackagist.org"
},
{
"type": "vcs",
"url": "git#gitlab.example.com:sales/kreplach.git"
}
],
"require": {
"php": ">=5.4",
"wpackagist-plugin/akismet": "*",
"wpackagist-plugin/contact-form-7": "*",
"wpackagist-plugin/wordpress-importer": "*",
"sales/kreplach": "master",
"johnpbloch/wordpress": "4.*",
"composer/installers": "*"
},
"extra": {
"wordpress-install-dir": "wp"
}
}
What I think SHOULD happen:
Composer looks through the git repo for composer.json
Composer matches the name "sales/kreplach" found in the build host's composer.json
Composer copies the contents of the master branch into wp-content/plugins/kreplach on my build host.
My fake plug-in does nothing, as designed.
What actually happens:
Bitter, bitter failure.
Loading composer repositories with package information Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.
Problem 1
- The requested package sales/kreplach could not be found in any version, there may be a typo in the package name.
Potential causes:
- A typo in the package name
- The package is not available in a stable-enough version according to your minimum-stability setting
see <https://getcomposer.org/doc/04-schema.md#minimum-stability> for more details.
Read <https://getcomposer.org/doc/articles/troubleshooting.md> for further common problems.
I have tested cloning the sales/kreplach repo onto the same host I'm attempting to install the plugin on.
To make sure that composer is actually reading the composer.json file from the git repo, I introduced a typo (yeah, totally on purpose, like) which threw a "hey, this json file is broken, Foam Head" error.
My version of gitlab is omnibus edition 8.6.4 (installed today).
I have successfully done this same sort of trick with pip/requirements.txt to install custom python modules, so I'm not unused to following directions. Am I missing a step, or some sort of non-obvious (to me at least) nomenclature?
Update 2021, 5 years later, since GitLab 13.3 (Aug. 2020), GitLab (even in its free edition) has a Package Registry, establishing GitLab as a private repository.
You can publish in it Composer packages, and, with GitLab 13.11 (April 2021):
Use Composer v2 with the GitLab Package Registry
You use Composer to publish, share, and download your PHP dependencies to your GitLab Project. Six months ago, a new major version (v2) of Composer was launched with a variety of changes, including significant performance improvements, architectural updates, and runtime features.
You can read more about the changes here.
Until recently, you couldn’t take advantage of these improvements because the GitLab registry didn’t support Composer v2.
This prevented some of you from using the GitLab registry at all.
As an MVC, we focused on adding support for the mandatory parameter metadata-URL. We added a new endpoint GET group/:id/-/packages/composer/p2/:package_name, which returns the metadata for all packages in your repository.
When Composer looks for a package, it replaces %package% with the package name and fetches that URL.
This means we’ve added a new endpoint GET group/:id/-/packages/composer/p2/:package_name which will return the metadata for all packages in your repository.
Please note that there are two parameters considered optional.
We have issues open to add support for the providers-api and list-api parameters. We hope to prioritize them in an upcoming milestone.
See Documentation and Issue.
And (still GitLab 13.11, April 2021):
Download Composer dependencies from version control
You have two options when downloading Composer dependencies: source or dist. For stable versions, Composer uses dist by default and downloads the dependency as a zip file.
However, you can also download it directly from version control.
If --prefer-source is enabled, Composer downloads your dependency as a Git clone instead of as a packaged zip file.
This is useful if you want to make a bug fix for a project and get a local Git clone of the dependency directly.
Until recently, you could not use the prefer-source and related preferred-install commands and configurations when downloading Composer dependencies.
This prevented many of you from using the GitLab Package Registry for your Composer dependencies.
We are happy to announce that you can now download your Composer dependencies from source.
Do so by simply adding the prefer-source option to your install command like this: composer update --prefer-source.
See Documentation and Issue.
I've not used gitlab but have used this method quite a bit with Bitbucket and GitHub.
You need to specify "sales/kreplach": "dev-master" in the server's composer.json - note that the branch name must be prefixed with "dev-".
Apparently Composer has special support for GitHub and BitBucket, which may not exist for Gitlab...so you may need to specify git as the repository type rather than vcs.
Good luck!
Refs:
https://lornajane.net/posts/2014/use-a-github-branch-as-a-composer-dependency
https://getcomposer.org/doc/05-repositories.md#vcs
https://getcomposer.org/doc/05-repositories.md#git-alternatives

Private composer packages - no valid composer.json was found

I'm trying to load a library I have hosted on BitBucket using composer as explained both in the official documentation and here, but keep receiving the following error:
[Composer\Repository\InvalidRepositoryException]
No valid composer.json was found in any branch or tag of [repository URL], could not load a package from it.
Here is my project composer.json:
{
"name": "Project name",
"require": {
"my-vendor/my-package": "dev-master"
},
"repositories": [
{
"type": "vcs",
"url": [repository URL]
}
]
}
And here is the composer.json in my remote repository (that apparently can't be found):
{
"name": "my-vendor/my-package",
"version": "0.3",
"autoload": {
"psr-0": {
"NS_": "src"
}
}
}
I should mention that both composer.json files are in the root directory as they should be.
Some other things to note:
I've also tried the "non-composer package" approach, whereby I specify the package information in my project composer.json, and omit the composer.json from my remote repository, as outlined in the documentation. This successfully clones the master branch but then results in the following error:
[RuntimeException]
Failed to execute git checkout "master" && git reset --hard "master"
fatal: Not a git repository (or any of the parent directories): .git
However, the package is downloaded to /vendor as expected, so I'm not sure why it's trying to checkout master again.
This is not the way I wish to solve this problem (as I'd rather make use of a composer.json in the remote repository), but it might help identify an issue elsewhere.
Thanks for any help.
EDIT
I've managed to get it working by referencing a package.json over HTTP:
"repositories": [
{
"type": "composer",
"url": "http://localhost/packages.json"
}
]
The packages.json looks like:
{
"packages": {
"vendor/my-package": {
"dev-master": {
"name": "vendor/my-package",
"version": "dev-master",
"source": {
"url": [repository URL],
"type": "git",
"reference": "master"
}
}
}
}
}
Is this the only way to get this working? It seems a bit overkill to host my own packages.json file if I'm only going to be using one or two in-house packages.
Regardless, this is giving me the same Git error as I mentioned previously.
EDIT 2
Forcing an error (invalid SSH passphrase) gives this:
[RuntimeException]
Failed to execute git clone "[repository URL]" "C:\workspace\DFv3\vendor\vendor/my-package" && cd /D "C:\workspace\DFv3\vendor\vendor/my-package" && git remote add composer "[repository URL]" && git fetch composer
So I can clearly see what it's doing here. However, it seems after this command runs it cds into the .git directory and tries running:
git checkout "master" && git reset --hard "master"
Presumably to get rid of the composer instance it pulled. However, it's running this in the wrong directory and I can't figure out why..
I know this is a bit old, but for some that might encounter this issue, this is how it works for me.
Clear the composer cache.
composer clearcache
Rerun the satis build script.
You must not include a version specification in your library's composer.json if it is actually managed by a supported source control system. Currently you are saying that your master branch IS version 0.3 (which is a stable version), but you are trying to include "dev-master" (which is an unstable version). Composer might get confused if that software really is "dev-master" or "version 0.3".
If you actually are developing new releases for the 0.3.x series in your master branch, you should define a branch alias instead. Add this to your current development branch for versions 0.3.x:
"extra": {
"branch-alias": {
"dev-master": "0.3.x-dev"
}
}
If you want to move on to version 0.4 or 1.0, you'd branch at the "last" state of the 0.3 series with a branch named "0.3.x" and then update the composer.json in the master branch to point dev-master to a new alias (like "dev-master": "0.4.x-dev"). You could also name your old 0.3 branch anyway you like and then add an alias for THAT branch.
Doing this will enable you to require the latest development version of 0.3.x like this:
"require": {
"my-vendor/my-package": "0.3.*#dev"
}
This will pull the latest 0.3 version - which currently would be the latest commit in the master branch because of the defined alias.
The way you are currently set up forces you to explicitly include version 0.3, which is a moving target without making that fact explicitly known.
Giving an explicit version tag should only be done if there is no version control system available that is able to give Composer the version number, i.e. there are no tags available, or the tags do not comply with Composer's requirement for version numbers. Since you seem to be in control of that vcs, it probably is a good idea to make the tags conform to Composers standard instead of making it troublesome to release a new version.
After you fixed this, I do expect your installation to NOT require that package.json file anymore, because that file now repairs the trouble you created with that version declaration. You'd then also not need that composer reference anymore, but can revert back to mentioning the original repository like you did.
If you feel you are using too many private repositories which are all requiring more private repositories, and are sick of mentioning them all in a long list, you could think about using Satis to create such a list of found packages instead of manually creating them.
I had the same error, after deleting folders from vcs everything works fine
sudo rm -R ~/.composer/cache/vcs/*
On Windows (as #Serbu suggested):
Clearing the vcs, repo and files directories under
C:\Users\Me\AppData\Local\Composer\
I've managed to get it working by referencing a package.json over HTTP:
"repositories": [
{
"type": "composer",
"url": "http://localhost/packages.json"
}
]
so the packages.json file looks like:
{
"packages": {
"vendor/my-package": {
"dev-master": {
"name": "vendor/my-package",
"version": "dev-master",
"source": {
"url": [repository URL],
"type": "git",
"reference": "master"
}
}
}
}
}
Also, its seems an autorun registry entry I had for command prompt was interfering with composer running.
See: Requiring a private git Bitbucket repository fails to find valid composer.json.
While this might be considered necromancy, I stumbled across this question yesterday while having an issue just like this (although in my case I was running an Ubuntu Docker container and not Windows as the OP was) and thought I would leave my thoughts and resolution here should anyone else stumble across this.
The Ubuntu repo version of Composer is currently sitting at 1.6.x (at the time of writing, Composer is up to 1.9.1 I believe) and I was getting different errors depending on if I ran composer install with different levels of logging. Without logging, it moaned that it couldn't find a valid composer.json. With logging, it moaned that it couldn't access the repo (despite scanning the tags).
The solution for me was to globally install the latest version of Composer as the Ubuntu repo version was using outdated BitBucket API calls (v1 is deprecated). Once I had updated to a newer version of Composer, the install ran perfectly.
So check your Composer version and install an updated version if possible (a local/project install should work too).
I've just updated composer.json to last version and the problem gone away.

Where do PHP Composer Packages Come From?

When I run
$ composer.phar install
where do the packages that get installed come from?
I understand that Packagist is the default repository for PHP packages, and that lacking a different package in composer.json, this is where composer will look for packages.
However, what I'm not clear on is how Composer and Packagist interact.
Does Composer download files directly from packagist.org
Or does Composer get a git/svn/hg repository link from packagist and download the files from the repository directly?
Or something else?
It depends on the contents of your composer.json file.
For example, if your composer.json contained simply
{
"require": {
"phpunit/phpunit": "3.8.*#dev"
}
}
then composer searches packagist, and finds phpunit here:
https://packagist.org/packages/phpunit/phpunit
which tells composer to load phpunit from here:
https://github.com/sebastianbergmann/phpunit.git
If instead your composer.json contained
{
"repositories": [
{
"type": "vcs",
"url": "http://github.com/sebastianbergmann/phpunit"
}
],
"require": {
"phpunit/phpunit": "3.8.*#dev"
}
}
then composer will not look to packagist, but go directly to github to download the repo.
The packages registered on Packagist are usually the "authoritative" version of the package (not a fork), but I have found several instances where this is NOT the case, so you should check it to be sure you are pulling the package you expect.
Packagist.org offers users to register their software there by pointing Packagist to read their composer.json file that is published somewhere on the web.
The usual case would be some of the common open source hosters like github, which makes it really easy because composer can deal with such a git repo right away. You could however host your own git or svn or hg repository, or even just publish ready-made ZIP or TGZ files for each software version.
Composer downloads directly from the source, e.g. Packagist only knows those source and tells your composer instance where to go. It does this by downloading a bunch of json files from Packagist.org that have all the infos. This is way easier than to find out where the libraries that you want are hosted and add this info as a repository entry into your local composer.json file. :)

How to preserve modifications in a composer library for future private projects?

I have made many modifications and fixes to a composer library that gets it's data from github , and it does have a dependency.
How can I preserve them easily while being able to get updates from package owner?
You could fork the project on Github, commit your modifications to your fork, then point composer at it.
When new updates come from the original package owner, you can merge them into your project using git's standard merge features.
When I have a project I have forked on github, I will often keep two remotes on my local copy, like so:
git clone [url of my fork]
cd [project name]
git remote add upstream [url of original project]
When updates are applied to the original project, I do something like:
git fetch upstream
git merge upstream/master
As my edit are rejected for absurd reasons. Fork like rjmunro suggests.
Then you need to refence your fork in composer.json
Example assuming you patched monolog to fix a bug in the bugfix branch:
{
"repositories": [
{
"type": "vcs",
"url": "https://github.com/igorw/monolog"
}
],
"require": {
"monolog/monolog": "dev-bugfix"
}
}
Take a look at the VCS part in the documentation!

Categories