Repository: conda/conda

Issue:
Enable ssl_verify with config --get
`config get ssl_verify`

Gives

```
usage: conda config [-h] [--json] [--debug] [--verbose]
                    [--system | --env | --file FILE]
                    (--show | --show-sources | --validate | --describe | --get [KEY [KEY ...]] | --append KEY VALUE | --prepend KEY VALUE | --set KEY VALUE | --remove KEY VALUE | --remove-key KEY)
conda config: error: argument --get: invalid choice: 'ssl_verify' (choose from 'channels', 'disallow', 'create_default_packages', 'track_features', 'envs_dirs', 'pkgs_dirs', 'default_channels', 'pinned_packages', 'add_binstar_token', 'add_anaconda_token', 'add_pip_as_python_dependency', 'always_yes', 'always_copy', 'allow_softlinks', 'always_softlink', 'auto_update_conda', 'changeps1', 'use_pip', 'offline', 'binstar_upload', 'anaconda_upload', 'show_channel_urls', 'allow_other_channels', 'update_dependencies', 'channel_priority', 'shortcuts')
```

It should be possible to set it, it is a valid config parameter


Unable to set conda-build.root-dir with config
Not sure the right way to do this, but it looks like there might not be any right way ATM. I would like to be able to use `conda config` to get the following added to my `.condarc` file.

```yaml
conda-build:
    root-dir: /tmp
```

If I try to set `conda-build.root-dir` with `conda config`, I get this error.

```bash
$ conda config --set "conda-build.root-dir" "/tmp"


CondaValueError: Value error: Error key must be one of add_anaconda_token, shortcuts, add_pip_as_python_dependency, ssl_verify, client_tls_cert, binstar_upload, use_pip, add_binstar_token, always_copy, always_yes, client_tls_cert_key, channel_alias, changeps1, channel_priority, show_channel_urls, update_dependencies, allow_softlinks, anaconda_upload, offline, allow_other_channels, auto_update_conda, not conda-build.root-dir


```


Discussion:

cc @msarahan
`conda config --set` doesn't currently support map-type parameters.
It should be possible to do

`conda config --set proxy_servers.http 1.2.3.4:4004`

and

`conda config --get proxy_servers.http`

Resolving patch:
diff --git a/conda/cli/main_config.py b/conda/cli/main_config.py
--- a/conda/cli/main_config.py
+++ b/conda/cli/main_config.py
@@ -21,8 +21,7 @@
 from ..common.configuration import pretty_list, pretty_map
 from ..common.constants import NULL
 from ..common.yaml import yaml_dump, yaml_load
-from ..config import (rc_bool_keys, rc_list_keys, rc_other, rc_string_keys, sys_rc_path,
-                      user_rc_path)
+from ..config import rc_other, sys_rc_path, user_rc_path
 
 descr = """
 Modify configuration values in .condarc.  This is modeled after the git
@@ -228,6 +227,10 @@ def format_dict(d):
 
 
 def execute_config(args, parser):
+    try:
+        from cytoolz.itertoolz import groupby
+    except ImportError:  # pragma: no cover
+        from .._vendor.toolz.itertoolz import groupby  # NOQA
     from .._vendor.auxlib.entity import EntityEncoder
     json_warnings = []
     json_get = {}
@@ -317,13 +320,19 @@ def execute_config(args, parser):
     else:
         rc_config = {}
 
+    grouped_paramaters = groupby(lambda p: context.describe_parameter(p)['parameter_type'],
+                                 context.list_parameters())
+    primitive_parameters = grouped_paramaters['primitive']
+    sequence_parameters = grouped_paramaters['sequence']
+    map_parameters = grouped_paramaters['map']
+
     # Get
     if args.get is not None:
         context.validate_all()
         if args.get == []:
             args.get = sorted(rc_config.keys())
         for key in args.get:
-            if key not in rc_list_keys + rc_bool_keys + rc_string_keys:
+            if key not in primitive_parameters + sequence_parameters:
                 if key not in rc_other:
                     message = "unknown key %s" % key
                     if not context.json:
@@ -356,8 +365,6 @@ def execute_config(args, parser):
 
     # prepend, append, add
     for arg, prepend in zip((args.prepend, args.append), (True, False)):
-        sequence_parameters = [p for p in context.list_parameters()
-                               if context.describe_parameter(p)['parameter_type'] == 'sequence']
         for key, item in arg:
             if key == 'channels' and key not in rc_config:
                 rc_config[key] = ['defaults']
@@ -385,16 +392,20 @@ def execute_config(args, parser):
 
     # Set
     for key, item in args.set:
-        primitive_parameters = [p for p in context.list_parameters()
-                                if context.describe_parameter(p)['parameter_type'] == 'primitive']
-        if key not in primitive_parameters:
+        key, subkey = key.split('.', 1) if '.' in key else (key, None)
+        if key in primitive_parameters:
+            value = context.typify_parameter(key, item)
+            rc_config[key] = value
+        elif key in map_parameters:
+            argmap = rc_config.setdefault(key, {})
+            argmap[subkey] = item
+        else:
             from ..exceptions import CondaValueError
             raise CondaValueError("Key '%s' is not a known primitive parameter." % key)
-        value = context.typify_parameter(key, item)
-        rc_config[key] = value
 
     # Remove
     for key, item in args.remove:
+        key, subkey = key.split('.', 1) if '.' in key else (key, None)
         if key not in rc_config:
             if key != 'channels':
                 from ..exceptions import CondaKeyError
@@ -408,6 +419,7 @@ def execute_config(args, parser):
 
     # Remove Key
     for key, in args.remove_key:
+        key, subkey = key.split('.', 1) if '.' in key else (key, None)
         if key not in rc_config:
             from ..exceptions import CondaKeyError
             raise CondaKeyError(key, "key %r is not in the config file" %


Test patch:
diff --git a/tests/test_config.py b/tests/test_config.py
--- a/tests/test_config.py
+++ b/tests/test_config.py
@@ -656,15 +656,38 @@ def test_config_set():
     with make_temp_condarc() as rc:
         stdout, stderr, return_code = run_command(Commands.CONFIG, '--file', rc,
                                                   '--set', 'always_yes', 'yes')
-
         assert stdout == ''
         assert stderr == ''
+        with open(rc) as fh:
+            content = yaml_load(fh.read())
+            assert content['always_yes'] is True
 
         stdout, stderr, return_code = run_command(Commands.CONFIG, '--file', rc,
                                                   '--set', 'always_yes', 'no')
+        assert stdout == ''
+        assert stderr == ''
+        with open(rc) as fh:
+            content = yaml_load(fh.read())
+            assert content['always_yes'] is False
 
+        stdout, stderr, return_code = run_command(Commands.CONFIG, '--file', rc,
+                                                  '--set', 'proxy_servers.http', '1.2.3.4:5678')
         assert stdout == ''
         assert stderr == ''
+        with open(rc) as fh:
+            content = yaml_load(fh.read())
+            assert content['always_yes'] is False
+            assert content['proxy_servers'] == {'http': '1.2.3.4:5678'}
+
+        stdout, stderr, return_code = run_command(Commands.CONFIG, '--file', rc,
+                                                  '--set', 'ssl_verify', 'false')
+        assert stdout == ''
+        assert stderr == ''
+
+        stdout, stderr, return_code = run_command(Commands.CONFIG, '--file', rc,
+                                                  '--get', 'ssl_verify')
+        assert stdout.strip() == '--set ssl_verify False'
+        assert stderr == ''
 
 
 def test_set_rc_string():