Repository: strawberry-graphql/strawberry

Issue:
Refactor CLI folder structure



Discussion:
Can you elaborate a bit on what you meant by refactor?
@harry-7 hi there!

Currently our CLI consist of only one file: https://github.com/strawberry-graphql/strawberry/blob/master/strawberry/cli/__init__.py

Would be nice to move to multiple files as we are going to have multiple commands in future. I'd love to fix the reloader too, which seems to be a bit broken at the moment.
Hello. So I don't see what else I need to move that directory. 

Resolving patch:
diff --git a/strawberry/cli/__init__.py b/strawberry/cli/__init__.py
--- a/strawberry/cli/__init__.py
+++ b/strawberry/cli/__init__.py
@@ -1,17 +1,6 @@
 import click
-import sys
 
-import os
-from starlette.applications import Starlette
-from starlette.middleware.cors import CORSMiddleware
-
-import importlib
-
-import uvicorn
-
-import hupper
-
-from strawberry.asgi import GraphQL
+from .commands.server import server as cmd_server
 
 
 @click.group()
@@ -19,30 +8,4 @@ def run():
     pass
 
 
-@run.command("server")
-@click.argument("module", type=str)
-@click.option("-h", "--host", default="0.0.0.0", type=str)
-@click.option("-p", "--port", default=8000, type=int)
-def server(module, host, port):
-    sys.path.append(os.getcwd())
-
-    reloader = hupper.start_reloader("strawberry.cli.run", verbose=False)
-
-    schema_module = importlib.import_module(module)
-
-    reloader.watch_files([schema_module.__file__])
-
-    app = Starlette(debug=True)
-
-    app.add_middleware(
-        CORSMiddleware, allow_headers=["*"], allow_origins=["*"], allow_methods=["*"]
-    )
-
-    graphql_app = GraphQL(schema_module.schema, debug=True)
-
-    app.add_route("/graphql", graphql_app)
-    app.add_websocket_route("/graphql", graphql_app)
-
-    print(f"Running strawberry on http://{host}:{port}/graphql 🍓")
-
-    uvicorn.run(app, host=host, port=port, log_level="error")
+run.add_command(cmd_server)
diff --git a/strawberry/cli/commands/__init__.py b/strawberry/cli/commands/__init__.py
new file mode 100644
diff --git a/strawberry/cli/commands/server.py b/strawberry/cli/commands/server.py
new file mode 100644
--- /dev/null
+++ b/strawberry/cli/commands/server.py
@@ -0,0 +1,43 @@
+import click
+import sys
+
+import os
+from starlette.applications import Starlette
+from starlette.middleware.cors import CORSMiddleware
+
+import importlib
+
+import uvicorn
+
+import hupper
+
+from strawberry.asgi import GraphQL
+
+
+@click.command("server", short_help='Starts debug server')
+@click.argument("module", type=str)
+@click.option("-h", "--host", default="0.0.0.0", type=str)
+@click.option("-p", "--port", default=8000, type=int)
+def server(module, host, port):
+    sys.path.append(os.getcwd())
+
+    reloader = hupper.start_reloader("strawberry.cli.run", verbose=False)
+
+    schema_module = importlib.import_module(module)
+
+    reloader.watch_files([schema_module.__file__])
+
+    app = Starlette(debug=True)
+
+    app.add_middleware(
+        CORSMiddleware, allow_headers=["*"], allow_origins=["*"], allow_methods=["*"]
+    )
+
+    graphql_app = GraphQL(schema_module.schema, debug=True)
+
+    app.add_route("/graphql", graphql_app)
+    app.add_websocket_route("/graphql", graphql_app)
+
+    print(f"Running strawberry on http://{host}:{port}/graphql 🍓")
+
+    uvicorn.run(app, host=host, port=port, log_level="error")


Test patch:
diff --git a/tests/cli/__init__.py b/tests/cli/__init__.py
new file mode 100644
diff --git a/tests/cli/helpers/sample_schema.py b/tests/cli/helpers/sample_schema.py
new file mode 100644
--- /dev/null
+++ b/tests/cli/helpers/sample_schema.py
@@ -0,0 +1,17 @@
+import strawberry
+
+
+@strawberry.type
+class User:
+    name: str
+    age: int
+
+
+@strawberry.type
+class Query:
+    @strawberry.field
+    def user(self, info) -> User:
+        return User(name="Patrick", age=100)
+
+
+schema = strawberry.Schema(query=Query)
diff --git a/tests/cli/test_server.py b/tests/cli/test_server.py
new file mode 100644
--- /dev/null
+++ b/tests/cli/test_server.py
@@ -0,0 +1,32 @@
+from click.testing import CliRunner
+
+from strawberry.cli.commands.server import server as cmd_server
+
+import uvicorn
+import hupper
+
+
+def test_cli_cmd_server(mocker):
+
+    # Mock of uvicorn.run
+    uvicorn_run_patch = mocker.patch('uvicorn.run')
+    uvicorn_run_patch.return_value = True
+    # Mock to prevent the reloader from kicking in
+    hupper_reloader_patch = mocker.patch('hupper.start_reloader')
+    hupper_reloader_patch.return_value = MockReloader()
+    runner = CliRunner()
+
+    result = runner.invoke(cmd_server, ['tests.cli.helpers.sample_schema'], "")
+    assert result.exit_code == 0
+
+    # We started the reloader
+    assert hupper.start_reloader.call_count == 1
+    assert uvicorn.run.call_count == 1
+
+    assert result.output == 'Running strawberry on http://0.0.0.0:8000/graphql 🍓\n'
+
+
+class MockReloader:
+    @staticmethod
+    def watch_files(*args, **kwargs):
+        return True