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

Version specific URL overrides won't propagate to newer versions #8565

Merged
merged 2 commits into from
Jul 11, 2018

Conversation

alalazo
Copy link
Member

@alalazo alalazo commented Jun 25, 2018

fixes #2737

The issue with #2737 was due to the logic with which the nearest URL of a version was computed. This commit changes that logic, so that overrides are local to the versions declaring them.

A unit test has been added to avoid regressions on this issue.

@alalazo alalazo added bug Something isn't working versions labels Jun 25, 2018
return url
candidates = sorted([x for x in self.version_urls() if x >= version])

# If we don't have candidates, return the default. Here we let
Copy link
Contributor

Choose a reason for hiding this comment

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

maybe catch the error and emit a custom message? Not sure if this should be done here or in package.py though. But the end results ideally would be that the error message contains the version and package the url should have been computed for

Copy link
Member Author

Choose a reason for hiding this comment

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

Hmm, I would be more for maybe documenting that this function might raise an AttributeError. If need be we could catch it in url_for_version. Waiting for @tgamblin and @adamjstewart opinion on that.

Copy link
Member

Choose a reason for hiding this comment

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

I would make this consistent with the existing behavior of returning None and look into making the errors more consistent in another PR. There are places where Spack checks whether it can get a url from a package by looking for None and I don't remember if raising an error here will break anything.

Copy link
Member

@tgamblin tgamblin left a comment

Choose a reason for hiding this comment

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

Minor change requests for nearest_url

if version_urls[v]:
url = version_urls[v]
return url
candidates = sorted([x for x in self.version_urls() if x >= version])
Copy link
Member

Choose a reason for hiding this comment

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

No need for [] here.

We should probably make the self.versions dict an OrderedDict and guarantee that it's in order to begin with, so implementing versions_urls and nearest_url wouldn't require sorting at all. versions_urls should return an OrderedDict, so that its docstring is actually correct!

3. If there's no such a version return the default URL from
the package.

The idea of the algorithm is that the package-level URL should be
Copy link
Member

Choose a reason for hiding this comment

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

Just say "The package-level URL should be..." and omit "The idea of ..." :).

return url
candidates = sorted([x for x in self.version_urls() if x >= version])

# If we don't have candidates, return the default. Here we let
Copy link
Member

Choose a reason for hiding this comment

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

I would make this consistent with the existing behavior of returning None and look into making the errors more consistent in another PR. There are places where Spack checks whether it can get a url from a package by looking for None and I don't remember if raising an error here will break anything.

if not candidates:
return getattr(self.__class__, 'url')

return self.version_urls()[candidates[0]]
Copy link
Member

Choose a reason for hiding this comment

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

if you take my suggestion and make version_urls return a properly sorted OrderedDict, this whole function just becomes:

return next((url for v, url in reversed(self.version_urls().items()) if v >= version), None)

URL will be returned.

2. Otherwise return the URL associated with the closest higher
version.
Copy link
Member

Choose a reason for hiding this comment

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

I would like to avoid this behavior. It seems like this is the reverse of the current behavior, which is just as non-intuitive.

For a package like:

class UrlOverride(Package):
    homepage = 'http://www.doesnotexist.org'
    url      = 'http://www.doesnotexist.org/url_override-1.0.0.tar.gz'

    version('1.0.0', 'cxyzab')
    version('0.9.0', 'bcxyza', url='http://www.anothersite.org/uo-0.9.0.tgz')
    version('0.8.1', 'cxyzab')

I would expect that versions 0.8.1 and 1.0.0 would download from doesnotexist.org, while version 0.9.0 would download from anothersite.org.

If a package does change it's download site in newer releases, this is easy to support with a url_for_version function. In my mind, version-specific URL overrides are intended for a single one-off version, and that seems to be the case in the majority of packages that use them in Spack.

Copy link
Member Author

Choose a reason for hiding this comment

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

If a package does change it's download site in newer releases, this is easy to support with a url_for_version function.

To be fair it's easy to support also a one-off version... Usually I resort to url_for_version only when I need more flexibility for weird versioning schemes (e.g. where the version appear formatted in different ways across a single url). Anyhow, what you ask for shouldn't be difficult to implement. Waiting for confirmation on how to proceed..

Copy link
Member

Choose a reason for hiding this comment

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

I vote for @adamjstewart's suggestion

Copy link
Member

Choose a reason for hiding this comment

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

I believe this is also how git and hg arguments work. If you have a single version that downloads from git=..., the versions above and below this version aren't affected.

Copy link
Member Author

Choose a reason for hiding this comment

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

Ready for a second review. Implementing @adamjstewart's suggestion I could get rid completely of the function.

@alalazo
Copy link
Member Author

alalazo commented Jul 4, 2018

ping

@adamjstewart
Copy link
Member

Ping @tgamblin

@alalazo
Copy link
Member Author

alalazo commented Jul 10, 2018

@scheibelp ?

@scheibelp
Copy link
Member

I think it would have been worth stating in the PR description that this reverts intended behavior.

That being said, given that there are no tests for the original behavior, and since this doesn't appear to be mentioned in the documentation (e.g. http://spack.readthedocs.io/en/latest/packaging_guide.html#versions-and-fetching), I think it should be OK to make this change.

The other question is whether packages took advantage of the original behavior (e.g. hypre looks like it could have taken advantage but the way it is written now, it will not be affected by this change) - have you skimmed through packages to check if any would be broken by this?

I think it's fine if we miss something here and there (and I haven't found any problems skimming packages myself).

@adamjstewart
Copy link
Member

have you skimmed through packages to check if any would be broken by this?

I just took a look through the 94 packages with version-specific URLs. I didn't find a single package that relied on the previous behavior. I think we are safe to merge!

I did find 1 package (py-quantities) that currently does not fetch due to the bug reported in #2737 but will be fixed by this PR.

There are a few packages mentioned in #2737 that included extra URLs to hack things to work that could be removed now:

  • bwa
  • jellyfish
  • py-backports-functools-lru-cache
  • py-scipy
  • star

@scheibelp scheibelp dismissed tgamblin’s stale review July 10, 2018 21:32

Original review is stale since a new approach has been taken (#8565 (comment))

def test_urls_for_versions(self):
# Checks that a version directive without a 'url' argument
# specified uses the default url, or one that is specific
# to the closest newer version found.
Copy link
Member

Choose a reason for hiding this comment

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

@alalazo The last part of this comment appears stale:

or one that is specific to the closest newer version found

It looks like the default url is always used if there is not a version-specific url.

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed.

fixes spack#2737

The issue with spack#2737 was due to the logic with which the nearest URL
of a version was computed. This commit changes that logic, so that
overrides propagate only to older versions and not to newer ones.

A unit test has been added to avoid regressions on this issue.
@alalazo alalazo force-pushed the features/url_override_mechanics branch from faf5184 to 36520f1 Compare July 11, 2018 11:35
@scheibelp scheibelp merged commit e3a556c into spack:develop Jul 11, 2018
@scheibelp
Copy link
Member

Thanks!

@alalazo alalazo deleted the features/url_override_mechanics branch July 11, 2018 20:18
muffgaga pushed a commit to electronicvisions/spack that referenced this pull request Sep 10, 2018
* Add url for version(1.1.0) due to missing spack#8565 and associated
  bugfixes

Change-Id: Ibd83e37b85dc66fe2891dd0901f3b580fbe3c8ad
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working versions
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Version-specific URL overrides package-specific URL of newer version
5 participants