bndr / pipreqs

pipreqs - Generate pip requirements.txt file based on imports of any project. Looking for maintainers to move this project forward.
Apache License 2.0
6.38k stars 388 forks source link

New Option for Dynamic Versioning, e.g. wheel==0.23.*, wheel==0.* or wheel #237

Closed mapattacker closed 3 years ago

mapattacker commented 3 years ago

Added new option "dynamic", for dynamic versioning.

Example: wheel==0.23.0

There will be 3 possible args for this option, micro, minor or all. The result in requirements.txt will be as below.

This will enable more targeted installations, esp if one is only looking at bug fixes, security patches or minor/micro version updates, or simply just install most recent updates.

--no-pin option is merged within this new option as the "all" arg.

@jcch94

coveralls commented 3 years ago

Coverage Status

Coverage increased (+1.6%) to 73.134% when pulling 4eae4794a0548710099ae22ce5b9fcfd2a8845b7 on mapattacker:master into 1aff63c049fdb73184b2fe1d821d418010c3954e on bndr:master.

coveralls commented 3 years ago

Coverage Status

Coverage increased (+1.6%) to 73.134% when pulling 4eae4794a0548710099ae22ce5b9fcfd2a8845b7 on mapattacker:master into 1aff63c049fdb73184b2fe1d821d418010c3954e on bndr:master.

coveralls commented 3 years ago

Coverage Status

Coverage increased (+1.6%) to 73.134% when pulling 4eae4794a0548710099ae22ce5b9fcfd2a8845b7 on mapattacker:master into 1aff63c049fdb73184b2fe1d821d418010c3954e on bndr:master.

coveralls commented 3 years ago

Coverage Status

Coverage increased (+1.6%) to 73.134% when pulling 4eae4794a0548710099ae22ce5b9fcfd2a8845b7 on mapattacker:master into 1aff63c049fdb73184b2fe1d821d418010c3954e on bndr:master.

coveralls commented 3 years ago

Coverage Status

Coverage increased (+1.6%) to 73.134% when pulling 4eae4794a0548710099ae22ce5b9fcfd2a8845b7 on mapattacker:master into 1aff63c049fdb73184b2fe1d821d418010c3954e on bndr:master.

alan-barzilay commented 3 years ago

Hi, thank you for the PR! This seems like a good opportunity to also add support to the compatible release version specifier as a scheme, what do you think?

mapattacker commented 3 years ago

Hi, thank you for the PR! This seems like a good opportunity to also add support to the compatible release version specifier as a scheme, what do you think?

@alan-barzilay Saw u commented at the other post, glad there's a new maintainer to help out in this important library. :)

Can I understand the reason to add the compatible release format? Since, the current format using asterisks in this PR kinda achieves the same purpose. If compatible release is a standard by PEP 440, and * is going to be obsolete eventually, I can change to format entirely using ~= instead.

My team and I will be happy to settle any issues related to this PR efficiently, as this feature is something our team will like to incorporate. :)

alan-barzilay commented 3 years ago

Can I understand the reason to add the compatible release format?

My understanding of the compatible release format is that it is useful if you want to ensure that you will have a compatible version of a package. Lets say you have a package in version 3.1.2 in your current project. By using ~=3.1.2 in your requirements, you will guarantee that you will get version 3.1.2 or later, but not version 3.2.0 or later. If you need a feature that was introduced in version 3.1.2 this will guarantee that you will have it, but it also guarantees that you will not get version 3.2.0 or later since a breaking change may have been introduced.

I agree that using asterisks kinda achieves the same purpose but I believe using the ~= notation would provide a more robust requirements.txt. Maybe we could adapt the micro and minor schemes to use ~=? The micro scheme would simply use the  compatible release notation and the minor scheme would also use ~= but only after stripping everything after the second ".". This approach would also have a smaller code surface to worry about.

If I may, I have a suggestion that would also contemplate PR #107. I see 5 different mutually exclusive use cases: 1) no-pin: I don't care what version of the packages I get, I just need these packages to exist in my environment regardless of their version 2) >=: I don't care what version of the packages I get, I just need them to have a version equal or higher than X.Y.Z 3) ~=: I want to ensure that the packages installed will have a version compatible with my project but I don't want to completely freeze their versions(similar to your micro scheme). 4) ~=/minor: I want to ensure that the packages installed will have a version compatible with my project but I don't want to completely freeze their versions and I'm only worried about major version changes. 5) (default)==: I want to be able to replicate my exact setup and will completely freeze all package versions

What do you think?

mapattacker commented 3 years ago

@alan-barzilay thanks for the detailed explanation.

It makes sense, and also a good idea to consider PR #107.

As they sort of belong to the same family, should we lump them together as a single option like below? Do edit the wordings if I used any of them inappropriately.

Options:

    --dynamic <scheme>    Enables dynamic version install by <minor>, <micro>, <gt> or <non-pin> schemes.
                          <micro>  | e.g. Flask~=1.1.2 | install micro updates only
                          <minor>  | e.g. Flask~=1.1   | install minor updates only
                          <gt>     | e.g. Flask>=1.1.2 | install version greater or equals to stated
                          <no-pin> | e.g. Flask        | version not important, if not exist install the latest
alan-barzilay commented 3 years ago

I have a question for you @mapattacker, what is the use case that you envisioned for the minor scheme? After thinking about it I realized I never had the need for such a mode. To me it seems like an unlikely situation wanting to keep compatibility and also being able to ensure that only "major" versions can break compatibility given that each package has their own versioning policies. I would appreciate if you could help me understand the motivation behind this scheme.

As they sort of belong to the same family, should we lump them together as a single option like below?

Agreed! I edited a few things to make it more succinct and intuitive, let me know what you think :) (I skipped the minor scheme because I couldn't think of an intuitive/descriptive name for it, maybe something like weak or relaxed compatibility? )

Options:
      --mode <scheme>      Enables dynamic versioning with <compat>, <gt> or <non-pin> schemes. 
                           <compat> | e.g. Flask~=1.1.2 (equivalent to >=1.1.2,==1.1.*)
                           <gt>     | e.g. Flask>=1.1.2 
                           <no-pin> | e.g. Flask 
mapattacker commented 3 years ago

I have a question for you @mapattacker, what is the use case that you envisioned for the minor scheme? I would appreciate if you could help me understand the motivation behind this scheme.

@alan-barzilay That's a good question haha, our main goal for this PR is actually for the micro/compat scheme. I just thought there might be somebody who might value a minor scheme update for some reason. I guess till someone require it, then only it makes sense to include in. The code changes will be a lot simplified without that option too.

                       <compat> | e.g. Flask~=1.1.2 (equivalent to >=1.1.2,==1.1.*)

I think for this line, I feel we should remove >=1.1.2, as despite citing in PEP 440, it is still not exactly equivalent. E.g. if we put Flask>=1.1.2, pip will install the latest version, e.g. Flask 2.0.0 if the environment does not have an existing installation. There might also be some confusion of why having the "gt" option if this is equivalent. What do u think?

If the above are ok, me and @Jcch94 should be able to update the PR pretty soon.

alan-barzilay commented 3 years ago

Ok! Lets drop the minor scheme then and remove the "explanation" for the compat mode.

Options:
      --mode <scheme>      Enables dynamic versioning with <compat>, <gt> or <non-pin> schemes. 
                           <compat> | e.g. Flask~=1.1.2 
                           <gt>     | e.g. Flask>=1.1.2 
                           <no-pin> | e.g. Flask 
alan-barzilay commented 3 years ago

Feature implemented in PR#239