Repository: e-valuation/EvaP

Issue:
Remove sass + ts compilation from ./manage.py run
These slow down starting the development server.

For developers actually changing TS or SASS files, they are not helpful enough, and those will likely start a `--watch` job anyway. We can simply provide a ´./manage.py watch` script for this use case.

For anyone else, they simply slow down the development server startup, which is a bit annoying.

Opinions?


Discussion:
I thought about this again and just removing compilation could really do us more harm than good. Before, we came to the conclusion that we can spare newcomers the burden of thinking about compiling ts and scss by doing it for them in the provision script, but what happens when they pull updates from main that change these files or add new ones? This could lead to great confusion / frustration for them and us. Maybe the solution we want is opt-in behavior, like a `--no-compile` / `--fast` / `-f` flag that skips the two and that we can tell people to use once they are comfortable with the project setup / annoyed by the long startup time. What do you think?
Good point. Similar things are true for dependencies (npm, pip), but those probably change less frequently.

Honestly: I'm lazy and don't want to type `-f` (+3 key strokes = +37% compared to `./m<TAB> ru<TAB>`) -> I think the default should be fast.

I would be fine with starting the jobs in the background. They could even be `--watch` jobs running the background. I think the main reason we didn't make them --watch jobs is because their output was mushed together (or we just couldn't get it to work), but honestly, if you're editing TS and you want clean output, I think then you could just `./manage.py run --no-watch` and `./manage.py ts compile --watch` in another console.
Haven't thought about background jobs yet, how do you feel about starting a background process that compiles the files once? This way, we don't get (much) output mangled in the python output

Resolving patch:
diff --git a/evap/development/management/commands/run.py b/evap/development/management/commands/run.py
--- a/evap/development/management/commands/run.py
+++ b/evap/development/management/commands/run.py
@@ -1,4 +1,5 @@
 import sys
+from subprocess import Popen  # nosec
 
 from django.core.management import execute_from_command_line
 from django.core.management.base import BaseCommand
@@ -9,10 +10,8 @@ class Command(BaseCommand):
     help = 'Execute "runserver 0.0.0.0:8000"'
 
     def handle(self, *args, **options):
-        self.stdout.write('Executing "manage.py scss"')
-        execute_from_command_line(["manage.py", "scss"])
-        self.stdout.write('Executing "manage.py ts compile"')
-        execute_from_command_line(["manage.py", "ts", "compile"])
-        self.stdout.write('Executing "manage.py runserver 0.0.0.0:8000"')
-        sys.argv = ["manage.py", "runserver", "0.0.0.0:8000"]
-        execute_from_command_line(sys.argv)
+        self.stdout.write('Executing "manage.py scss" and "manage.py ts compile"')
+        with Popen(["./manage.py", "scss"]), Popen(["./manage.py", "ts", "compile"]):  # nosec
+            self.stdout.write('Executing "manage.py runserver 0.0.0.0:8000"')
+            sys.argv = ["manage.py", "runserver", "0.0.0.0:8000"]
+            execute_from_command_line(sys.argv)


Test patch:
diff --git a/evap/development/tests/test_commands.py b/evap/development/tests/test_commands.py
--- a/evap/development/tests/test_commands.py
+++ b/evap/development/tests/test_commands.py
@@ -57,15 +57,17 @@ def test_executes_key_commands(self, mock_call_command, mock_input):
 
 
 class TestRunCommand(TestCase):
-    @staticmethod
-    def test_calls_runserver():
-        with patch("django.core.management.execute_from_command_line") as mock:
-            management.call_command("run", stdout=StringIO())
+    def test_calls_runserver(self):
+        with patch("django.core.management.execute_from_command_line") as execute_mock:
+            with patch("subprocess.Popen") as popen_mock:
+                management.call_command("run", stdout=StringIO())
 
-        mock.assert_has_calls(
+        execute_mock.assert_called_once_with(["manage.py", "runserver", "0.0.0.0:8000"])
+        self.assertEqual(popen_mock.call_count, 2)
+        popen_mock.assert_has_calls(
             [
-                call(["manage.py", "scss"]),
-                call(["manage.py", "ts", "compile"]),
-                call(["manage.py", "runserver", "0.0.0.0:8000"]),
-            ]
+                call(["./manage.py", "scss"]),
+                call(["./manage.py", "ts", "compile"]),
+            ],
+            any_order=True,
         )