-
Notifications
You must be signed in to change notification settings - Fork 25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
using composer autoload and strauss autoload #34
Comments
What you're doing should work without issue. Strauss uses Composer's own tooling to create its You can add the
Then run A little problem now is you still have the old files in your project, so you can have Strauss delete them as it runs by setting
I'll leave this issue open until I add some verbose output to the end of |
I forgot to add, if you have your Strauss output directory already in your This won't handle |
Thanks Brian. Here's my composer.json
I'm using the composer autoload...
however I get
It looks like the delete is removing some of the code that composer needs. Any help appreciated. |
I guess this is a bug. The files from the As I searched for a solution, I saw this comment from one of the Composer maintainers!
I have a solution for you for today. A script that reads two of Composer's PHP files and does a string replace with the updated path. Save this in your project folder as <?php
/**
* @see https://github.com/BrianHenryIE/strauss/issues/34
*/
$straussOutputDir = 'strauss';
$autoloadFilesDotPhpTxt = file_get_contents( __DIR__ . '/vendor/composer/autoload_files.php' );
preg_match_all('/(\'\w*\' => )(\$vendorDir \. \')(.*)/', $autoloadFilesDotPhpTxt, $autoloadFilesMatches);
$autoloadStaticDotPhpTxt = file_get_contents( __DIR__ . '/vendor/composer/autoload_static.php' );
preg_match_all('/(\'\w*\' => )(__DIR__ \. \'\/\.\.\' \. \')(.*)/', $autoloadStaticDotPhpTxt, $autoloadStaticMatches);
$autoloadStaticReplacements = array();
foreach( $autoloadStaticMatches[0] as $index => $staticFileMatches ) {
// `autoload_static.php` contains `files` autoloaders and more. ONLY operate on the files.
// Check is it in the autoload_files file.
if( in_array( $autoloadStaticMatches[3][$index], $autoloadFilesMatches[3] ) ) {
$autoloadStaticReplacements[$staticFileMatches] = $autoloadStaticMatches[1][$index] . "__DIR__ .'/../../$straussOutputDir" . $autoloadStaticMatches[3][$index];
}
}
$autoloadFilesReplacements = array();
foreach( $autoloadFilesMatches[0] as $index => $match ) {
$autoloadFilesReplacements[$match] = $autoloadFilesMatches[1][$index] . "__DIR__ .'/../../$straussOutputDir" . $autoloadFilesMatches[3][$index];
}
// Make the changes:
foreach ($autoloadStaticReplacements as $search => $replace ) {
$autoloadStaticDotPhpTxt = str_replace( $search, $replace, $autoloadStaticDotPhpTxt );
}
file_put_contents(__DIR__ . '/vendor/composer/autoload_static.php', $autoloadStaticDotPhpTxt);
foreach ($autoloadFilesReplacements as $search => $replace ) {
$autoloadFilesDotPhpTxt = str_replace( $search, $replace, $autoloadFilesDotPhpTxt );
}
file_put_contents(__DIR__ . '/vendor/composer/autoload_files.php', $autoloadFilesDotPhpTxt); I was testing this on geniepress/plugin. For some reason (another bug to investigate!) it needed these packages explicitly required:
Then this should work
And confirm no errors with:
I'll have to think about how to get that working seamlessly. It looks like I can register Strauss as Composer Plugin, hook into |
Another, more straightforward solution! I've created a branch Your
Then tell Composer to download Strauss from the new branch and reinstall everything:
This has just briefly been tested on I'll test it myself over the next few weeks and get it merged and released. |
Hi Brian - sorry I missed these update - This is great . I managed to build my own autoloader for my own classes ( 5 lines of code) and include the strauss autoloader. works perfectly. |
Hi Brian, Did this get merged? What is the proper way to do this in 2022? I'm having similar troubles as the OP (at least to my untrained eye, it could be something else) |
Something to note if you use this approach, make sure to enable Authoritative Classmaps in composer. Otherwise, you may get "class already declared" errors if another plugin tries to load an unprefixed version of a class you also require. The classmap won't find the prefixed version, but the PSR autoloading rules will load the namespaced file. If your plugin loads first, then you'll end up with a duplicate classname error. |
Just wanted to leave an update for others who find this issue: this branch works brilliantly 😁 As @TimothyBJacobs says you need Authorative classmaps and I've included an example below. You also need to run My composer.json {
"require": {
"...insert your packages here...": "as usual. delete this line obviously"
},
"autoload": {
"psr-4": {
"PeterHas\\": "src/"
},
"classmap": [
"vendor"
]
},
"require-dev": {
"brianhenryie/strauss": "dev-in-situ"
},
"scripts": {
"strauss": [
"vendor/bin/strauss"
],
"post-install-cmd": [
"@strauss"
],
"post-update-cmd": [
"@strauss"
]
},
"extra": {
"strauss": {
"target_directory": "vendor",
"namespace_prefix": "PeterHas\\Vendor\\",
"classmap_prefix": "PeterHas_Vendor_",
"constant_prefix": "PHV_",
"exclude_from_prefix": {
"packages": [
],
"namespaces": [
],
"file_patterns": [
]
}
}
},
"config": {
"classmap-authoritative": true,
"optimize-autoloader": true,
"sort-packages": true
}
} And then
Thanks @BrianHenryIE for this superb tool! |
I've encountered a bug (I think) using the configuration above if I install packages more than once. {
"require": {
"monolog/monolog": "^3.2",
"ruflin/elastica": "^7.3",
"elasticsearch/elasticsearch": "^7.17",
"symfony/console": "^5.4"
},
"autoload": {
"psr-4": {
"PicturingHistory\\": "src/"
},
"classmap": [
"vendor"
]
},
"require-dev": {
"brianhenryie/strauss": "dev-in-situ"
},
"scripts": {
"strauss": [
"vendor/bin/strauss"
],
"post-install-cmd": [
"@strauss"
],
"post-update-cmd": [
"@strauss"
]
},
"extra": {
"strauss": {
"target_directory": "vendor",
"namespace_prefix": "PeterHas\\Vendor\\",
"classmap_prefix": "PeterHas_Vendor_",
"constant_prefix": "PHV_",
"exclude_from_prefix": {
"packages": [
],
"namespaces": [
],
"file_patterns": [
]
}
}
},
"config": {
"classmap-authoritative": true,
"optimize-autoloader": true,
"sort-packages": true
}
} On the first run:
So far so good. Let's run the command again:
My understanding is that the paths within Strauss are not being rewritten this time, so it can't find the packages. However a diff shows nothing wrong: $ git diff --no-index good bad
diff --git a/good/composer/installed.php b/bad/composer/installed.php
index 984933607..a2ea3573f 100644
--- a/good/composer/installed.php
+++ b/bad/composer/installed.php
@@ -241,8 +241,8 @@
'psr/log-implementation' => array(
'dev_requirement' => false,
'provided' => array(
- 0 => '1.0|2.0',
- 1 => '3.0.0',
+ 0 => '3.0.0',
+ 1 => '1.0|2.0',
),
),
'psr/simple-cache' => array( Any ideas? |
@BrianHenryIE I've updated my comment with my |
Hey, here's half a fix. Basically, build the phar from this branch yourself and run it against a
But... When you run this twice, the namespaces get prefixed twice. I'll mark this as a bug and look into it later. This additional configuration should work but isn't:
I think the match is correct, I'm not 100% sure why it's not working. |
I've merged the I would like proper tests around this, particularly since it's doing some deep dive edits to Composer's own work, which I think most of us don't ever read. Example It may be possible to hook into Composer's plugin actions and make this a very seamless setup. |
Thanks @BrianHenryIE. I'm back on this project today and tested using the Phar from the master branch which works great - but as you say on second run duplicates the namespace prefix. I haven't made a regex fix for that work yet either. Edit: I got the regex to match by removing the doubling of the slashes on the first part:
Unfortunately whatever regex I try the resulting statement in the vendor files is |
Hello, I did not understand if there is a configuration that lets me autoload the prefixed classes and my classes (using psr4), but not the unprefixed ones. |
@BrianHenryIE Have you found any solution for the duplicate namespace problem?
|
@arjen-mediasoep try the latest release, please, 0.16.0 The code I had written earlier had a stupid mistake where I got the argument order wrong in |
@BrianHenryIE It works! You're my hero! |
@TimothyBJacobs Thanks for the tip with the authoritative class maps. I also had the same problem with the newer version |
@TimothyBJacobs I'd like to use this with normal class maps (not authoritative). Do you know why this is causing “class already declared” errors? I'd be willing to help fix this, but I first need to understand why this is happening. |
After adding strauss, it seems that I need to use both the composer autoload and the strauss autoload.
The staruss process doesn't generate autoload data for my own classes / namespace.
Is there a setting I need add so that I only need to use one autoloader? Or am I missing something ?
Thanks
The text was updated successfully, but these errors were encountered: