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
Install a list of system packages #7779
Install a list of system packages #7779
Conversation
Support different packages to be installed by a single list Signed-off-by: Uilian Ries <uilianries@gmail.com>
6cfaed7
to
05befc0
Compare
Hey, why pr-merge didn't restart? |
Probably an issue with the Ci regarding the log. cc/ @czoido |
Signed-off-by: Uilian Ries <uilianries@gmail.com>
…ix/spt-install-list
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 problem with this is that it implements the functionality correctly, but it would probably not solve the underlying issue. I expect that many users will still do the install(["nano vim emacs"])
, and will not read the documentation deeply enough to realize there is an opt-in all=True
argument they need to pass if they want all packages installed.
The only way to achieve this is breaking the contract. We could do it gradually, and propose something like a new install_packages
method, that will try to install all of them, and if some want to propose variants, it could do in a nested tuple or list. Or any other new interface, while we deprecate the old one.
I am approving, but will ask for further reviews.
The SystemPackageTool
IMHO is a monster which probably needs a whole refactor.
The extra line in the docs is quite unfortunate so we cannot change without breaking besides that, the examples in the docs are not taking advantage of that feature, and the PR in CCI is not using it either: I agree it is more expected to install all the packages from the list than to return as soon as one of them is installed. I'm trying to think about a different implementation, but I cannot figure out how not to break existing behavior (yes, I'm not a big fan of adding extra arguments). If we were 100% sure we will have def system_requirements(self):
spt = SystemPackageTools(v2_behavior=True) # CONAN_V2_MODE activates it by default
spt.install('pkg_a') # <-- installs the only one package
# Breaking change activated by the `v2_behavior=True`)
spt.install(['pkg_a', 'pkg_b', 'pkg_c']) # <-- installs three different packages (this would be the new CONAN_V2 behavior)
# Using a list of lists: If a list of alternatives is provided, Conan installs only one from each group
spt.install([('pkg_a-alt1', 'pkg_a-alt2'), 'pkg_b', 'pkg_c' ]) # <-- installs one package from each group
spt.install([('pkg_a-alt1', 'pkg_a-alt2'), ]) # <-- installs one package from each group IMHO it is more natural: every entry in the list installs one package, if alternatives are given for entry only one of them is installed. I'm not asking for these changes, just proposing the alternative and, if we agree with it, then we can change the PR. |
Yes, I also like the syntax: spt.install([('pkg_a-alt1', 'pkg_a-alt2'), 'pkg_b', 'pkg_c' ]) But I wouldn't like to have the flag explicit here: spt = SystemPackageTools()
spt.install_pkgs(("alt1", "alt2", "alt3"), "pkg2", "pkg3") # or install_system... There is a chance if we replace the whole |
Adding an explicit flag or adding a dedicated method is more or less the same (IMHO it's more explicit the flag than the method, unless we find a name other than Whatever is used it is ok for me, I'll review again when the PR is updated. |
I was thinking of a new method name that can remain forever, so it is only necessary to change it once, before Conan 2.0, but no necessary to deprecate again and move back after 2.0. |
I vote for the new method name. Why? When reading the documentation, method are empathized, using bold color, but for parameters you have to read to find any detail, so anyone who reads the docs, will find the new method name easily. For Conan 2.0, we can break and use only one method, the tuple for variants seems be more correct. |
Signed-off-by: Uilian Ries <uilianries@gmail.com>
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.
If we go for a new method, I prefer the suggested install_pkgs
over install_all
. Taking into account that the method will last forever and it will be the only method in Conan 2.0 I feel like the suffix _all
is a bit unexpected. wdyt?
I agree, but I prefer the full name |
Co-authored-by: Javier G. Sogo <jgsogo@gmail.com>
Signed-off-by: Uilian Ries <uilianries@gmail.com>
conans/client/tools/system_pm.py
Outdated
@@ -91,10 +91,10 @@ def update(self): | |||
self._is_up_to_date = True | |||
self._tool.update() | |||
|
|||
def install(self, packages, update=True, force=False, arch_names=None): | |||
""" Get the system package tool install command. | |||
def install(self, packages, update=True, force=False, arch_names=None, all=False): |
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 all
argument is not used anymore?
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.
Agree with the previous comments, add a new test for the (2).
Signed-off-by: Uilian Ries <uilianries@gmail.com>
This new commit is able to support (1) (2) (3) options:
I still use a different when installing multiple packages, because it is faster install all packages at once. |
conans/client/tools/system_pm.py
Outdated
:return: None | ||
""" | ||
packages = [packages] if isinstance(packages, str) else list(packages) | ||
variants = list(filter(lambda x: isinstance(x, tuple), packages)) |
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 we want to consider here a list
too?
package_install([['pkg1-var1', 'pkg1-var2'], 'pkg2'])
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.
That's a good question. I think only tuple keep more explicit, but on the other hand, people need to read to documentation to understand that only tuple is allowed. I think accepting list should not be a problem, I'll update it.
conans/client/tools/system_pm.py
Outdated
["pkg-variant1", "otherpkg", "thirdpkg"] # (2) List of strings: all must be installed | ||
[("pkg-variant1", "pkg-variant2"), "otherpkg", "thirdpkg"] # (3) List with alternatives | ||
|
||
:param packages: String/List/Tuple with all packages to be installed e.g. "libusb-dev libfoobar-dev" |
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.
If we are accepting the syntax install_packages("pkg1 pkg2")
, please add it to the docstring.
But, IMHO, we should avoid that syntax because it can be confusing: what does it mean?
- will it install
pkg1
andpkg2
or just one of them? - what if I use
install_packages(["pkg1 pkg2", "pkg3 pkg4"])
?
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.
If we are accepting the syntax install_packages("pkg1 pkg2"), please add it to the docstring.
Sure, indeed the docstring is outdated since the last commit.
what if I use install_packages(["pkg1 pkg2", "pkg3 pkg4"])?
I would like to avoid it, but is totally valid for the current behavior, it will install all packages.
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.
All packages? pkg1, pkg2, pkg3 and pkg4? It doesn't match the expectations when you use a list of tuples...
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.
install_packages(["pkg1 pkg2", "pkg3 pkg4"])
will install all packages pkg1, pkg2, pkg3 and pkg4, yes. Variants should be a nested list or a tuple in a list, like:
install_packages([["pkg1 pkg2"], "pkg3 pkg4"])
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.
IMHO, it is very confusing if install_packages(["pkg1 pkg2", "pkg3 pkg4"])
installs all packages, but install_packages([("pkg1", "pkg2"), ("pkg3", "pkg4")])
install only some of them. I'd totally forbid (raise) the syntax with blank-separated packages (pkg1 pkg2
).
...but this is my point of view, what do other reviewers think about it? cc/ @memsharded
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 agree with @jgsogo
Space separated list introduce another way to do the same thing, but the semantics are now not clear and difficult to dissambiguate. I think it is better to have the following logic:
- Each argument could be either a string, or a list/tuple.
- If a string, that is a package name to install
- If a list/tuple, that is a set of alternatives, install the first successful one.
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.
If a string, that is a package name to install
Considering the previous case, it's a string and contains more than one package. It's totally valid for install(), it will install a variant, but only because install() only installs variants, not all packages. I'll update to set is as invalid, but it won't follow the same design as did for install().
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.
Done, now ["foo bar"] and "foo bar" are considered invalid. Actually doesn't matter if you pass a string or list, it's convert to a list at the first step.
Co-authored-by: Javier G. Sogo <jgsogo@gmail.com>
Signed-off-by: Uilian Ries <uilianries@gmail.com>
Signed-off-by: Uilian Ries <uilianries@gmail.com>
New change: Why? It's the natural behavior when installing packages when we don't force. Also, it's faster, as the system don't need to process and print "package xyz already installed". |
Signed-off-by: Uilian Ries <uilianries@gmail.com>
Signed-off-by: Uilian Ries <uilianries@gmail.com>
Signed-off-by: Uilian Ries <uilianries@gmail.com>
… into hotfix/spt-install-list Signed-off-by: Uilian Ries <uilianries@gmail.com>
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.
Looking good. Let's finish this feature and then we can refactor this class a little bit
Signed-off-by: Uilian Ries <uilianries@gmail.com>
One approval! Maybe it will be merged before US election ending! |
Support a list of package to be installed by SystemPackageTools. The current behavior only supports a single package, or its variants by a list. However, most system package managers accept a list of different names e.g.
apt install vim nano emacs
Changelog: Feature: System package tools can install a list of different packages.
Docs: conan-io/docs#1937
fixes #6961
fixes #6960
develop
branch, documenting this one.Note: By default this PR will skip the slower tests and will use a limited set of python versions. Check here how to increase the testing level by writing some tags in the current PR body text.