Platform independent composer post-install-cmd script - composer-php

Lets say my project has following structure
project\
templates\
web\assets\
composer.json
When running the composer update by default symlink to my project is created in vendor/ directory. I would like to create a custom post-install-cmd script that would create symlink to templates\ and web\assets\ folder in a different location.
Since my team is working on Windows/Mac/Linux I planned in running a simple php commands to make this happen. I can't seem to figure out where to start ...
The thing is, I can't figure out where is my current location when starting a php script? I've tried creating an empty file to see where it creates it, but it doesn't even create it.
This is what I wish to get working
"scripts": {
"post-install-cmd": [
"php -r \"symlink('/vendor/project/templates', '/templates/project');\"",
"php -r \"symlink('/vendor/project/web/assets', '/web/project/assets');\""
]
}

You should probably remove leading slashes from paths - at least on unix it will be interpreted as absolute path and definitely will not point to your project.
"scripts": {
"post-install-cmd": [
"php -r \"symlink('vendor/project/templates', 'templates/project');\"",
"php -r \"symlink('vendor/project/web/assets', 'web/project/assets');\""
]
}
If you want a bulletproof solution, you should probably create PHP helper class and use __DIR__ lub composer API to define correct paths. See examples in documentation.

Related

Laravel Nova tool wouldn't update if symlink is set to true on composer.json

So I am running into a weird issue. I used Laravel Nova (2) command to generate a tool. It sits at ./nova-components/CustomNovaDashboard. In order for the deployment to work on Laravel Vapor, I had to add the below to my parent composer.json.
{
"type": "path",
"url": "./nova-components/CustomNovaDashboard",
"options": {
"symlink": false
}
}
This above allows the code to get deployed, because the absence of symlink in options would otherwise throw the following error:
include(/tmp/vendor/composer/../acme/custom-nova-dashboard/src/ToolServiceProvider.php): failed to open stream: No such file or directory
But the problem now is that when I run npm run watch inside ./nova-components/CustomNovaDashboard, the code in development never updates, because somehow there is a copy of the code that sits in vendor/acme/custom-nova-dashboard that doesn't pick up the changes.
How can I solve this?
I found a solution, it was quite simple.
In my vapor.yml, I had to add COMPOSER_MIRROR_PATH_REPOS=1 before composer install.
build:
- 'COMPOSER_MIRROR_PATH_REPOS=1 composer install'
- 'php artisan event:cache'
- 'npm ci && npm run dev && rm -rf node_modules'
This ensures the symbolic link generated by nova:tool works on dev and prod similarly.
Just don't forget to set "symlink": true in your composer.json. Or leave it as is originally generated by the nova:tool command.

Laravel5.5 after use php artisan app:name Class not found

I am new developer on Laravel, now I'm using Laravel version 5.5
I got the problem after used php artisan app:name on my project, I got the problem:
In ProviderRepository.php line 208: Class
'App\Providers\AppServiceProvider' not found
as the captured image below:
As this error, I can not use php artisan commands or composer commands anymore can you guys please help me to solve this problem I am really appreciated for time. Thanks you
Best Regards
Siripong Gaewmaneechot
I would suggest looking in your config files, and the main classes which were generated when you started your laravel project (User class, etc) because they are all set to App\User App..... etc.
So for example, in the image you have in the question, it says it can not find App\AppProviders... - This indicates that somewhere you still have a use statement pointed to App\AppProviders.. but you changed the app name, so it's no longer App. something I do if I made that mistake, is I do a global search in my project files for App\ (you may need to put App\\ in the search because \ is an escape character
So if you did not change the app name immediately after starting the project, some of the paths will not be pointing to the correct directories. Let me know if that makes sense.
The command changes the PSR-4 configuration in composer.json.
Assume it was App before, your composer.json looks like this:
"autoload": {
"psr-4": {
"App\\": "app/"
}
},
After running the command with php artisan app:name Foo, it will look like:
"autoload": {
"psr-4": {
"Foo\\": "app/"
}
},
Therefore the whole namespace has changed and your classes can't be found by the Autoloader. To fix this, you have to either go back to the old name or do a global search and replace to change the namespace from App to Foo.

composer.json: change the vendor-dir dynamically through a script

In a project using Composer, shared by many developers and environments, I need to have the vendor-dir config parameter of composer.json to be set dynamically. That is, a script that runs when composer install/update is launched, must be able to change the value of this entry:
//composer.json
"config": {
"vendor-dir": "/var/www/html/......",
I tried the following:
//composer.json
"scripts": {
"pre-install-cmd": "MyBundle\\Composer\\Hook::setVendorDir",
The class Hook has this method:
//MyBundle/Composer/Hook.php
public static function setVendorDir(Event $event)
{
// ... some code set the $vendorDir variable here depending on many thing
$event->getComposer()->getConfig()->merge([
'config' => [
'vendor-dir' => $vendorDir
]
]);
// ...
}
The result is that the file autoloader.php and a composer folder are created in the right vendor directory, but all other packages are still installed in the default vendor directory!
The composer folder I mentioned only contains some PHP files (ClassLoader.php, _autoload\_*.php_, and LICENSE)
Notice: When I change the vendor-dir parameter in composer.json, it works flawlessly.
How may I set vendor-dir dynamically and have it taken into account for every package installations?
You can e.g. write a batch script (Windows) or bash script (Linux) or even a PHP script which you run instead of composer install. The script sets the correct vendor-dir in the composer.json and then runs composer install or whatever.
To set vendor dir just run in your script:
composer config vendor-dir /your/path/to/your/vendor/dir
For more info about composer config see the Composer documentation.

Composer autoload path not working

I have this script that use composer to setup the project but for some reasons does not work
<?php
include_once 'vendor/autoload.php';
use \LeagueWrap\Api;
$api = new Api($key = "somekey"); // Load up the API
$summoner = $api->summoner(); // Load up the summoner request object.
$bakasan = $summoner->info('bakasan'); // Get the information about this user.
$bakasan = $summoner->info(74602); // same thing as above, just to show that an id will wo$
echo $bakasan->summonerLevel; // 30
echo $bakasan->id; // 74602
echo $bakasan->name; // "bakasan"
echo $bakasan->profileIconId; // 24
echo $bakasan->revisionDate; // 1387391523000
echo $bakasan->revisionDateStr; // "12/18/2013 06:32 PM UTC"
?>
you can check here http://70.37.98.151/leaguewrap/tests/test2.php the error I get
Warning: include_once(vendor/autoload.php): failed to open stream: No such file or directory in /var/www/html/leaguewrap/tests/test2.php on line 3
my composer.json is
{
"name": "paquettg/leaguewrap",
"type": "library",
"description": "A wrapper for the League of Legends API.",
"version": "0.6.2",
"keywords": ["League", "legends", "wrap", "api", "facade", "proxy"],
"homepage": "https://github.com/paquettg/leaguewrap",
"license": "MIT",
"authors": [
{
"name": "Gilles Paquette",
"email": "paquettg#gmail.com",
"homepage": "http://gillespaquette.ca"
}
],
"require": {
"php": ">=5.4",
"guzzlehttp/guzzle": "4.0.*"
},
"require-dev": {
"phpunit/phpunit": "3.7.*",
"mockery/mockery": "0.8.*",
"satooshi/php-coveralls": "0.6.*"
},
"autoload": {
"psr-0": {
"LeagueWrap": "src/"
}
},
"minimum-stability": "dev"
}
and here folders tree
Your script cannot find the autoload file.
Including that file is like any other file: The path must be right, and which path is right depends on whether you are using an absolute path (unusual) or a relative path. Currently you are using a relative path.
Assuming your script is somewhere inside that src folder you showed, the path to the vendor/autoload.php must at least contain one ../ to go one directory level up - maybe more.
Seems like its the problem with your Composer Installation.
Follow these steps -
First make sure you have the Composer.json file created with all the dependencies.
Let's say you are creating a project, and you need a library that does logging. You decide to use monolog. In order to add it to your project, all you need to do is create a composer.json file which describes the project's dependencies.
{
"require": {
"monolog/monolog": "1.2.*"
}
}
Installation - Linux / Unix / OSX
Downloading the Composer Executable
There are in short, two ways to install Composer. Locally as part of your project, or globally as a system wide executable.
Locally
Installing Composer locally is a matter of just running the installer in your project directory:
curl -sS https://getcomposer.org/installer | php
Note: If the above fails for some reason, you can download the installer with php instead:
php -r "readfile('https://getcomposer.org/installer');" | php
The installer will just check a few PHP settings and then download composer.phar to your working directory. This file is the Composer binary. It is a PHAR (PHP archive), which is an archive format for PHP which can be run on the command line, amongst other things.
You can install Composer to a specific directory by using the --install-dir option and providing a target directory (it can be an absolute or relative path):
curl -sS https://getcomposer.org/installer | php -- --install-dir=bin
Globally
You can place this file anywhere you wish. If you put it in your PATH, you can access it globally. On unixy systems you can even make it executable and invoke it without php.
You can run these commands to easily access composer from anywhere on your system:
curl -sS https://getcomposer.org/installer | php
mv composer.phar /usr/local/bin/composer
Note: If the above fails due to permissions, run the mv line again with sudo.
Note: In OSX Yosemite the /usr directory does not exist by default. If you receive the error "/usr/local/bin/composer: No such file or directory" then you must create /usr/local/bin/ manually before proceeding.
Then, just run composer in order to run Composer instead of php composer.phar.
Installation - Windows
Using the Installer
This is the easiest way to get Composer set up on your machine.
Download and run Composer-Setup.exe, it will install the latest Composer version and set up your PATH so that you can just call composer from any directory in your command line.
Note: Close your current terminal. Test usage with a new terminal: That is
important since the PATH only gets loaded when the terminal starts.
Manual Installation#
Change to a directory on your PATH and run the install snippet to download composer.phar:
C:\Users\username>cd C:\bin
C:\bin>php -r "readfile('https://getcomposer.org/installer');" | php
Note: If the above fails due to readfile, use the http url or enable php_openssl.dll in php.ini
Create a new composer.bat file alongside composer.phar:
C:\bin>echo #php "%~dp0composer.phar" %*>composer.bat
Close your current terminal. Test usage with a new terminal:
C:\Users\username>composer -V
Composer version 27d8904
Using Composer
We will now use Composer to install the dependencies of the project.
To resolve and download dependencies, run the install command:
php composer.phar install
If you did a global install and do not have the phar in that directory run this instead:
composer install
Following the example above, this will download monolog into
the vendor/monolog/monolog directory.
Autoloading
Besides downloading the library, Composer also prepares an autoload file that's capable of autoloading all of the classes in any of the libraries that it downloads. To use it, just add the following line to your code's bootstrap process:
require 'vendor/autoload.php';
You can also try with below require form -
defined('__ROOT__') or define('__ROOT__', dirname(dirname(__FILE__)));
require_once implode(
    DIRECTORY_SEPARATOR, array(__ROOT__, 'vendor', 'autoload.php')
);

Laravel config subfolder not recognized on new server

I have some config files of US state counties, for example:
config/
state/
alabama/
counties.php
alaska/
counties.php
...
And on my development localhost server, I call them with:
Config::get('state/alabama/counties');
and it works, it loads an array of counties which I display somewhere.
But when I deploy this app on the Heroku, they won't show up.
I was thinking that it maybe has a problem with treating the config/state/subfolder as an environment config?
I do have a config/staging subfolder, in which I have new DB config stuff, and it works with no problem,
but on the Heroku app, the states just won't show up.
Have you added this directory to your autoload mapping in composer.json and then run composer dump-autoload? Without this, Laravel doesn't know to load your new files in to consideration.
Composer is a CLI-run file that exists in the Root of each laravel installation. composer.json is the config file for Composer - it uses this to manage your dependencies.
There's a section in composer.json called "autoload." These are the files that will automatically be loaded each time the app boots. Mine looks like this:
"autoload": {
"classmap": [
"app/commands",
"app/controllers",
"app/database/migrations",
"app/database/seeds",
"app/tests/TestCase.php",
"app/core"
]
For each folder that didn't exist before and that I wanted Laravel to understand, I added an entry here. Then, I ran composer dump-autoload and Laravel "understood" where the files I wanted to use were.
Each time you add a file, class, repository - anything that you want Laravel to automatically use, you'll have to run composer dump-autoload.
P.S: If composer dump-autoload doesn't work, try composer.phar dump-autoload.

Resources