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
Feature/graph lock new #5035
Feature/graph lock new #5035
Conversation
Question: Is there a reason why the |
Added --json, and "lockfile folder" in help descriptions Regarding |
Having a look at this, just reading the commands and help messages (I suppose you have already talk about some of these things, but this is my first approach to the feature):
More on And, from my point of view, we shouldn't add commands to manipulate the graph into |
@@ -21,6 +21,7 @@ def __init__(self, proxy, range_resolver): | |||
self._check_updates = False | |||
self._update = False | |||
self._remote_name = None | |||
self.locked_versions = None |
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.
Having a look at the way you are using this locked_versions
attribute, I feel like it should be a context_manager
:
class ConanPythonRequire(object):
...
@contextmanagere
def lock_versions(self, versions_to_lock):
old_cache = self._cached_requires
try:
self._cache_requires.update( <data from versions_to_lock>)
return
catch:
finally:
self._cached_requires = old_cache
I think it will result in a cleaner implementation
self.cached_conanfiles[conanfile_path] = conanfile | ||
|
||
self._python_requires.locked_versions = None | ||
self.cached_conanfiles[conanfile_path] = (conanfile, lock_python_requires) |
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.
The conanfile
object already stores the python requires list/dict, conanfile.python_requires
. I know it makes a little bit more difficult the above getter, but we won't duplicate info.
return result | ||
|
||
|
||
class GraphLock(object): |
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.
Need to know the motivation for these classes.
I agree that we need to store the graph lock and have a memory representation of it, but here there are more things: we are at least duplicating business logic that was already available. If the plan is to substitute existing implementation, then I think it is worth considering a more standard representation of the graph so we can implement different algorithms on top of it.
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.
Need to keep things as much decoupled as possible. Premature engineering is evil, much better to have some duplication until behavior is much more stabilized, than refactoring and abstracting away too early.
This is not substituting anything, it is totally a new feature, not replacing or changing any existing functionality.
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.
So, the plan is to substitute the existing graph? Without entering into the details (and without having a look at how it is used) I see that both graphs have neighbours, closure, inverse levels,... and I'm assuming that they should have the same information, right? So, we are going to maintain both implementations during some releases.
It's ok, I just want to know. If this is going to be merged soon, I will need to add all the changes related to cross-building to this new graph too.
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.
No, this doesn't plan to substitute the existing dependency graph at all.
Yes, some concepts are very similar, indeed. Still the implementation is very different in the details and interfaces, so that is why better keep them decoupled.
Regarding cross-building, this should be totally transparent to it. This graph does not manage conanfiles or settings at all. It doesn't even model build_requires!
It is just some data that the other graph will use. I'd say this doesn't need any modification for the cross-building model.
graph_node = GraphLockNode(node.pref if node.ref else None, python_reqs, | ||
node.conanfile.options.values, False) | ||
self._nodes[node.id] = graph_node | ||
self._edges[node.id] = dependencies |
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.
Do not create the edge
if the dependency list dependencies
is empty.
Not true, export-pkg, info, test, they can generate locks too.
It was redundant with the
This is not the main use case we are trying to solve, lets focus on the main use case, which is implementing CI flows of whole products. Storing locks in packages is problematic, specially at this stage, because they will change for sure (and break if they are inside packages, outside, they can be migrated or re-generated without problems).
These commands look simple now, but for example, |
They can, but IMO they shouldn't, the same reason why they can generate the
From my point of view Conan should provide tools to help people "implement CI flows of whole products", but it shouldn't get mixed with a CI tool, this is also the point of my last paragraph. Also, it is easier to put new commands into a |
I don't think that is the discussion. Initially I don't want the So, about the conan createThe ìnstall-folder has been introduced in this branch. Note that the result of a Approach 1
Approach 2
conan installNote that the result of a Approach 1
Approach 2
conan infoWe need from conan info to generate a lock with the RREVs for the CI flows. Approach 1
Others? conan exportThe Approach 1
Question: Will the export lock something? conceptually the exported recipe could be locked but I don't think it is a real use case, right? conan export-pkgApproach 1
Same Question: Will the expor-pkg lock something? conceptually the exported package could be locked but I don't think it is a real use case, right? conan testThe Approach 1
Same Question: Will the test lock something? I don't think so |
WorkspacesCurrent behavior related to workspaces (current implementation):
IMO, the graphlock feature in the workspace world has two major applications:
Lock version rangesIt can we easily solved if we add all the editables to the root_list that is used to build the workspace. It is like overriding dependencies from the Packages depending on editablesThis is the other great use case of a graphlock outside the CI, but it is not implemented for workspaces yet: in a workspace I would like to be able to build a package locking the rest of the graph... the problem is that this graphlock has to take into account that some of the locked packages will be I think that the graphlock shouldn't be able to handle editable packages (also remember that these editables are temporary) or to store information related to the layout... somehow, by definition, editable packages are not packages themselves and might be hard to lock. In this first iteration, I would remove the graphlock related arguments from the Right now, I would leave any feedback regarding workspaces for the future. |
Changelog: (Feature | Fix | Bugfix): Describe here your pull request
Docs:
This PR provides the basic functionality for "lockfiles" in Conan, that allows to pin versions (when using version-ranges) and revisions (if using revisions).
The functionality can be summarized as:
graph_info.json
file (likeconan install <path>
), will generate also aconan.lock
file, that locks the graph dependencies versions and revisions. Nothing changes in the command line.--install-folder
argument to indicate where to ouput the resulting lockfiles. Some commands likeinstall
already have this by default, and other commands likecreate
have added this argument.--use-lock
to indicate the lockfile is to be used to pin dependencies. It is an opt-in feature. If--use-lock
is defined, the--install-folder
to indicate where the lockfiles are is necessary.--use-lock
argument is provided, version-ranges will not be evaluated, but resolved to the fixed one. Also, specific, pinned recipe and package revisions will be forcedThis is very experimental feature, expect it to fail in difficult and challenging graphs (like with multiple python-requires, or using complicated graphs of build-requires and private requires).
Testing and feedback very welcome.