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

feat: PVP Version implementation for the Stack build tool (Haskell) #13224

Closed
wants to merge 25 commits into from

Conversation

psilospore
Copy link

@psilospore psilospore commented Dec 21, 2021

Updates

  • I asked for clarifications on handling ranges on the renovate slack however I believe @rarkins is on vacation so this might be paused for a while.

Changes:

  • Added a pvp implementation in lib/versioning/

Context:

This adds a PVP implementation that can be used to integrate Stack support for Renovate.
@rarkins suggested approaching the implementation in 4 parts.
See this issue: #8187

Caribou uses Renovate and it's been great for our typescript repos, and it's been great. So thanks for creating this product! We would love to have support for our Haskell repos, and it would be great for the Haskell community in general.

TODOs

In the original issue they mention we only need to handle specific versions and not ranges, and that would also make the implementation easier. However, given that we were unsure how to implement some of the range-related functions.

How would do we run the tests?
I attempted npm run test but I get the following error:

> [email protected] git-check /Users/psilospore/develop/renovate
> node tools/check-git-version.mjs

(node:47255) ExperimentalWarning: The ESM module loader is experimental.
ERROR: Minimum Git version 2.33.0 is required
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] git-check: `node tools/check-git-version.mjs`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the [email protected] git-check script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/psilospore/.npm/_logs/2021-12-21T21_54_31_380Z-debug.log
ERROR: "git-check" exited with 1.

Documentation (please check one with an [x])

  • I have updated the documentation, or
  • No documentation update is required
  • I'm not sure if I need to update documentation yet until we've done the rest of the parts

How I've tested my work (please tick one)

I have verified these changes via:

  • Code inspection only, or
  • Newly added/modified unit tests, or
  • No unit tests but ran on a real repository, or
  • Both unit tests + ran on a real repository

psilospore and others added 2 commits December 21, 2021 16:54
@CLAassistant
Copy link

CLAassistant commented Dec 21, 2021

CLA assistant check
All committers have signed the CLA.

@viceice
Copy link
Member

viceice commented Dec 21, 2021

Your git version is outdated, you need to update or use one of our docker images to run tests

export const supportsRanges = true;

// https://pvp.haskell.org/#version-numbers
type PVP = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should use our generic versioning class as base for this, as it will provide most of your implemention.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, thanks for reviewing! Could you point out the generic versioning class? When I look at the other implementations I don't see any of them using a generic versioning class.

Ruby for instance takes a similar approach:

interface RubyVersion {
  major: number;
  minor: number;
  patch: number;
  prerelease: string[] | null;
}

Other ones seem to use the npm implementation if they use semver or pep440.

helm:

export const api: VersioningApi = {
  ...npm,
}

rez:

function getMajor(version: string): number {
  try {
    return npm.getMajor(padZeroes(version));
  } catch (err) /* istanbul ignore next */ {
    return pep440.getMajor(version);
}

Note those other implementations would be incompatible with PVP.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, this:

export abstract class GenericVersioningApi<

the stuff before is obsolete and will be removed soon

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for pointing that out. I'll try to refactor with that class now. That file also seems to calify our questions on ranges:

// since this file was meant for no range support, a range = version
// parse should return null if version not valid
// parse should return an object with property release, an array of version sections major.minor.patch

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have updated my PR to use the Generic versioning class now.

@psilospore psilospore changed the title feat: PVP implementation for the Stack build tool (Haskell) feat: PVP Version implementation for the Stack build tool (Haskell) Jan 20, 2022
lib/versioning/pvp/index.ts Outdated Show resolved Hide resolved
lib/versioning/pvp/index.ts Outdated Show resolved Hide resolved
lib/versioning/pvp/index.ts Outdated Show resolved Hide resolved
lib/versioning/pvp/index.ts Show resolved Hide resolved
lib/versioning/api.ts Outdated Show resolved Hide resolved
lib/versioning/pvp/readme.md Outdated Show resolved Hide resolved
Comment on lines 9 to 10
The one unusual difference between PVP and semver is that there are 2 major versions, and that
there could be additional version numbers past patch.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The one unusual difference between PVP and semver is that there are 2 major versions, and that
there could be additional version numbers past patch.
The one unusual difference between PVP and SemVer is that there are two major versions, and that there could be additional version numbers past _patch_.

This should go on one line (one sentence per line pattern).
SemVer is a specific term/name, so should be capitalized. 😉

Are you sure you that patch is the correct term? According to the Haskell Package Versioning Policy, c is called minor.

Copy link
Author

@psilospore psilospore Jan 26, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SemVer is a specific term/name, so should be capitalized. 😉

Sorry I have terrible grammar. Thanks for the suggestions!

Are you sure you that patch is the correct term? According to the Haskell Package Versioning Policy, c is called minor.

I've updated the instructions. Let me know if that's better.

lib/versioning/pvp/readme.md Outdated Show resolved Hide resolved
lib/versioning/pvp/readme.md Outdated Show resolved Hide resolved
lib/versioning/pvp/readme.md Outdated Show resolved Hide resolved
@psilospore psilospore marked this pull request as ready for review February 10, 2022 00:17
lib/versioning/pvp/index.spec.ts Outdated Show resolved Hide resolved
${'3.0.0.beta'} | ${false}
${'5.1.2-+'} | ${false}
`('isVersion("$input") === $expected', ({ input, expected }) => {
const res = !!pvp.isVersion(input);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

☝️

lib/versioning/pvp/index.ts Outdated Show resolved Hide resolved
lib/versioning/pvp/index.ts Outdated Show resolved Hide resolved

/**
* Compare similar to GenericVersioningApi._compare implementation
* except 2.1.1.0 and 2.1.1 are not equivalent instead 2.1.1.0 > 2.1.1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this now fixed in base class, so we can remove this overload?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

☝️

Copy link
Collaborator

@HonkingGoose HonkingGoose left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can probably use h2's here, this also creates "anchors/links", that you can use to link to a specific section of this document.

lib/versioning/pvp/readme.md Outdated Show resolved Hide resolved
lib/versioning/pvp/readme.md Outdated Show resolved Hide resolved
lib/versioning/pvp/readme.md Outdated Show resolved Hide resolved
Quotes from the [Haskell PVP Specification](https://pvp.haskell.org/):

> A package version number **SHOULD** have the form A.B.C, and **MAY** optionally have any number of additional components, for example 2.1.0.4 (in this case, A=2, B=1, C=0).
> A.B is known as the _major_ version number, and C the _minor_ version number.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
> A.B is known as the _major_ version number, and C the _minor_ version number.
> A.B is known as the _major_ version number, and C the _minor_ version number.

These are separate quotes in the upstream docs, so we should put a newline between them.

> A package version number **SHOULD** have the form A.B.C, and **MAY** optionally have any number of additional components, for example 2.1.0.4 (in this case, A=2, B=1, C=0).
> A.B is known as the _major_ version number, and C the _minor_ version number.

The one unusual difference between PVP and SemVer is that there are two major versions, and that there can be an optional number of additional version numbers past _minor_.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The one unusual difference between PVP and SemVer is that there are two major versions, and that there can be an optional number of additional version numbers past _minor_.
The main differences between PVP and SemVer:
- PVP allows _two_ major versions
- PVP allows an optional number of extra version numbers past _minor_

> A.B is known as the _major_ version number, and C the _minor_ version number.

The one unusual difference between PVP and SemVer is that there are two major versions, and that there can be an optional number of additional version numbers past _minor_.
For example `1.2.3` (note there's no _patch_ version here), `1.2.3.4` (`4` is the _patch_ version), or `1.2.3.4.5.6.7` are all valid version numbers.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
For example `1.2.3` (note there's no _patch_ version here), `1.2.3.4` (`4` is the _patch_ version), or `1.2.3.4.5.6.7` are all valid version numbers.
| PVP version | Note |
| --- | --- |
| `1.2.3` | No _patch_ version |
| `1.2.3.4` | `4` is the _patch_ version |
| `1.2.3.4.5.6.7` | This is also a valid version |

We can try a table here. You'll need to run yarn prettier-fix after applying the suggestion because it's not formatted the way Prettier wants.


## Are ranges supported?

Currently this is not supported but you can have ranges.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The h2 asks: Are ranges supported?
And our answer is: this is not supported, but right after: but you can have ranges.

This is really confusing me. I think there's some kind of difference between Cabal and Stack?

## Are ranges supported?

Currently this is not supported but you can have ranges.
This implementation just supports updating extra-deps in the Stack build tool which does not support ranges.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
This implementation just supports updating extra-deps in the Stack build tool which does not support ranges.
Our implementation supports updating extra-deps in the Stack build tool which does not support ranges.

We can probably say "our implementation" and get rid of the word "just". 😉


Currently this is not supported but you can have ranges.
This implementation just supports updating extra-deps in the Stack build tool which does not support ranges.
If this is used for Cabal then it would be useful to support ranges.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sentence doesn't really explain if I can use ranges with Cabal or not currently?

@rarkins rarkins marked this pull request as draft March 25, 2022 10:23
${'renovatebot/renovate#main'} | ${false}
${'https://github.com/renovatebot/renovate.git'} | ${false}
`('isValid("$version") === $isValid', ({ version, isValid }) => {
const res = pvp.isValid(version);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please inline

${'3.0.0.beta'} | ${false}
${'5.1.2-+'} | ${false}
`('isVersion("$input") === $expected', ({ input, expected }) => {
const res = !!pvp.isVersion(input);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

☝️

return { release: [major, ...rest] };
}

override getMajor(version: string): number | null {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why you need to override this?


/**
* Compare similar to GenericVersioningApi._compare implementation
* except 2.1.1.0 and 2.1.1 are not equivalent instead 2.1.1.0 > 2.1.1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

☝️

@rarkins
Copy link
Collaborator

rarkins commented Oct 19, 2022

Closing due to staleness

@rarkins rarkins closed this Oct 19, 2022
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Nov 19, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants