Repository: allenai/tango (language: python)

Issue:
Allow setting the run name as a command-line option
For example,

`tango run --name run1 config.jsonnet`

This would require:
- Adding another `click` option for the run name to the `run` command function: https://github.com/allenai/tango/blob/a17807666d39cecb82d23aa508c38348e7ff0edc/tango/__main__.py#L229
- Passing the run name to `Executor.execute_step_graph()` here: https://github.com/allenai/tango/blob/a17807666d39cecb82d23aa508c38348e7ff0edc/tango/__main__.py#L377
- Modifying [`Executor.execute_step_graph()`](https://github.com/allenai/tango/blob/a17807666d39cecb82d23aa508c38348e7ff0edc/tango/executor.py#L33) to accept the run name as a parameter.


Discussion / hints:

Fix patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6c909a6fc..7f7b90895 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 ### Added
 
+- Added the "-n/--name" option to `tango run`. This option allows the user to give the run an arbitrary name.
 - Added a convenience property `.workspace` to `Step` class that can be called from a step's `.run()` method to get the current `Workspace` being used.
 - Gave `FromParams` objects (which includes all `Registrable` objects) the ability to version themselves.
 
diff --git a/tango/__main__.py b/tango/__main__.py
index 74e6b28f7..de52b8bb8 100644
--- a/tango/__main__.py
+++ b/tango/__main__.py
@@ -227,6 +227,12 @@ def cleanup(*args, **kwargs):
     help="Start a server that visualizes the current run",
     default=True,
 )
+@click.option(
+    "-n",
+    "--name",
+    type=str,
+    help="""Specify the name for this run""",
+)
 @click.pass_obj
 def run(
     settings: TangoGlobalSettings,
@@ -236,6 +242,7 @@ def run(
     overrides: Optional[str] = None,
     include_package: Optional[Sequence[str]] = None,
     server: bool = True,
+    name: Optional[str] = None,
 ):
     """
     Run a tango experiment.
@@ -264,6 +271,7 @@ def run(
         overrides=overrides,
         include_package=include_package,
         start_server=server,
+        name=name,
     )
 
 
@@ -582,6 +590,7 @@ def _run(
     overrides: Optional[str] = None,
     include_package: Optional[Sequence[str]] = None,
     start_server: bool = True,
+    name: Optional[str] = None,
 ) -> str:
     from tango.executor import Executor
     from tango.server.workspace_server import WorkspaceServer
@@ -614,7 +623,7 @@ def _run(
     # Initialize step graph and register run.
     step_graph = StepGraph(params.pop("steps", keep_as_dict=True))
     params.assert_empty("'tango run'")
-    run = workspace.register_run(step for step in step_graph.values())
+    run = workspace.register_run((step for step in step_graph.values()), name)
 
     # Capture logs to file.
     with workspace.capture_logs_for_run(run.name):


Test patch:
diff --git a/tests/main_test.py b/tests/main_test.py
index 97fdb14ff..4f16505cd 100644
--- a/tests/main_test.py
+++ b/tests/main_test.py
@@ -150,6 +150,25 @@ def test_random_experiment(self):
         result = subprocess.run(cmd)
         assert result.returncode == 0
 
+    def test_run_name(self):
+        name = "unique-tango-run-name"
+        cmd = [
+            "tango",
+            "run",
+            str(self.FIXTURES_ROOT / "experiment" / "hello_world.jsonnet"),
+            "-i",
+            "test_fixtures.package",
+            "-w",
+            str(self.TEST_DIR),
+            "--name",
+            name,
+        ]
+        result = subprocess.run(cmd, capture_output=True)
+        run_dir = next((self.TEST_DIR / "runs").iterdir())
+        _, clean_log_lines = self.check_logs(run_dir, result)
+        assert result.returncode == 0
+        assert f"Starting new run {name}" == clean_log_lines[0]
+
     @pytest.mark.parametrize("start_method", ["fork", "spawn"])
     @pytest.mark.parametrize("file_friendly_logging", [True, False])
     def test_experiment_with_multiprocessing(self, file_friendly_logging, start_method):