You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by kl...@apache.org on 2017/05/29 12:42:46 UTC

[2/2] mesos git commit: Added Config class to manage the config file in the new Mesos CLI.

Added Config class to manage the config file in the new Mesos CLI.

This new class simplifies the management of the configuration file
given by the user; it loads the TOML file on initialization and
has one method for each element that the user can set.

This new class and its associated content is also passed to the
plugins at initialization so that they can read the user configuration
and use it.

Review: https://reviews.apache.org/r/59177/


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/8740ce8d
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/8740ce8d
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/8740ce8d

Branch: refs/heads/master
Commit: 8740ce8d3adc723162350f35b5508d811214ac7e
Parents: f6c2ee0
Author: Armand Grillet <ag...@mesosphere.io>
Authored: Mon May 29 05:12:33 2017 -0700
Committer: Kevin Klues <kl...@gmail.com>
Committed: Mon May 29 05:39:10 2017 -0700

----------------------------------------------------------------------
 src/cli_new/bin/main.py                    | 21 +++++---
 src/cli_new/bin/settings.py                | 41 ++-------------
 src/cli_new/lib/cli/__init__.py            |  1 +
 src/cli_new/lib/cli/config.py              | 67 +++++++++++++++++++++++++
 src/cli_new/lib/cli/plugins/base.py        |  3 +-
 src/cli_new/lib/cli/plugins/config/main.py | 12 +++--
 src/cli_new/lib/cli/util.py                | 15 ++++++
 7 files changed, 111 insertions(+), 49 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/8740ce8d/src/cli_new/bin/main.py
----------------------------------------------------------------------
diff --git a/src/cli_new/bin/main.py b/src/cli_new/bin/main.py
index 6369c08..d0ec2bd 100644
--- a/src/cli_new/bin/main.py
+++ b/src/cli_new/bin/main.py
@@ -23,6 +23,7 @@ import sys
 import settings
 
 import cli
+
 from cli.docopt import docopt
 from cli.exceptions import CLIException
 
@@ -49,7 +50,7 @@ See 'mesos help <command>' for more information on a specific command.
 """
 
 
-def autocomplete(cmds, plugins, argv):
+def autocomplete(cmds, plugins, config, argv):
     """
     Perform autocomplete for the given input arguments. If not
     completing a top level command (or "help"), this function passes
@@ -72,7 +73,9 @@ def autocomplete(cmds, plugins, argv):
     plugin = cli.util.get_module(plugins, argv[0])
     plugin_class = getattr(plugin, plugin.PLUGIN_CLASS)
 
-    return plugin_class(settings).__autocomplete_base__(current_word, argv[1:])
+    return plugin_class(settings, config).__autocomplete_base__(
+        current_word,
+        argv[1:])
 
 
 def main(argv):
@@ -80,8 +83,12 @@ def main(argv):
     This is the main function for the Mesos CLI.
     """
 
-    # Initialize the various plugins.
-    plugins = cli.util.import_modules(settings.PLUGINS, "plugins")
+    # Load the CLI config.
+    config = cli.config.Config()
+
+    plugins = cli.util.import_modules(
+        cli.util.join_plugin_paths(settings, config),
+        "plugins")
 
     cmds = {
         cli.util.get_module(plugins, plugin).PLUGIN_NAME:
@@ -111,7 +118,7 @@ def main(argv):
         # passing the erroring stack trace back as the list of words
         # to complete on.
         try:
-            option, comp_words = autocomplete(cmds, plugins, argv)
+            option, comp_words = autocomplete(cmds, plugins, config, argv)
         except Exception:
             pass
 
@@ -124,7 +131,7 @@ def main(argv):
         if len(argv) > 0 and argv[0] in cmds:
             plugin = cli.util.get_module(plugins, argv[0])
             plugin_class = getattr(plugin, plugin.PLUGIN_CLASS)
-            plugin_class(settings).main(argv[1:] + ["--help"])
+            plugin_class(settings, config).main(argv[1:] + ["--help"])
         else:
             main(["--help"])
 
@@ -132,7 +139,7 @@ def main(argv):
     elif cmd in cmds.keys():
         plugin = cli.util.get_module(plugins, cmd)
         plugin_class = getattr(plugin, plugin.PLUGIN_CLASS)
-        plugin_class(settings).main(argv)
+        plugin_class(settings, config).main(argv)
 
     # Print help information if no commands match.
     else:

http://git-wip-us.apache.org/repos/asf/mesos/blob/8740ce8d/src/cli_new/bin/settings.py
----------------------------------------------------------------------
diff --git a/src/cli_new/bin/settings.py b/src/cli_new/bin/settings.py
index 0ef07cc..d42df04 100644
--- a/src/cli_new/bin/settings.py
+++ b/src/cli_new/bin/settings.py
@@ -21,9 +21,6 @@ parsing a configuration file.
 """
 
 import os
-import toml
-
-from cli.exceptions import CLIException
 
 
 # There is no version module included in this package. However,
@@ -41,38 +38,10 @@ PROJECT_DIR = os.path.join(os.path.dirname(__file__), os.pardir)
 
 # The builtin plugins.
 PLUGINS = [
-    os.path.join(PROJECT_DIR, "lib/mesos/plugins", "config")
+    os.path.join(PROJECT_DIR, "lib", "mesos", "plugins", "config")
 ]
 
-MESOS_CLI_DEFAULT_CONFIG_PATH = os.path.join(
-    os.path.expanduser("~"), ".mesos/config.toml")
-
-# Load the configuration file path for the CLI.
-if os.environ.get("MESOS_CLI_CONFIG"):
-    MESOS_CLI_CONFIG_PATH = os.environ["MESOS_CLI_CONFIG"]
-else:
-    MESOS_CLI_CONFIG_PATH = MESOS_CLI_DEFAULT_CONFIG_PATH
-
-# Load the configuration file as a TOML file.
-try:
-    CONFIG_DATA = toml.load(MESOS_CLI_CONFIG_PATH)
-except Exception as exception:
-    if MESOS_CLI_CONFIG_PATH is not MESOS_CLI_DEFAULT_CONFIG_PATH:
-        raise CLIException("Error loading config file as TOML: {error}"
-                           .format(error=exception))
-    else:
-        CONFIG_DATA = {}
-
-# Allow extra plugins to be pulled in from the configuration file.
-if "plugins" in CONFIG_DATA:
-    if not isinstance(CONFIG_DATA["plugins"], list):
-        raise CLIException("Unable to parse config file '{path}': 'plugins' "
-                           "field must be a list"
-                           .format(path=MESOS_CLI_CONFIG_PATH))
-
-    for plugin in CONFIG_DATA["plugins"]:
-        if os.path.exists(plugin):
-            PLUGINS.append(plugin)
-        else:
-            raise CLIException("Plugin path not found: {path}"
-                               .format(path=plugin))
+DEFAULT_MESOS_CLI_CONFIG = os.path.join(
+    os.path.expanduser("~"),
+    ".mesos",
+    "config.toml")

http://git-wip-us.apache.org/repos/asf/mesos/blob/8740ce8d/src/cli_new/lib/cli/__init__.py
----------------------------------------------------------------------
diff --git a/src/cli_new/lib/cli/__init__.py b/src/cli_new/lib/cli/__init__.py
index f4fc3f1..4ddbb0e 100644
--- a/src/cli_new/lib/cli/__init__.py
+++ b/src/cli_new/lib/cli/__init__.py
@@ -18,6 +18,7 @@
 Mesos Module
 """
 
+from . import config
 from . import exceptions
 from . import plugins
 from . import util

http://git-wip-us.apache.org/repos/asf/mesos/blob/8740ce8d/src/cli_new/lib/cli/config.py
----------------------------------------------------------------------
diff --git a/src/cli_new/lib/cli/config.py b/src/cli_new/lib/cli/config.py
new file mode 100644
index 0000000..978db80
--- /dev/null
+++ b/src/cli_new/lib/cli/config.py
@@ -0,0 +1,67 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+Config class to manage the configuration file.
+"""
+
+import os
+import toml
+
+import settings
+from cli.exceptions import CLIException
+
+
+class Config(object):
+    """
+    The Config class loads the configuration file on initialization and has
+    one method for each element that can be specified in the config file.
+    """
+
+    def __init__(self):
+        # Load the configuration file path for the CLI.
+        if os.environ.get("MESOS_CLI_CONFIG"):
+            self.path = os.environ["MESOS_CLI_CONFIG"]
+        else:
+            self.path = settings.DEFAULT_MESOS_CLI_CONFIG
+
+        # Load the configuration file as a TOML file.
+        try:
+            self.data = toml.load(self.path)
+        except Exception as exception:
+            raise CLIException("Error loading config file as TOML: {error}"
+                               .format(error=exception))
+
+    def plugins(self):
+        """
+        Parse and load the builtin plugins and the ones in the configuration
+        file. If this method is called using 'mesos config plugins', it
+        displays the plugins that can be used.
+        """
+        # Allow extra plugins to be pulled in from the configuration file.
+        if "plugins" in self.data:
+            if not isinstance(self.data["plugins"], list):
+                raise CLIException("Unable to parse config file '{path}':"
+                                   " 'plugins' field must be a list"
+                                   .format(path=self.path))
+
+            for plugin in self.data["plugins"]:
+                if not os.path.exists(plugin):
+                    raise CLIException("Plugin path not found: {path}"
+                                       .format(path=plugin))
+            return self.data["plugins"]
+
+        return []

http://git-wip-us.apache.org/repos/asf/mesos/blob/8740ce8d/src/cli_new/lib/cli/plugins/base.py
----------------------------------------------------------------------
diff --git a/src/cli_new/lib/cli/plugins/base.py b/src/cli_new/lib/cli/plugins/base.py
index c10d70f..edbe1ec 100644
--- a/src/cli_new/lib/cli/plugins/base.py
+++ b/src/cli_new/lib/cli/plugins/base.py
@@ -79,7 +79,7 @@ class PluginBase(object):
     def __module_reference__(self):
         return sys.modules[self.__module__]
 
-    def __init__(self, config):
+    def __init__(self, settings, config):
         # pylint: disable=C0103
         self.PLUGIN_NAME = PLUGIN_NAME
         self.PLUGIN_CLASS = PLUGIN_CLASS
@@ -99,6 +99,7 @@ class PluginBase(object):
         if hasattr(module, "USAGE"):
             self.USAGE = getattr(module, "USAGE")
 
+        self.settings = settings
         self.config = config
 
     def __autocomplete__(self, command, current_word, argv):

http://git-wip-us.apache.org/repos/asf/mesos/blob/8740ce8d/src/cli_new/lib/cli/plugins/config/main.py
----------------------------------------------------------------------
diff --git a/src/cli_new/lib/cli/plugins/config/main.py b/src/cli_new/lib/cli/plugins/config/main.py
index d95a36f..6e19e5c 100644
--- a/src/cli_new/lib/cli/plugins/config/main.py
+++ b/src/cli_new/lib/cli/plugins/config/main.py
@@ -20,7 +20,6 @@ The config plugin.
 
 import sys
 
-import settings
 import cli
 
 from cli.plugins import PluginBase
@@ -59,10 +58,13 @@ class Config(PluginBase):
         plugins_table = Table(["NAME", "DESCRIPTION"])
 
         # Load the plugins
-        loaded_plugins = cli.util.import_modules(settings.PLUGINS, "plugins")
-        for plugin in loaded_plugins:
+        plugins = cli.util.import_modules(
+            cli.util.join_plugin_paths(self.settings, self.config),
+            "plugins")
+
+        for plugin in plugins:
             plugins_table.add_row([
-                cli.util.get_module(loaded_plugins, plugin).PLUGIN_NAME,
-                cli.util.get_module(loaded_plugins, plugin).SHORT_HELP
+                cli.util.get_module(plugins, plugin).PLUGIN_NAME,
+                cli.util.get_module(plugins, plugin).SHORT_HELP
             ])
         sys.stdout.write("{}\n".format(plugins_table))

http://git-wip-us.apache.org/repos/asf/mesos/blob/8740ce8d/src/cli_new/lib/cli/util.py
----------------------------------------------------------------------
diff --git a/src/cli_new/lib/cli/util.py b/src/cli_new/lib/cli/util.py
index 27c4f17..7371f83 100644
--- a/src/cli_new/lib/cli/util.py
+++ b/src/cli_new/lib/cli/util.py
@@ -152,6 +152,21 @@ def format_subcommands_help(cmd):
     return (arguments, short_help, long_help, flag_string)
 
 
+def join_plugin_paths(settings, config):
+    """
+    Return all the plugin paths combined
+    from both settings and the config file.
+    """
+    builtin_paths = settings.PLUGINS
+
+    try:
+        config_paths = config.plugins()
+    except Exception as exception:
+        raise CLIException("Error: {error}.".format(error=str(exception)))
+
+    return builtin_paths + config_paths
+
+
 class Table(object):
     """
     Defines a custom table structure for printing to the terminal.