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

Fixes issues with pip arguments being used when they shouldn't and not being used when they should #1583

Closed
wants to merge 4 commits into from
Closed
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 26 additions & 6 deletions src/octoprint/plugins/pluginmanager/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@
import os
import pkg_resources

class PipUsageTypes(object):
INSTALL = "install"
UNINSTALL = "uninstall"

class PluginManagerPlugin(octoprint.plugin.SimpleApiPlugin,
octoprint.plugin.TemplatePlugin,
octoprint.plugin.AssetPlugin,
Expand Down Expand Up @@ -265,15 +269,15 @@ def command_install(self, url=None, path=None, force=False, reinstall=None, depe
success_string = "Successfully installed"
failure_string = "Could not install"
try:
returncode, stdout, stderr = self._call_pip(pip_args)
returncode, stdout, stderr = self._call_pip(pip_args, PipUsageTypes.INSTALL)
except:
self._logger.exception("Could not install plugin from %s" % url)
return make_response("Could not install plugin from URL, see the log for more details", 500)
else:
if force:
pip_args += ["--ignore-installed", "--force-reinstall", "--no-deps"]
try:
returncode, stdout, stderr = self._call_pip(pip_args)
returncode, stdout, stderr = self._call_pip(pip_args, PipUsageTypes.INSTALL)
except:
self._logger.exception("Could not install plugin from %s" % url)
return make_response("Could not install plugin from URL, see the log for more details", 500)
Expand Down Expand Up @@ -384,7 +388,7 @@ def command_uninstall(self, plugin):

pip_args = ["uninstall", "--yes", origin]
try:
self._call_pip(pip_args)
self._call_pip(pip_args, PipUsageTypes.UNINSTALL)
except:
self._logger.exception(u"Could not uninstall plugin via pip")
return make_response("Could not uninstall plugin via pip, see the log for more details", 500)
Expand Down Expand Up @@ -474,16 +478,32 @@ def _send_result_notification(self, action, result):
notification.update(result)
self._plugin_manager.send_plugin_message(self._identifier, notification)

def _call_pip(self, args):
def _call_pip(self, args, pip_usage_type):
if self._pip_caller is None or not self._pip_caller.available:
raise RuntimeError(u"No pip available, can't operate".format(**locals()))

if "--process-dependency-links" in args:
self._log_message(u"Installation needs to process external dependencies, that might make it take a bit longer than usual depending on the pip version")

additional_args = self._settings.get(["pip_args"])
if additional_args:
args.append(additional_args)

Copy link
Member

Choose a reason for hiding this comment

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

Suggestion: The pip_usage_type is actually always the first argument we have in our args. Why not have a class property pip_inapplicable_arguments which is a dict, with the pip command as key and the inapplicable arguments list as value?

pip_inapplicable_arguments = dict(uninstall=["--user"])

Then, we can simplify that whole segment to

if additional_args is not None:
    inapplicable_arguments = self.__class__.pip_inapplicable_arguments.get(args[0], list())
    for inapplicable_argument in inapplicable_arguments:
        additional_args = re.sub("(^|\s)" + re.escape(inapplicable_argument) + "\\b", "", additional_args)
    if additional_args:
        args.append(additional_args)

That way, if the list has to be extended later, simply adjusting the contents of the dict will be enough.

if additional_args is not None:

inapplicable_arguments = []

if pip_usage_type == PipUsageTypes.INSTALL:
inapplicable_arguments += []

elif pip_usage_type == PipUsageTypes.UNINSTALL:
inapplicable_arguments += [
"--user"
]

for inapplicable_argument in inapplicable_arguments:
additional_args = re.sub("(^|\s)" + re.escape(inapplicable_argument) + "\\b", "", additional_args)

if additional_args:
args.append(additional_args)

return self._pip_caller.execute(*args)

Expand Down