Repository: dbt-labs/dbt-core

Issue:
If opening a new tab in the local web browser blocks, dbt deadlocks
### Describe the bug
If `webbrowser.open_new_tab` blocks (for example, because your only browser is `w3m` and it takes over your console), `dbt docs serve` deadlocks until the browser process is killed.

### Steps To Reproduce
Two choices
- Install w3m and make a small code change to serve.py's first `try:` block:
`webbrowser.get('w3m').open_new_tab('http://127.0.0.1:{}'.format(port))`
- try to `dbt docs serve`, note that it hangs locally waiting for localhost
- note that even opening a tab in firefox doesn't work!
- note that killing the `w3m` process dbt opened makes the server start properly

Alternatively:
- Uninstall all browsers except w3m (or provision a new system with only w3m)
- try to `dbt docs serve`, note that it hangs locally waiting for localhost
- note that even opening a tab from another system doesn't work!
- note that killing the `w3m` process dbt opened makes the server start properly


### Expected behavior
dbt should probably do two things
1) let me not get stuck in w3m in the first place by providing a flag to avoid the `open_new_tab` call
2) not deadlock at all, probably by calling `webbrowser` stuff in a subprocess or something?

But if you solve the first you can just ignore the second, really.

### Screenshots and log output
If applicable, add screenshots or log output to help explain your problem.

### System information
**Which database are you using dbt with?**
Any


**The output of `dbt --version`:**
```
installed version: 0.15.0
   latest version: 0.15.0

Up to date!
```

**The operating system you're using:**
macos, user reported it on ubuntu or something, I assume it's a problem anywhere

**The output of `python --version`:**
Any

### Additional context
dbt actually deadlocks here - the browser won't open the window because the server isn't started, but the server won't start until `webbrowser.open_new_tab` has finished!


Discussion:

Resolving patch:
diff --git a/core/dbt/main.py b/core/dbt/main.py
--- a/core/dbt/main.py
+++ b/core/dbt/main.py
@@ -536,6 +536,11 @@ def _build_docs_serve_subparser(subparsers, base_subparser):
         Specify the port number for the docs server.
         '''
     )
+    serve_sub.add_argument(
+        '--no-browser',
+        dest='open_browser',
+        action='store_false',
+    )
     serve_sub.set_defaults(cls=serve_task.ServeTask, which='serve',
                            rpc_method=None)
     return serve_sub
diff --git a/core/dbt/task/serve.py b/core/dbt/task/serve.py
--- a/core/dbt/task/serve.py
+++ b/core/dbt/task/serve.py
@@ -31,10 +31,11 @@ def run(self):
             SimpleHTTPRequestHandler  # type: ignore
         )  # type: ignore
 
-        try:
-            webbrowser.open_new_tab('http://127.0.0.1:{}'.format(port))
-        except webbrowser.Error:
-            pass
+        if self.args.open_browser:
+            try:
+                webbrowser.open_new_tab(f'http://127.0.0.1:{port}')
+            except webbrowser.Error:
+                pass
 
         try:
             httpd.serve_forever()  # blocks


Test patch: