Certain folders and files missing when using composer to install silverstripe? - composer-php

When I run $ composer install in the terminal to install silverstripe using the following composer.json file, it does not bring through certain folder/files. E.g it does not bring in the mysite folder or assets folder and things like the main .htaccess file...
{
"name": "silverstripe/installer",
"description": "The SilverStripe Framework Installer",
"require": {
"php": ">=5.3.2",
"silverstripe/cms": "3.2.1",
"silverstripe/framework": "3.2.1",
"silverstripe-themes/simple": "*"
},
"minimum-stability": "dev"
}
Where as if I run the create project command from the silverstripe website it creates everything
E.g
$ composer create-project silverstripe/installer /path/to/project 3.2.1
How can I bring everything in using my composer.json file?

There is a StackOverflow answer similar to this: Difference between require and install vs create-project in composer
The create-project in essence clones the following repository, which has the files and folders you are looking for:
https://github.com/silverstripe/silverstripe-installer
It also has the composer.json file and runs the composer install after the cloning has finished.
So that is a base you can start your work on.
Note, you wouldn't want composer install to replace your .htaccess as that is something you edit per project (for redirects and things like that).
We have our own fork, of sorts, of the installer that contains our commonly used SilverStripe extensions in the composer.json already.
In our "base repo" we have:
.htaccess with samples of various redirects that you should have (forcing www, exceptions for development domains, etc)
Our own "project" base template that contains loads of helpers
Our commonly used SilverStripe extensions in the composer.json
We start our SilverStripe project by forking the base repository and then cloning that. We then run composer install on it and then start working on the project. We then commit the changes to our forked repository that relates to the project.
Also, in our repository we have vagrant file to start up a dev machine with all the goodies.

Related

Build with Composer

In a life cycle of a php project we have
install: composer install
publish: composer push
But, what would be the command to build a php project with composer?
what would be the command to build a php project with composer?
Simply speaking, you build the PHP project. Composer is a utility you can use to manage a PHP projects dependencies. Additionally you can also use it to define your PHP project.
How you build the PHP project is entirely up to you. This is normally dependent of what kind of PHP project that is and how you organize it.
To give an example: Lets consider your PHP project just is the project directory with the composer.json at its root with all the other sub-directories and files.
Composer operates within that directory. So when you want to create a build artifact of that project you do the following:
composer install --no-dev - Prepare the vendor folder with the production dependencies and the autoloader.
composer archive - Create the build artifact.
As you will do this quite often and over and over again you could add a Composer Script named build or similar to put things together:
{
"scripts": {
"build": [
"#composer --no-plugins --no-interaction install --no-scripts --no-dev",
"#composer --no-plugins --no-interaction archive"
]
},
"scripts-descriptions": {
"build": "Build project artifact."
}
}
You can then run:
$ composer build
...
Composer will then output the file-name. By default it should be a .tar file (tarfile, tarball), you can inspect it on the commandline with the tar utility (here gnutar):
$ tar -tvf "$(composer show -sN | sed 's|/|-|')"*.tar | less
And that would be the example. Whatever composer push is, I don't know. It is likely that you have it somewhere in your Composer configuration. So I can't comment on it.
To extend a bit on the given example: I manage most (if not even all) of my PHP projects with Composer. However this is not the full truth. I actually version control them with Git. Looking from a birds perspective, the Git utility is way more leading than the Composer utility. That is for example, that I want to be able to build a specific git revision.
Now Composer is not that bad with Git. It recognizes if the project exists and in case of the composer archive example, it even puts the git revision hash into the file name of the build artifact.
However Composer operates in-tree. That is the place where the development happens as well, so this can easily clash (you don't want the build to remove the development dependencies while you're running tests as well - or afterwards). And even Composer recognizes that the project is managed by Git, it is otherwise a bit dumb as Composer is merely concerned about the dependencies and knows very little about the project itself - it can't just guess how you manage the overall project.
So what then commonly happens is that you still use Composer during the build but you have a dedicated build process and runner that knows the ins and outs of the project and its build.
$ make
is such a runner. Works with a Makefile in the project, e.g.
$ make deploy
knows when it needs to build again. And speaking of PHP projects: It certainly can just rsync to remotes and run smoke-tests to mark the deployment as green (use old, dumb tech and keep it simple).

Composer install and update: why does it not set the PHP interpretor in the "vendor" folder?

According to docs, composer install (composer update too, since it includes install script), among other things, downloads the requirements and puts these packages inside the vendor directory: https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies :
It then implicitly runs the install command. This will download the dependencies' files into the vendor directory in your project.
What the docs don't say is: we often write the following in composer.JSON...
"require": {
"php": "^8.0",
... so if we try to apply what the docs say, it means that Composer would download the PHP interpretor (a package available in Packagist for example) and put it inside the vendor directory, when we run either composer install or composer update. What is the interest of putting a PHP interpretor inside a site's folder (here, vendor)?
But we know it doesn't do that. It won't download any PHP interpretor. It won't obviously put it inside the vendor directory. Instead, it will just check the server's PHP interpretor's version and returns a fatal error or something else if this version doesn't match the requirement's version.
So does it mean that in the Composer's install and update scripts, there is an exception made for PHP when treating the require's lines in the composer.JSON file?
In composer there's a special exception for require php, it only checks if your system's PHP version meets the requirement.
It's in the composer website under Package links: https://getcomposer.org/doc/04-schema.md#package-links.
Its not literally written though, its quite hard to find in the composer documentation.
If your require contains something like with
"php": "^8.0",
"ext-json": "*",
this does not mean: Install PHP or the JSON extension through Composer, but require that PHP and that extension in the given versions are already installed. That's what the documentation at https://getcomposer.org/doc/04-schema.md#package-links tells you:
require and require-dev also support references to specific PHP versions and PHP extensions your project needs to run successfully.
A regular expression that matches all such platform requirements can be found at https://github.com/composer/composer/blob/9ba042ded8b26230d33ebceb692bf29111d51ba4/src/Composer/Repository/PlatformRepository.php#L34 - currently, it contains:
const PLATFORM_PACKAGE_REGEX = '{^(?:php(?:-64bit|-ipv6|-zts|-debug)?|hhvm|(?:ext|lib)-[a-z0-9](?:[_.-]?[a-z0-9]+)*|composer-(?:plugin|runtime)-api)$}iD';
...which matches:
PHP runtimes in several versions
HHVM, a virtual machine that runs a forked version of PHP
all kinds of extensions and core libraries, like ext-json or lib-bz2
Composer itself, as some packages require special features of Composer v2 which were not available in v1
All lines in require section of composer.JSON are not packages available on a repository like Packagist: indeed, we can put some "virtual packages" inside this require section (https://getcomposer.org/doc/01-basic-usage.md#platform-packages).
php is one of these virtual packages. So Composer treat the following line...
"require": {
"php": "^8.0",
... as a virtual package (other name: "plateform package"), and not a package that could be put in vendor.
Then, if we extend a little the following definition of require...
Map of packages required by this package. The package will not be installed unless those requirements can be met.
(https://getcomposer.org/doc/04-schema.md#require)
..., then we can say that "if server's PHP interpretor's version doesn't meet the requirements versions, then Composer will raise a fatal error or something like that.
**Conclusion: being seen as a "virtual/plateform package" by Composer, php won't be installed (put) in vendor directory. It will just make Composer to check if server PHP version matches or not the requirements (if not, an error will be raised). This behavior is different than for other packages that would be, them, downloaded from for example Packagist and installed (put) inside vendor directory. **

What happens when new items are placed in composer.json file within Laravel Application

I am having a hard time thoroughly understanding how the composer.json file works within a Laravel application. I can build Laravel projects, but I am self-taught and have never fully understand what happens in the composer.json file.
For example, I have a current project that has the following within composer.json:
"require": {
"php": "^7.2",
I attempted doing composer require livewire/livewire, but then realized livewire required a newer version of php. I am using XAMPP 3.2.4 and the php version is 7.2.28. So, I backed up my files from my htdocs and database and am downloading a newer version of XAMPP.
I assume I would then change my composer.json file to:
"require": {
"php": "^7.4",
But, I cannot understand what is really happening here. Is this just saying that the server needs to have php version 7.4 or higher on it for the application to work? Or is it placing new files in the vendor directory? Do I need to delete any files out of the vendor directory?
composer is the php packages and dependency manager. to not copy past all what you need for your project you use composer.
when you write a package name in the composer.json require section then composer will fetch it from his sources (The main source of composer is packagist).
About the vendor directory, if you delete it your application will simply don't work, if you are storing the app somewhere (in a repo for example), you provide only the composer.json and then you will have the same vendor with taping 'Composer install'
Good luck

Get production versions of packages on "composer install"

Since composer was created, it made our life a lot easier. However, running composer install often ends up with so many files that can be useful for development, but just bloat the production server. Shared hosting often has limited inodes, or you must upload the "vendor" folder yourself since composer isn't on the server.
When the vendor folder has 6,000 files+ this is an issue, especially if you have multiple projects with 6,000 files each. And so many of these files are "README.MD" or "TODO". Production servers don't need the dev's "TODO" file.
I tried searching on Google but I can't find any clues, so anyone knows if there is a composer command that will install a production version?
There was a feature request for that, but it was rejected (several times). Right now the best what you can get from Composer is:
composer install --no-dev --prefer-dist
It will skip installation dev packages and prefer dist archives, which usually does not contain tests and other files not necessary to run package on production.
If this is still not enough, you may try to use octolab/cleaner plugin.
composer install --no-dev
The official link:
https://getcomposer.org/doc/03-cli.md#install
If you want to exclude something very specific, you want archive.
https://getcomposer.org/doc/04-schema.md#archive
"archive": {
"exclude": ["*.md", "vendor/**/tests", "/*.test"]
}

forcing composer to regenerate autoloads when composer.json of a dependency is changed?

My workflow for developing Symfony bundles is the following:
install Symfony
create a git repo for the new bundle, put a composer.json file in there
require the new package in the top-level composer.json, using #dev version
composer update newpackage => the package is downloaded, using git clone
work on the git clone inside vendors, committing and pushing from it
This is all fine and dandy, but seems to break in one specific case:
if I alter the 'autoload' tag of the already-installed package, it seems that Composer has a hard time taking it into account:
I tried 'composer dumpautoload', and it does nothing
I do not want to remove the composer.lock file, as I do not want other packages to be updated to a newer version, I only want to alter the autoload config of that one package
I tried removing by hand vendor/composer/installed.json, and what happened is that Composer re-downloaded all the vendors and wiped any data which happened to be in there at that moment
The same problem manifested itself when I did alter the autoload section of the package on a separate clone, pushed the changes to git and ran 'composer update mypackage' - although that might have been related to packagist not having received the ping from github.
I can of course alter by hand the composer.lock and vendor/composer/installed.json files, but that seems too hackish. It also does not gives the guarantee that user downloading the package the 1st time will see it working.
Try:
./composer.phar dumpautoload -o
It reads the composer.json files and rewrites all the autoload files which pick up the new paths.
dumpautoload uses the package information from vendor/composer/installed.json and not the individual composer.json files. You need to change the autoload info there, too.
The file installed.json is only being update when you run a
composer update

Resources