Commit 62c9ff3f authored by Theophile GENTILHOMME's avatar Theophile GENTILHOMME
Browse files

[experiments] Click implementation of toolchains commands

Reimplement experiments existing
commands using  plugin-based command line mechanism (Click).
parent a50d3907
......@@ -26,60 +26,10 @@
###############################################################################
"""Usage:
%(prog)s experiments run [--force] <name> [(--docker|--local)]
%(prog)s experiments caches [--list | --delete | --checksum] <name>
%(prog)s experiments list [--remote]
%(prog)s experiments check [<name>]...
%(prog)s experiments path [<name>]...
%(prog)s experiments edit <name>...
%(prog)s experiments pull [--force] [<name>]...
%(prog)s experiments push [--force] [--dry-run] [<name>]...
%(prog)s experiments diff <name>
%(prog)s experiments status
%(prog)s experiments fork <src> <dst>
%(prog)s experiments rm [--remote] <name>...
%(prog)s experiments draw [--path=<dir>] [<name>]...
%(prog)s experiments plot [--force] [--remote] [--show] [--outputfolder=<folder>][<name>]...
%(prog)s experiments --help
Commands:
run Runs an experiment locally
caches Lists all cache files used by this experiment
list Lists all the experiments available on the platform
path Displays local path of experiments files
edit Edit local experiment file
check Checks a local experiment for validity
pull Downloads the specified experiments from the server
push Uploads experiments to the server
diff Shows changes between the local experiment and the remote version
status Shows (editing) status for all available experiments
fork Forks a local experiment
rm Deletes a local experiment (unless --remote is specified)
draw Creates a visual representation of the experiment
plot Plots output images of the experiment
Options:
--force Performs operation regardless of conflicts
--dry-run Doesn't really perform the task, just comments what would do
--remote Only acts on the remote copy of the experiment
--list List cache files matching output if they exist
--delete Delete cache files matching output if they exist (also,
recursively deletes empty directories)
--checksum Checksums indexes for cache files
--help Display this screen
--path=<dir> Use path to write files to disk (instead of the current
directory)
--local Uses the local executor to execute the experiment on the local machine (default).
--docker Uses the docker executor to execute the experiment using docker containers.
"""
import os
import logging
import glob
import click
import oset
import simplejson
......@@ -312,7 +262,7 @@ def run_experiment(configuration, name, force, use_docker, use_local):
return 0
def caches(configuration, name, ls, delete, checksum):
def caches_impl(configuration, name, ls, delete, checksum):
'''List all cache files involved in this experiment'''
dataformat_cache = {}
......@@ -379,7 +329,7 @@ def caches(configuration, name, ls, delete, checksum):
return 0
def pull(webapi, prefix, names, force, indentation, format_cache):
def pull_impl(webapi, prefix, names, force, indentation, format_cache):
"""Copies experiments (and required toolchains/algorithms) from the server.
Parameters:
......@@ -453,7 +403,7 @@ def pull(webapi, prefix, names, force, indentation, format_cache):
return status + tc_status + db_status + algo_status
def plot(webapi, configuration, prefix, names, remote_results, show, force, indentation, format_cache, outputfolder=None):
def plot_impl(webapi, configuration, prefix, names, remote_results, show, force, indentation, format_cache, outputfolder=None):
"""Plots experiments from the server.
Parameters:
......@@ -582,77 +532,227 @@ def plot(webapi, configuration, prefix, names, remote_results, show, force, inde
return status
def process(args):
config = args['config']
names = args['<name>']
force = args['--force']
if args['run']:
return run_experiment(config, names[0], force,
args['--docker'], args['--local'])
if args['caches']:
return caches(config, names[0], args['--list'],
args['--delete'], args['--checksum'])
elif args['list']:
if args['--remote']:
with common.make_webapi(config) as webapi:
return common.display_remote_list(webapi, 'experiment')
else:
return common.display_local_list(config.path, 'experiment')
elif args['path']:
return common.display_local_path(config.path, 'experiment', names)
elif args['edit']:
return common.edit_local_file(config.path, config.editor, 'experiment', names[0])
elif args['check']:
return common.check(config.path, 'experiment', names)
elif args['pull']:
@click.group()
@click.pass_context
def experiments(ctx):
"""experiments commands"""
pass
@experiments.command()
@click.argument('name', nargs=1)
@click.option('--force', help='Performs operation regardless of conflicts',
is_flag=True)
@click.option('--docker', help='Uses the docker executor to execute the '
'experiment using docker containers',
is_flag=True)
@click.option('--local', help='Uses the local executor to execute the '
'experiment on the local machine (default)',
default=True, is_flag=True)
@click.pass_context
def run(ctx, name, force, docker, local):
''' Runs an experiment locally'''
config = ctx.meta.get('config')
return run_experiment(config, name, force, docker, local or True)
@experiments.command()
@click.argument('name', nargs=1)
@click.option('--list', help='List cache files matching output if they exist',
is_flag=True)
@click.option('--delete', help='Delete cache files matching output if they '
'exist (also, recursively deletes empty directories)',
is_flag=True)
@click.option('--checksum', help='Checksums indexes for cache files',
is_flag=True)
@click.pass_context
def caches(ctx, name, list, delete, checksum):
'''Lists all cache files used by this experiment'''
config = ctx.meta.get('config')
return caches(config, name, list, delete, checksum)
@experiments.command()
@click.option('--remote', help='Only acts on the remote copy of the list.',
is_flag=True)
@click.pass_context
def list(ctx, remote):
'''Lists all the experiments available on the platform.
To list all existing experiments on your local prefix:
$ beat experiments list
'''
config = ctx.meta.get('config')
if remote:
with common.make_webapi(config) as webapi:
return pull(webapi, config.path, names, force,
0, {})
elif args['push']:
return common.display_remote_list(webapi, 'experiment')
else:
return common.display_local_list(config.path, 'experiment')
@experiments.command()
@click.argument('names', nargs=-1)
@click.pass_context
def path(ctx, names):
'''Displays local path of experiment files
Example:
$ beat experiments path xxx
'''
return common.display_local_path(ctx.meta['config'].path, 'experiment', names)
@experiments.command()
@click.argument('name', nargs=1)
@click.pass_context
def edit(ctx, name):
'''Edit local experiment file
Example:
$ beat experiments edit xxx
'''
return common.edit_local_file(ctx.meta['config'].path,
ctx.meta['config'].editor, 'experiment',
name)
@experiments.command()
@click.argument('name', nargs=1)
@click.pass_context
def check(ctx, name):
'''Checks a local experiment for validity.
$ beat experiments check xxx
'''
config = ctx.meta.get('config')
return common.check(config.path, 'experiment', name)
@experiments.command()
@click.argument('name', nargs=1)
@click.option('--force', help='Force',
is_flag=True)
@click.pass_context
def pull(ctx, name, force):
'''Downloads the specified experiments from the server.
$ beat experiments pull xxx.
'''
config = ctx.meta.get('config')
with common.make_webapi(config) as webapi:
return pull_impl(webapi, config.path, name, force, 0, {})
@experiments.command()
@click.argument('name', nargs=1)
@click.option('--force', help='Performs operation regardless of conflicts',
is_flag=True)
@click.option('--dry-run', help="Doesn't really perform the task, just "
"comments what would do", is_flag=True)
@click.pass_context
def push(ctx, name, force, dry_run):
'''Uploads experiments to the server.
Example:
$ beat experiments push --dry-run yyy
'''
config = ctx.meta.get('config')
with common.make_webapi(config) as webapi:
return common.push(
webapi, config.path, 'experiment', name,
['name', 'declaration', 'toolchain', 'description'],
{}, force, dry_run, 0
)
@experiments.command()
@click.argument('name', nargs=1)
@click.pass_context
def diff(ctx, name):
'''Shows changes between the local dataformat and the remote version.
Example:
$ beat experiments diff xxx
'''
config = ctx.meta.get('config')
with common.make_webapi(config) as webapi:
return common.diff(
webapi, config.path, 'experiment', name,
['declaration', 'description']
)
@experiments.command()
@click.pass_context
def status(ctx):
'''Shows (editing) status for all available experiments.
Example:
$ beat experiments status
'''
config = ctx.meta.get('config')
with common.make_webapi(config) as webapi:
return common.status(webapi, config.path, 'experiment')[0]
@experiments.command()
@click.argument('src', nargs=1)
@click.argument('dst', nargs=1)
@click.pass_context
def fork(ctx, src, dst):
'''Forks a local experiment.
$ beat experiments fork xxx yyy
'''
config = ctx.meta.get('config')
return common.fork(config.path, 'experiment', src, dst)
@experiments.command()
@click.argument('name', nargs=1)
@click.option('--remote', help='Only acts on the remote copy of the experiment',
is_flag=True)
@click.pass_context
def rm(ctx, name, remote):
'''Deletes a local experiment (unless --remote is specified).
$ beat experiments rm xxx
'''
config = ctx.meta.get('config')
if remote:
with common.make_webapi(config) as webapi:
return common.push(webapi, config.path, 'experiment',
names,
['name', 'declaration',
'toolchain', 'description'],
{}, force, args['--dry-run'], 0)
elif args['diff']:
with common.make_webapi(config) as webapi:
return common.diff(webapi, config.path, 'experiment',
names[0], ['declaration', 'description'])
elif args['status']:
with common.make_webapi(config) as webapi:
return common.status(webapi, config.path, 'experiment')[0]
elif args['fork']:
return common.fork(config.path, 'experiment',
args['<src>'], args['<dst>'])
elif args['rm']:
if args['--remote']:
with common.make_webapi(config) as webapi:
return common.delete_remote(webapi, 'experiment', names)
else:
return common.delete_local(config.path, 'experiment', names)
elif args['draw']:
return common.dot_diagram(config.path, 'experiment',
names, args['--path'], [])
elif args['plot']:
with common.make_webapi(config) as webapi:
return plot(webapi, config, 'experiment', names, args['--remote'],
args['--show'], force, 0, {}, args['--outputfolder'])
# Should not happen
logger.error("unrecognized `experiments' subcommand")
return 1
return common.delete_remote(webapi, 'experiment', name)
else:
return common.delete_local(config.path, 'experiment', name)
@experiments.command()
@click.argument('name', nargs=1)
@click.option('--path', help='Use path to write files to disk (instead of the '
'current directory)', type=click.Path())
@click.pass_context
def draw(ctx, name, path):
'''Creates a visual representation of the experiment.'''
config = ctx.meta.get('config')
return common.dot_diagram(config.path, 'experiment', names, path, [])
@experiments.command()
@click.argument('name', nargs=1)
@click.option('--force', help='Performs operation regardless of conflicts',
is_flag=True)
@click.option('--remote', help='Only acts on the remote copy of the experiment',
is_flag=True)
@click.option('--show', help='Show...',
is_flag=True)
@click.option('--output-folder', help='<folder>', type=click.Path(exists=True))
@click.pass_context
def plot(ctx, name, force, remote, show, output_folder):
'''Plots output images of the experiment.'''
config = ctx.meta.get('config')
with common.make_webapi(config) as webapi:
return plot_impl(
webapi, config, 'experiment', name, remote, show, force, 0, {},
output_folder
)
......@@ -67,7 +67,7 @@ def path(ctx, names):
return common.display_local_path(ctx.meta['config'].path, 'toolchain', names)
@plotters.command()
@toolchains.command()
@click.argument('name', nargs=1)
@click.pass_context
def edit(ctx, name):
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment