api/freeze_operations: by default, reset the known operations

We use the `path` of collected operations to
perform the reset. This should cover most reasonnable
scenarios but not those where some operations have
been moved from one module to another.
5 files changed, 28 insertions(+), 15 deletions(-)

M rework/api.py
M rework/cli.py
M tests/conftest.py
M tests/test_api.py
M tests/test_cli.py
M rework/api.py +10 -1
@@ 259,7 259,7 @@ def unprepare(engine, sid):
     return count
 
 
-def freeze_operations(engine, domain=None, hostid=None):
+def freeze_operations(engine, domain=None, hostid=None, reset=True):
     values = []
     if hostid is None:
         hostid = host()

          
@@ 292,6 292,15 @@ def freeze_operations(engine, domain=Non
             )
         values.append(val)
 
+    if reset:
+        with engine.begin() as cn:
+            for path in [val['path'] for val in values]:
+                cn.execute(
+                    'delete from rework.operation '
+                    'where path=%(path)s',
+                    path=path
+                )
+
     recorded = []
     alreadyknown = []
     for value in values:

          
M rework/cli.py +3 -2
@@ 50,7 50,8 @@ def init_db(ctx, dburi):
 @click.argument('module', type=click.Path(exists=True, dir_okay=False, resolve_path=True))
 @click.option('--domain')
 @click.option('--asdomain')
-def register_operations(dburi, module, domain=None, asdomain=None):
+@click.option('--reset/--no-reset', is_flag=True, default=True)
+def register_operations(dburi, module, domain=None, asdomain=None, reset=True):
     """register operations from a python module containing
     python functions decorated with `api.task`
 

          
@@ 62,7 63,7 @@ def register_operations(dburi, module, d
     # load the module
     load_source('operations', module)
     engine = create_engine(find_dburi(dburi))
-    ok, ko = api.freeze_operations(engine, domain)
+    ok, ko = api.freeze_operations(engine, domain, reset=reset)
     print(f'registered {len(ok)} new operation ({len(ko)} already known)')
 
 

          
M tests/conftest.py +3 -0
@@ 38,6 38,9 @@ def cli():
     def runner(*args, **kw):
         args = [str(a) for a in args]
         for k, v in kw.items():
+            if isinstance(v, bool):
+                args.append(f'--{k}' if v else f'--no-{k}')
+                continue
             args.append('--{}'.format(k))
             args.append(str(v))
         return CliRunner().invoke(rcli.rework, args)

          
M tests/test_api.py +5 -5
@@ 254,8 254,8 @@ def test_freeze_ops(engine, cleanup):
 
     reset_ops(engine)
     register_tasks()
-    api.freeze_operations(engine, domain='default')
-    api.freeze_operations(engine, domain='ham')
+    api.freeze_operations(engine, domain='default', reset=False)
+    api.freeze_operations(engine, domain='ham', reset=False)
 
     res = engine.execute(
         'select name, domain from rework.operation order by domain, name'

          
@@ 651,9 651,9 @@ def test_schedule_domain(engine, cleanup
     from . import task_testenv  # noqa
     from . import task_prodenv  # noqa
 
-    api.freeze_operations(engine, domain='test')
-    api.freeze_operations(engine, domain='production')
-    api.freeze_operations(engine, domain='production', hostid='192.168.122.42')
+    api.freeze_operations(engine, domain='test', reset=False)
+    api.freeze_operations(engine, domain='production', reset=False)
+    api.freeze_operations(engine, domain='production', hostid='192.168.122.42', reset=False)
 
     with pytest.raises(ValueError) as err:
         api.schedule(engine, 'foo')

          
M tests/test_cli.py +7 -7
@@ 46,7 46,7 @@ def test_register_operations(engine, cli
     newtaskspath = Path(__file__).parent / 'newtasks.py'
     r = cli('register-operations', engine.url, newtaskspath)
     assert 'registered 2 new operation (0 already known)' in r.output
-    r = cli('register-operations', engine.url, newtaskspath)
+    r = cli('register-operations', engine.url, newtaskspath, reset=False)
     assert 'registered 0 new operation (2 already known)' in r.output
 
     r = cli('list-operations', engine.url)

          
@@ 63,13 63,13 @@ def test_register_operations(engine, cli
     cleanup()
 
     # per-domain
-    r = cli('register-operations', engine.url, newtaskspath, domain='default')
+    r = cli('register-operations', engine.url, newtaskspath, domain='default', reset=False)
     assert 'registered 1 new operation (0 already known)' in r.output
     r = cli('list-operations', engine.url)
     assert 'boring_task' in r.output
     assert 'scrap_sites' not in r.output
 
-    r = cli('register-operations', engine.url, newtaskspath, domain='scrappers')
+    r = cli('register-operations', engine.url, newtaskspath, domain='scrappers', reset=False)
     assert 'registered 1 new operation (0 already known)' in r.output
     r = cli('list-operations', engine.url)
     assert 'boring_task' in r.output

          
@@ 79,14 79,14 @@ def test_register_operations(engine, cli
 
     # per-domain + asdomain
     r = cli('register-operations', engine.url, newtaskspath,
-            domain='default', asdomain='cloudhost')
+            domain='default', asdomain='cloudhost', reset=False)
     assert 'registered 1 new operation (0 already known)' in r.output
     r = cli('list-operations', engine.url)
     assert 'boring_task' in r.output
     assert 'scrap_sites' not in r.output
 
     r = cli('register-operations', engine.url, newtaskspath,
-            domain='scrappers', asdomain='cloudscrappers')
+            domain='scrappers', asdomain='cloudscrappers', reset=False)
     assert 'registered 1 new operation (0 already known)' in r.output
     r = cli('list-operations', engine.url)
     assert 'boring_task' in r.output

          
@@ 100,8 100,8 @@ def test_register_operations(engine, cli
             domain='nu-such-domain')
     assert 'registered 0 new operation (0 already known)' in r.output
 
-    r = cli('register-operations', engine.url, newtaskspath, domain='default')
-    r = cli('register-operations', engine.url, newtaskspath)  # all domains
+    r = cli('register-operations', engine.url, newtaskspath, domain='default', reset=False)
+    r = cli('register-operations', engine.url, newtaskspath, reset=False)  # all domains
     assert 'registered 1 new operation (1 already known)' in r.output
 
     # keep the other tests sane !