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

Add core.version_ranges:resolve_prereleases conf #13321

Merged
merged 17 commits into from
Mar 14, 2023

Conversation

AbrilRBS
Copy link
Member

@AbrilRBS AbrilRBS commented Mar 3, 2023

Changelog: Omit
Docs: Omit

Future changelog: Feature: Add core.version_ranges:resolve_prereleases conf to control whether version ranges can resolve to prerelease versions

I still have some questions regarding the implementation of the feature itself,
but this is now at a point where it makes sense to open the PR,
even though there are still places that need updating (And so tests are failing)

Specially I'd need to discuss if changing the VersionRange api is ok,
as this removes the __contains__ function in favour of a contains method,
to be able to pass it extra arguments, which can't be done with the in operator.

The logic for the conf is:

  • True: Always allows to resolve prerelease versions, whatever the expression says
  • False: Never allows prerelease versions to be resolved
  • None: Listens to whatever the the range expression says

The open questions are:

  • Is None the best default for an unspecified conf? My guess it that yes, but I better make sure
  • Is the current implementation even ok? I had a good look into how this could be done, and this seemed to me like the only viable alternative, but happy to hear otherwise.
  • Is there a better name for the conf?: A: Yes. core.version_ranges:resolve_prereleases (Was core.ranges_resolve_prereleases)

@AbrilRBS AbrilRBS requested a review from memsharded March 3, 2023 19:22
@AbrilRBS AbrilRBS marked this pull request as ready for review March 3, 2023 19:23
@AbrilRBS AbrilRBS marked this pull request as draft March 3, 2023 20:18
@AbrilRBS AbrilRBS changed the title Add core.ranges_resolve_prereleases conf WIP: Add core.ranges_resolve_prereleases conf Mar 3, 2023
@AbrilRBS AbrilRBS removed the request for review from memsharded March 3, 2023 20:34
Copy link
Member

@memsharded memsharded left a comment

Choose a reason for hiding this comment

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

I know it is not as clean, but a global class attribute VersionRange.accept_prereleases would simplify a lot the implementation and avoid having to propagate the parameter everywhere? Most likely better to do it right as you did, but seemed a bit painful to see so many changes to deliver 1 bit of information to the right place.

conans/client/graph/range_resolver.py Outdated Show resolved Hide resolved
@AbrilRBS AbrilRBS changed the title WIP: Add core.ranges_resolve_prereleases conf WIP: Add core.version_ranges:resolve_prereleases conf Mar 5, 2023
@AbrilRBS AbrilRBS assigned AbrilRBS and unassigned AbrilRBS Mar 6, 2023
@AbrilRBS AbrilRBS changed the title WIP: Add core.version_ranges:resolve_prereleases conf Add core.version_ranges:resolve_prereleases conf Mar 9, 2023
@AbrilRBS AbrilRBS marked this pull request as ready for review March 9, 2023 12:55
@memsharded memsharded added this to the 2.0.2 milestone Mar 10, 2023
@AbrilRBS
Copy link
Member Author

AbrilRBS commented Mar 10, 2023

Would be great to have an example in the docu telling the story for this feature (Or at the very least tests for CI!)

conans/client/graph/range_resolver.py Outdated Show resolved Hide resolved
@@ -96,9 +101,10 @@ def __init__(self, expression):
def __str__(self):
return self._expression

def __contains__(self, version):
def contains(self, version, conf_resolve_prerelease=None):
Copy link
Member

Choose a reason for hiding this comment

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

I'd say this default is not the safest, we might skip some version in range occurrence that needs the conf passed, and we are not passing it. I'd suggest dropping the =None default and having this forced, even if it needs changing more tests.

Copy link
Member Author

Choose a reason for hiding this comment

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

This already breaks the version in range syntax, so it would be failing because it wouldn't be able to find the __contains__ operator, but I understand your point, having so many defaults smells a bit :)

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, I meant that we had some if range.contains(version) without really providing the necessary conf there, which seems mandatory.

conans/model/version_range.py Outdated Show resolved Hide resolved
conans/model/graph_lock.py Outdated Show resolved Hide resolved
@@ -157,12 +160,12 @@ def _prepare_node(node, profile_host, profile_build, down_options):
node.conanfile.requires.tool_require(str(tool_require),
raise_if_duplicated=False)

def _initialize_requires(self, node, graph, graph_lock):
def _initialize_requires(self, node, graph, graph_lock, resolve_prereleases):
Copy link
Member

Choose a reason for hiding this comment

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

I think we might have another approach here:
if we define here for all requires we define that such a require allows pre-releases, and that is automatically passed to the VersionRange when requested via property, then the number of modifications necessary might be way less?

Just an idea, I am still not super happy with this PR, it is likely that if we remove the =None defaults, it would require even more changes.

@AbrilRBS AbrilRBS closed this Mar 14, 2023
@AbrilRBS AbrilRBS reopened this Mar 14, 2023
@AbrilRBS AbrilRBS closed this Mar 14, 2023
@AbrilRBS AbrilRBS reopened this Mar 14, 2023
assert not r.contains(Version(v), None)


@pytest.mark.parametrize("version_range, resolve_prereleases, versions_in, versions_out", [
Copy link
Member

Choose a reason for hiding this comment

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

Do you know that multiple pytest.mark.parametrize one on top of the other do the cartesian product? you can reduce these lines 3x with it.

@pytest.mark.parametrize("resolve_prereleases", [True, False, None])
@pytest.mark.parametrize("version_range, versions_in, versions_out", [

Copy link
Member

Choose a reason for hiding this comment

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

Furthermore, you can also factorize the version_range and versions_in/out, and it will be even shorter

conans/client/graph/graph_builder.py Show resolved Hide resolved
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

Successfully merging this pull request may close these issues.

2 participants