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

Adds docs for plugin writers on declaring deps #3176

Merged
merged 1 commit into from Sep 19, 2022

Conversation

bmbouter
Copy link
Member

@bmbouter bmbouter commented Sep 7, 2022

closes #2997

@bmbouter
Copy link
Member Author

bmbouter commented Sep 7, 2022

@pulp/core I'm looking for two reviews for this docs PR. This is designed to be a general policy, so not just language and clarity, but on the recommendations too. Thanks!

``jsonschema<5.0`` - This is appropriate if ``jsonschema`` could release breaking changes in
``jsonschema`` 5.0 and you are compatible with 4.* and lower.

``jsonschema~=4.4`` - This would be appropriate if you have a known incompatibility with
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 should a void these, because dependabot will try to upgrade this to jsonschema~=5.0 once that is released. Instead jsonschema>=4.4,<5.0 will be upgraded to jsonschema>=4.4,<6.0 eventually, as far as i understand.

The greatest problem i see is that we never test that our lover bounds are (still) correct.

Copy link
Member Author

Choose a reason for hiding this comment

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

To make sure I understand, is the idea that I show the ~= example and then explain it should be avoided?

Copy link
Member

Choose a reason for hiding this comment

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

The first question is: Do we agree it should be avoided. If yes, then your question.

@ipanova ipanova self-requested a review September 8, 2022 13:34
``jsonschema<4.4`` *and* it's possible ``jsonschema`` could release breaking changes in
``jsonschema>=5.0``.

``jsonschema==4.4.0`` - This is a last resort and needs an exceptional reason to do so.
Copy link
Member

Choose a reason for hiding this comment

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

can we say that such declaration makes it very high probability it will create version conflicts with other plugins?i mean this is self explanatory but still..

Copy link
Member Author

Choose a reason for hiding this comment

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

I think calling it out as discouraged is my intention with the PR. I didn't write that, but after reading what I wrote that is what makes sense to me. Basically these types of dependency declarations is what this PR is all about.

Copy link
Member Author

Choose a reason for hiding this comment

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

@ipanova would you be ok w/ me pushing a revision like that?

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 am ok with that too

@ipanova
Copy link
Member

ipanova commented Sep 8, 2022

can you also add a paragraph about transitive vs explicit deps declaration - for example, python-gnupg might be currently pulled in by pulpcore but te plugin should explicitly define its dependency on python-gnupg

@mdellweg
Copy link
Member

mdellweg commented Sep 9, 2022

can you also add a paragraph about transitive vs explicit deps declaration - for example, python-gnupg might be currently pulled in by pulpcore but te plugin should explicitly define its dependency on python-gnupg

I'm not sure about this. At least we need some good guidance around this We currently have pulpcore and pulp_ansible pinning two different versions of aiofiles. I'd rather consider the availablility of aiofiles as being part of the plugin-api. But maybe we need to state the libraries that are. And at that point adding or removing one is a breaking change.

@bmbouter bmbouter force-pushed the add-version-range-docs branch 2 times, most recently from d65dd1a to 8a77e83 Compare September 9, 2022 14:08
uses Django directly, your plugin should declare its dependency on Django.

Why? To continue with the Django example... Django can introduce breaking changes with each
release, so if your plugin relies on pulpcore to declare the Django requirement, and then
Copy link
Member

Choose a reason for hiding this comment

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

The only problem i have is with this specific example you decided to take - Django is being used in pulpcore and plugin api. We have our policy and promise of not breaking our plugins with the plugin-api policy we have in place, coming back to what @mdellweg said in this comment #3176 (comment) - dependencies that are part of plugin api, in my opinion should not be explicitly declared in plugins. Plugin writers have the whole right to rely on our breaking changes policy.

Copy link
Member Author

Choose a reason for hiding this comment

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

Django isn't directly part of the plugin API though. Things get so much more complicated when we start to think that pulpcore is "delivering" the dependency tree. What motivation do we have for that?

Here's an example showing why I think that approach would be intractable. Say pulpcore uses library 'foo' and so does some plugin. foo comes out with a new version which could have breaking changes in it, but they don't affect pulpcore and the pulpcore CI says everything is fine so we increase the upper bound. Oh wait though, we've just broken the plugin which was affected by the breaking change in 'foo' yet that plugin didn't run as part of the CI testing the new version of 'foo'.

Now imagine ^ same story, only with 'bar' which is a dependency of 'foo', and some plugin happens to also use 'bar'. What I see in this is that no dep upgrade could ever be safely evaluated all the way down the dependency tree.

Copy link
Member

Choose a reason for hiding this comment

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

My main takeaway is that bumping the lower bound of a dependency is a breaking change, and new features that need such a change (we will probably never recognize this, making matters worse) can only be introduced in a breaking change release. The same goes for adding a new dependency. (Removing one is now absolutely fine.)

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes it's a breaking change, but semver allows breaking changes with bugfixes.

What can I do to improve (or merge) this PR?

Copy link
Member

Choose a reason for hiding this comment

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

I feel that the term "as broad a range [...] as possible" is dangerous. Can you add that extra care and awareness is needed to keep the lower bound of a dependency in sync with the features used from that library? And also that bumping the lower bound may break plugin compatibilities? We should at least recognize that there is danger.

BTW: Even when not importing from a library directly, a plugin may be faced to interact with its objects. So pulpcore adopting a new version can break plugins in any case. In the end we need to accept that the pulp plugin api is not an island.

Copy link
Member

Choose a reason for hiding this comment

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

I keep wondering, if this is the working and accepted way to do things in the python ecosystem, why do we even need to write a single line about it?

Copy link
Member Author

Choose a reason for hiding this comment

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

I keep wondering, if this is the working and accepted way to do things in the python ecosystem, why do we even need to write a single line about it?

It's the norm for Python software that operates as a "library" because those softwares are installed side-by-side a lot of other software it can't control. End-user python code though tends to be the only thing installed in an environment so there is really only one dependency tree. I believe we need clarification on this because Pulp had been operating as if it was the latter but really it's the former.

Copy link
Member Author

Choose a reason for hiding this comment

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

@mdellweg ty for the comment it outlines pretty clearly the two things I should add:

  • dependabot should handle the upper bound and plugin writers are enocuraged to use it
  • reasons for increasing the lower bound, e.g. usage of new features or bugfixes only available in newer versions

Let me add those and you can tell me what you think.

Copy link
Member Author

Choose a reason for hiding this comment

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

While working on the revisions I found this, which aligns I think what we're recommending pretty well too https://pip.pypa.io/en/latest/topics/dependency-resolution/#loosen-your-top-level-requirements

Copy link
Member

Choose a reason for hiding this comment

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

The big takeaway for me is: "Try to have less dependencies." aka: "Ask yourself if it is necessary to add another dependency!" Can we add something like that too?

@ipanova
Copy link
Member

ipanova commented Sep 9, 2022

can you also add a paragraph about transitive vs explicit deps declaration - for example, python-gnupg might be currently pulled in by pulpcore but te plugin should explicitly define its dependency on python-gnupg

I'm not sure about this. At least we need some good guidance around this We currently have pulpcore and pulp_ansible pinning two different versions of aiofiles. I'd rather consider the availablility of aiofiles as being part of the plugin-api. But maybe we need to state the libraries that are. And at that point adding or removing one is a breaking change.

That is ok as long as it's not done in a bugfix release.

Copy link
Member

@ipanova ipanova left a comment

Choose a reason for hiding this comment

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

based on what has been discussed at the pulpcore meeting this looks good to me, thank you for working on this!

Copy link
Member

@mdellweg mdellweg left a comment

Choose a reason for hiding this comment

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

Let's see how this works out. Also please consider adding a note about "having less dependencies" keeps you further from "dependency hell".

@bmbouter
Copy link
Member Author

I'm declining to add a part about having fewer dependencies since I believe if there's a dependency we should use it. This has downsides though so I also won't add a statement suggesting that either.

Thank you all for the engaging discussion and reviews!

@bmbouter bmbouter merged commit 3e6d68e into pulp:main Sep 19, 2022
@bmbouter bmbouter deleted the add-version-range-docs branch September 19, 2022 18:38
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.

Document how to declare dependencies to minimize install-time conflicts
3 participants