Plugin management and versioning in Octobercms - composer-php

I'm wondering how to version the plugin dependencies of a project in Octobercms.
When I use the command php artisan plugin:install PLUGIN, all plugin files are added to the plugins/ folder, not ignored by git.
Do I have to do this again each time I clone the repo ?
Isn't there a better solution (submodules, composer) ?

Just create project on their website, add plugins to created project and associate installation with that project. Plugins will be updating automatically as well as they will be synced. For example: you add plugin through website to the project and your installation will automatically install it

I'll answer my own question. There's an ongoing discussion as how an OctoberCMS projet should be deployed so it's a bit difficult to know what the best practices are.
Dependencies in Plugin definition
The core dev solution seems to add dependencies in your plugin as an Array :
/**
* #var array Plugin dependencies
*/
public $require = ['RainLab.Blog', 'RainLab.User', 'RainLab.Pages', 'Manogi.Mediathumb'];```
In my case though dependencies are not installed automatically and while I get a warning, my plugin is still loaded with errors.
Using composer
I realised that plugins from RainLab have a composer.json file with october-plugin as type (See RainLab.User plugin for example).
So you could simply require a plugin as any composer package, and they'll install in your plugin/ directory :
composer require rainlab/user-plugin
Not every plugin has this convention though, like the Manogi.Mediathumb plugin. I haven't tried to require it but I'm guessing it'll be installed in the vendor/ directory.
Example composer.json requirements :
"require": {
"php": ">=5.5.9",
"october/rain": "~1.0",
"october/system": "~1.0",
"october/backend": "~1.0",
"october/cms": "~1.0",
"laravel/framework": "5.1.*",
"wikimedia/composer-merge-plugin": "dev-master",
"vojtasvoboda/oc-twigextensions-plugin": "dev-master",
"rainlab/blog-plugin": "dev-master",
"rainlab/pages-plugin": "dev-master",
"rainlab/user-plugin": "dev-master",
}
Ignore plugin folders in git
As for ignoring vendor plugins, you could add rules in your .gitignore file that ignores every plugin except for your namespace :
plugins/*
!plugins
!plugins/mynamespace/
Disable update feature in CMS
Last step is to change the disableCoreUpdates variable in config/cms.php :
'disableCoreUpdates' => true,
As stated in a comment section in this file :
If using composer or git to download updates to the core files, set this value to 'true' to prevent the update gateway from trying to download these files again as part of the application update process. Plugins and themes will still be downloaded.
Update with composer
Now if you want to update the core packages and plugins, run
composer update
Create a project on October website
Suggested here. I'm not a fan on depending on a service for this kind of stuff though.
Conclusion
I guess the two first approaches are valid and depend on whether you'd like to update in CLI or directly in the CMS (also whether you'd like your client to be able to update I guess).
I'll test the first one again and see if I can make the CMS download the plugins automatically. If I succeed I'll go with this solution since I can update from the CMS and from the command line with php artisan october:update. Best of both worlds.

Related

Gatsby doesn't update theme when modified in node_modules

I'm developing my own gatsby.js theme (actually I've forked and modified another theme, then created new npm package for it). When I change any theme file in node_modules, for example footer.js, I don't see any changes while running gatsby develop until I delete cache with gatsby clean. In the past (2 years ago) when I was making first changes to my npm module, everything was updating as it should. I must also mention that I've cleaned node_modules and updated all dependencies with yarn to the latest available versions.
For example, I'm making this change:
<p className="text-lead"><b>Last modified</b> {lastUpdate}</p>
to
<p className="text-lead"><b>Last change</b> {lastUpdate}</p>
Then gatsby develop detects change:
success onPreExtractQueries - 0.004s
success extract queries from components - 0.128s
success write out requires - 0.003s
success Re-building development bundle - 0.198s
success Writing page-data.json and slice-data.json files to public directory - 0.014s - 0/1 73.40/s
But I see no change in the browser window until I run gatsby clean.
Here's part of my gatsby-config.js at root project folder:
...
plugins: [
{
resolve: "#arturthemaslov/gatsby-theme-intro-maslov",
options: {
basePath: pathPrefix,
contentPath: "content/",
showThemeLogo: false,
theme: "gh-inspired",
},
},
...
Also, I've noticed this warning when running gatsby develop:
warn The #arturthemaslov/gatsby-theme-intro-maslov plugin has generated no Gatsby nodes. Do you need it? This could also suggest the plugin is misconfigured.
Maybe that's something to do with this problem? I've also tried ghosting parts of theme plugin by putting theme files into root src folder, but no luck.
Reason why it isn't working is because you shouldn't be modifying anything in the node_modules directory and when you:
I must also mention that I've cleaned node_modules and updated all
dependencies with yarn to the latest available versions.
You just reverted or updated every dependency within the node_modules directory and if you updated to the latest you need to go through every dependency and see if you have any conflicts which you likely do.
Do note you're also using a theme with Gatsby "^2.20.12" and Gatsby is now on version "^5.2.0".
You also mentioned in the comments you're updated the NPM package while the repository source code is dated a few years. Do not think this is a good approach and you should look at building a release and using the Github Action NPM Publish

How do I add shared dependencies to a monorepo using Yarn workspaces?

I am using Yarn's Workspaces feature to manage a monorepo. Some of the individual workspaces have their own dependencies defined in their own package.json, however I also have some shared dependencies (some are for testing the whole repo, some are used by all the workspaces). How do I declare these the correct way?
If I try to add them to the root package.json, Yarn gives me a warning. But adding the same dependency to all n workspaces (there are a lot and it's liable to grow) seems tedious and hard to maintain when upgrading dependencies.
Is the right thing to do to add the shared dependency (say, typescript, or jest or serverless) to every single individual workspace?
Using Yarn 1/classic.
I found also Yarn Workspaces: How and where should I install my dependencies? but it's unanswered
Yarn workspaces shared dependencies talks about using peer dependencies but the user is experiencing trouble
After a half-day search and trying, I found multiple ways to manage shared dependencies
1. Sync dependency version with syncpack
https://github.com/JamieMason/syncpack/
Given the fact that yarn workspaces will share the dependencies if their versions are the same (see https://classic.yarnpkg.com/lang/en/docs/workspaces/), all we have to do is to keep the dependency versions in sync to make dependencies sharing, which is exactly what syncpack does.
I found this is the least harmful way to make sharing dependencies works, while other methods require some degree of twisting package.json.
2. Use peer dependencies
For each package, set sharing dependencies as peerDependencies with version “*”, and set root workspace set the real dependencies. For example:
# ./package.json
{
...
"workspaces": ["packages/*"],
"dependencies": [
"some-lib": "^1.0.0",
]
}
# ./packages/pkg-a/package.json
{
...
"peerDependencies": [
"some-lib": "*",
]
}
and yarn install at workspace root.
3. Share script (require yarn v2)
See https://yarnpkg.com/getting-started/qa#how-to-share-scripts-between-workspaces
Miscellaneous
yarn provides workspace cli to add/remove package, see https://classic.yarnpkg.com/lang/en/docs/cli/workspace/
yarn workspace awesome-package add react react-dom --dev
yarn workspace web-project remove some-package

Running 2 composer.json files

I have PHP (Laravel) project that I'm developing, and it uses a helper package that I've developed and that gets modified as well while I work on the original project. I want to know the best way to deal with this in composer.
Right now, in my composer.json file, I have a repository path so that the project knows to always use my current version.
"repositories": {
"local": {
"type": "path",
"url": "../../packages/my-account/my-package"
}
}
The path is in the require path of the main project as it contains files that are extended in the project.
"require": {
"php": "^7.1.3",
"fideloper/proxy": "^4.0",
"laravel/framework": "5.8.*",
"laravel/tinker": "^1.0",
"nothingworks/blade-svg": "^0.3.0",
"my-account/my-package": "^0.3.8#dev",
...
I used to just have both projects open, and then update the package, and push it to packagist. Then wait while the other package downloads the update but it seemed to be such a time waster, especially since to run some unit tests I'd only find the issue after upgrading.
Instead, I have a soft link in my system (MacOS Mojave) from my vendor folder to my account folder to make sure that in PhpStorm, I can open the files I need to and make changes to the projects both at the same time. I basically only ever have to commit, when everything is working as expected. This has been a massive time save, however it has a drawback...
Every time I commit to the primary project I need to remove the repositories chunk from my composer.json to push it to staging or to production. Since there is no repositories-dev or something of that nature.
Is there a better workflow? Using 2 composer.jsons? OR some PhpStorm magic that can solve this so I'm not stripping out the hunk of code on each commit?
You can use https://github.com/franzliedke/studio which solves your exact problem. It saves you from modifying the composer.json file to add a symlink to your package, as it does the exact same thing on the fly, via a Composer plugin.

multiple projects with same vendor folder on Laravel 4

I have multiple projects with very little space to keep.
since most of them uses nearly same packages (only 1 uses phpexcel and the other one swiftmailer ) and vendor folder required biggest space on laravel.
I thought maybe I could use same vendor folder for every of them.
I actually messed with autoload.php and some other config files however I couldn't make it.
simply I'll put vendor folder under public_html and create folder like project1 project2.
under those folders I'll put everything about my projects except vendor folder and then make them subdomain.
Short answer:
You can't.
Long answer:
/vendor folder is not just about packages, you also have in there vendor/composer folder, where your application classes names are stored for autoloading purposes. Everytime you run composer dump-autoload, Composer changes the content of some files there. Take a look at the vendor/composer/autoload_classmap.php file, you'll see that some of those classes are from your own project.
Workaroud:
Please note that I don't see a thing like this going well, but you can, actually, create a blank project, just for package downloading and symlink all packages from all your vendors folders to that one. It's a lot of trouble for a little gain. But it's up to you, of course.
Source: http://www.wenda.io/questions/2416709/laravel-4-1-vendor-directory-config.html
edit composer.json
"config": {
"preferred-install": "dist",
"vendor-dir": "../vendor"
},
edit bootstrap/autoload.php file
require __DIR__.'/../../vendor/autoload.php'
edit bootstrap/start.php file
$framework = $app['path.base'].
'/../vendor/laravel/framework/src';
edit ../vendor/laravel/framework/src/Illuminate/Foundation/Console/Optimize/config.php
$basePath = $app['path.base'].'/../';
then run composer install, you will find vendor dir created ../
php artisan optimize -v --force
Generating optimized class loader
Compiling common classes

Composer option to use alternative to composer.json?

I've just started using the Composer feature where you tell it to look at local directories for dependencies, so that you can develop a library and something that uses that library in parallel without having to push to git to update all the time, which is awesome. e.g.
"repositories": [
{
"type": "vcs",
"url": "/documents/projects/github/guzzle"
}
],
"require":{
"guzzle/guzzle": "3.7.*#dev"
}
So when you do a composer update, Composer will pull in the version of Guzzle from the local directory, so you can test the code for a library in another application that uses that library without having to push to a repository between each code change.
However I just almost checked in the composer.json for my project with that set - which is obviously not going to work on anyone elses machine.
Is there anyway to tell composer to use a different file than composer.json, or other way to be able to tell composer to use local directories safely, without the high probability of accidentally committing a broken version of composer.json to your repository?
Use the COMPOSER environment variable:
env COMPOSER=composer-dev.json composer install
It has actually been available since at least 2012.
Instead of fetching from a local repository elsewhere you could add the option --prefer-source to the composer install/update command and remove the local repository reference.
That way composer will call git clone the software into the vendor directory, and you can develop both your software and commit to the vendor software, because that also is a fully working git repo.
Adding local repository references is not really recommended. It works when using them for real local software, but maintaining it has it's overhead: You have to mention this repository in every composer.json file that will ever load that software, even if it is only an indirect dependency (i.e. you add a software that needs THIS software as a dependency in your local repo).
Hardcoding the URL of the repository will also prevent you from changing it at will. Even though you could move the repo and change the URL accordingly, all older versions of your software still have the old URL in both composer.json and composer.lock files, and will try to load from there.
It looks like there isn't a way to do this nicely within Composer, however it is possible to hack around it.
In your composer.json file put a comment where you want to hack in some data.
{
"name": "base-reality/intahwebz",
"//": "LOCALHACK",
"require":{
"base-reality/php-to-javascript": ">=0.1.17",
"guzzle/danackguzzle": "3.3.*#dev",
...
...
}
...
}
Then have a separate file composer.local (not committed to Git) that contains the references to local directories:
"LOCALHACK",
"repositories": [
{
"type": "vcs",
"url": "/documents/projects/github/intahwebz-core"
}
],
Add a tiny PHP script called composerLocal.php to generate the new composer.json file
<?php
$srcFile = file_get_contents("composer.json");
$hackFile = file_get_contents("composer.local");
$finalString = str_replace('"LOCALHACK",', $hackFile, $srcFile);
file_put_contents("composer.json", $finalString);
?>
And a little bash script called localupdate.sh to backup the real composer.json file, generate the hacked composer.json, run Composer and then restore the original composer.json file
cp -f composer.json composer.json.bak
php composerLocal.php
composer update
cp -f composer.json.bak composer.json
Running the localupdate.sh script allows you to test the commits locally without having the danger of modifying the actual composer.json file used by the project, so there is less chance of accidentally pushing an invalid composer.json into the repository.
Just to note, Composer doesn't read the files from the respository directory, it reads the commited files in Git so you do need to commit changes made to the library code. The above process just skips the pushing step.
This should also work:
composer config --file=composer2.json && composer install
see https://getcomposer.org/doc/03-cli.md#usage
Easy, just use artifact.
In repositories add this:
{
"type": "artifact",
"url": "path/to/artifact/files/"
},
Now you just need to create the directory and zip a copy of your repository into that dir.
Name zipped files like so:
[vendorname]-[packagename]-[version].zip
example:
querypath-QueryPath-3.0.0.zip
Now you can modify the package locally and it will pull from the zip file instead of the online repo.
In require add it like so and specify version as defined in zip:
"querypath/QueryPath": "3.0.0",
With this method you will have the ability to edit the vendor files and composer will still update any autoloaders relative to the changes and it will leave your changes alone.

Resources