Repository: skypyproject/skypy

Issue:
Rerun yaml file requires to delete the output files
**Describe the bug**
Re-running `.yaml ` files returns an error with the message that the output files already exist. 

**To Reproduce**
```
skypy -c examples/herbel_galaxies.yaml -f fits
```
```
skypy -c examples/herbel_galaxies.yaml -f fits
```

**Expected behavior**
It should run without problems and updating the output files.


Discussion:

Patch:
diff --git a/skypy/pipeline/driver.py b/skypy/pipeline/driver.py
index e834c00..36872d8 100644
--- a/skypy/pipeline/driver.py
+++ b/skypy/pipeline/driver.py
@@ -22,7 +22,7 @@ class SkyPyDriver:
     and using their results to generate variables and tables.
     '''
 
-    def execute(self, configuration, file_format=None):
+    def execute(self, configuration, file_format=None, overwrite=False):
         r'''Run a pipeline.
 
         This function runs a pipeline of functions to generate variables and
@@ -38,6 +38,8 @@ class SkyPyDriver:
             File format used to write tables. Files are written using the
             Astropy unified file read/write interface; see [2]_ for supported
             file formats. If None (default) tables are not written to file.
+        overwrite : bool
+            Whether to overwrite any existing files without warning.
 
         Notes
         -----
@@ -131,7 +133,7 @@ class SkyPyDriver:
         if file_format:
             for table in table_config.keys():
                 filename = '.'.join((table, file_format))
-                getattr(self, table).write(filename)
+                getattr(self, table).write(filename, overwrite=overwrite)
 
     def _call_from_config(self, config):
 
diff --git a/skypy/pipeline/scripts/skypy.py b/skypy/pipeline/scripts/skypy.py
index f1a6e2b..763a5eb 100644
--- a/skypy/pipeline/scripts/skypy.py
+++ b/skypy/pipeline/scripts/skypy.py
@@ -44,10 +44,12 @@ def main(args=None):
     import yaml
 
     parser = argparse.ArgumentParser(description="SkyPy pipeline driver")
-    parser.add_argument('-c', '--config', required=True,
-                        type=argparse.FileType('r'), help='Config file name')
+    parser.add_argument('config', type=argparse.FileType('r'),
+                        help='Config file name')
     parser.add_argument('-f', '--format', required=False,
                         choices=['fits', 'hdf5'], help='Table file format')
+    parser.add_argument('-o', '--overwrite', action='store_true',
+                        help='Whether to overwrite existing files')
 
     # get system args if none passed
     if args is None:
@@ -57,5 +59,5 @@ def main(args=None):
     config = yaml.safe_load(args.config)
     config = {} if config is None else config
     driver = SkyPyDriver()
-    driver.execute(config, file_format=args.format)
+    driver.execute(config, file_format=args.format, overwrite=args.overwrite)
     return(0)


Test patch:
diff --git a/skypy/pipeline/tests/test_driver.py b/skypy/pipeline/tests/test_driver.py
index 84d8a18..4231f08 100644
--- a/skypy/pipeline/tests/test_driver.py
+++ b/skypy/pipeline/tests/test_driver.py
@@ -21,13 +21,14 @@ def test_driver():
 
     # Generate a simple two column table with a dependency. Also write the
     # table to a fits file and check it's contents.
+    size = 100
     config = {'tables': {
                 'test_table': {
                   'column1': {
                     'module': 'numpy.random',
                     'function': 'uniform',
                     'kwargs': {
-                      'size': 100}},
+                      'size': size}},
                   'column2': {
                     'module': 'numpy.random',
                     'function': 'uniform',
@@ -36,11 +37,24 @@ def test_driver():
 
     driver = SkyPyDriver()
     driver.execute(config, file_format='fits')
-    assert len(driver.test_table) == 100
+    assert len(driver.test_table) == size
     assert np.all(driver.test_table['column1'] < driver.test_table['column2'])
     with fits.open('test_table.fits') as hdu:
         assert np.all(Table(hdu[1].data) == driver.test_table)
 
+    # Check for failure if output files already exist and overwrite is False
+    driver = SkyPyDriver()
+    with pytest.raises(OSError):
+        driver.execute(config, file_format='fits', overwrite=False)
+
+    # Check that the existing output files are modified if overwrite is True
+    new_size = 2 * size
+    config['tables']['test_table']['column1']['kwargs']['size'] = new_size
+    driver = SkyPyDriver()
+    driver.execute(config, file_format='fits', overwrite=True)
+    with fits.open('test_table.fits') as hdu:
+        assert len(hdu[1].data) == new_size
+
     # Check for failure if 'column1' requires itself creating a cyclic
     # dependency graph
     config['tables']['test_table']['column1']['requires'] = \
diff --git a/skypy/pipeline/tests/test_skypy.py b/skypy/pipeline/tests/test_skypy.py
index b64656d..eb44563 100644
--- a/skypy/pipeline/tests/test_skypy.py
+++ b/skypy/pipeline/tests/test_skypy.py
@@ -15,20 +15,20 @@ def test_skypy():
         skypy.main(['--help'])
     assert e.value.code == 0
 
-    # Missing required argument '-c'
+    # Missing positional argument 'config'
     with pytest.raises(SystemExit) as e:
         skypy.main(['--format', 'fits'])
     assert e.value.code == 2
 
     # Invalid file format
     with pytest.raises(SystemExit) as e:
-        skypy.main(['--config', 'config.filename', '--format', 'invalid'])
+        skypy.main(['--format', 'invalid', 'config.filename'])
     assert e.value.code == 2
 
     # Process empty config file
     filename = get_pkg_data_filename('data/empty_config.yml')
-    assert skypy.main(['--config', filename]) == 0
+    assert skypy.main([filename]) == 0
 
     # Process test config file
     filename = get_pkg_data_filename('data/test_config.yml')
-    assert skypy.main(['--config', filename]) == 0
+    assert skypy.main([filename]) == 0