We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Exceptions on the command line with invalid arguments in the archive position
When trying to run `python -m insights foo` or `python -m insights existent_but_invalid.py`, an exception is raised all the way to the top, and if the file exists, a partial execution against the current machine happens. We should catch the exception, never partially execute, and provide a simple message for a better CLI experience.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `insights/__init__.py`
Content:
```
1 """
2 Insights Core is a data collection and analysis framework that is built for
3 extensibility and rapid development. It includes a set of reusable components
4 for gathering data in myriad ways and providing a reliable object model for it.
5 
6 .. code-block: python
7 
8     >>> from insights import run
9     >>> from insights.parsers import installed_rpms as rpm
10     >>> lower = rpm.Rpm("bash-4.4.11-1.fc26")
11     >>> upper = rpm.Rpm("bash-4.4.22-1.fc26")
12     >>> results = run(rpm.Installed)
13     >>> rpms = results[rpm.Installed]
14     >>> rpms.newest("bash")
15     "0:bash-4.4.12-7.fc26"
16     >>> lower <= rpms.newest("bash") < upper
17     True
18 """
19 from __future__ import print_function
20 import logging
21 import pkgutil
22 import os
23 import sys
24 import yaml
25 
26 from .core import Scannable, LogFileOutput, Parser, IniConfigFile  # noqa: F401
27 from .core import FileListing, LegacyItemAccess, SysconfigOptions  # noqa: F401
28 from .core import YAMLParser, JSONParser, XMLParser, CommandParser  # noqa: F401
29 from .core import AttributeDict  # noqa: F401
30 from .core import Syslog  # noqa: F401
31 from .core.archives import COMPRESSION_TYPES, extract  # noqa: F401
32 from .core import dr  # noqa: F401
33 from .core.context import ClusterArchiveContext, HostContext, HostArchiveContext, SerializedArchiveContext  # noqa: F401
34 from .core.dr import SkipComponent  # noqa: F401
35 from .core.hydration import create_context
36 from .core.plugins import combiner, fact, metadata, parser, rule  # noqa: F401
37 from .core.plugins import datasource, condition, incident  # noqa: F401
38 from .core.plugins import make_response, make_metadata, make_fingerprint  # noqa: F401
39 from .core.plugins import make_pass, make_fail  # noqa: F401
40 from .core.filters import add_filter, apply_filters, get_filters  # noqa: F401
41 from .core.serde import Hydration
42 from .formats import get_formatter
43 from .parsers import get_active_lines  # noqa: F401
44 from .util import defaults  # noqa: F401
45 
46 log = logging.getLogger(__name__)
47 
48 
49 package_info = dict((k, None) for k in ["RELEASE", "COMMIT", "VERSION", "NAME"])
50 
51 
52 for name in package_info:
53     package_info[name] = pkgutil.get_data(__name__, name).strip().decode("utf-8")
54 
55 
56 def get_nvr():
57     return "{0}-{1}-{2}".format(package_info["NAME"],
58                                 package_info["VERSION"],
59                                 package_info["RELEASE"])
60 
61 
62 RULES_STATUS = {}
63 """
64 Mapping of dictionaries containing nvr and commitid for each rule repo included
65 in this instance
66 
67 {"rule_repo_1": {"version": nvr(), "commit": sha1}}
68 """
69 
70 
71 def add_status(name, nvr, commit):
72     """
73     Rule repositories should call this method in their package __init__ to
74     register their version information.
75     """
76     RULES_STATUS[name] = {"version": nvr, "commit": commit}
77 
78 
79 def process_dir(broker, root, graph, context, inventory=None):
80     ctx = create_context(root, context)
81     log.debug("Processing %s with %s" % (root, ctx))
82 
83     if isinstance(ctx, ClusterArchiveContext):
84         from .core.cluster import process_cluster
85         archives = [f for f in ctx.all_files if f.endswith(COMPRESSION_TYPES)]
86         return process_cluster(archives, broker=broker, inventory=inventory)
87 
88     broker[ctx.__class__] = ctx
89     if isinstance(ctx, SerializedArchiveContext):
90         h = Hydration(ctx.root)
91         broker = h.hydrate(broker=broker)
92     broker = dr.run(graph, broker=broker)
93     return broker
94 
95 
96 def _run(broker, graph=None, root=None, context=None, inventory=None):
97     """
98     run is a general interface that is meant for stand alone scripts to use
99     when executing insights components.
100 
101     Args:
102         root (str): None will causes a host collection in which command and
103             file specs are run. A directory or archive path will cause
104             collection from the directory or archive, and only file type specs
105             or those that depend on `insights.core.context.HostArchiveContext`
106             will execute.
107         component (function or class): The component to execute. Will only execute
108             the component and its dependency graph. If None, all components with
109             met dependencies will execute.
110 
111     Returns:
112         broker: object containing the result of the evaluation.
113     """
114 
115     if not root:
116         context = context or HostContext
117         broker[context] = context()
118         return dr.run(graph, broker=broker)
119 
120     if os.path.isdir(root):
121         return process_dir(broker, root, graph, context, inventory=inventory)
122     else:
123         with extract(root) as ex:
124             return process_dir(broker, ex.tmp_dir, graph, context, inventory=inventory)
125 
126 
127 def apply_configs(configs):
128     """
129     Configures components. They can be enabled or disabled, have timeouts set
130     if applicable, and have metadata customized. Valid keys are name, enabled,
131     metadata, and timeout.
132 
133     Args:
134         configs (list): a list of dictionaries with the following keys:
135             name, enabled, metadata, and timeout. All keys are optional except
136             name.
137 
138             name is the prefix or exact name of any loaded component. Any
139             component starting with name will have the associated configuration
140             applied.
141 
142             enabled is whether the matching components will execute even if
143             their dependencies are met. Defaults to True.
144 
145             timeout sets the class level timeout attribute of any component so
146             long as the attribute already exists.
147 
148             metadata is any dictionary that you want to attach to the
149             component. The dictionary can be retrieved by the component at
150             runtime.
151     """
152     delegate_keys = sorted(dr.DELEGATES, key=dr.get_name)
153     for comp_cfg in configs:
154         name = comp_cfg["name"]
155         for c in delegate_keys:
156             delegate = dr.DELEGATES[c]
157             cname = dr.get_name(c)
158             if cname.startswith(name):
159                 dr.ENABLED[c] = comp_cfg.get("enabled", True)
160                 delegate.metadata.update(comp_cfg.get("metadata", {}))
161                 delegate.tags = set(comp_cfg.get("tags", delegate.tags))
162                 for k, v in delegate.metadata.items():
163                     if hasattr(c, k):
164                         setattr(c, k, v)
165                 if hasattr(c, "timeout"):
166                     c.timeout = comp_cfg.get("timeout", c.timeout)
167             if cname == name:
168                 break
169 
170 
171 def _load_context(path):
172     if path is None:
173         return
174 
175     if "." not in path:
176         path = ".".join(["insights.core.context", path])
177     return dr.get_component(path)
178 
179 
180 def run(component=None, root=None, print_summary=False,
181         context=None, inventory=None, print_component=None):
182 
183     from .core import dr
184     dr.load_components("insights.specs.default")
185     dr.load_components("insights.specs.insights_archive")
186     dr.load_components("insights.specs.sos_archive")
187     dr.load_components("insights.specs.jdr_archive")
188 
189     args = None
190     formatter = None
191     if print_summary:
192         import argparse
193         import logging
194         p = argparse.ArgumentParser(add_help=False)
195         p.add_argument("archive", nargs="?", help="Archive or directory to analyze.")
196         p.add_argument("-p", "--plugins", default="", help="Comma-separated list without spaces of package(s) or module(s) containing plugins.")
197         p.add_argument("-c", "--config", help="Configure components.")
198         p.add_argument("-i", "--inventory", help="Ansible inventory file for cluster analysis.")
199         p.add_argument("-v", "--verbose", help="Verbose output.", action="store_true")
200         p.add_argument("-f", "--format", help="Output format.", default="insights.formats.text")
201         p.add_argument("-D", "--debug", help="Verbose debug output.", action="store_true")
202         p.add_argument("--context", help="Execution Context. Defaults to HostContext if an archive isn't passed.")
203 
204         class Args(object):
205             pass
206 
207         args = Args()
208         p.parse_known_args(namespace=args)
209         p = argparse.ArgumentParser(parents=[p])
210         args.format = "insights.formats._json" if args.format == "json" else args.format
211         args.format = "insights.formats._yaml" if args.format == "yaml" else args.format
212         fmt = args.format if "." in args.format else "insights.formats." + args.format
213         Formatter = dr.get_component(fmt)
214         if not Formatter:
215             dr.load_components(fmt, continue_on_error=False)
216             Formatter = get_formatter(fmt)
217         Formatter.configure(p)
218         p.parse_args(namespace=args)
219         formatter = Formatter(args)
220 
221         logging.basicConfig(level=logging.DEBUG if args.debug else logging.INFO if args.verbose else logging.ERROR)
222         context = _load_context(args.context) or context
223         inventory = args.inventory
224 
225         root = args.archive or root
226         if root:
227             root = os.path.realpath(root)
228 
229         plugins = []
230         if args.plugins:
231             for path in args.plugins.split(","):
232                 path = path.strip()
233                 if path.endswith(".py"):
234                     path, _ = os.path.splitext(path)
235                 path = path.rstrip("/").replace("/", ".")
236                 plugins.append(path)
237 
238         for p in plugins:
239             dr.load_components(p, continue_on_error=False)
240 
241         if args.config:
242             with open(args.config) as f:
243                 apply_configs(yaml.safe_load(f))
244 
245         if component is None:
246             component = []
247             plugins = tuple(plugins)
248             for c in dr.DELEGATES:
249                 if c.__module__.startswith(plugins):
250                     component.append(c)
251 
252     if component:
253         if not isinstance(component, (list, set)):
254             component = [component]
255         graph = {}
256         for c in component:
257             graph.update(dr.get_dependency_graph(c))
258     else:
259         graph = dr.COMPONENTS[dr.GROUPS.single]
260 
261     broker = dr.Broker()
262 
263     if formatter:
264         formatter.preprocess(broker)
265         broker = _run(broker, graph, root, context=context, inventory=inventory)
266         formatter.postprocess(broker)
267     elif print_component:
268         broker = _run(broker, graph, root, context=context, inventory=inventory)
269         broker.print_component(print_component)
270     else:
271         broker = _run(broker, graph, root, context=context, inventory=inventory)
272 
273     return broker
274 
275 
276 def main():
277     if "" not in sys.path:
278         sys.path.insert(0, "")
279     run(print_summary=True)
280 
281 
282 if __name__ == "__main__":
283     main()
284
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/insights/__init__.py b/insights/__init__.py
--- a/insights/__init__.py
+++ b/insights/__init__.py
@@ -28,7 +28,7 @@
 from .core import YAMLParser, JSONParser, XMLParser, CommandParser  # noqa: F401
 from .core import AttributeDict  # noqa: F401
 from .core import Syslog  # noqa: F401
-from .core.archives import COMPRESSION_TYPES, extract  # noqa: F401
+from .core.archives import COMPRESSION_TYPES, extract, InvalidArchive, InvalidContentType  # noqa: F401
 from .core import dr  # noqa: F401
 from .core.context import ClusterArchiveContext, HostContext, HostArchiveContext, SerializedArchiveContext  # noqa: F401
 from .core.dr import SkipComponent  # noqa: F401
@@ -260,17 +260,25 @@
 
     broker = dr.Broker()
 
-    if formatter:
-        formatter.preprocess(broker)
-        broker = _run(broker, graph, root, context=context, inventory=inventory)
-        formatter.postprocess(broker)
-    elif print_component:
-        broker = _run(broker, graph, root, context=context, inventory=inventory)
-        broker.print_component(print_component)
-    else:
-        broker = _run(broker, graph, root, context=context, inventory=inventory)
-
-    return broker
+    try:
+        if formatter:
+            formatter.preprocess(broker)
+            broker = _run(broker, graph, root, context=context, inventory=inventory)
+            formatter.postprocess(broker)
+        elif print_component:
+            broker = _run(broker, graph, root, context=context, inventory=inventory)
+            broker.print_component(print_component)
+        else:
+            broker = _run(broker, graph, root, context=context, inventory=inventory)
+
+        return broker
+    except (InvalidContentType, InvalidArchive):
+        if args and args.archive:
+            path = args.archive
+            msg = "Invalid directory or archive. Did you mean to pass -p {p}?"
+            log.error(msg.format(p=path))
+        else:
+            raise
 
 
 def main():

{"golden_diff": "diff --git a/insights/__init__.py b/insights/__init__.py\n--- a/insights/__init__.py\n+++ b/insights/__init__.py\n@@ -28,7 +28,7 @@\n from .core import YAMLParser, JSONParser, XMLParser, CommandParser  # noqa: F401\n from .core import AttributeDict  # noqa: F401\n from .core import Syslog  # noqa: F401\n-from .core.archives import COMPRESSION_TYPES, extract  # noqa: F401\n+from .core.archives import COMPRESSION_TYPES, extract, InvalidArchive, InvalidContentType  # noqa: F401\n from .core import dr  # noqa: F401\n from .core.context import ClusterArchiveContext, HostContext, HostArchiveContext, SerializedArchiveContext  # noqa: F401\n from .core.dr import SkipComponent  # noqa: F401\n@@ -260,17 +260,25 @@\n \n     broker = dr.Broker()\n \n-    if formatter:\n-        formatter.preprocess(broker)\n-        broker = _run(broker, graph, root, context=context, inventory=inventory)\n-        formatter.postprocess(broker)\n-    elif print_component:\n-        broker = _run(broker, graph, root, context=context, inventory=inventory)\n-        broker.print_component(print_component)\n-    else:\n-        broker = _run(broker, graph, root, context=context, inventory=inventory)\n-\n-    return broker\n+    try:\n+        if formatter:\n+            formatter.preprocess(broker)\n+            broker = _run(broker, graph, root, context=context, inventory=inventory)\n+            formatter.postprocess(broker)\n+        elif print_component:\n+            broker = _run(broker, graph, root, context=context, inventory=inventory)\n+            broker.print_component(print_component)\n+        else:\n+            broker = _run(broker, graph, root, context=context, inventory=inventory)\n+\n+        return broker\n+    except (InvalidContentType, InvalidArchive):\n+        if args and args.archive:\n+            path = args.archive\n+            msg = \"Invalid directory or archive. Did you mean to pass -p {p}?\"\n+            log.error(msg.format(p=path))\n+        else:\n+            raise\n \n \n def main():\n", "issue": "Exceptions on the command line with invalid arguments in the archive position\nWhen trying to run `python -m insights foo` or `python -m insights existent_but_invalid.py`, an exception is raised all the way to the top, and if the file exists, a partial execution against the current machine happens. We should catch the exception, never partially execute, and provide a simple message for a better CLI experience.\n", "before_files": [{"content": "\"\"\"\nInsights Core is a data collection and analysis framework that is built for\nextensibility and rapid development. It includes a set of reusable components\nfor gathering data in myriad ways and providing a reliable object model for it.\n\n.. code-block: python\n\n    >>> from insights import run\n    >>> from insights.parsers import installed_rpms as rpm\n    >>> lower = rpm.Rpm(\"bash-4.4.11-1.fc26\")\n    >>> upper = rpm.Rpm(\"bash-4.4.22-1.fc26\")\n    >>> results = run(rpm.Installed)\n    >>> rpms = results[rpm.Installed]\n    >>> rpms.newest(\"bash\")\n    \"0:bash-4.4.12-7.fc26\"\n    >>> lower <= rpms.newest(\"bash\") < upper\n    True\n\"\"\"\nfrom __future__ import print_function\nimport logging\nimport pkgutil\nimport os\nimport sys\nimport yaml\n\nfrom .core import Scannable, LogFileOutput, Parser, IniConfigFile  # noqa: F401\nfrom .core import FileListing, LegacyItemAccess, SysconfigOptions  # noqa: F401\nfrom .core import YAMLParser, JSONParser, XMLParser, CommandParser  # noqa: F401\nfrom .core import AttributeDict  # noqa: F401\nfrom .core import Syslog  # noqa: F401\nfrom .core.archives import COMPRESSION_TYPES, extract  # noqa: F401\nfrom .core import dr  # noqa: F401\nfrom .core.context import ClusterArchiveContext, HostContext, HostArchiveContext, SerializedArchiveContext  # noqa: F401\nfrom .core.dr import SkipComponent  # noqa: F401\nfrom .core.hydration import create_context\nfrom .core.plugins import combiner, fact, metadata, parser, rule  # noqa: F401\nfrom .core.plugins import datasource, condition, incident  # noqa: F401\nfrom .core.plugins import make_response, make_metadata, make_fingerprint  # noqa: F401\nfrom .core.plugins import make_pass, make_fail  # noqa: F401\nfrom .core.filters import add_filter, apply_filters, get_filters  # noqa: F401\nfrom .core.serde import Hydration\nfrom .formats import get_formatter\nfrom .parsers import get_active_lines  # noqa: F401\nfrom .util import defaults  # noqa: F401\n\nlog = logging.getLogger(__name__)\n\n\npackage_info = dict((k, None) for k in [\"RELEASE\", \"COMMIT\", \"VERSION\", \"NAME\"])\n\n\nfor name in package_info:\n    package_info[name] = pkgutil.get_data(__name__, name).strip().decode(\"utf-8\")\n\n\ndef get_nvr():\n    return \"{0}-{1}-{2}\".format(package_info[\"NAME\"],\n                                package_info[\"VERSION\"],\n                                package_info[\"RELEASE\"])\n\n\nRULES_STATUS = {}\n\"\"\"\nMapping of dictionaries containing nvr and commitid for each rule repo included\nin this instance\n\n{\"rule_repo_1\": {\"version\": nvr(), \"commit\": sha1}}\n\"\"\"\n\n\ndef add_status(name, nvr, commit):\n    \"\"\"\n    Rule repositories should call this method in their package __init__ to\n    register their version information.\n    \"\"\"\n    RULES_STATUS[name] = {\"version\": nvr, \"commit\": commit}\n\n\ndef process_dir(broker, root, graph, context, inventory=None):\n    ctx = create_context(root, context)\n    log.debug(\"Processing %s with %s\" % (root, ctx))\n\n    if isinstance(ctx, ClusterArchiveContext):\n        from .core.cluster import process_cluster\n        archives = [f for f in ctx.all_files if f.endswith(COMPRESSION_TYPES)]\n        return process_cluster(archives, broker=broker, inventory=inventory)\n\n    broker[ctx.__class__] = ctx\n    if isinstance(ctx, SerializedArchiveContext):\n        h = Hydration(ctx.root)\n        broker = h.hydrate(broker=broker)\n    broker = dr.run(graph, broker=broker)\n    return broker\n\n\ndef _run(broker, graph=None, root=None, context=None, inventory=None):\n    \"\"\"\n    run is a general interface that is meant for stand alone scripts to use\n    when executing insights components.\n\n    Args:\n        root (str): None will causes a host collection in which command and\n            file specs are run. A directory or archive path will cause\n            collection from the directory or archive, and only file type specs\n            or those that depend on `insights.core.context.HostArchiveContext`\n            will execute.\n        component (function or class): The component to execute. Will only execute\n            the component and its dependency graph. If None, all components with\n            met dependencies will execute.\n\n    Returns:\n        broker: object containing the result of the evaluation.\n    \"\"\"\n\n    if not root:\n        context = context or HostContext\n        broker[context] = context()\n        return dr.run(graph, broker=broker)\n\n    if os.path.isdir(root):\n        return process_dir(broker, root, graph, context, inventory=inventory)\n    else:\n        with extract(root) as ex:\n            return process_dir(broker, ex.tmp_dir, graph, context, inventory=inventory)\n\n\ndef apply_configs(configs):\n    \"\"\"\n    Configures components. They can be enabled or disabled, have timeouts set\n    if applicable, and have metadata customized. Valid keys are name, enabled,\n    metadata, and timeout.\n\n    Args:\n        configs (list): a list of dictionaries with the following keys:\n            name, enabled, metadata, and timeout. All keys are optional except\n            name.\n\n            name is the prefix or exact name of any loaded component. Any\n            component starting with name will have the associated configuration\n            applied.\n\n            enabled is whether the matching components will execute even if\n            their dependencies are met. Defaults to True.\n\n            timeout sets the class level timeout attribute of any component so\n            long as the attribute already exists.\n\n            metadata is any dictionary that you want to attach to the\n            component. The dictionary can be retrieved by the component at\n            runtime.\n    \"\"\"\n    delegate_keys = sorted(dr.DELEGATES, key=dr.get_name)\n    for comp_cfg in configs:\n        name = comp_cfg[\"name\"]\n        for c in delegate_keys:\n            delegate = dr.DELEGATES[c]\n            cname = dr.get_name(c)\n            if cname.startswith(name):\n                dr.ENABLED[c] = comp_cfg.get(\"enabled\", True)\n                delegate.metadata.update(comp_cfg.get(\"metadata\", {}))\n                delegate.tags = set(comp_cfg.get(\"tags\", delegate.tags))\n                for k, v in delegate.metadata.items():\n                    if hasattr(c, k):\n                        setattr(c, k, v)\n                if hasattr(c, \"timeout\"):\n                    c.timeout = comp_cfg.get(\"timeout\", c.timeout)\n            if cname == name:\n                break\n\n\ndef _load_context(path):\n    if path is None:\n        return\n\n    if \".\" not in path:\n        path = \".\".join([\"insights.core.context\", path])\n    return dr.get_component(path)\n\n\ndef run(component=None, root=None, print_summary=False,\n        context=None, inventory=None, print_component=None):\n\n    from .core import dr\n    dr.load_components(\"insights.specs.default\")\n    dr.load_components(\"insights.specs.insights_archive\")\n    dr.load_components(\"insights.specs.sos_archive\")\n    dr.load_components(\"insights.specs.jdr_archive\")\n\n    args = None\n    formatter = None\n    if print_summary:\n        import argparse\n        import logging\n        p = argparse.ArgumentParser(add_help=False)\n        p.add_argument(\"archive\", nargs=\"?\", help=\"Archive or directory to analyze.\")\n        p.add_argument(\"-p\", \"--plugins\", default=\"\", help=\"Comma-separated list without spaces of package(s) or module(s) containing plugins.\")\n        p.add_argument(\"-c\", \"--config\", help=\"Configure components.\")\n        p.add_argument(\"-i\", \"--inventory\", help=\"Ansible inventory file for cluster analysis.\")\n        p.add_argument(\"-v\", \"--verbose\", help=\"Verbose output.\", action=\"store_true\")\n        p.add_argument(\"-f\", \"--format\", help=\"Output format.\", default=\"insights.formats.text\")\n        p.add_argument(\"-D\", \"--debug\", help=\"Verbose debug output.\", action=\"store_true\")\n        p.add_argument(\"--context\", help=\"Execution Context. Defaults to HostContext if an archive isn't passed.\")\n\n        class Args(object):\n            pass\n\n        args = Args()\n        p.parse_known_args(namespace=args)\n        p = argparse.ArgumentParser(parents=[p])\n        args.format = \"insights.formats._json\" if args.format == \"json\" else args.format\n        args.format = \"insights.formats._yaml\" if args.format == \"yaml\" else args.format\n        fmt = args.format if \".\" in args.format else \"insights.formats.\" + args.format\n        Formatter = dr.get_component(fmt)\n        if not Formatter:\n            dr.load_components(fmt, continue_on_error=False)\n            Formatter = get_formatter(fmt)\n        Formatter.configure(p)\n        p.parse_args(namespace=args)\n        formatter = Formatter(args)\n\n        logging.basicConfig(level=logging.DEBUG if args.debug else logging.INFO if args.verbose else logging.ERROR)\n        context = _load_context(args.context) or context\n        inventory = args.inventory\n\n        root = args.archive or root\n        if root:\n            root = os.path.realpath(root)\n\n        plugins = []\n        if args.plugins:\n            for path in args.plugins.split(\",\"):\n                path = path.strip()\n                if path.endswith(\".py\"):\n                    path, _ = os.path.splitext(path)\n                path = path.rstrip(\"/\").replace(\"/\", \".\")\n                plugins.append(path)\n\n        for p in plugins:\n            dr.load_components(p, continue_on_error=False)\n\n        if args.config:\n            with open(args.config) as f:\n                apply_configs(yaml.safe_load(f))\n\n        if component is None:\n            component = []\n            plugins = tuple(plugins)\n            for c in dr.DELEGATES:\n                if c.__module__.startswith(plugins):\n                    component.append(c)\n\n    if component:\n        if not isinstance(component, (list, set)):\n            component = [component]\n        graph = {}\n        for c in component:\n            graph.update(dr.get_dependency_graph(c))\n    else:\n        graph = dr.COMPONENTS[dr.GROUPS.single]\n\n    broker = dr.Broker()\n\n    if formatter:\n        formatter.preprocess(broker)\n        broker = _run(broker, graph, root, context=context, inventory=inventory)\n        formatter.postprocess(broker)\n    elif print_component:\n        broker = _run(broker, graph, root, context=context, inventory=inventory)\n        broker.print_component(print_component)\n    else:\n        broker = _run(broker, graph, root, context=context, inventory=inventory)\n\n    return broker\n\n\ndef main():\n    if \"\" not in sys.path:\n        sys.path.insert(0, \"\")\n    run(print_summary=True)\n\n\nif __name__ == \"__main__\":\n    main()\n", "path": "insights/__init__.py"}], "after_files": [{"content": "\"\"\"\nInsights Core is a data collection and analysis framework that is built for\nextensibility and rapid development. It includes a set of reusable components\nfor gathering data in myriad ways and providing a reliable object model for it.\n\n.. code-block: python\n\n    >>> from insights import run\n    >>> from insights.parsers import installed_rpms as rpm\n    >>> lower = rpm.Rpm(\"bash-4.4.11-1.fc26\")\n    >>> upper = rpm.Rpm(\"bash-4.4.22-1.fc26\")\n    >>> results = run(rpm.Installed)\n    >>> rpms = results[rpm.Installed]\n    >>> rpms.newest(\"bash\")\n    \"0:bash-4.4.12-7.fc26\"\n    >>> lower <= rpms.newest(\"bash\") < upper\n    True\n\"\"\"\nfrom __future__ import print_function\nimport logging\nimport pkgutil\nimport os\nimport sys\nimport yaml\n\nfrom .core import Scannable, LogFileOutput, Parser, IniConfigFile  # noqa: F401\nfrom .core import FileListing, LegacyItemAccess, SysconfigOptions  # noqa: F401\nfrom .core import YAMLParser, JSONParser, XMLParser, CommandParser  # noqa: F401\nfrom .core import AttributeDict  # noqa: F401\nfrom .core import Syslog  # noqa: F401\nfrom .core.archives import COMPRESSION_TYPES, extract, InvalidArchive, InvalidContentType  # noqa: F401\nfrom .core import dr  # noqa: F401\nfrom .core.context import ClusterArchiveContext, HostContext, HostArchiveContext, SerializedArchiveContext  # noqa: F401\nfrom .core.dr import SkipComponent  # noqa: F401\nfrom .core.hydration import create_context\nfrom .core.plugins import combiner, fact, metadata, parser, rule  # noqa: F401\nfrom .core.plugins import datasource, condition, incident  # noqa: F401\nfrom .core.plugins import make_response, make_metadata, make_fingerprint  # noqa: F401\nfrom .core.plugins import make_pass, make_fail  # noqa: F401\nfrom .core.filters import add_filter, apply_filters, get_filters  # noqa: F401\nfrom .core.serde import Hydration\nfrom .formats import get_formatter\nfrom .parsers import get_active_lines  # noqa: F401\nfrom .util import defaults  # noqa: F401\n\nlog = logging.getLogger(__name__)\n\n\npackage_info = dict((k, None) for k in [\"RELEASE\", \"COMMIT\", \"VERSION\", \"NAME\"])\n\n\nfor name in package_info:\n    package_info[name] = pkgutil.get_data(__name__, name).strip().decode(\"utf-8\")\n\n\ndef get_nvr():\n    return \"{0}-{1}-{2}\".format(package_info[\"NAME\"],\n                                package_info[\"VERSION\"],\n                                package_info[\"RELEASE\"])\n\n\nRULES_STATUS = {}\n\"\"\"\nMapping of dictionaries containing nvr and commitid for each rule repo included\nin this instance\n\n{\"rule_repo_1\": {\"version\": nvr(), \"commit\": sha1}}\n\"\"\"\n\n\ndef add_status(name, nvr, commit):\n    \"\"\"\n    Rule repositories should call this method in their package __init__ to\n    register their version information.\n    \"\"\"\n    RULES_STATUS[name] = {\"version\": nvr, \"commit\": commit}\n\n\ndef process_dir(broker, root, graph, context, inventory=None):\n    ctx = create_context(root, context)\n    log.debug(\"Processing %s with %s\" % (root, ctx))\n\n    if isinstance(ctx, ClusterArchiveContext):\n        from .core.cluster import process_cluster\n        archives = [f for f in ctx.all_files if f.endswith(COMPRESSION_TYPES)]\n        return process_cluster(archives, broker=broker, inventory=inventory)\n\n    broker[ctx.__class__] = ctx\n    if isinstance(ctx, SerializedArchiveContext):\n        h = Hydration(ctx.root)\n        broker = h.hydrate(broker=broker)\n    broker = dr.run(graph, broker=broker)\n    return broker\n\n\ndef _run(broker, graph=None, root=None, context=None, inventory=None):\n    \"\"\"\n    run is a general interface that is meant for stand alone scripts to use\n    when executing insights components.\n\n    Args:\n        root (str): None will causes a host collection in which command and\n            file specs are run. A directory or archive path will cause\n            collection from the directory or archive, and only file type specs\n            or those that depend on `insights.core.context.HostArchiveContext`\n            will execute.\n        component (function or class): The component to execute. Will only execute\n            the component and its dependency graph. If None, all components with\n            met dependencies will execute.\n\n    Returns:\n        broker: object containing the result of the evaluation.\n    \"\"\"\n\n    if not root:\n        context = context or HostContext\n        broker[context] = context()\n        return dr.run(graph, broker=broker)\n\n    if os.path.isdir(root):\n        return process_dir(broker, root, graph, context, inventory=inventory)\n    else:\n        with extract(root) as ex:\n            return process_dir(broker, ex.tmp_dir, graph, context, inventory=inventory)\n\n\ndef apply_configs(configs):\n    \"\"\"\n    Configures components. They can be enabled or disabled, have timeouts set\n    if applicable, and have metadata customized. Valid keys are name, enabled,\n    metadata, and timeout.\n\n    Args:\n        configs (list): a list of dictionaries with the following keys:\n            name, enabled, metadata, and timeout. All keys are optional except\n            name.\n\n            name is the prefix or exact name of any loaded component. Any\n            component starting with name will have the associated configuration\n            applied.\n\n            enabled is whether the matching components will execute even if\n            their dependencies are met. Defaults to True.\n\n            timeout sets the class level timeout attribute of any component so\n            long as the attribute already exists.\n\n            metadata is any dictionary that you want to attach to the\n            component. The dictionary can be retrieved by the component at\n            runtime.\n    \"\"\"\n    delegate_keys = sorted(dr.DELEGATES, key=dr.get_name)\n    for comp_cfg in configs:\n        name = comp_cfg[\"name\"]\n        for c in delegate_keys:\n            delegate = dr.DELEGATES[c]\n            cname = dr.get_name(c)\n            if cname.startswith(name):\n                dr.ENABLED[c] = comp_cfg.get(\"enabled\", True)\n                delegate.metadata.update(comp_cfg.get(\"metadata\", {}))\n                delegate.tags = set(comp_cfg.get(\"tags\", delegate.tags))\n                for k, v in delegate.metadata.items():\n                    if hasattr(c, k):\n                        setattr(c, k, v)\n                if hasattr(c, \"timeout\"):\n                    c.timeout = comp_cfg.get(\"timeout\", c.timeout)\n            if cname == name:\n                break\n\n\ndef _load_context(path):\n    if path is None:\n        return\n\n    if \".\" not in path:\n        path = \".\".join([\"insights.core.context\", path])\n    return dr.get_component(path)\n\n\ndef run(component=None, root=None, print_summary=False,\n        context=None, inventory=None, print_component=None):\n\n    from .core import dr\n    dr.load_components(\"insights.specs.default\")\n    dr.load_components(\"insights.specs.insights_archive\")\n    dr.load_components(\"insights.specs.sos_archive\")\n    dr.load_components(\"insights.specs.jdr_archive\")\n\n    args = None\n    formatter = None\n    if print_summary:\n        import argparse\n        import logging\n        p = argparse.ArgumentParser(add_help=False)\n        p.add_argument(\"archive\", nargs=\"?\", help=\"Archive or directory to analyze.\")\n        p.add_argument(\"-p\", \"--plugins\", default=\"\", help=\"Comma-separated list without spaces of package(s) or module(s) containing plugins.\")\n        p.add_argument(\"-c\", \"--config\", help=\"Configure components.\")\n        p.add_argument(\"-i\", \"--inventory\", help=\"Ansible inventory file for cluster analysis.\")\n        p.add_argument(\"-v\", \"--verbose\", help=\"Verbose output.\", action=\"store_true\")\n        p.add_argument(\"-f\", \"--format\", help=\"Output format.\", default=\"insights.formats.text\")\n        p.add_argument(\"-D\", \"--debug\", help=\"Verbose debug output.\", action=\"store_true\")\n        p.add_argument(\"--context\", help=\"Execution Context. Defaults to HostContext if an archive isn't passed.\")\n\n        class Args(object):\n            pass\n\n        args = Args()\n        p.parse_known_args(namespace=args)\n        p = argparse.ArgumentParser(parents=[p])\n        args.format = \"insights.formats._json\" if args.format == \"json\" else args.format\n        args.format = \"insights.formats._yaml\" if args.format == \"yaml\" else args.format\n        fmt = args.format if \".\" in args.format else \"insights.formats.\" + args.format\n        Formatter = dr.get_component(fmt)\n        if not Formatter:\n            dr.load_components(fmt, continue_on_error=False)\n            Formatter = get_formatter(fmt)\n        Formatter.configure(p)\n        p.parse_args(namespace=args)\n        formatter = Formatter(args)\n\n        logging.basicConfig(level=logging.DEBUG if args.debug else logging.INFO if args.verbose else logging.ERROR)\n        context = _load_context(args.context) or context\n        inventory = args.inventory\n\n        root = args.archive or root\n        if root:\n            root = os.path.realpath(root)\n\n        plugins = []\n        if args.plugins:\n            for path in args.plugins.split(\",\"):\n                path = path.strip()\n                if path.endswith(\".py\"):\n                    path, _ = os.path.splitext(path)\n                path = path.rstrip(\"/\").replace(\"/\", \".\")\n                plugins.append(path)\n\n        for p in plugins:\n            dr.load_components(p, continue_on_error=False)\n\n        if args.config:\n            with open(args.config) as f:\n                apply_configs(yaml.safe_load(f))\n\n        if component is None:\n            component = []\n            plugins = tuple(plugins)\n            for c in dr.DELEGATES:\n                if c.__module__.startswith(plugins):\n                    component.append(c)\n\n    if component:\n        if not isinstance(component, (list, set)):\n            component = [component]\n        graph = {}\n        for c in component:\n            graph.update(dr.get_dependency_graph(c))\n    else:\n        graph = dr.COMPONENTS[dr.GROUPS.single]\n\n    broker = dr.Broker()\n\n    try:\n        if formatter:\n            formatter.preprocess(broker)\n            broker = _run(broker, graph, root, context=context, inventory=inventory)\n            formatter.postprocess(broker)\n        elif print_component:\n            broker = _run(broker, graph, root, context=context, inventory=inventory)\n            broker.print_component(print_component)\n        else:\n            broker = _run(broker, graph, root, context=context, inventory=inventory)\n\n        return broker\n    except (InvalidContentType, InvalidArchive):\n        if args and args.archive:\n            path = args.archive\n            msg = \"Invalid directory or archive. Did you mean to pass -p {p}?\"\n            log.error(msg.format(p=path))\n        else:\n            raise\n\n\ndef main():\n    if \"\" not in sys.path:\n        sys.path.insert(0, \"\")\n    run(print_summary=True)\n\n\nif __name__ == \"__main__\":\n    main()\n", "path": "insights/__init__.py"}]}