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

Transform / Normalize perl module versions to rpm-like versions #47

Open
perlpunk opened this issue Jul 21, 2023 · 2 comments
Open

Transform / Normalize perl module versions to rpm-like versions #47

perlpunk opened this issue Jul 21, 2023 · 2 comments

Comments

@perlpunk
Copy link
Collaborator

perlpunk commented Jul 21, 2023

Motivation

Perl modules usually have decimal versions. We just take the version from the module literally and put it into the rpm spec file. That can lead to wrong behaviour. New releases suddenly have lower versions (if you ask rpm); Requires: lines can lead to the wrong result.

For details see below.

I now decided to give that problem another shot.

Migration plan

My idea was to collect all module versions in d:l:p at a given time, and save
that in a file in the cpanpec distribution. Let's call it "dlp.tsv". That
file would never change.

Everyone generating a spec file for a perl module in d:l:p must then use
this file when calling cpanspec.

cpanspec will use an algorithm which you can see in the following gist
in next-version.pl:

https://gist.github.com/perlpunk/9a40bfde89e55685f6358dfb76fc3961

e.g.

perl next-version.pl perl-YAML-PP 0.037
new version: 0.37.0
perl next-version.pl perl-YAML-PP 0.035
new version: 0.035

So for all versions that are lower or equal to the saved version, we use the
old format which we directly get from CPAN.
For versions newer than the saved one we normalize it to an rpm version.
Only for versions that currently have more than 3 decimals it gets a bit more
complicated, e.g. 1.2023. For those we keep the old format until the major
version eventually increases. Otherwise the next version would be 1.202.4, which
would falsely be lower.

I will prepare cpanspec for this and would cleanup devel:languages:perl:autoupdate
at some point and generate the dlp.tsv, and release a new cpanspec version.

Now it would be cool if some of you have time to take a look at the code,
maybe play with it and see if it makes sense.
We would have to keep that tsv file practically forever, but hopefully never
have to deal with manually fiddling with modules that changed the number
of decimals.

Background

Perl versions work differently than rpm versions.

In Perl, a version is simply a decimal number. Examples of versions
and how they would (and should) be consistently translated as rpm versions:
(You can do that with version->parse($cpan_version)->normal)

3.14    -> 3.140.0
3.140   -> 3.140.0
3.014   -> 3.14.0
3.001   -> 3.1.0
3.14159 -> 3.141.590

What we currently do when generating a spec file with cpanspec: We just take
the CPAN version literally. So this is what we put into the spec file, and on
the right side you see how rpm understands the version:

3.14    -> 3.14.0
3.140   -> 3.140.0
3.014   -> 3.14.0
3.001   -> 3.1.0
3.14159 -> 3.14159.0

One typical situation is, the current version of a module is 3.19, and the next
version is then 3.2, because mathematically, that's perfectly correct.

rpm reads that as 3.19.0 and 3.2.0, so the new version would be lower.

Another module having Requires: Foo > 3.19 would now be unresolvable.

Until now, we just manually added a zero, e.g. 3.2 -> 3.20, to make it work,
and in the next version the module would use two decimals again anyway.
But that's not always the case. For some modules, we added hardcoded (!)
eceptions into the cpanspec script.

Now, if we correctly translate the versions, 3.19 would become 3.190.0, and 3.2
would become 3.200.0.

As in my plan, only new versions starting with a specific date would be
translated into the correct format, existing requirements would
still work, e.g. the existing Requires: Foo > 3.19 would stay like that
to ensure that requirements would be satisfied for repositories where the
newer version 3.200.0 has not yet landed.

This process should work for all versions having up to 3 decimals.
This is the majority in d:l:p, currently 2702 modules.

For modules having more than 3 decimals, like 3.14159, the translation would
make newer versions lower, so we have to keep the old decimal format. Until the
module eventually increases its major version. We have currently 316 modules
in this category.

Then we have 20 modules that use integers. We can think about just
leaving them as they are, because they can't be misinterpreted. A typical
example: Perl::Tidy: 20230309
And then we have 125 modules that are already using versions with more than one
dot, so we can just normalize them (e.g. 3.014.015 -> 3.14.15). They might
have been using decimal versions in the past, so for older versions we will
do the same as for all other modules - use the given CPAN version format.

It is a bit of work, but if I'm correct we don't have to intervene manually
when a module changes its amount of decimals.

@perlpunk
Copy link
Collaborator Author

I'm currently preparing a new cpanspec version that takes
a new commandline parameter --dlp, which will then load the
shared file version-snapshot/opensuse-dlp.tsv (either from the git
checkout or from /usr/share/cpanspec).
My data munging I'm currently doing in this branch:
https://github.com/perlpunk/cpanspec/tree/version-fun
This includes exports of 02packages.details.txt from CPAN and using it to determine
all current module versions in dlp.

When this is active, every submission/update for devel:languages:perl
should use the --dlp switch.
I'm also thinking about adding a general option --versionformat (rpm|cpan)
for people using cpanspec outside of dlp.

Here's the updated cpanspec using the new --dlp switch: https://build.opensuse.org/package/show/home:tinita:branches:devel:languages:perl/cpanspec

@perlpunk
Copy link
Collaborator Author

I made some submit requests from https://build.opensuse.org/project/show/devel:languages:perl:autoupdate today, but there are a few hopefully simple problems to be solved.

  • I need to add also core perl modules to the version snapshot file
  • detection of packages inside a module (implemented in cpanspec with PPI) seems to find more than perl.prov; need to check
  • ...

perlpunk added a commit to perlpunk/cpanspec that referenced this issue Jul 25, 2023
perlpunk added a commit to perlpunk/rpm that referenced this issue Jul 26, 2023
Perl module ersions are decimal versions, and semantically split in triplets.

    CPAN       --> Normalized, semantical meaning from perl's point of view
    0.7        --> 0.700.0
    0.71       --> 0.71.0
    0.70       --> 0.70.0
    0.07       --> 0.70.0
    0.007      --> 0.7.0
    1.20230726 --> 1.202.307.260

Currently, perl.prov takes the module versions literally, which
can lead to false / broken dependencies if the number
of decimals for a module version changes.
E.g. a very common thing is a module with the current version
1.29 (which is semantically 1.290.0) that releases 1.3 (1.300.0) as the
next version.
Taking the 1.29 and 1.3 literally in the rpm, 1.3 would be lower than
1.29.

We usually fix that manually, but we have 3200 perl modules
in devel:languages:perl and 1400 in Factory.

The correct way would be to use

    version->parse($cpan_version)->normal

However, we can't just fix the existing perl.prov because we cannot
guarantee that all packages will be rebuilt at once across all
repositories.  There needs to be a transition period also.

Also other users of rpm maybe don't want that new behaviour.

So I created a new script besides perl.prov, perl.prov.normalize
It would be good if I could actually reuse most og it's code, maybe
evan simply call perl.prov and then manipulate the output.

But for this frst draft I wanted to get your feedback if such a PR is
welcome or if it should be done in a new package outside of rpm.

I could then use this script in the spec files of new perl module
releases. Until then there will be a transition period where
I might generate Provides lines in the spec file additionally to
the current perl.prov, which would guarantee that we don't get
unresolvables.

For the detailed background see: openSUSE/cpanspec#47
cpanspec is the script which we use to generate the spec files.
perlpunk added a commit to perlpunk/rpm that referenced this issue Jul 26, 2023
Perl module ersions are decimal versions, and semantically split in triplets.

    CPAN       --> Normalized, semantical meaning from perl's point of view
    0.7        --> 0.700.0
    0.71       --> 0.71.0
    0.70       --> 0.70.0
    0.07       --> 0.70.0
    0.007      --> 0.7.0
    1.20230726 --> 1.202.307.260

Currently, perl.prov takes the module versions literally, which
can lead to false / broken dependencies if the number
of decimals for a module version changes.
E.g. a very common thing is a module with the current version
1.29 (which is semantically 1.290.0) that releases 1.3 (1.300.0) as the
next version.
Taking the 1.29 and 1.3 literally in the rpm, 1.3 would be lower than
1.29.

We usually fix that manually, but we have 3200 perl modules
in devel:languages:perl and 1400 in Factory.

The correct way would be to use

    version->parse($cpan_version)->normal

However, we can't just fix the existing perl.prov because we cannot
guarantee that all packages will be rebuilt at once across all
repositories.  There needs to be a transition period also.

Also other users of rpm maybe don't want that new behaviour.

So I created a new script besides perl.prov, perl.prov.normalize
It would be good if I could actually reuse most og it's code, maybe
evan simply call perl.prov and then manipulate the output.

But for this frst draft I wanted to get your feedback if such a PR is
welcome or if it should be done in a new package outside of rpm.

I could then use this script in the spec files of new perl module
releases. Until then there will be a transition period where
I might generate Provides lines in the spec file additionally to
the current perl.prov, which would guarantee that we don't get
unresolvables.

For the detailed background see: openSUSE/cpanspec#47
cpanspec is the script which we use to generate the spec files.
perlpunk added a commit to perlpunk/rpm that referenced this issue Jul 26, 2023
Perl module versions are decimal versions, and semantically split in triplets.

    CPAN       --> Normalized, semantical meaning from perl's point of view
    0.7        --> 0.700.0
    0.71       --> 0.71.0
    0.70       --> 0.70.0
    0.07       --> 0.70.0
    0.007      --> 0.7.0
    1.20230726 --> 1.202.307.260

Currently, perl.prov takes the module versions literally, which
can lead to false / broken dependencies if the number
of decimals for a module version changes.
E.g. a very common thing is a module with the current version
1.29 (which is semantically 1.290.0) that releases 1.3 (1.300.0) as the
next version.
Taking the 1.29 and 1.3 literally in the rpm, 1.3 would be lower than
1.29.

We usually fix that manually, but we have 3200 perl modules
in devel:languages:perl and 1400 in Factory.

The correct way would be to use

    version->parse($cpan_version)->normal

However, we can't just fix the existing perl.prov because we cannot
guarantee that all packages will be rebuilt at once across all
repositories.  There needs to be a transition period also.

Also other users of rpm maybe don't want that new behaviour.

So I created a new script besides perl.prov, perl.prov.normalize
It would be good if I could actually reuse most og it's code, maybe
evan simply call perl.prov and then manipulate the output.

But for this frst draft I wanted to get your feedback if such a PR is
welcome or if it should be done in a new package outside of rpm.

I could then use this script in the spec files of new perl module
releases. Until then there will be a transition period where
I might generate Provides lines in the spec file additionally to
the current perl.prov, which would guarantee that we don't get
unresolvables.

For the detailed background see: openSUSE/cpanspec#47
cpanspec is the script which we use to generate the spec files.
perlpunk added a commit to perlpunk/rpm that referenced this issue Jul 26, 2023
Background

I'm the current maintainer of  https://github.com/openSUSE/cpanspec and
I do automatic updates to devel:languages:perl with it.

Perl module versions are decimal versions, and semantically split in triplets.

    CPAN       --> Normalized, semantical meaning from perl's point of view
    0.7        --> 0.700.0
    0.71       --> 0.71.0
    0.70       --> 0.70.0
    0.07       --> 0.70.0
    0.007      --> 0.7.0
    1.20230726 --> 1.202.307.260

Currently, perl.prov takes the module versions literally, which
can lead to false / broken dependencies if the number
of decimals for a module version changes.
E.g. a very common thing is a module with the current version
1.29 (which is semantically 1.290.0) that releases 1.3 (1.300.0) as the
next version.
Taking the 1.29 and 1.3 literally in the rpm, 1.3 would be lower than
1.29.

We usually fix that manually, but we have 3200 perl modules
in devel:languages:perl and 1400 in Factory.

The correct way would be to use

    version->parse($cpan_version)->normal

However, we can't just fix the existing perl.prov because we cannot
guarantee that all packages will be rebuilt at once across all
repositories. There needs to be a transition period also.

Also other users of rpm maybe don't want that new behaviour.

Proposal

So I created a new script besides `perl.prov`, `perl.prov.normalize`.

It would be good if I could actually reuse most of it's code, maybe
even simply call `perl.prov` and then manipulate the output.

But for this frst draft I wanted to get your feedback if such a PR is
welcome or if it should be done in a new package outside of rpm.

I could then use this script in the spec files of new perl module
releases. Until then there will be a transition period where
I might generate Provides lines in the spec file additionally to
the current perl.prov, which would guarantee that we don't get
unresolvables.

For the detailed background see: openSUSE/cpanspec#47
cpanspec is the script which we use to generate the spec files.
@perlpunk perlpunk changed the title Transform perl module versions to rpm-like versions Transform / Normalize perl module versions to rpm-like versions Jul 27, 2023
bmwiedemann pushed a commit to bmwiedemann/openSUSE that referenced this issue Aug 12, 2023
https://build.opensuse.org/request/show/1103547
by user tinita + dimstar_suse
- new version format, see openSUSE/cpanspec#47
- updated to 2.01
   see /usr/share/doc/packages/perl-File-Rename/Changes
- Update change-command-name.patch
perlpunk added a commit to perlpunk/cpanspec that referenced this issue Mar 7, 2024
perlpunk added a commit to perlpunk/cpanspec that referenced this issue Jul 14, 2024
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

1 participant