Repository: rasterio/rasterio

Issue:
Revisit CLI API for implicitly overwriting output files
Per #747, there are cases where `-o`allows us to implicitly overwrite outputs.  We should rethink this.  There probably should just be one way to force overwrite existing outputs.



Discussion:

Resolving patch:
diff --git a/rasterio/rio/helpers.py b/rasterio/rio/helpers.py
--- a/rasterio/rio/helpers.py
+++ b/rasterio/rio/helpers.py
@@ -83,12 +83,11 @@ def resolve_inout(input=None, output=None, files=None, force_overwrite=False):
     :param:`force_overwrite` is `True`.
     """
     resolved_output = output or (files[-1] if files else None)
-    force_overwrite = output is not None or force_overwrite
     if not force_overwrite and resolved_output and os.path.exists(
             resolved_output):
         raise FileOverwriteError(
             "file exists and won't be overwritten without use of the "
-            "`--force-overwrite` or `--output` options.")
+            "`--force-overwrite` option.")
     resolved_inputs = (
         [input] if input else [] +
         list(files[:-1 if not output else None]) if files else [])
diff --git a/rasterio/rio/options.py b/rasterio/rio/options.py
--- a/rasterio/rio/options.py
+++ b/rasterio/rio/options.py
@@ -95,7 +95,8 @@ def file_in_handler(ctx, param, value):
     except ValueError as exc:
         raise click.BadParameter(str(exc))
     path_to_check = archive or path
-    if not scheme in ['http', 'https', 's3'] and not os.path.exists(path_to_check):
+    if (scheme not in ['http', 'https', 's3'] and not
+            os.path.exists(path_to_check)):
         raise click.BadParameter(
             "Input file {0} does not exist".format(path_to_check))
     if archive and scheme:
@@ -201,9 +202,7 @@ def nodata_handler(ctx, param, value):
     '-o', '--output',
     default=None,
     type=click.Path(resolve_path=True),
-    help="Path to output file (optional alternative to a positional arg). "
-         "Existing files will be overwritten (`--force-overwrite` is "
-         "implied).")
+    help="Path to output file (optional alternative to a positional arg).")
 
 resolution_opt = click.option(
     '-r', '--res',
diff --git a/rasterio/warp.py b/rasterio/warp.py
--- a/rasterio/warp.py
+++ b/rasterio/warp.py
@@ -12,12 +12,12 @@
 from rasterio._warp import (
     _transform_geom, _reproject, _calculate_default_transform)
 from rasterio.enums import Resampling
-from rasterio.env import ensure_env
+from rasterio.env import ensure_env, Env
 from rasterio.transform import guard_transform
 
 
 @ensure_env
-def transform(src_crs, dst_crs, xs, ys, zs=None):
+def transform(src_crs, dst_crs, xs, ys, zs=None, **options):
     """Transform vectors from source to target coordinate reference system.
 
     Transform vectors of x, y and optionally z from source
@@ -43,7 +43,8 @@ def transform(src_crs, dst_crs, xs, ys, zs=None):
     Tuple of x, y, and optionally z vectors, transformed into the target
     coordinate reference system.
     """
-    return _transform(src_crs, dst_crs, xs, ys, zs)
+    with Env(**options):
+        return _transform(src_crs, dst_crs, xs, ys, zs)
 
 
 @ensure_env


Test patch:
diff --git a/tests/test_rio_features.py b/tests/test_rio_features.py
--- a/tests/test_rio_features.py
+++ b/tests/test_rio_features.py
@@ -574,7 +574,7 @@ def test_rasterize_existing_output(tmpdir, runner, basic_feature):
             'rasterize', output,
             '--dimensions', DEFAULT_SHAPE[0], DEFAULT_SHAPE[1],
             '--bounds', 0, 10, 10, 0],
-        input=json.dumps(basic_feature))
+        input=json.dumps(basic_feature), catch_exceptions=False)
 
     assert result.exit_code == 0
     assert os.path.exists(output)
@@ -584,7 +584,7 @@ def test_rasterize_existing_output(tmpdir, runner, basic_feature):
 
     result = runner.invoke(
         main_group, [
-            'rasterize', '-o', output, '--dimensions', DEFAULT_SHAPE[0],
+            'rasterize', '--force-overwrite', '-o', output, '--dimensions', DEFAULT_SHAPE[0],
             DEFAULT_SHAPE[1]],
         input=json.dumps(basic_feature))
 
diff --git a/tests/test_rio_helpers.py b/tests/test_rio_helpers.py
--- a/tests/test_rio_helpers.py
+++ b/tests/test_rio_helpers.py
@@ -39,11 +39,11 @@ def test_force_overwrite(tmpdir):
 
 
 def test_implicit_overwrite(tmpdir):
-    """Implicit overwrite of existing file succeeds."""
+    """Implicit overwrite of existing file fails."""
     foo_tif = tmpdir.join('foo.tif')
     foo_tif.write("content")
-    output, inputs = helpers.resolve_inout(output=str(foo_tif))
-    assert output == str(foo_tif)
+    with pytest.raises(FileOverwriteError):
+        helpers.resolve_inout(output=str(foo_tif))
 
 
 def test_to_lower():