How can I require Gulp in a composer.json file? The composer (php>=7.0) should install gulp and gulp-sass (and probably npm) for a developer who has not installed them. The possible solution should be the code to add in a composer.json file. I want to know how developers handle this situation. How do they create a composer-ready development project?
Asset Packagist might be the solution : https://asset-packagist.org/site/about
"repositories": [
{
"type": "composer",
"url": "https://asset-packagist.org"
}
],
"require": {
"npm-asset/gulp": "^4.0.2",
"npm-asset/gulp-sass": "^4.1.0"
}
NPM has it's own file packages.json to hold dependencies. When you install a new project you have to run npm install and all packages will be installed on the system in the node_modules folder. But first you have to install npm in your own. Every system has it's own package manager to install npm and most people download it from the website to get the latest version.
I think it's not really common to run everything from your composer file. I think it's possible but not really common.
https://nodesource.com/blog/an-absolute-beginners-guide-to-using-npm/
I am trying to run composer install in the command shell section of jenkins, but when I build the job, its failing because composer.json contains a repository section.
"repositories": [
{
"type": "vcs",
"url": "git#gitlab*****"
}
],
in jenkin's Source Code Management I did added the git credentials plus the repository URL (this is working fine and building fine) this is a different repo than the one in the composer.json.
The only problem is that I cant pull the git repo inside the composer.json file (giving permission denied), my thinking is that jenkins doesnt store the ssh keys, it only execute when its building and then remove, am i right to think this? and if so how can I overcome this? And if not what am I doing wrong, how can i avoid having permission denied when pulling git repos inside a composer.json?
How do I install a composer package with dev dependencies?
So for example:
When I have this package:
https://github.com/spatie/laravel-demo-mode
And I run:
composer require spatie/laravel-demo-mode
The tests folder is not installed?!
In short you don't (ever). If you want to contribute, you need to set up new Laravel project and set up composer to autoload your version of package, either from your fork or from somewhere on your disk. And when you do that you are just using your version of the package (again without the possibility to run packages's tests).
In order to run tests of the package you need to change directory to the root of the package and install its dependencies ($ composer install), after you've done that you may run $ phpunit.
What I am usually doing in when I want to contribute is:
have empty Laravel project ready (unversioned)
have packages folder in root
in that packages folder I usually do $ git clone <repo fork> (It may be more than one package at once)
in case I want to run package's tests I do $ composer install and $ phpunit (your IDE may squeak at you about duplicate definitions but you may ignore it)
improve and test the code of package in packages folder
test your changes "live" on Laravel project right-away
composer.json may look like:
...
"autoload": {
"classmap": [
"database/seeds",
"database/factories"
],
"psr-4": {
"App\\": "app/",
"Vendor\\Package\\": "packages/path-to-src/"
}
},
...
You may find useful this example repo I use https://github.com/Kyslik/column-sortable-example to demonstrate how to work with package I maintain. Mainly take a look at folder structure and composer.json.
There may be better ways on how to do contributing but I have only found (and developed) this one.
If I have small changes in mind (like typo, or just return type or whatever is "small") I do change package within vendor folder, and see if it breaks anything; after that I fork package source and edit the change right in the Github's web interface. To clean up just run $ composer install/update from root folder of your Laravel project.
Scenario: I am working with Symfony 2.2. In my list of required packages is also one of my github repositories, let's call it "TestLib".
I know that I can define the github url as additional repository in Symfony's composer.json to download "TestLib" via Composer from Github.
Problem: I cannot commit to "TestLib" repository as there is no local .git directory in the "TestLib" directory. I guess composer is fetching a zip from Github and not cloning it.
So my question is: is there a way to specifiy in Symfony's composer.json that Composer should clone TestLib?
Question 2: Maybe my workflow is wrong - so if you also have this scenario - how do you handle this?
Adding #dev to the package version clones the repository too.
{
"require": {
'package': '*#dev'
}
}
Also is possible setup source as preference in the composer.json
{
"config": {
"preferred-install": "source"
}
}
What I typically do if I notice that a vendor has an issue is rm -rf vendor/foo/bar to remove it and then I run composer install --prefer-source to get it back as a git repo.
What I did was add my github repo to packagist.org then I did this:
composer require malhal/createdby dev-master --prefer-source
This appears to add the require line to composer.json and also get it as a git repo, unfortunately this only works once so if you wouldn't be able to reuse the composer.json for a new install and would need to delete the require line and then remember to do this same command again. This command also downloads the git repo you don't have to do another composer update.
This is my composer.json file:
"require": {
"php": ">=5.4",
"zendframework/zendframework": "2.*",
"doctrine/doctrine-module": "dev-master",
"doctrine/doctrine-orm-module": "0.*",
"gedmo/doctrine-extensions": "dev-master"
},
"require-dev": {
"phpunit/phpunit": "3.7.*"
},
"scripts": {
"post-update-cmd": [
"rm -rf vendor/Behat",
"git clone git://github.com/Behat/Behat.git",
"cp composer.phar Behat/composer.phar",
"cd Behat && git submodule update --init",
"cd Behat && php composer.phar install",
"cd Behat && php composer.phar require guzzle/guzzle:3.0.*",
"mv Behat vendor/Behat",
"ln -sf ../Behat/bin/behat vendor/bin/"
]
}
How can I make it so the scripts are only run in the dev environment?
Basically I want the scripts to run only when I call:
php composer.phar update --dev
To do the non-development environment update without triggering any scripts, use the --no-scripts command line switch for the update command:
php composer.phar update --no-scripts
^^^^^^^^^^^^
By default, Composer scripts are only executed1 in the base package2. So you could have one package for development and in the live environment make it a dependency of the live system.
Apart from that, I do not see any way to differentiate scripts automatically.
This answer is back from 2012, the additional options in order of appearance can now safely be listed. As the list is composer-only and the original question smells to fall for x/y, the general answer is to use a build manager.
But turns out this could be done already at the day of asking, as in this composer-json example:
{
"scripts": {
"post-update-cmd": "composer::dev-post-update-cmd",
"dev-post-update-cmd": [
"rm -rf vendor/Behat",
": ... ",
"ln -sf ../Behat/bin/behat vendor/bin/"
]
}
}
1.0.0-alpha6 (2012-10-23): dispatch dev-only scripts with PHP script class and __callStatic, e.g. composer::dev-post-update-cmd. if in_array('--dev', $_SERVER['argv']) then $eventDispatcher->dispatchCommandEvent($name).
1.0.0-alpha7 (2013-05-04): --dev is now default and henceforth optional, --no-dev required for not --dev script dispatching. this effectively changes the command-line in question from: composer update --dev running only to: not running on composer update --no-dev. $event->isDevMode() now available, also required for new second parameter on dispatching the script on the event dispatcher. Compare with answer by Christian Koch.
1.0.0-alpha9 (2014-12-07): autoload-dev now allows to not have the script class in --no-dev automatically by removing it from autoload. this works b/c non-existing classes fall-through w/o error.
1.3.0-RC (2016-12-11): --dev is deprecated. COMPOSER_DEV_MODE environment parameter now available in update/install/dumpautoload scripts. no inherit need any longer for the PHP script class, unless enviroment parameters do not work in your setup, then use a PHP class script for a workaround. Compare with answer by Veda.
3 (future): --dev will needlessly make composer fatal, at least this is announced. this closes the circle to pre-1.0.0-alpha7 which also failed on the opposite, --no-dev. the command-line library in use then and yet in the future is not able to cope with -[-not]-args symmetrically, and if the pair is divided and one must go, then it can only throw.
References
See "Note:" in What is a script? - Scripts - Composer Docs
Base package is commonly referred to as root package in the Composer documentation.
Introduction
Some of the answers are a bit brief and don't go into detail about the context in which this is done. I'd like to share some knowledge with whoever is still puzzled after reading the previous answers.
Determine the right option for you
First, take a moment to realise that you're effectively creating a different flow, specific for a certain environment (i.e. your development server/container). This is against any best practices, as it is generally prone to errors. Having said that, you can achieve what you want in several ways;
Not triggering any scripts (docs)
If on some environment you do not want to trigger any scripts, you can prevent this using the --no-scripts flag.
Documentation reads: --no-scripts: Skips execution of scripts defined in composer.json.
composer upgrade --no-scripts
This is especially useful when upgrading packages while your code is currently not working. It would also work if your only scripts are development and test-related.
Running one script separately (docs)
Simply run the specific command as needed:
composer run-script [--dev] [--no-dev] script
This is useful when you want to run a script only on specific occasions.
For example, on build systems that have to perform a certain script before running any tests; build systems offer configuration options to call custom scripts like the above.
Defining a condition in the command (docs)
Documentation reads: During a composer install or update process, a variable named COMPOSER_DEV_MODE will be added to the environment. If the command was run with the --no-dev flag, this variable will be set to 0, otherwise it will be set to 1.
An example could look like
"scripts": {
"post-install-cmd": [
"[ $COMPOSER_DEV_MODE -eq 0 ] || <your command>"
]
}
Personally i would say this is the recommended way if you are using containers.
Note: this does not work on windows, since it would need %COMPOSER_DEV_MODE%.
There are also packages (like scriptsdev by neronmoon) that help you achieve the same goal without having to type the above in all commands, using a dev-scripts section in the extra section in composer.json
Defining a condition in your PHP script (docs)
Call a PHP method, that checks your environment based on how your application already does this. You can even reuse this condition by combining it with the method above; "Defining a condition in the command".
"scripts": {
"post-update-cmd": [
"AppNameSpaceName\\YourClassName::methodName"
]
}
You can then go ahead and create the class, like so:
<?php
namespace AppNameSpaceName;
class YourClassName
{
methodName() {
// do stuff
}
}
In many modern frameworks there is already a mechanism present to determine the runtime environment of the application (Symfony way, Laravel way).
Yarn run (docs)
Since most PHP applications nowadays also transpile their javascript files, either NPM or Yarn would be installed. You can use the scripts section to run this part only on development machines/containers. For example:
yarn run dev-only-script
having a section in package.json
"scripts": {
"dev-only-script": "rm some/folder && ln -s path/to/your/folder some/"
}
The point of this is would be to your composer.json clean. In yarn you could have scripts for dev-server, test and build.
It's not possible to choose different script for default install and the --dev option but you can use the method isDevMode() in Composer\Script\Event to run command only in a development enviroment. http://getcomposer.org/apidoc/master/Composer/Script/Event.html
You can use the COMPOSER_DEV_MODE environment variable (new in version 1.3.0-RC - 2016-12-11):
"scripts": {
"post-install-cmd": [
"[ $COMPOSER_DEV_MODE -eq 0 ] || echo devmode only"
]
},
You can achieve the same effect by setting up a custom script for the dev pathway, instead of using the post-update-cmd hook.
"scripts": {
"update-behat": [
"rm -rf vendor/Behat",
"git clone git://github.com/Behat/Behat.git",
"cp composer.phar Behat/composer.phar",
"cd Behat && git submodule update --init",
"cd Behat && php composer.phar install",
"cd Behat && php composer.phar require guzzle/guzzle:3.0.*",
"mv Behat vendor/Behat",
"ln -sf ../Behat/bin/behat vendor/bin/"
],
"dev-update": [
"#composer update --dev",
"#update-behat"
]
}
Then simply run php composer.phar dev-update
Run the following command.
composer update --no-scripts
Here is the small package, that you may use to do that
https://github.com/neronmoon/scriptsdev
It adds ability to define only-dev scripts.
usage
...
"extra": {
"scripts-dev": {
"post-install-cmd": [
"npm install --dev"
],
"post-update-cmd": "php ./someCoolCommand.php"
},
}
...
You can run either one and check,
composer update --no-scripts
or
composer dump-autoload