-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Check dbt-core version requirements when installing Hub packages #5651
Conversation
Thank you for your pull request! We could not find a changelog entry for this change. For details on how to document a change, see the contributing guide. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
core/dbt/exceptions.py
Outdated
" Requested range: {}\n" | ||
" Available versions: {}" | ||
" Compatible versions: {}\n" | ||
" (Not shown: versions incompatible with installed version of dbt-core)" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we recommend using the no-version-check flag here, like we do when a dbt project fails to run due to mismatching versions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good idea!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are two main cases in regards to pre-release versions of dbt-core:
- excluded, because it's not within the range specified in
require_dbt_version
. - included, because it is within the range specified in
require_dbt_version
.
It looks like the first case is covered in the tests, but I couldn't tell if the second case is covered or not. Could you shed light if both are covered or not?
core/dbt/deps/registry.py
Outdated
) | ||
available_latest = installable[-1] | ||
latest_compatible = installable[-1] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible for installable
to be empty?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good call! We should be sure to raise a good exception before we try to access an element. I'll rearrange the logic accordingly
core/dbt/exceptions.py
Outdated
"Could not find a matching compatible version for package {}\n" | ||
" Requested range: {}\n" | ||
" Available versions: {}" | ||
" Compatible versions: {}\n" | ||
" (Not shown: versions incompatible with installed version of dbt-core)" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very nice 🤩
def package(self, package_name, registry_base_url=None): | ||
try: | ||
pkg = self.packages[name] | ||
pkg = self.packages[package_name] | ||
except KeyError: | ||
return [] | ||
return list(pkg) | ||
return pkg |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice add, especially registry_base_url=None
.
Prereleases! A great callout. We're using the exact same As you note, it's possible for a pre-release version of
After both checks, if there are no compatible + desired versions remaining in |
It sounds like there are two different contexts to consider prereleases (which of course makes it harder for me to think clearly, 😅 ):
I'm curious if the following case is represented in the continuous integration testing or not:
AlsoSeparately (but related), do we have functional tests that cover all these relevant permutations?
This is 8 different permutations (if I'm doing the math correctly). Potentially, there are some permutations that are not relevant for some reason -- I didn't expand it out fully and consider each. |
@dbeatty10 You're right to push on this! There may very well be an edge case we're missing. There is definitely a distinction in this functionality between prerelease and final releases of dbt packages. That's already pretty well tested for. For the purposes of this functionality, I don't actually think there's any distinction between running with a prerelease versus final release of So for instance:
|
}) | ||
resolved = resolve_packages(package_config.packages, mock.MagicMock(project_name='test')) | ||
self.assertEqual(resolved[0].name, 'dbt-labs-test/a') | ||
self.assertEqual(resolved[0].version, '0.1.4a1') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤩
core/dbt/deps/registry.py
Outdated
installable = semver.filter_installable( | ||
available, self.install_prerelease or prerelease_version_specified | ||
compatible_versions, self.install_prerelease or prerelease_version_specified | ||
) | ||
available_latest = installable[-1] | ||
|
||
# for now, pick a version and then recurse. later on, | ||
# we'll probably want to traverse multiple options | ||
# so we can match packages. not going to make a difference | ||
# right now. | ||
target = semver.resolve_to_specific_version(range_, installable) | ||
if installable: | ||
# for now, pick a version and then recurse. later on, | ||
# we'll probably want to traverse multiple options | ||
# so we can match packages. not going to make a difference | ||
# right now. | ||
target = semver.resolve_to_specific_version(range_, installable) | ||
else: | ||
target = None | ||
if not target: | ||
package_version_not_found(self.package, range_, installable) | ||
package_version_not_found(self.package, range_, installable, should_version_check) | ||
latest_compatible = installable[-1] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I might be misreading this, but it looks like this will throw an error if installable
is empty or None
when it tries to get the last item via installable[-1]
.
Do we have a test case for when there are no installable versions available after the semver filter?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah! If installable
is None
or []
, then we'll set target = None
on line 146. That would cause us to raise the package_version_not_found
exception, rather than proceed to get the indexed element [-1]
.
Does that logic feel too tricky? Another way you'd want to express it, or an additional annotation?
Co-authored-by: Doug Beatty <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jtcohen6 Ready to rock 🎸
* First cut at checking version compat for hub pkgs * Account for field rename * Add changelog entry * Update error message * Fix unit test * PR feedback * Try fixing test * Edit exception msg * Expand unit test to include pkg prerelease * Update core/dbt/deps/registry.py Co-authored-by: Doug Beatty <[email protected]> Co-authored-by: Doug Beatty <[email protected]>
…-labs#5651) * First cut at checking version compat for hub pkgs * Account for field rename * Add changelog entry * Update error message * Fix unit test * PR feedback * Try fixing test * Edit exception msg * Expand unit test to include pkg prerelease * Update core/dbt/deps/registry.py Co-authored-by: Doug Beatty <[email protected]> Co-authored-by: Doug Beatty <[email protected]>
…-labs#5651) * First cut at checking version compat for hub pkgs * Account for field rename * Add changelog entry * Update error message * Fix unit test * PR feedback * Try fixing test * Edit exception msg * Expand unit test to include pkg prerelease * Update core/dbt/deps/registry.py Co-authored-by: Doug Beatty <[email protected]> Co-authored-by: Doug Beatty <[email protected]>
Resolves #5648
Depends on dbt-labs/hubcap#146
For testing, check out dbt-labs/hub.getdbt.com#1770
As mentioned in the Hubcap PR above, I'm reusing the existing (and always empty)This PR leverages a new API field added in the Hubcap PR above:works_with
field from the Hub API to represent the package'srequire-dbt-version
. I'm not sure it's an old field being used for something in very old versions ofdbt-core
.require_dbt_version
.Description
registry.get_available_versions
withregistry.get_compatible_versions
, which only returns package versions whoserequire-dbt-version
config is compatible with the currently installed version ofdbt-core
VERSION_CHECK
(e.g.dbt --no-version-check deps
), then dbt will not check for version compatibilityChecklist
I have opened an issue to add/update docs, ordocs changes are not required/relevant for this PRchangie new
to create a changelog entry