We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Implement `--dry-run` / `-n` option in CLI
We should have a `--dry-run`/`-n` option in the CLI which will print information about the commands to be run, but not actually run them. The CLI option exists, but needs to be implemented in the code.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/rastervision/cli/main.py`
Content:
```
1 """Raster Vision main program"""
2 import sys
3 from tempfile import TemporaryDirectory
4 
5 import click
6 
7 import rastervision as rv
8 from rastervision.experiment import (ExperimentLoader, LoaderError)
9 from rastervision.runner import (ExperimentRunner)
10 
11 
12 def print_error(msg):
13     click.echo(click.style(msg, fg='red'), err=True)
14 
15 
16 @click.group()
17 @click.option(
18     '--profile', '-p', help='Sets the configuration profile name to use.')
19 def main(profile):
20     # Initialize configuration
21     if profile:
22         rv._registry.initialize_config(profile=profile)
23 
24 
25 @main.command(
26     'run', short_help='Run Raster Vision commands against Experiments.')
27 @click.argument('runner')
28 @click.argument('commands', nargs=-1)
29 @click.option(
30     '--experiment_module',
31     '-e',
32     help=('Name of an importable module to look for experiment sets '
33           'in. If not supplied, experiments will be loaded '
34           'from __main__'))
35 @click.option(
36     '--dry-run',
37     '-n',
38     is_flag=True,
39     help=('Execute a dry run, which will print out information '
40           'about the commands to be run, but will not actually '
41           'run the commands'))
42 @click.option(
43     '--skip-file-check',
44     '-x',
45     is_flag=True,
46     help=('Skip the step that verifies that file exist.'))
47 @click.option(
48     '--arg',
49     '-a',
50     type=(str, str),
51     multiple=True,
52     metavar='KEY VALUE',
53     help=('Pass a parameter to the experiments if the method '
54           'parameter list takes in a parameter with that key. '
55           'Multiple args can be supplied'))
56 @click.option(
57     '--prefix',
58     metavar='PREFIX',
59     default='exp_',
60     help=('Prefix for methods containing experiments. (default: "exp_")'))
61 @click.option(
62     '--method',
63     '-m',
64     'methods',
65     multiple=True,
66     metavar='PATTERN',
67     help=('Pattern to match method names to run.'))
68 @click.option(
69     '--filter',
70     '-f',
71     'filters',
72     multiple=True,
73     metavar='PATTERN',
74     help=('Pattern to match experiment names to run.'))
75 @click.option(
76     '--rerun',
77     '-r',
78     is_flag=True,
79     default=False,
80     help=('Rerun commands, regardless if '
81           'their output files already exist.'))
82 def run(runner, commands, experiment_module, dry_run, skip_file_check, arg,
83         prefix, methods, filters, rerun):
84     """Run Raster Vision commands from experiments, using the
85     experiment runner named RUNNER."""
86     # Validate runner
87     valid_runners = list(
88         map(lambda x: x.lower(), rv.ExperimentRunner.list_runners()))
89     if runner not in valid_runners:
90         print_error('Invalid experiment runner: "{}". '
91                     'Must be one of: "{}"'.format(runner,
92                                                   '", "'.join(valid_runners)))
93         sys.exit(1)
94 
95     runner = ExperimentRunner.get_runner(runner)
96 
97     if experiment_module:
98         module_to_load = experiment_module
99     else:
100         module_to_load = '__main__'
101 
102     if not commands:
103         commands = rv.ALL_COMMANDS
104     else:
105         commands = list(map(lambda x: x.upper(), commands))
106 
107     experiment_args = {}
108     for k, v in arg:
109         experiment_args[k] = v
110 
111     loader = ExperimentLoader(
112         experiment_args=experiment_args,
113         experiment_method_prefix=prefix,
114         experiment_method_patterns=methods,
115         experiment_name_patterns=filters)
116     try:
117         experiments = loader.load_from_module(module_to_load)
118     except LoaderError as e:
119         print_error(str(e))
120         sys.exit(1)
121 
122     if not experiments:
123         if experiment_module:
124             print_error(
125                 'No experiments found in {}.'.format(experiment_module))
126         else:
127             print_error('No experiments found.')
128 
129     runner.run(
130         experiments,
131         commands_to_run=commands,
132         rerun_commands=rerun,
133         skip_file_check=skip_file_check)
134 
135 
136 @main.command()
137 @click.option(
138     '--experiment_module',
139     '-e',
140     help=('Name of an importable module to look for experiment sets '
141           'in. If not supplied, experiments will be loaded '
142           'from __main__'))
143 @click.option(
144     '--arg',
145     '-a',
146     type=(str, str),
147     multiple=True,
148     metavar='KEY VALUE',
149     help=('Pass a parameter to the experiments if the method '
150           'parameter list takes in a parameter with that key. '
151           'Multiple args can be supplied'))
152 def ls(experiment_module, arg):
153     """Print out a list of Experiment IDs."""
154     if experiment_module:
155         module_to_load = experiment_module
156     else:
157         module_to_load = '__main__'
158 
159     experiment_args = {}
160     for k, v in arg:
161         experiment_args[k] = v
162 
163     loader = ExperimentLoader(experiment_args=experiment_args)
164     try:
165         experiments = loader.load_from_module(module_to_load)
166     except LoaderError as e:
167         print_error(str(e))
168         sys.exit(1)
169 
170     if not experiments:
171         if experiment_module:
172             print_error(
173                 'No experiments found in {}.'.format(experiment_module))
174         else:
175             print_error('No experiments found.')
176 
177     for e in experiments:
178         click.echo('{}'.format(e.id))
179 
180 
181 @main.command(
182     'predict', short_help='Make predictions using a predict package.')
183 @click.argument('predict_package', type=click.Path(exists=True))
184 @click.argument('image_uri', type=click.Path(exists=True))
185 @click.argument('output_uri', type=click.Path(exists=False))
186 @click.option(
187     '--update_stats',
188     '-a',
189     is_flag=True,
190     help=('Run an analysis on this individual image, as '
191           'opposed to using any analysis like statistics '
192           'that exist in the prediction package'))
193 @click.option(
194     '--channel-order',
195     help='String containing channel_order.' + ' Example: \"2 1 0\"')
196 def predict(predict_package, image_uri, output_uri, update_stats,
197             channel_order):
198     """Make predictions on the image at IMAGE_URI
199     using PREDICT_PACKAGE and store the
200     prediciton output at OUTPUT_URI.
201     """
202     if channel_order is not None:
203         channel_order = [
204             int(channel_ind) for channel_ind in channel_order.split(' ')
205         ]
206     with TemporaryDirectory() as tmp_dir:
207         predict = rv.Predictor(predict_package, tmp_dir, update_stats,
208                                channel_order).predict
209         predict(image_uri, output_uri)
210 
211 
212 @main.command(
213     'run_command', short_help='Run a command from configuration file.')
214 @click.argument('command_config_uri')
215 def run_command(command_config_uri):
216     """Run a command from a serialized command configuration
217     at COMMAND_CONFIG_URI.
218     """
219     rv.runner.CommandRunner.run(command_config_uri)
220 
221 
222 if __name__ == '__main__':
223     main()
224
```

Path: `src/rastervision/runner/experiment_runner.py`
Content:
```
1 from abc import (ABC, abstractmethod)
2 from typing import (List, Union)
3 
4 import rastervision as rv
5 from rastervision.runner import (CommandDefinition, CommandDAG)
6 
7 
8 class ExperimentRunner(ABC):
9     def run(self,
10             experiments: Union[List[rv.ExperimentConfig], rv.ExperimentConfig],
11             commands_to_run=rv.ALL_COMMANDS,
12             rerun_commands=False,
13             skip_file_check=False):
14         if not isinstance(experiments, list):
15             experiments = [experiments]
16 
17         command_definitions = CommandDefinition.from_experiments(experiments)
18 
19         # Filter  out commands we aren't running.
20         command_definitions = CommandDefinition.filter_commands(
21             command_definitions, commands_to_run)
22 
23         # Check if there are any unsatisfied inputs.
24         missing_inputs = CommandDefinition.get_missing_inputs(
25             command_definitions)
26         if missing_inputs:
27             # TODO: Replace with logging?
28             s = ''
29             for exp_id in missing_inputs:
30                 s += 'In {}:\n\t{}\n'.format(
31                     exp_id, '\t{}\n'.join(missing_inputs[exp_id]))
32 
33             raise rv.ConfigError('There were missing input URIs '
34                                  'that are required, but were not '
35                                  'able to be derived: \n{}'.format(s))
36 
37         # Remove duplicate commands, defining equality for a command by
38         # the tuple (command_type, input_uris, output_uris)
39         (unique_commands, skipped_commands
40          ) = CommandDefinition.remove_duplicates(command_definitions)
41 
42         # Ensure that for each type of command, there are none that clobber
43         # each other's output.
44         clashing_commands = CommandDefinition.get_clashing_commands(
45             unique_commands)
46 
47         if clashing_commands:
48             clashing_msgs = []
49             for (output_uri, c_defs) in clashing_commands:
50                 command_type = c_defs[0].command_config.command_type
51                 experiments = ', '.join(map(lambda c: c.experiment_id, c_defs))
52                 clashing_msgs.append(
53                     'The {} command in the follwoing experiments '
54                     'output {}, but are not equal: {}'.format(
55                         command_type, output_uri, experiments))
56             # TODO: Replace with logging?
57             s = '\t\n'.join(clashing_msgs)
58 
59             raise rv.ConfigurationError(
60                 'ERROR: Command outputs will'
61                 'override each other: \n{}\n'.format(s))
62 
63         command_dag = CommandDAG(
64             unique_commands, rerun_commands, skip_file_check=skip_file_check)
65 
66         if skipped_commands or command_dag.skipped_commands:
67             # TODO: Report skipped commands, either in the dry run or elsewhere.
68             pass
69 
70         # Save experiment configs
71         experiments_by_id = dict(map(lambda e: (e.id, e), experiments))
72         seen_ids = set([])
73         for command_def in command_dag.get_command_definitions():
74             if command_def.experiment_id not in seen_ids:
75                 seen_ids.add(command_def.experiment_id)
76                 experiment = experiments_by_id[command_def.experiment_id]
77                 experiment.fully_resolve().save_config()
78 
79         self._run_experiment(command_dag)
80 
81     @abstractmethod
82     def _run_experiment(self, command_dag):
83         pass
84 
85     @staticmethod
86     def get_runner(runner_type):
87         """Gets the runner associated with this runner type."""
88         # Runner keys are upper cased.
89         return rv._registry.get_experiment_runner(runner_type.upper())
90 
91     @staticmethod
92     def list_runners():
93         """Returns a list of valid runner keys."""
94         return rv._registry.get_experiment_runner_keys()
95
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/src/rastervision/cli/main.py b/src/rastervision/cli/main.py
--- a/src/rastervision/cli/main.py
+++ b/src/rastervision/cli/main.py
@@ -130,7 +130,8 @@
         experiments,
         commands_to_run=commands,
         rerun_commands=rerun,
-        skip_file_check=skip_file_check)
+        skip_file_check=skip_file_check,
+        dry_run=dry_run)
 
 
 @main.command()
diff --git a/src/rastervision/runner/experiment_runner.py b/src/rastervision/runner/experiment_runner.py
--- a/src/rastervision/runner/experiment_runner.py
+++ b/src/rastervision/runner/experiment_runner.py
@@ -1,7 +1,8 @@
+import rastervision as rv
+
 from abc import (ABC, abstractmethod)
 from typing import (List, Union)
 
-import rastervision as rv
 from rastervision.runner import (CommandDefinition, CommandDAG)
 
 
@@ -10,15 +11,28 @@
             experiments: Union[List[rv.ExperimentConfig], rv.ExperimentConfig],
             commands_to_run=rv.ALL_COMMANDS,
             rerun_commands=False,
-            skip_file_check=False):
+            skip_file_check=False,
+            dry_run: bool = False):
         if not isinstance(experiments, list):
             experiments = [experiments]
 
-        command_definitions = CommandDefinition.from_experiments(experiments)
+        _command_definitions = CommandDefinition.from_experiments(experiments)
 
         # Filter  out commands we aren't running.
         command_definitions = CommandDefinition.filter_commands(
-            command_definitions, commands_to_run)
+            _command_definitions, commands_to_run)
+
+        # Print unrequested commands
+        if dry_run:
+            not_requested = set(_command_definitions) - set(command_definitions)
+            if not_requested:
+                print()
+                print('Not requsted:')
+                for command in not_requested:
+                    command_type = command.command_config.command_type
+                    experiment_id = command.experiment_id
+                    print('{} from {}'.format(command_type, experiment_id))
+                print()
 
         # Check if there are any unsatisfied inputs.
         missing_inputs = CommandDefinition.get_missing_inputs(
@@ -63,9 +77,17 @@
         command_dag = CommandDAG(
             unique_commands, rerun_commands, skip_file_check=skip_file_check)
 
-        if skipped_commands or command_dag.skipped_commands:
-            # TODO: Report skipped commands, either in the dry run or elsewhere.
-            pass
+        # Print conflicating or alread fulfilled commands
+        if dry_run:
+            skipped_commands.extend(command_dag.skipped_commands)
+            if skipped_commands:
+                print()
+                print('Skipped due to output conflicts:')
+                for command in skipped_commands:
+                    command_type = command.command_config.command_type
+                    experiment_id = command.experiment_id
+                    print('{} from {}'.format(command_type, experiment_id))
+                print()
 
         # Save experiment configs
         experiments_by_id = dict(map(lambda e: (e.id, e), experiments))
@@ -74,9 +96,19 @@
             if command_def.experiment_id not in seen_ids:
                 seen_ids.add(command_def.experiment_id)
                 experiment = experiments_by_id[command_def.experiment_id]
-                experiment.fully_resolve().save_config()
-
-        self._run_experiment(command_dag)
+                if not dry_run:
+                    experiment.fully_resolve().save_config()
+
+        if dry_run:
+            print()
+            print('To be run:')
+            for command in command_dag.get_sorted_commands():
+                command_type = command.command_type
+                root_uri = command.root_uri
+                print('{} in {}'.format(command_type, root_uri))
+            print()
+        else:
+            self._run_experiment(command_dag)
 
     @abstractmethod
     def _run_experiment(self, command_dag):

{"golden_diff": "diff --git a/src/rastervision/cli/main.py b/src/rastervision/cli/main.py\n--- a/src/rastervision/cli/main.py\n+++ b/src/rastervision/cli/main.py\n@@ -130,7 +130,8 @@\n         experiments,\n         commands_to_run=commands,\n         rerun_commands=rerun,\n-        skip_file_check=skip_file_check)\n+        skip_file_check=skip_file_check,\n+        dry_run=dry_run)\n \n \n @main.command()\ndiff --git a/src/rastervision/runner/experiment_runner.py b/src/rastervision/runner/experiment_runner.py\n--- a/src/rastervision/runner/experiment_runner.py\n+++ b/src/rastervision/runner/experiment_runner.py\n@@ -1,7 +1,8 @@\n+import rastervision as rv\n+\n from abc import (ABC, abstractmethod)\n from typing import (List, Union)\n \n-import rastervision as rv\n from rastervision.runner import (CommandDefinition, CommandDAG)\n \n \n@@ -10,15 +11,28 @@\n             experiments: Union[List[rv.ExperimentConfig], rv.ExperimentConfig],\n             commands_to_run=rv.ALL_COMMANDS,\n             rerun_commands=False,\n-            skip_file_check=False):\n+            skip_file_check=False,\n+            dry_run: bool = False):\n         if not isinstance(experiments, list):\n             experiments = [experiments]\n \n-        command_definitions = CommandDefinition.from_experiments(experiments)\n+        _command_definitions = CommandDefinition.from_experiments(experiments)\n \n         # Filter  out commands we aren't running.\n         command_definitions = CommandDefinition.filter_commands(\n-            command_definitions, commands_to_run)\n+            _command_definitions, commands_to_run)\n+\n+        # Print unrequested commands\n+        if dry_run:\n+            not_requested = set(_command_definitions) - set(command_definitions)\n+            if not_requested:\n+                print()\n+                print('Not requsted:')\n+                for command in not_requested:\n+                    command_type = command.command_config.command_type\n+                    experiment_id = command.experiment_id\n+                    print('{} from {}'.format(command_type, experiment_id))\n+                print()\n \n         # Check if there are any unsatisfied inputs.\n         missing_inputs = CommandDefinition.get_missing_inputs(\n@@ -63,9 +77,17 @@\n         command_dag = CommandDAG(\n             unique_commands, rerun_commands, skip_file_check=skip_file_check)\n \n-        if skipped_commands or command_dag.skipped_commands:\n-            # TODO: Report skipped commands, either in the dry run or elsewhere.\n-            pass\n+        # Print conflicating or alread fulfilled commands\n+        if dry_run:\n+            skipped_commands.extend(command_dag.skipped_commands)\n+            if skipped_commands:\n+                print()\n+                print('Skipped due to output conflicts:')\n+                for command in skipped_commands:\n+                    command_type = command.command_config.command_type\n+                    experiment_id = command.experiment_id\n+                    print('{} from {}'.format(command_type, experiment_id))\n+                print()\n \n         # Save experiment configs\n         experiments_by_id = dict(map(lambda e: (e.id, e), experiments))\n@@ -74,9 +96,19 @@\n             if command_def.experiment_id not in seen_ids:\n                 seen_ids.add(command_def.experiment_id)\n                 experiment = experiments_by_id[command_def.experiment_id]\n-                experiment.fully_resolve().save_config()\n-\n-        self._run_experiment(command_dag)\n+                if not dry_run:\n+                    experiment.fully_resolve().save_config()\n+\n+        if dry_run:\n+            print()\n+            print('To be run:')\n+            for command in command_dag.get_sorted_commands():\n+                command_type = command.command_type\n+                root_uri = command.root_uri\n+                print('{} in {}'.format(command_type, root_uri))\n+            print()\n+        else:\n+            self._run_experiment(command_dag)\n \n     @abstractmethod\n     def _run_experiment(self, command_dag):\n", "issue": "Implement `--dry-run` / `-n` option in CLI\nWe should have a `--dry-run`/`-n` option in the CLI which will print information about the commands to be run, but not actually run them. The CLI option exists, but needs to be implemented in the code.\n", "before_files": [{"content": "\"\"\"Raster Vision main program\"\"\"\nimport sys\nfrom tempfile import TemporaryDirectory\n\nimport click\n\nimport rastervision as rv\nfrom rastervision.experiment import (ExperimentLoader, LoaderError)\nfrom rastervision.runner import (ExperimentRunner)\n\n\ndef print_error(msg):\n    click.echo(click.style(msg, fg='red'), err=True)\n\n\n@click.group()\n@click.option(\n    '--profile', '-p', help='Sets the configuration profile name to use.')\ndef main(profile):\n    # Initialize configuration\n    if profile:\n        rv._registry.initialize_config(profile=profile)\n\n\n@main.command(\n    'run', short_help='Run Raster Vision commands against Experiments.')\n@click.argument('runner')\n@click.argument('commands', nargs=-1)\n@click.option(\n    '--experiment_module',\n    '-e',\n    help=('Name of an importable module to look for experiment sets '\n          'in. If not supplied, experiments will be loaded '\n          'from __main__'))\n@click.option(\n    '--dry-run',\n    '-n',\n    is_flag=True,\n    help=('Execute a dry run, which will print out information '\n          'about the commands to be run, but will not actually '\n          'run the commands'))\n@click.option(\n    '--skip-file-check',\n    '-x',\n    is_flag=True,\n    help=('Skip the step that verifies that file exist.'))\n@click.option(\n    '--arg',\n    '-a',\n    type=(str, str),\n    multiple=True,\n    metavar='KEY VALUE',\n    help=('Pass a parameter to the experiments if the method '\n          'parameter list takes in a parameter with that key. '\n          'Multiple args can be supplied'))\n@click.option(\n    '--prefix',\n    metavar='PREFIX',\n    default='exp_',\n    help=('Prefix for methods containing experiments. (default: \"exp_\")'))\n@click.option(\n    '--method',\n    '-m',\n    'methods',\n    multiple=True,\n    metavar='PATTERN',\n    help=('Pattern to match method names to run.'))\n@click.option(\n    '--filter',\n    '-f',\n    'filters',\n    multiple=True,\n    metavar='PATTERN',\n    help=('Pattern to match experiment names to run.'))\n@click.option(\n    '--rerun',\n    '-r',\n    is_flag=True,\n    default=False,\n    help=('Rerun commands, regardless if '\n          'their output files already exist.'))\ndef run(runner, commands, experiment_module, dry_run, skip_file_check, arg,\n        prefix, methods, filters, rerun):\n    \"\"\"Run Raster Vision commands from experiments, using the\n    experiment runner named RUNNER.\"\"\"\n    # Validate runner\n    valid_runners = list(\n        map(lambda x: x.lower(), rv.ExperimentRunner.list_runners()))\n    if runner not in valid_runners:\n        print_error('Invalid experiment runner: \"{}\". '\n                    'Must be one of: \"{}\"'.format(runner,\n                                                  '\", \"'.join(valid_runners)))\n        sys.exit(1)\n\n    runner = ExperimentRunner.get_runner(runner)\n\n    if experiment_module:\n        module_to_load = experiment_module\n    else:\n        module_to_load = '__main__'\n\n    if not commands:\n        commands = rv.ALL_COMMANDS\n    else:\n        commands = list(map(lambda x: x.upper(), commands))\n\n    experiment_args = {}\n    for k, v in arg:\n        experiment_args[k] = v\n\n    loader = ExperimentLoader(\n        experiment_args=experiment_args,\n        experiment_method_prefix=prefix,\n        experiment_method_patterns=methods,\n        experiment_name_patterns=filters)\n    try:\n        experiments = loader.load_from_module(module_to_load)\n    except LoaderError as e:\n        print_error(str(e))\n        sys.exit(1)\n\n    if not experiments:\n        if experiment_module:\n            print_error(\n                'No experiments found in {}.'.format(experiment_module))\n        else:\n            print_error('No experiments found.')\n\n    runner.run(\n        experiments,\n        commands_to_run=commands,\n        rerun_commands=rerun,\n        skip_file_check=skip_file_check)\n\n\n@main.command()\n@click.option(\n    '--experiment_module',\n    '-e',\n    help=('Name of an importable module to look for experiment sets '\n          'in. If not supplied, experiments will be loaded '\n          'from __main__'))\n@click.option(\n    '--arg',\n    '-a',\n    type=(str, str),\n    multiple=True,\n    metavar='KEY VALUE',\n    help=('Pass a parameter to the experiments if the method '\n          'parameter list takes in a parameter with that key. '\n          'Multiple args can be supplied'))\ndef ls(experiment_module, arg):\n    \"\"\"Print out a list of Experiment IDs.\"\"\"\n    if experiment_module:\n        module_to_load = experiment_module\n    else:\n        module_to_load = '__main__'\n\n    experiment_args = {}\n    for k, v in arg:\n        experiment_args[k] = v\n\n    loader = ExperimentLoader(experiment_args=experiment_args)\n    try:\n        experiments = loader.load_from_module(module_to_load)\n    except LoaderError as e:\n        print_error(str(e))\n        sys.exit(1)\n\n    if not experiments:\n        if experiment_module:\n            print_error(\n                'No experiments found in {}.'.format(experiment_module))\n        else:\n            print_error('No experiments found.')\n\n    for e in experiments:\n        click.echo('{}'.format(e.id))\n\n\n@main.command(\n    'predict', short_help='Make predictions using a predict package.')\n@click.argument('predict_package', type=click.Path(exists=True))\n@click.argument('image_uri', type=click.Path(exists=True))\n@click.argument('output_uri', type=click.Path(exists=False))\n@click.option(\n    '--update_stats',\n    '-a',\n    is_flag=True,\n    help=('Run an analysis on this individual image, as '\n          'opposed to using any analysis like statistics '\n          'that exist in the prediction package'))\n@click.option(\n    '--channel-order',\n    help='String containing channel_order.' + ' Example: \\\"2 1 0\\\"')\ndef predict(predict_package, image_uri, output_uri, update_stats,\n            channel_order):\n    \"\"\"Make predictions on the image at IMAGE_URI\n    using PREDICT_PACKAGE and store the\n    prediciton output at OUTPUT_URI.\n    \"\"\"\n    if channel_order is not None:\n        channel_order = [\n            int(channel_ind) for channel_ind in channel_order.split(' ')\n        ]\n    with TemporaryDirectory() as tmp_dir:\n        predict = rv.Predictor(predict_package, tmp_dir, update_stats,\n                               channel_order).predict\n        predict(image_uri, output_uri)\n\n\n@main.command(\n    'run_command', short_help='Run a command from configuration file.')\n@click.argument('command_config_uri')\ndef run_command(command_config_uri):\n    \"\"\"Run a command from a serialized command configuration\n    at COMMAND_CONFIG_URI.\n    \"\"\"\n    rv.runner.CommandRunner.run(command_config_uri)\n\n\nif __name__ == '__main__':\n    main()\n", "path": "src/rastervision/cli/main.py"}, {"content": "from abc import (ABC, abstractmethod)\nfrom typing import (List, Union)\n\nimport rastervision as rv\nfrom rastervision.runner import (CommandDefinition, CommandDAG)\n\n\nclass ExperimentRunner(ABC):\n    def run(self,\n            experiments: Union[List[rv.ExperimentConfig], rv.ExperimentConfig],\n            commands_to_run=rv.ALL_COMMANDS,\n            rerun_commands=False,\n            skip_file_check=False):\n        if not isinstance(experiments, list):\n            experiments = [experiments]\n\n        command_definitions = CommandDefinition.from_experiments(experiments)\n\n        # Filter  out commands we aren't running.\n        command_definitions = CommandDefinition.filter_commands(\n            command_definitions, commands_to_run)\n\n        # Check if there are any unsatisfied inputs.\n        missing_inputs = CommandDefinition.get_missing_inputs(\n            command_definitions)\n        if missing_inputs:\n            # TODO: Replace with logging?\n            s = ''\n            for exp_id in missing_inputs:\n                s += 'In {}:\\n\\t{}\\n'.format(\n                    exp_id, '\\t{}\\n'.join(missing_inputs[exp_id]))\n\n            raise rv.ConfigError('There were missing input URIs '\n                                 'that are required, but were not '\n                                 'able to be derived: \\n{}'.format(s))\n\n        # Remove duplicate commands, defining equality for a command by\n        # the tuple (command_type, input_uris, output_uris)\n        (unique_commands, skipped_commands\n         ) = CommandDefinition.remove_duplicates(command_definitions)\n\n        # Ensure that for each type of command, there are none that clobber\n        # each other's output.\n        clashing_commands = CommandDefinition.get_clashing_commands(\n            unique_commands)\n\n        if clashing_commands:\n            clashing_msgs = []\n            for (output_uri, c_defs) in clashing_commands:\n                command_type = c_defs[0].command_config.command_type\n                experiments = ', '.join(map(lambda c: c.experiment_id, c_defs))\n                clashing_msgs.append(\n                    'The {} command in the follwoing experiments '\n                    'output {}, but are not equal: {}'.format(\n                        command_type, output_uri, experiments))\n            # TODO: Replace with logging?\n            s = '\\t\\n'.join(clashing_msgs)\n\n            raise rv.ConfigurationError(\n                'ERROR: Command outputs will'\n                'override each other: \\n{}\\n'.format(s))\n\n        command_dag = CommandDAG(\n            unique_commands, rerun_commands, skip_file_check=skip_file_check)\n\n        if skipped_commands or command_dag.skipped_commands:\n            # TODO: Report skipped commands, either in the dry run or elsewhere.\n            pass\n\n        # Save experiment configs\n        experiments_by_id = dict(map(lambda e: (e.id, e), experiments))\n        seen_ids = set([])\n        for command_def in command_dag.get_command_definitions():\n            if command_def.experiment_id not in seen_ids:\n                seen_ids.add(command_def.experiment_id)\n                experiment = experiments_by_id[command_def.experiment_id]\n                experiment.fully_resolve().save_config()\n\n        self._run_experiment(command_dag)\n\n    @abstractmethod\n    def _run_experiment(self, command_dag):\n        pass\n\n    @staticmethod\n    def get_runner(runner_type):\n        \"\"\"Gets the runner associated with this runner type.\"\"\"\n        # Runner keys are upper cased.\n        return rv._registry.get_experiment_runner(runner_type.upper())\n\n    @staticmethod\n    def list_runners():\n        \"\"\"Returns a list of valid runner keys.\"\"\"\n        return rv._registry.get_experiment_runner_keys()\n", "path": "src/rastervision/runner/experiment_runner.py"}], "after_files": [{"content": "\"\"\"Raster Vision main program\"\"\"\nimport sys\nfrom tempfile import TemporaryDirectory\n\nimport click\n\nimport rastervision as rv\nfrom rastervision.experiment import (ExperimentLoader, LoaderError)\nfrom rastervision.runner import (ExperimentRunner)\n\n\ndef print_error(msg):\n    click.echo(click.style(msg, fg='red'), err=True)\n\n\n@click.group()\n@click.option(\n    '--profile', '-p', help='Sets the configuration profile name to use.')\ndef main(profile):\n    # Initialize configuration\n    if profile:\n        rv._registry.initialize_config(profile=profile)\n\n\n@main.command(\n    'run', short_help='Run Raster Vision commands against Experiments.')\n@click.argument('runner')\n@click.argument('commands', nargs=-1)\n@click.option(\n    '--experiment_module',\n    '-e',\n    help=('Name of an importable module to look for experiment sets '\n          'in. If not supplied, experiments will be loaded '\n          'from __main__'))\n@click.option(\n    '--dry-run',\n    '-n',\n    is_flag=True,\n    help=('Execute a dry run, which will print out information '\n          'about the commands to be run, but will not actually '\n          'run the commands'))\n@click.option(\n    '--skip-file-check',\n    '-x',\n    is_flag=True,\n    help=('Skip the step that verifies that file exist.'))\n@click.option(\n    '--arg',\n    '-a',\n    type=(str, str),\n    multiple=True,\n    metavar='KEY VALUE',\n    help=('Pass a parameter to the experiments if the method '\n          'parameter list takes in a parameter with that key. '\n          'Multiple args can be supplied'))\n@click.option(\n    '--prefix',\n    metavar='PREFIX',\n    default='exp_',\n    help=('Prefix for methods containing experiments. (default: \"exp_\")'))\n@click.option(\n    '--method',\n    '-m',\n    'methods',\n    multiple=True,\n    metavar='PATTERN',\n    help=('Pattern to match method names to run.'))\n@click.option(\n    '--filter',\n    '-f',\n    'filters',\n    multiple=True,\n    metavar='PATTERN',\n    help=('Pattern to match experiment names to run.'))\n@click.option(\n    '--rerun',\n    '-r',\n    is_flag=True,\n    default=False,\n    help=('Rerun commands, regardless if '\n          'their output files already exist.'))\ndef run(runner, commands, experiment_module, dry_run, skip_file_check, arg,\n        prefix, methods, filters, rerun):\n    \"\"\"Run Raster Vision commands from experiments, using the\n    experiment runner named RUNNER.\"\"\"\n    # Validate runner\n    valid_runners = list(\n        map(lambda x: x.lower(), rv.ExperimentRunner.list_runners()))\n    if runner not in valid_runners:\n        print_error('Invalid experiment runner: \"{}\". '\n                    'Must be one of: \"{}\"'.format(runner,\n                                                  '\", \"'.join(valid_runners)))\n        sys.exit(1)\n\n    runner = ExperimentRunner.get_runner(runner)\n\n    if experiment_module:\n        module_to_load = experiment_module\n    else:\n        module_to_load = '__main__'\n\n    if not commands:\n        commands = rv.ALL_COMMANDS\n    else:\n        commands = list(map(lambda x: x.upper(), commands))\n\n    experiment_args = {}\n    for k, v in arg:\n        experiment_args[k] = v\n\n    loader = ExperimentLoader(\n        experiment_args=experiment_args,\n        experiment_method_prefix=prefix,\n        experiment_method_patterns=methods,\n        experiment_name_patterns=filters)\n    try:\n        experiments = loader.load_from_module(module_to_load)\n    except LoaderError as e:\n        print_error(str(e))\n        sys.exit(1)\n\n    if not experiments:\n        if experiment_module:\n            print_error(\n                'No experiments found in {}.'.format(experiment_module))\n        else:\n            print_error('No experiments found.')\n\n    runner.run(\n        experiments,\n        commands_to_run=commands,\n        rerun_commands=rerun,\n        skip_file_check=skip_file_check,\n        dry_run=dry_run)\n\n\n@main.command()\n@click.option(\n    '--experiment_module',\n    '-e',\n    help=('Name of an importable module to look for experiment sets '\n          'in. If not supplied, experiments will be loaded '\n          'from __main__'))\n@click.option(\n    '--arg',\n    '-a',\n    type=(str, str),\n    multiple=True,\n    metavar='KEY VALUE',\n    help=('Pass a parameter to the experiments if the method '\n          'parameter list takes in a parameter with that key. '\n          'Multiple args can be supplied'))\ndef ls(experiment_module, arg):\n    \"\"\"Print out a list of Experiment IDs.\"\"\"\n    if experiment_module:\n        module_to_load = experiment_module\n    else:\n        module_to_load = '__main__'\n\n    experiment_args = {}\n    for k, v in arg:\n        experiment_args[k] = v\n\n    loader = ExperimentLoader(experiment_args=experiment_args)\n    try:\n        experiments = loader.load_from_module(module_to_load)\n    except LoaderError as e:\n        print_error(str(e))\n        sys.exit(1)\n\n    if not experiments:\n        if experiment_module:\n            print_error(\n                'No experiments found in {}.'.format(experiment_module))\n        else:\n            print_error('No experiments found.')\n\n    for e in experiments:\n        click.echo('{}'.format(e.id))\n\n\n@main.command(\n    'predict', short_help='Make predictions using a predict package.')\n@click.argument('predict_package', type=click.Path(exists=True))\n@click.argument('image_uri', type=click.Path(exists=True))\n@click.argument('output_uri', type=click.Path(exists=False))\n@click.option(\n    '--update_stats',\n    '-a',\n    is_flag=True,\n    help=('Run an analysis on this individual image, as '\n          'opposed to using any analysis like statistics '\n          'that exist in the prediction package'))\n@click.option(\n    '--channel-order',\n    help='String containing channel_order.' + ' Example: \\\"2 1 0\\\"')\ndef predict(predict_package, image_uri, output_uri, update_stats,\n            channel_order):\n    \"\"\"Make predictions on the image at IMAGE_URI\n    using PREDICT_PACKAGE and store the\n    prediciton output at OUTPUT_URI.\n    \"\"\"\n    if channel_order is not None:\n        channel_order = [\n            int(channel_ind) for channel_ind in channel_order.split(' ')\n        ]\n    with TemporaryDirectory() as tmp_dir:\n        predict = rv.Predictor(predict_package, tmp_dir, update_stats,\n                               channel_order).predict\n        predict(image_uri, output_uri)\n\n\n@main.command(\n    'run_command', short_help='Run a command from configuration file.')\n@click.argument('command_config_uri')\ndef run_command(command_config_uri):\n    \"\"\"Run a command from a serialized command configuration\n    at COMMAND_CONFIG_URI.\n    \"\"\"\n    rv.runner.CommandRunner.run(command_config_uri)\n\n\nif __name__ == '__main__':\n    main()\n", "path": "src/rastervision/cli/main.py"}, {"content": "import rastervision as rv\n\nfrom abc import (ABC, abstractmethod)\nfrom typing import (List, Union)\n\nfrom rastervision.runner import (CommandDefinition, CommandDAG)\n\n\nclass ExperimentRunner(ABC):\n    def run(self,\n            experiments: Union[List[rv.ExperimentConfig], rv.ExperimentConfig],\n            commands_to_run=rv.ALL_COMMANDS,\n            rerun_commands=False,\n            skip_file_check=False,\n            dry_run: bool = False):\n        if not isinstance(experiments, list):\n            experiments = [experiments]\n\n        _command_definitions = CommandDefinition.from_experiments(experiments)\n\n        # Filter  out commands we aren't running.\n        command_definitions = CommandDefinition.filter_commands(\n            _command_definitions, commands_to_run)\n\n        # Print unrequested commands\n        if dry_run:\n            not_requested = set(_command_definitions) - set(command_definitions)\n            if not_requested:\n                print()\n                print('Not requsted:')\n                for command in not_requested:\n                    command_type = command.command_config.command_type\n                    experiment_id = command.experiment_id\n                    print('{} from {}'.format(command_type, experiment_id))\n                print()\n\n        # Check if there are any unsatisfied inputs.\n        missing_inputs = CommandDefinition.get_missing_inputs(\n            command_definitions)\n        if missing_inputs:\n            # TODO: Replace with logging?\n            s = ''\n            for exp_id in missing_inputs:\n                s += 'In {}:\\n\\t{}\\n'.format(\n                    exp_id, '\\t{}\\n'.join(missing_inputs[exp_id]))\n\n            raise rv.ConfigError('There were missing input URIs '\n                                 'that are required, but were not '\n                                 'able to be derived: \\n{}'.format(s))\n\n        # Remove duplicate commands, defining equality for a command by\n        # the tuple (command_type, input_uris, output_uris)\n        (unique_commands, skipped_commands\n         ) = CommandDefinition.remove_duplicates(command_definitions)\n\n        # Ensure that for each type of command, there are none that clobber\n        # each other's output.\n        clashing_commands = CommandDefinition.get_clashing_commands(\n            unique_commands)\n\n        if clashing_commands:\n            clashing_msgs = []\n            for (output_uri, c_defs) in clashing_commands:\n                command_type = c_defs[0].command_config.command_type\n                experiments = ', '.join(map(lambda c: c.experiment_id, c_defs))\n                clashing_msgs.append(\n                    'The {} command in the follwoing experiments '\n                    'output {}, but are not equal: {}'.format(\n                        command_type, output_uri, experiments))\n            # TODO: Replace with logging?\n            s = '\\t\\n'.join(clashing_msgs)\n\n            raise rv.ConfigurationError(\n                'ERROR: Command outputs will'\n                'override each other: \\n{}\\n'.format(s))\n\n        command_dag = CommandDAG(\n            unique_commands, rerun_commands, skip_file_check=skip_file_check)\n\n        # Print conflicating or alread fulfilled commands\n        if dry_run:\n            skipped_commands.extend(command_dag.skipped_commands)\n            if skipped_commands:\n                print()\n                print('Skipped due to output conflicts:')\n                for command in skipped_commands:\n                    command_type = command.command_config.command_type\n                    experiment_id = command.experiment_id\n                    print('{} from {}'.format(command_type, experiment_id))\n                print()\n\n        # Save experiment configs\n        experiments_by_id = dict(map(lambda e: (e.id, e), experiments))\n        seen_ids = set([])\n        for command_def in command_dag.get_command_definitions():\n            if command_def.experiment_id not in seen_ids:\n                seen_ids.add(command_def.experiment_id)\n                experiment = experiments_by_id[command_def.experiment_id]\n                if not dry_run:\n                    experiment.fully_resolve().save_config()\n\n        if dry_run:\n            print()\n            print('To be run:')\n            for command in command_dag.get_sorted_commands():\n                command_type = command.command_type\n                root_uri = command.root_uri\n                print('{} in {}'.format(command_type, root_uri))\n            print()\n        else:\n            self._run_experiment(command_dag)\n\n    @abstractmethod\n    def _run_experiment(self, command_dag):\n        pass\n\n    @staticmethod\n    def get_runner(runner_type):\n        \"\"\"Gets the runner associated with this runner type.\"\"\"\n        # Runner keys are upper cased.\n        return rv._registry.get_experiment_runner(runner_type.upper())\n\n    @staticmethod\n    def list_runners():\n        \"\"\"Returns a list of valid runner keys.\"\"\"\n        return rv._registry.get_experiment_runner_keys()\n", "path": "src/rastervision/runner/experiment_runner.py"}]}