I am developing a Laravel package, I have the main project and the package folder inside the same folder.
code
/mainproject
/package
Inside my composer.json in the main project I have:
"repositories": [
{
"type": "path",
"url": "../package"
}
],
running composer require for that package works fine and the code works, but then when I make any changes inside of the package, the changes aren't reflected, and so I have to use composer to remove, then re-require it.
I am using Laravel Sail as my local development environment and setting up the repository in the way that I did has created a sym-link in the vendor folder of the main project.
is there additional setup required when doing package development inside Laravel Sail?
This is a normal behaviour, you must run composer update your/package every time you make a change, so composer tracks all of that. This is due to how it works internally.
In one workplace, I have created some code as packages so it is easier to edit and I do not end up with a giant monolith, so I have created "local" packages like you.
Everytime you have done a change, you must run composer update your-package/name.
What I have done to keep it going normally is adding "version": "1.2.3" to my package's composer.json, like this:
{
"name": "my/package",
"description": "My package",
"keywords": ["my", "package"],
"version": "1.2.3",
So, when I have done a change, I would just bump it like 1.2.4 or whatever the desired number would be following the correct semver, and in my laravel's composer.json I would have:
{
"require": {
"my/package": "^1.0.0"
}
}
So, any time I made a change (and updated the version on the package), I would just run composer update my/package, so I have a new composer.lock using this new reference, that would update everything in composer.
Related
I've got a local PHP project (a website), and I want to use another project I've made (a tiny web framework) as a Composer package for the website project. I'm developing them in tandem, but want to keep them as separate projects; when I deploy the website, I want to use Composer to install the framework project as a package, just like I would with Guzzle or any other common Composer package.
The website project has the following composer.json:
{
"repositories": [
{
"type": "path",
"url": "/local/path/to/framework/package"
"options": {
"symlink": true
}
}
],
"require": {
"my/framework": "dev-master",
"guzzlehttp/guzzle": "6.3.3"
}
}
In /local/path/to/framework/package/composer.json I have:
{
"name": "my/framework",
"description": "A tiny framework.",
"autoload": {
"psr-4": {
"MyFramework\\": "src"
}
}
}
I run php composer.phar update and it sets up a symlink to the framework package in my website project. If I update code in the framework, it's immediately available to the website code. This is great.
However, later on I want to deploy the website project to my web server. For a clean deployment, I have a deploy script that exports an archive copy of the appropriate branch of the website git repo, and then runs php composer.phar install to make sure all the proper packages are installed. With the above config, the deploy script creates a symlink to the framework package, which is obviously no good when the deployment artifact is zipped up and scp'd out to the web server.
If I remove the symlink option above, then I have to run php composer.phar update every time I make any changes in the framework package, which is irritating since I'm developing the packages in tandem. But then on deploy, the package is copied in, rather than being symlinked in; this is good for deploy, except it always copies in the master branch (because I specified dev-master in composer.json).
Is there a way to set up Composer so that I can have the convenience of a local symlinked package for development, but to let the deployment script get a clean copy of the framework package, without having to change composer.json every time I want to deploy?
I also tried changing the repository type to vcs instead of path, but then Composer clones the framework package repository, and I really don't need a clone of the repo in my local vendor/ tree, either during development or deployment. I just want to be able to have a symlinked tree (which gets me instant updates) during development, and have a clean package installed for deplotment.
I may have to resign myself to developing the framework project "properly," that is, as a Composer package that I tag with actual release version numbers, and then update my website project to use a specific version of when it comes time for a deployment. I still haven't figured out the easiest way to do that, though.
You can use Composer Studio plugin.
It uses a separate file for configuration and allows you to have symlinks in development and a regular Composer install for prod deploy, without touching composer.json.
With it, your website composer.json will look like a regular file:
{
"require": {
"my/framework": "dev-master",
"guzzlehttp/guzzle": "6.3.3"
}
}
And with studio.json in the root of the project, with the following content:
{
"version": 2,
"paths": [
"/local/path/to/framework/package"
]
}
you can tell the plugin where to locate my/framework. Studio will then symlink the packages from the provided paths.
To have a regular install, just remove or rename studio.json, remove the vendor folder and composer.lock file and run the install again when deploying.
I made a composer plugin to make it more easy to test packages.
It doesn't require a configuration file, changing your composer.json and doesn't change the upgrade behavior of composer update
https://github.com/SanderSander/composer-link
It works as simple as calling composer link ../path-to-package to link the local package into your project.
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 tried to publish a project with composer. The project resides at github, and are published through packagist.org.
But when I try to create my project with composer it fails with this error message:
"Could not find package madskullcreations/simplicity with stability
stable."
I use the following command:
composer create-project madskullcreations/simplicity
The composer.json contains this:
{
"name": "madskullcreations/simplicity",
"description": "Website made simple!",
"homepage": "https://madskullcreations.com",
"type": "project",
"license": "GPL-3.0-or-later",
"minimum-stability": "dev",
"require": {
"php": ">=5.6",
"cakephp/cakephp": "3.5.*"
}
}
My repository contains just one file for testing. What is wrong? I tried to remove the dependencies, the entire "require"-block, but no real change...
Beginner as I am, I don't even know where I would define the packages "stability", can't find anything at github or at packagist.
Please help me get this started!
Working solution:
I eventually got it working with the help from Flying, see his answer further down. Since I think it is a wee bit complicated to get composer up'n working, I try to put the steps I did to get it working here:
Create a repository at github.
Create a composer.json with your depencencies. Check it in.
Release it. There are a "Releases" link somewhere, use it and give the release a name.
Now, to skip the packagist.org step during your testing, follow these steps. It is not good style to publish a non-working solution (like I did) on packagist.org, and it's no fun at all to do all the steps necessary ten times over.
Create a local folder somewhere, and create a new composer.json file there.
Put something like this in it:
{
"require": {
"madskullcreations/simplicity":"dev-master#dev"
},
"repositories": [
{
"type": "vcs",
"url": "https://github.com/madskullcreations/simplicity"
}
]
}
Run the following command in your new folder:
composer create-project
It should now download and install your project.
And, read the error messages given by composer and make sure you understand them. They are useful. My headache was a missing PHP-extension (intl) and that I assumed it was using php version 7.1, while it actually listened to my requirement in the composer.json file, and used v5.6. (I have several php-versions installed in iis, but my fuzzy head did not consider that.)
Packages stability requirement is defined into minimum-stability setting of composer.json of your project, not a composer.json of the external package.
Your madskullcreations/simplicity package have no releases defined so the only branch that is available in it - is dev-master "release" (it can be seen at the right side of package page on Packagist). This "release" have "dev" stability level.
Because of above if you're requiring this package into your project without either setting minimum-stability: dev or without specifying stability requirement for a package as
"require": {
"madskullcreations/simplicity":"dev-master#dev"
}
(notice #dev into version requirement) it is correct behavior of Composer to complain about lack of compatible releases.
Also it is generally bad practice to publish your test packages into public registry like Packagist. Instead you should use direct repository specification into your composer.json as explained here. In your case it will be:
"repositories": [
{
"type": "vcs",
"url": "https://github.com/madskullcreations/simplicity"
}
]
After specifying direct repository reference - it will be safe to remove your test package from Packagist unless you're really want to share it with open source community.
I create a package and pushed it to github, My composer.json for that package looks like such:
{
"name": "adam.balan/AisisAjax",
"description": "This is a component for AisisCore, that is - it should be installed to the Components section of the web based framework for wordpress.",
"license": "GPL v3",
"authors": [
{
"name": "Adam Kyle Balan",
"email": "AdamKyleBalan#gmail.com"
}
],
"minimum-stability": "dev",
"require": {
}
}
It all works fine for me - for using composer install the first time, how ever if I make a change and push it to the repository and run composer install (or even delete the vendor folder and run the command again to do a fresh install) I get a version that reflects the first commit I ever did to this repo. In other words my chanegs do not show up in whats being downloaded.
I have read about caching issues with composer and went to C:\Users\<user>\AppData\Local\Composer and deleted all the files in there - same issue.
What gives?
If you do not use a defined version that is tagged in the repository, but a branch you are developing on, Composer detects which commit was downloaded and will always download that exact commit if you only "install".
If you want Composer to update any dependency, you have to call composer update.
Note that Composer creates a lock file that contains this info, because the usual case is that someone wants to restore the exact combination of dependencies that were used when the software was composed. If you develop actively on the software, simply update your dependencies more often. :)
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.