Skip to content
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

delete_vendor_packages deletes needed composer files #69

Closed
TussendoorHQ opened this issue Jun 21, 2023 · 2 comments
Closed

delete_vendor_packages deletes needed composer files #69

TussendoorHQ opened this issue Jun 21, 2023 · 2 comments
Labels
bug Something isn't working

Comments

@TussendoorHQ
Copy link

First of all; thank you for this package. It works wonderfull.

Although I'm running into an issue when using delete_vendor_packages in the config. The reason I want to use this is to cleanup my vendor directory so only specific dependencies stay there and only those will be autoloaded using composer. That is because I use the composer autoloader for some packages that are not using namespaces and I also use the composer autoloader to load my custom plugin classes.

That means I include both of the autoloaders in my plugin like so:

/**
 * Autoload non prefixed- and plugin classes using Composer.
 * @see https://getcomposer.org/doc/01-basic-usage.md#autoloading
 */
require_once __DIR__ . '/vendor/autoload.php';

/** 
 * Autoload prefixed classes using Strauss.
 * @see https://github.com/BrianHenryIE/strauss
 */ 
require_once __DIR__ . '/vendor/prefixed/autoload.php';

This is my config in the composer.json:

"scripts": {
    "post-install-cmd": [
        "sh prefixer.sh"
    ],
    "post-update-cmd": [
        "sh prefixer.sh"
    ]
},
"extra": {
    "strauss": {
        "target_directory": "vendor/prefixed",
        "namespace_prefix": "Tussendoor\\Bol\\Vendor\\",
        "constant_prefix": "TSD_BOL_VENDOR_",
        "include_modified_date": false,
        "include_author": false,
        "delete_vendor_packages": true,
        "exclude_from_copy": {
            "packages": [
                "yahnis-elsts/plugin-update-checker",
                "woocommerce/action-scheduler"
            ]
        }
    }
}

As you can see I am running a custom shell script after the regular composer commands like install and update. The shell script is looking like this:

#!/bin/bash

printf "\n"
printf "Composer action is completed! Wait for the new actions. \n"
printf "\n"
printf "Starting Strauss to prefix all dependencies \n"

vendor/bin/strauss

printf "\n"
printf "Strauss action is completed! \n"
printf "Dumping the composer autoload to prevent errors. \n"

composer dump-autoload

printf "\n"
printf "Autoload has been dumped. \n"
printf "Cleaning the empty folders in the vendor directory. \n"

find vendor -type d -empty -delete

printf "\n"
printf "All done! \n"

So after running vendor/bin/strauss my vendor directory is looking like this. (leaving some stuff out for simplicity):

- vendor
    - bin
        - composer
        - strauss
    - composer
        - (no directories only files like autoload.php)
    - excluded-package 
    - moved-package-directories-that-are-now-empty
    - prefixed
        - (all packages except excluded) 
        - composer
            - src
                - Composer
                - (some folders and some files)

All good until now. But the next step is to dump the composer autoload by composer dump-autoload and this is where I run into the following errors:

PHP Warning:  include(/vendor/bin/../composer/composer/bin/composer): Failed to open stream: No such file or directory in /vendor/bin/composer on line 120

Warning: include(/vendor/bin/../composer/composer/bin/composer): Failed to open stream: No such file or directory in /vendor/bin/composer on line 120
PHP Warning:  include(): Failed opening '/vendor/bin/../composer/composer/bin/composer' for inclusion (include_path='.:/opt/homebrew/Cellar/php@8.1/8.1.19/share/php@8.1/pear') in /vendor/bin/composer on line 120

Warning: include(): Failed opening '/vendor/bin/../composer/composer/bin/composer' for inclusion (include_path='.:/opt/homebrew/Cellar/php@8.1/8.1.19/share/php@8.1/pear') in /vendor/bin/composer on line 120

This is originating from vendor/bin/composer on line 120. That is the following:
include __DIR__ . '/..'.'/composer/composer/bin/composer';

This file isnt present anymore after using delete_vendor_packages and it also is not in the new vendor/prefixed/composer directory. I've tried excluding the composer/composer package by adding it to the exclude_from_copy config but that resulted in even more errors.

I believe this error could be resolved when the composer directory would not be copied to the target_directory. This directory should also not be cleaned so the file that is being searched for will still be present.

I've got the following questions:

  • Is this something anybody else is running into?
  • Should I change my config?
  • Should composer be moved to my target_directory at all?
  • Any other tips would be welcome.
@BrianHenryIE
Copy link
Owner

I suspect what's happening is that composer/composer is an explicit require dependency of one of your dependencies (a full composer.json would be helpful here) and so it is being copied and then deleted. An exclusion rule should be written for the Composer autoload files.

You could try setting the target_directory to vendor, and use the exclude_from_prefix setting for your two exclusions. Then it will prefix in-place and won't delete anything at all.

require_once __DIR__ . '/vendor/prefixed/autoload.php';

I think maybe that line won't be necessary after composer dump-autoload is run because you're using a sub-directory of vendor to copy the files to, and dump-autoload should scan the entire vendor directory

find vendor -type d -empty -delete

I've been meaning to add this to Strauss itself.

@BrianHenryIE BrianHenryIE added the bug Something isn't working label Jun 21, 2023
@TussendoorHQ
Copy link
Author

TussendoorHQ commented Jun 22, 2023

Thanks for the astonishing fast reply Brian!

I searched for the requirement that had composer/composer in their requirements and funnily enough it was the strauss package itself! After switching to the .phar file the problem was resolved. I needed some extra changes too (also based on your reply). So for anybody coming accross this, these are my changes:

  1. Removed brianhenryie/strauss from my requirements.
  2. Now using the .phar from the latest release.
  3. Changed the command in my prefixer.sh from vendor/bin/strauss to: php strauss.phar
  4. Changed target_directory to: vendor
  5. Renamed exclude_from_copy to exclude_from_prefix in my config to acommodate for the target_directory change.
  6. Added the below to my autoload config as per issue 34 and this reply. (using composer autoload and strauss autoload #34)
"classmap": [
    "vendor"
]
  1. Also removed the autoload from the prefixed folder as this doesnt exist anymore. Only this line is now sufficient to autoload everything:
require_once __DIR__ . '/vendor/autoload.php';

The issue mentioned here is resolved. Still running into another issue where a specific directory (/lazy) of nesbot/carbon doesnt get prefixed. But I will create a new issue for it as it is not related.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants