Repository: typesafehub/conductr-cli

Issue:
Working directory being unlinked causes failure
When a working directory has been unlinked, the CLI fails to operate:

Reproduce:

```bash
$ mkdir ~/testing-dir && cd ~/testing-dir && rm -r ~/testing-dir && conduct load visualizer
sh: 0: getcwd() failed: No such file or directory
Retrieving bundle..
Loading bundle from cache typesafe/bundle/visualizer
Bintray credentials loaded from /home/longshorej/.lightbend/commercial.credentials
Error: Encountered unexpected error.
Error: Reason: FileNotFoundError [Errno 2] No such file or directory
Error: Further information of the error can be found in the error log file: /home/longshorej/.conductr/errors.log
-> 1
```

Stack trace:

```bash
2017-06-21 10:19:31,962: Failure running the following command: ['/home/longshorej/.local/bin/conduct', 'load', 'visualizer']
Traceback (most recent call last):
  File "/home/longshorej/work/lightbend/conductr-cli/conductr_cli/main_handler.py", line 14, in run
    result = callback()
  File "/home/longshorej/work/lightbend/conductr-cli/conductr_cli/conduct.py", line 35, in main_method
    conduct_main.run()
  File "/home/longshorej/work/lightbend/conductr-cli/conductr_cli/conduct_main.py", line 610, in run
    is_completed_without_error = args.func(args)
  File "/home/longshorej/work/lightbend/conductr-cli/conductr_cli/validation.py", line 43, in handler
    return func(*args, **kwargs)
  File "/home/longshorej/work/lightbend/conductr-cli/conductr_cli/validation.py", line 59, in handler
    return func(*args, **kwargs)
  File "/home/longshorej/work/lightbend/conductr-cli/conductr_cli/validation.py", line 99, in handler
    return func(*args, **kwargs)
  File "/home/longshorej/work/lightbend/conductr-cli/conductr_cli/validation.py", line 116, in handler
    return func(*args, **kwargs)
  File "/home/longshorej/work/lightbend/conductr-cli/conductr_cli/validation.py", line 136, in handler
    return func(*args, **kwargs)
  File "/home/longshorej/work/lightbend/conductr-cli/conductr_cli/validation.py", line 152, in handler
    return func(*args, **kwargs)
  File "/home/longshorej/work/lightbend/conductr-cli/conductr_cli/validation.py", line 198, in handler
    return func(*args, **kwargs)
  File "/home/longshorej/work/lightbend/conductr-cli/conductr_cli/validation.py", line 222, in handler
    return func(*args, **kwargs)
  File "/home/longshorej/work/lightbend/conductr-cli/conductr_cli/validation.py", line 238, in handler
    return func(*args, **kwargs)
  File "/home/longshorej/work/lightbend/conductr-cli/conductr_cli/validation.py", line 256, in handler
    return func(*args, **kwargs)
  File "/home/longshorej/work/lightbend/conductr-cli/conductr_cli/validation.py", line 428, in handler
    return func(*args, **kwargs)
  File "/home/longshorej/work/lightbend/conductr-cli/conductr_cli/validation.py", line 464, in handler
    return func(*args, **kwargs)
  File "/home/longshorej/work/lightbend/conductr-cli/conductr_cli/conduct_load.py", line 71, in load
    return load_v2(args)
  File "/home/longshorej/work/lightbend/conductr-cli/conductr_cli/conduct_load.py", line 249, in load_v2
    args.bundle, args.offline_mode)
  File "/home/longshorej/work/lightbend/conductr-cli/conductr_cli/resolver.py", line 28, in resolve_bundle
    is_resolved, bundle_file_name, bundle_file, error = resolver.resolve_bundle(cache_dir, uri)
  File "/home/longshorej/work/lightbend/conductr-cli/conductr_cli/resolvers/uri_resolver.py", line 17, in resolve_bundle
    return resolve_file(cache_dir, uri, auth)
  File "/home/longshorej/work/lightbend/conductr-cli/conductr_cli/resolvers/uri_resolver.py", line 28, in resolve_file
    file_name, file_url = get_url(uri)
  File "/home/longshorej/work/lightbend/conductr-cli/conductr_cli/resolvers/uri_resolver.py", line 91, in get_url
    np = str(op.cwd() / op)
  File "/usr/lib/python3.5/pathlib.py", line 1023, in cwd
    return cls(os.getcwd())
FileNotFoundError: [Errno 2] No such file or directory
```

Comments:

Patch:
diff --git a/1 b/1
new file mode 100644
index 0000000..e69de29
diff --git a/conductr_cli/__init__.py b/conductr_cli/__init__.py
index 7311807..dee93a9 100644
--- a/conductr_cli/__init__.py
+++ b/conductr_cli/__init__.py
@@ -1,1 +1,1 @@
-__version__ = '1.2.15'
+__version__ = '1.2.16'
diff --git a/conductr_cli/main_handler.py b/conductr_cli/main_handler.py
index 2f4056a..fc0cc8e 100644
--- a/conductr_cli/main_handler.py
+++ b/conductr_cli/main_handler.py
@@ -11,6 +11,7 @@ SUPPORTED_PYTHON_VERSION = (3, 4)
 def run(callback):
     try:
         enforce_python_version()
+        enforce_cwd_exists()
         result = callback()
         return result
     except KeyboardInterrupt:
@@ -46,6 +47,14 @@ def run(callback):
         sys.exit(1)
 
 
+def enforce_cwd_exists():
+    try:
+        os.getcwd()
+    except FileNotFoundError:
+        sys.exit('Unable to start CLI due to missing current/working directory.\n'
+                 'Change into a new directory and try again.\n')
+
+
 def enforce_python_version():
     if sys.version_info < SUPPORTED_PYTHON_VERSION:
         major, minor, micro, release_level, serial = sys.version_info
diff --git a/conductr_cli/resolvers/bintray_resolver.py b/conductr_cli/resolvers/bintray_resolver.py
index 4501b87..b01da9e 100644
--- a/conductr_cli/resolvers/bintray_resolver.py
+++ b/conductr_cli/resolvers/bintray_resolver.py
@@ -15,7 +15,7 @@ BINTRAY_API_BASE_URL = 'https://api.bintray.com'
 BINTRAY_DOWNLOAD_BASE_URL = 'https://dl.bintray.com'
 BINTRAY_DOWNLOAD_REALM = 'Bintray'
 BINTRAY_CREDENTIAL_FILE_PATH = '{}/.lightbend/commercial.credentials'.format(os.path.expanduser('~'))
-BINTRAY_PROPERTIES_RE = re.compile('^\s*(\S+)\s*=\s*([\S]+)\s*$')
+BINTRAY_PROPERTIES_RE = re.compile('^\s*(\S+)\s*=\s*((\S|\S+\s+\S+)+)\s*$')
 BINTRAY_LIGHTBEND_ORG = 'lightbend'
 BINTRAY_CONDUCTR_COMMERCIAL_REPO = 'commercial-releases'
 BINTRAY_CONDUCTR_GENERIC_REPO = 'generic'
@@ -168,12 +168,16 @@ def load_bintray_credentials(raise_error=True, disable_instructions=False):
         with open(BINTRAY_CREDENTIAL_FILE_PATH, 'r') as cred_file:
             lines = [line.replace('\n', '') for line in cred_file.readlines()]
             data = dict()
+            realm = BINTRAY_DOWNLOAD_REALM
             for line in lines:
                 match = BINTRAY_PROPERTIES_RE.match(line)
                 if match is not None:
                     try:
                         key, value = match.group(1, 2)
-                        data[key] = value
+                        if key == 'realm':
+                            realm = value
+                        elif realm == BINTRAY_DOWNLOAD_REALM:
+                            data[key] = value
                     except IndexError:
                         pass
 


Test patch:
diff --git a/conductr_cli/resolvers/test/test_bintray_resolver.py b/conductr_cli/resolvers/test/test_bintray_resolver.py
index 4790058..9cc48c3 100644
--- a/conductr_cli/resolvers/test/test_bintray_resolver.py
+++ b/conductr_cli/resolvers/test/test_bintray_resolver.py
@@ -1018,6 +1018,29 @@ class TestLoadBintrayCredentials(TestCase):
         exists_mock.assert_called_with('{}/.lightbend/commercial.credentials'.format(os.path.expanduser('~')))
         open_mock.assert_called_with('{}/.lightbend/commercial.credentials'.format(os.path.expanduser('~')), 'r')
 
+    def test_success_multiple_realms(self):
+        bintray_credential_file = (
+            'realm = Bintray\n'
+            'user = user1\n'
+            'password = sec=ret\n'
+            'realm = Bintray API Realm\n'
+            'user = user2\n'
+            'password = sec=ret2\n'
+        )
+
+        exists_mock = MagicMock(return_value=True)
+        open_mock = MagicMock(return_value=io.StringIO(bintray_credential_file))
+
+        with patch('os.path.exists', exists_mock), \
+                patch('builtins.open', open_mock):
+            realm, username, password = bintray_resolver.load_bintray_credentials()
+            self.assertEqual('Bintray', realm)
+            self.assertEqual('user1', username)
+            self.assertEqual('sec=ret', password)
+
+        exists_mock.assert_called_with('{}/.lightbend/commercial.credentials'.format(os.path.expanduser('~')))
+        open_mock.assert_called_with('{}/.lightbend/commercial.credentials'.format(os.path.expanduser('~')), 'r')
+
     def test_credential_file_not_having_username_password(self):
         bintray_credential_file = strip_margin(
             """|dummy = yes