diff --git a/terracotta/scripts/optimize_rasters.py b/terracotta/scripts/optimize_rasters.py index 61b21d80..0452ff90 100644 --- a/terracotta/scripts/optimize_rasters.py +++ b/terracotta/scripts/optimize_rasters.py @@ -118,6 +118,9 @@ def _named_tempfile(basedir: Union[str, Path]) -> Iterator[str]: type=PathlibPath(file_okay=False, writable=True), help='Output folder for cloud-optimized rasters. Subdirectories will be flattened.' ) +@click.option( + '--skip-existing', is_flag=True, default=False, help='Skip existing files' +) @click.option( '--overwrite', is_flag=True, default=False, help='Force overwrite of existing files' ) @@ -145,6 +148,7 @@ def _named_tempfile(basedir: Union[str, Path]) -> Iterator[str]: def optimize_rasters(raster_files: Sequence[Sequence[Path]], output_folder: Path, overwrite: bool = False, + skip_existing: bool = False, resampling_method: str = 'average', reproject: bool = False, in_memory: bool = None, @@ -214,10 +218,13 @@ def optimize_rasters(raster_files: Sequence[Sequence[Path]], output_file = output_folder / input_file.with_suffix('.tif').name - if not overwrite and output_file.is_file(): - raise click.BadParameter( - f'Output file {output_file!s} exists (use --overwrite to ignore)' - ) + if output_file.is_file(): + if skip_existing: + continue + if not overwrite: + raise click.BadParameter( + f'Output file {output_file!s} exists (use --overwrite or --skip-existing)' + ) with contextlib.ExitStack() as es, warnings.catch_warnings(): warnings.filterwarnings('ignore', message='invalid value encountered.*') diff --git a/tests/scripts/test_optimize_rasters.py b/tests/scripts/test_optimize_rasters.py index 7eae8ef9..74c16e7d 100644 --- a/tests/scripts/test_optimize_rasters.py +++ b/tests/scripts/test_optimize_rasters.py @@ -1,3 +1,4 @@ +import os import warnings import traceback @@ -149,3 +150,34 @@ def test_optimize_rasters_multiband(tmpdir, unoptimized_raster_file): with warnings.catch_warnings(): warnings.filterwarnings('ignore', 'invalid value encountered.*') np.testing.assert_array_equal(src1.read(), src2.read()) + + +@pytest.mark.parametrize('extra_flag', ['skip-existing', 'overwrite', None]) +def test_reoptimize(tmpdir, unoptimized_raster_file, extra_flag): + from terracotta.scripts import cli + + infile = str(unoptimized_raster_file.dirpath('*.tif')) + outfile = tmpdir / 'out.tif' + + # first time + runner = CliRunner() + args = ['optimize-rasters', infile, '-o', str(outfile)] + result = runner.invoke(cli.cli, args) + assert result.exit_code == 0 + ctime = os.stat(outfile).st_ctime + + # second time + args = ['optimize-rasters', infile, '-o', str(outfile)] + if extra_flag: + args.append(f'--{extra_flag}') + + result = runner.invoke(cli.cli, args) + + if extra_flag == 'skip-existing': + assert result.exit_code == 0 + assert os.stat(outfile).st_ctime == ctime + elif extra_flag == 'overwrite': + assert result.exit_code == 0 + assert os.stat(outfile).st_ctime != ctime + else: + assert result.exit_code == 2