Repository: conda/conda

Issue:
conda config needs --prepend; change behavior of --add to --append
referencing https://github.com/conda/conda/issues/2841
- conda config needs `--prepend`
- change behavior of `--add` to `--append`
- un-reverse order of `conda config --get channels`



Discussion:

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
@@ -151,21 +151,19 @@ def configure_parser(sub_parsers):
         choices=BoolOrListKey()
     )
     action.add_argument(
-        "--add",
+        "--append", "--add",
         nargs=2,
         action="append",
-        help="""Add one configuration value to the beginning of a list key.
-        To add to the end of the list, use --append.""",
+        help="""Add one configuration value to the end of a list key.""",
         default=[],
         choices=ListKey(),
         metavar=('KEY', 'VALUE'),
     )
     action.add_argument(
-        "--append",
+        "--prepend",
         nargs=2,
         action="append",
-        help="""Add one configuration value to a list key. The default
-        behavior is to prepend.""",
+        help="""Add one configuration value to the beginning of a list key.""",
         default=[],
         choices=ListKey(),
         metavar=('KEY', 'VALUE'),
@@ -260,7 +258,7 @@ def execute_config(args, parser):
                 # recreate the same file
                 items = rc_config.get(key, [])
                 numitems = len(items)
-                for q, item in enumerate(reversed(items)):
+                for q, item in enumerate(items):
                     # Use repr so that it can be pasted back in to conda config --add
                     if key == "channels" and q in (0, numitems-1):
                         print("--add", key, repr(item),
@@ -268,8 +266,8 @@ def execute_config(args, parser):
                     else:
                         print("--add", key, repr(item))
 
-    # Add, append
-    for arg, prepend in zip((args.add, args.append), (True, False)):
+    # prepend, append, add
+    for arg, prepend in zip((args.prepend, args.append), (True, False)):
         for key, item in arg:
             if key == 'channels' and key not in rc_config:
                 rc_config[key] = ['defaults']
@@ -287,7 +285,7 @@ def execute_config(args, parser):
             if item in arglist:
                 # Right now, all list keys should not contain duplicates
                 message = "Warning: '%s' already in '%s' list, moving to the %s" % (
-                    item, key, "front" if prepend else "back")
+                    item, key, "top" if prepend else "bottom")
                 arglist = rc_config[key] = [p for p in arglist if p != item]
                 if not args.json:
                     print(message, file=sys.stderr)
diff --git a/conda/exceptions.py b/conda/exceptions.py
--- a/conda/exceptions.py
+++ b/conda/exceptions.py
@@ -197,6 +197,12 @@ def __init__(self, message, *args, **kwargs):
         super(PackageNotFoundError, self).__init__(msg, *args, **kwargs)
 
 
+class CondaHTTPError(CondaError):
+    def __init__(self, message, *args, **kwargs):
+        msg = 'HTTP Error: %s\n' % message
+        super(CondaHTTPError, self).__init__(msg, *args, **kwargs)
+
+
 class NoPackagesFoundError(CondaError, RuntimeError):
     '''An exception to report that requested packages are missing.
 
@@ -352,7 +358,7 @@ def print_exception(exception):
 
 
 def get_info():
-    from StringIO import StringIO
+    from conda.compat import StringIO
     from contextlib import contextmanager
     from conda.cli import conda_argparse
     from conda.cli.main_info import configure_parser
diff --git a/conda/fetch.py b/conda/fetch.py
--- a/conda/fetch.py
+++ b/conda/fetch.py
@@ -27,8 +27,8 @@
                       rm_rf, exp_backoff_fn)
 from .lock import Locked as Locked
 from .utils import memoized
-from .exceptions import ProxyError, ChannelNotAllowed, CondaRuntimeError, CondaSignatureError
-
+from .exceptions import ProxyError, ChannelNotAllowed, CondaRuntimeError, CondaSignatureError, \
+    CondaError, CondaHTTPError
 
 log = getLogger(__name__)
 dotlog = getLogger('dotupdate')
@@ -159,7 +159,7 @@ def fetch_repodata(url, cache_dir=None, use_cache=False, session=None):
             msg = "HTTPError: %s: %s\n" % (e, remove_binstar_tokens(url))
 
         log.debug(msg)
-        raise CondaRuntimeError(msg)
+        raise CondaHTTPError(msg)
 
     except requests.exceptions.SSLError as e:
         msg = "SSL Error: %s\n" % e


Test patch:
diff --git a/tests/test_config.py b/tests/test_config.py
--- a/tests/test_config.py
+++ b/tests/test_config.py
@@ -303,19 +303,19 @@ def test_config_command_basics():
         assert stdout == stderr == ''
         assert _read_test_condarc(rc) == """\
 channels:
-  - test
   - defaults
+  - test
 """
     with make_temp_condarc() as rc:
         # When defaults is explicitly given, it should not be added
         stdout, stderr = run_conda_command('config', '--file', rc, '--add',
             'channels', 'test', '--add', 'channels', 'defaults')
         assert stdout == ''
-        assert stderr == "Warning: 'defaults' already in 'channels' list, moving to the front"
+        assert stderr == "Warning: 'defaults' already in 'channels' list, moving to the bottom"
         assert _read_test_condarc(rc) == """\
 channels:
-  - defaults
   - test
+  - defaults
 """
     # Duplicate keys should not be added twice
     with make_temp_condarc() as rc:
@@ -325,11 +325,11 @@ def test_config_command_basics():
         stdout, stderr = run_conda_command('config', '--file', rc, '--add',
             'channels', 'test')
         assert stdout == ''
-        assert stderr == "Warning: 'test' already in 'channels' list, moving to the front"
+        assert stderr == "Warning: 'test' already in 'channels' list, moving to the bottom"
         assert _read_test_condarc(rc) == """\
 channels:
-  - test
   - defaults
+  - test
 """
 
     # Test append
@@ -340,7 +340,7 @@ def test_config_command_basics():
         stdout, stderr = run_conda_command('config', '--file', rc, '--append',
             'channels', 'test')
         assert stdout == ''
-        assert stderr == "Warning: 'test' already in 'channels' list, moving to the back"
+        assert stderr == "Warning: 'test' already in 'channels' list, moving to the bottom"
         assert _read_test_condarc(rc) == """\
 channels:
   - defaults
@@ -394,10 +394,10 @@ def test_config_command_get():
 --set always_yes True
 --set changeps1 False
 --set channel_alias http://alpha.conda.anaconda.org
---add channels 'defaults'   # lowest priority
---add channels 'test'   # highest priority
---add create_default_packages 'numpy'
---add create_default_packages 'ipython'\
+--add channels 'test'   # lowest priority
+--add channels 'defaults'   # highest priority
+--add create_default_packages 'ipython'
+--add create_default_packages 'numpy'\
 """
         assert stderr == "unknown key invalid_key"
 
@@ -405,8 +405,8 @@ def test_config_command_get():
         '--get', 'channels')
 
         assert stdout == """\
---add channels 'defaults'   # lowest priority
---add channels 'test'   # highest priority\
+--add channels 'test'   # lowest priority
+--add channels 'defaults'   # highest priority\
 """
         assert stderr == ""
 
@@ -423,8 +423,8 @@ def test_config_command_get():
 
         assert stdout == """\
 --set changeps1 False
---add channels 'defaults'   # lowest priority
---add channels 'test'   # highest priority\
+--add channels 'test'   # lowest priority
+--add channels 'defaults'   # highest priority\
 """
         assert stderr == ""
 
@@ -484,16 +484,23 @@ def test_config_command_parser():
         assert stdout == """\
 --set always_yes True
 --set changeps1 False
---add channels 'defaults'   # lowest priority
---add channels 'test'   # highest priority
---add create_default_packages 'numpy'
---add create_default_packages 'ipython'\
+--add channels 'test'   # lowest priority
+--add channels 'defaults'   # highest priority
+--add create_default_packages 'ipython'
+--add create_default_packages 'numpy'\
 """
+        print(">>>>")
+        with open(rc, 'r') as fh:
+            print(fh.read())
 
-        stdout, stderr = run_conda_command('config', '--file', rc, '--add',
-            'channels', 'mychannel')
+
+
+        stdout, stderr = run_conda_command('config', '--file', rc, '--prepend', 'channels', 'mychannel')
         assert stdout == stderr == ''
 
+        with open(rc, 'r') as fh:
+            print(fh.read())
+
         assert _read_test_condarc(rc) == """\
 channels:
   - mychannel