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

Order of dependency installation #649

Open
rlauer6 opened this issue Aug 1, 2022 · 4 comments
Open

Order of dependency installation #649

rlauer6 opened this issue Aug 1, 2022 · 4 comments

Comments

@rlauer6
Copy link

rlauer6 commented Aug 1, 2022

The order of dependency installation is random and can lead to problems when a specific version of a module is required. Example:

suppose I require version 0.04 of some module Foo, the latest version of Foo being > 0.04
...now suppose another one of my dependencies Bar requires ANY version of Foo
...if Bar is installed before my explicit callout of the required Foo, then Bar's requirement of Foo will be satisfied by installing the latest version of Foo, not the one I specified in my manifest.

To correct this would it not be possible to:

  • maintain a list of specific versions of modules required if specified
  • if a dependency requires that module AND does not specify a version, install the version specified in the manifest
  • if a dependency requires a specific version of a module AND a different version of that module is specified in the manifest, error out with a conflict

...or maybe there is some other way to handle this situation?

@miyagawa
Copy link
Owner

miyagawa commented Aug 1, 2022

then Bar's requirement of Foo will be satisfied by installing the latest version of Foo, not the one I specified in my manifest.

What do you mean by "I specified in my manifest" and how do you specify it?

In general, cpanminus supports pinning to a specific version of a module in cpanfile using ==, and the dependency resolver should consider what's specified in the top level cpanfile.

# cpanfile
requires 'Foo', '== 0.04';
requires 'Bar';

if a dependency requires a specific version of a module AND a different version of that module is specified in the manifest, error out with a conflict

again, I believe cpanminus does support this if you specify them in cpanfile. If that's not the case you might want to try Carmel instead.

@rlauer6
Copy link
Author

rlauer6 commented Aug 1, 2022

then Bar's requirement of Foo will be satisfied by installing the latest version of Foo, not the one I specified in my manifest.

What do you mean by "I specified in my manifest" and how do you specify it?

In general, cpanminus supports pinning to a specific version of a module in cpanfile using ==, and the dependency resolver should consider what's specified in the top level cpanfile.

# cpanfile
requires 'Foo', '== 0.04';
requires 'Bar';

if a dependency requires a specific version of a module AND a different version of that module is specified in the manifest, error out with a conflict

again, I believe cpanminus does support this if you specify them in cpanfile. If that's not the case you might want to try Carmel instead.

I should have specified that the version is specified in the PREREQ_PM hash in Makefile.PL (which is why they are being installed in a random order). I was using cpanm against a CPAN distribution.

@miyagawa
Copy link
Owner

miyagawa commented Aug 1, 2022

I should have specified that the version is specified in the PREREQ_PM hash in Makefile.PL (which is why they are being installed in a random order).

The installation order is also random if you specify them in cpanfile, but the requirements specified in there is kept as a global context, to start walking down the requirements.

I was using cpanm against a CPAN distribution.

Right, stable version pinning is only supported if they're specified from the root level using cpanfile - they might be specified as part of the dependency chain, but as you describe, that depends on the order of dependency resolution tree. Otherwise, cpanm would need to do a two-pass of requirement resolution, by first examining all the configuration + requirements scanning, before actually building and installing the modules, which is not supported.

I recommend extracting these pinned requirements to a cpanfile so that cpanm can know which version of the module you need before the resolution even begins.

Also, Carmel has a nice way to handle all this in a version controlled manner and is definitely worth a look.

@rlauer6
Copy link
Author

rlauer6 commented Aug 1, 2022

I should have specified that the version is specified in the PREREQ_PM hash in Makefile.PL (which is why they are being installed in a random order).

The installation order is also random if you specify them in cpanfile, but the requirements specified in there is kept as a global context, to start walking down the requirements.

I was using cpanm against a CPAN distribution.

Right, stable version pinning is only supported if they're specified from the root level using cpanfile - they might be specified as part of the dependency chain, but as you describe, that depends on the order of dependency resolution tree. Otherwise, cpanm would need to do a two-pass of requirement resolution, by first examining all the configuration + requirements scanning, before actually building and installing the modules, which is not supported.

I recommend extracting these pinned requirements to a cpanfile so that cpanm can know which version of the module you need before the resolution even begins.

Also, Carmel has a nice way to handle all this in a version controlled manner and is definitely worth a look.

Thank you so much for your insight and suggestions...and thank you for such a useful tool.

P.S. As a CPAN author we don't always know how our modules will be installed...so users wishing to use CPAN modules will need to be aware of various these types of issues I would imagine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants