diff --git a/mcmd/__main__.py b/mcmd/__main__.py index 33aaae97..b3b29dac 100644 --- a/mcmd/__main__.py +++ b/mcmd/__main__.py @@ -20,9 +20,9 @@ from mcmd.core.context.home_context import HomeContext from mcmd.args.parser import parse_args from mcmd.config.loader import load_config -from mcmd.io import io -from mcmd.io.io import set_debug -from mcmd.io.logging import set_level +from mcmd.in_out import in_out +from mcmd.in_out.in_out import set_debug +from mcmd.in_out.logging import set_level def main(): @@ -69,7 +69,7 @@ def set_log_level(args): # noinspection PyUnusedLocal def interrupt_handler(sig, frame): - io.warn('Interrupted by user.') + in_out.warn('Interrupted by user.') sys.exit(0) diff --git a/mcmd/commands/add.py b/mcmd/commands/add.py index 5a80ed6e..57f99941 100644 --- a/mcmd/commands/add.py +++ b/mcmd/commands/add.py @@ -9,8 +9,8 @@ from mcmd.core.compatibility import version, deprecated from mcmd.core.context import context from mcmd.core.errors import McmdError -from mcmd.io import io -from mcmd.io.io import highlight +from mcmd.in_out import in_out +from mcmd.in_out.in_out import highlight from mcmd.molgenis import api from mcmd.molgenis.client import post, get, post_files from mcmd.molgenis.principals import to_role_name @@ -169,7 +169,7 @@ def add_arguments(subparsers): @command def add_user(args): - io.start('Adding user %s' % highlight(args.username)) + in_out.start('Adding user %s' % highlight(args.username)) password = args.set_password if args.set_password else args.username email = args.with_email if args.with_email else args.username + '@molgenis.org' @@ -190,7 +190,7 @@ def add_user(args): @command def add_role(args): role_name = to_role_name(args.rolename) - io.start('Adding role {}'.format(highlight(role_name))) + in_out.start('Adding role {}'.format(highlight(role_name))) role = {'name': role_name, 'label': role_name} @@ -241,7 +241,7 @@ def _get_role_ids(role_names) -> List[str]: @command def add_group(args): group_name = _to_group_name(args.name) - io.start('Adding group %s' % highlight(group_name)) + in_out.start('Adding group %s' % highlight(group_name)) post(api.group(), data={'name': group_name, 'label': args.name}) @@ -259,7 +259,7 @@ def _to_group_name(group_input: str): @command def add_package(args): - io.start('Adding package %s' % highlight(args.id)) + in_out.start('Adding package %s' % highlight(args.id)) data = {'id': args.id, 'label': args.id} @@ -272,7 +272,7 @@ def add_package(args): @command def add_token(args): - io.start('Adding token %s for user %s' % (highlight(args.token), highlight(args.user))) + in_out.start('Adding token %s for user %s' % (highlight(args.token), highlight(args.user))) user = get(api.rest2('sys_sec_User'), params={ @@ -312,12 +312,12 @@ def add_theme(args): paths.append(bs4) names.append('bootstrap4-style') bs4_name = file_utils.get_file_name_from_path(bs4) - io.start( + in_out.start( 'Adding bootstrap 3 theme {} and bootstrap 4 theme {} to bootstrap themes'.format( highlight(bs3_name), highlight(bs4_name))) else: - io.start( + in_out.start( 'Adding bootstrap 3 theme {} to bootstrap themes'.format( highlight(bs3_name))) if not args.from_path: @@ -337,10 +337,10 @@ def add_logo(args): valid_types = {'image/jpeg', 'image/png', 'image/gif'} logo = [args.logo] if not args.from_path: - io.start('Adding logo from path {}'.format(highlight(args.logo))) + in_out.start('Adding logo from path {}'.format(highlight(args.logo))) logo = [_get_path_from_quick_folders(args.logo)] else: - io.start('Adding logo {}'.format(highlight(args.logo))) + in_out.start('Adding logo {}'.format(highlight(args.logo))) files = _prepare_files_for_upload(logo, ['logo'], valid_types) post_files(files, api_) diff --git a/mcmd/commands/config.py b/mcmd/commands/config.py index 9451943b..ed5e8877 100644 --- a/mcmd/commands/config.py +++ b/mcmd/commands/config.py @@ -6,8 +6,8 @@ from mcmd.commands._registry import arguments from mcmd.core.command import command, CommandType from mcmd.core.errors import McmdError -from mcmd.io import io, ask -from mcmd.io.io import highlight +from mcmd.in_out import in_out, ask +from mcmd.in_out.in_out import highlight # ========= @@ -126,7 +126,7 @@ def config_set_host(args): urls = [auth['url'] for auth in auths] url = ask.multi_choice('Please select a host:', urls) - io.start("Switching to host {}".format(highlight(url))) + in_out.start("Switching to host {}".format(highlight(url))) if config.host_exists(url): config.set_host(url) @@ -143,21 +143,21 @@ def config_set_import_action(args): options = ['add', 'add_update_existing', 'update'] action = ask.multi_choice('Choose the default import action:', options) - io.start("Setting import action to {}".format(highlight(action))) + in_out.start("Setting import action to {}".format(highlight(action))) config.set_import_action(action) # noinspection PyUnusedLocal @command def config_set_non_interactive(args): - io.start('Switching to non-interactive mode') + in_out.start('Switching to non-interactive mode') config.set_non_interactive(True) # noinspection PyUnusedLocal @command def config_set_interactive(args): - io.start('Switching to interactive mode') + in_out.start('Switching to interactive mode') config.set_non_interactive(False) @@ -184,9 +184,9 @@ def config_add_host(args): password = ask.password("Password (Leave blank to use command line authentication)") password = None if len(password) == 0 else password - io.start("Adding host {}".format(highlight(url))) + in_out.start("Adding host {}".format(highlight(url))) config.add_host(url, username, password) - io.succeed() + in_out.succeed() if args.switch: _switch_to_new_host(url) @@ -196,7 +196,7 @@ def config_add_host(args): @command def config_add_dataset_folder(args): - io.start('Adding resource folder {}'.format(highlight(args.folder))) + in_out.start('Adding resource folder {}'.format(highlight(args.folder))) if not Path(args.folder).is_dir(): raise McmdError('Folder does not exist: {}'.format(args.folder)) config.add_dataset_folder(args.folder) @@ -204,7 +204,7 @@ def config_add_dataset_folder(args): @command def config_add_resource_folder(args): - io.start('Adding resource folder {}'.format(highlight(args.folder))) + in_out.start('Adding resource folder {}'.format(highlight(args.folder))) if not Path(args.folder).is_dir(): raise McmdError('Folder does not exist: {}'.format(args.folder)) config.add_resource_folder(args.folder) diff --git a/mcmd/commands/delete.py b/mcmd/commands/delete.py index 2c014d63..aa243bc5 100644 --- a/mcmd/commands/delete.py +++ b/mcmd/commands/delete.py @@ -1,11 +1,11 @@ from urllib.parse import urljoin -import mcmd.io.ask +import mcmd.in_out.ask import mcmd.molgenis.client as client from mcmd.commands._registry import arguments from mcmd.core.command import command -from mcmd.io import io -from mcmd.io.io import highlight +from mcmd.in_out import in_out +from mcmd.in_out.in_out import highlight from mcmd.molgenis import api from mcmd.molgenis.resources import detect_resource_type, ensure_resource_exists, ResourceType @@ -79,23 +79,23 @@ def delete(args): def _delete_entity_type(args): - if args.force or (not args.force and mcmd.io.ask.confirm( + if args.force or (not args.force and mcmd.in_out.ask.confirm( 'Are you sure you want to delete entity type {} including its data?'.format(args.resource))): - io.start('Deleting entity type {}'.format(highlight(args.resource))) + in_out.start('Deleting entity type {}'.format(highlight(args.resource))) _delete_rows(ResourceType.ENTITY_TYPE.get_entity_id(), [args.resource]) def _delete_entity_type_data(args): - if args.force or (not args.force and mcmd.io.ask.confirm( + if args.force or (not args.force and mcmd.in_out.ask.confirm( 'Are you sure you want to delete all data in entity type {}?'.format(args.resource))): - io.start('Deleting all data from entity {}'.format(highlight(args.resource))) + in_out.start('Deleting all data from entity {}'.format(highlight(args.resource))) client.delete(api.rest1(args.resource)) def _delete_entity_type_attribute(args): - if args.force or (not args.force and mcmd.io.ask.confirm( + if args.force or (not args.force and mcmd.in_out.ask.confirm( 'Are you sure you want to delete attribute {} of entity type {}?'.format(args.attribute, args.resource))): - io.start('Deleting attribute {} of entity {}'.format(highlight(args.attribute), highlight(args.resource))) + in_out.start('Deleting attribute {} of entity {}'.format(highlight(args.attribute), highlight(args.resource))) response = client.get(api.rest2('sys_md_Attribute'), params={ 'q': 'entity=={};name=={}'.format(args.resource, @@ -106,16 +106,16 @@ def _delete_entity_type_attribute(args): def _delete_package(args): - if args.force or (not args.force and mcmd.io.ask.confirm( + if args.force or (not args.force and mcmd.in_out.ask.confirm( 'Are you sure you want to delete package {} and all of its contents?'.format(args.resource))): - io.start('Deleting package {}'.format(highlight(args.resource))) + in_out.start('Deleting package {}'.format(highlight(args.resource))) _delete_rows(ResourceType.PACKAGE.get_entity_id(), [args.resource]) def _delete_package_contents(args): - if args.force or (not args.force and mcmd.io.ask.confirm( + if args.force or (not args.force and mcmd.in_out.ask.confirm( 'Are you sure you want to delete the contents of package {}?'.format(args.resource))): - io.start('Deleting contents of package {}'.format(highlight(args.resource))) + in_out.start('Deleting contents of package {}'.format(highlight(args.resource))) _delete_entity_types_in_package(args.resource) _delete_packages_in_package(args.resource) @@ -143,7 +143,7 @@ def _delete_packages_in_package(package_id): def _delete_group(args): - if args.force or (not args.force and mcmd.io.ask.confirm( + if args.force or (not args.force and mcmd.in_out.ask.confirm( 'Are you sure you want to delete group {}?'.format(args.resource))): io.start('Deleting group {}'.format(highlight(args.resource))) client.delete(urljoin(api.group(), args.resource)) diff --git a/mcmd/commands/disable.py b/mcmd/commands/disable.py index 7c3a838b..b46152db 100644 --- a/mcmd/commands/disable.py +++ b/mcmd/commands/disable.py @@ -1,8 +1,8 @@ from mcmd.commands._registry import arguments from mcmd.core.command import command -from mcmd.io import ask -from mcmd.io import io -from mcmd.io.io import highlight +from mcmd.in_out import ask +from mcmd.in_out import in_out +from mcmd.in_out.in_out import highlight from mcmd.molgenis import api from mcmd.molgenis.client import put from mcmd.molgenis.resources import ensure_resource_exists, ResourceType @@ -48,7 +48,7 @@ def disable_rls(args): if not ask.confirm('Are you sure you want to disable row level security on %s?' % args.entity): return - io.start('Disabling row level security on entity type %s' % highlight(args.entity)) + in_out.start('Disabling row level security on entity type %s' % highlight(args.entity)) ensure_resource_exists(args.entity, ResourceType.ENTITY_TYPE) security.disable_row_level_security(args.entity) @@ -56,6 +56,6 @@ def disable_rls(args): @command def disable_language(args): - io.start('Disabling language {}'.format(highlight(args.language))) + in_out.start('Disabling language {}'.format(highlight(args.language))) url = api.rest1('sys_Language/{}/active'.format(args.language)) put(url, 'false') diff --git a/mcmd/commands/enable.py b/mcmd/commands/enable.py index 67c82a5d..e6223243 100644 --- a/mcmd/commands/enable.py +++ b/mcmd/commands/enable.py @@ -5,8 +5,8 @@ from mcmd.core.command import command from mcmd.core.compatibility import deprecated from mcmd.core.errors import McmdError -from mcmd.io import io -from mcmd.io.io import highlight +from mcmd.in_out import in_out +from mcmd.in_out.in_out import highlight from mcmd.molgenis import api from mcmd.molgenis.client import post, put from mcmd.molgenis.resources import one_resource_exists, ensure_resource_exists, ResourceType @@ -70,7 +70,7 @@ def add_arguments(subparsers): @command def enable_rls(args): - io.start('Enabling row level security on entity type %s' % highlight(args.entity)) + in_out.start('Enabling row level security on entity type %s' % highlight(args.entity)) ensure_resource_exists(args.entity, ResourceType.ENTITY_TYPE) security.enable_row_level_security(args.entity) @@ -90,7 +90,7 @@ def enable_theme(args): :return None """ theme = args.theme.replace('.css', '').replace('.min', '') - io.start('Applying theme {}'.format(highlight(theme))) + in_out.start('Applying theme {}'.format(highlight(theme))) # Resource can be bootstrap-name.min.css (if molgenis theme), or name.min.css (if uploaded .min.css), or # name.css (if uploaded as .css). if one_resource_exists([theme + '.min.css', theme + '.css', 'bootstrap-' + theme + '.min.css'], ResourceType.THEME): @@ -106,6 +106,6 @@ def enable_theme(args): @command def enable_language(args): - io.start('Enabling language {}'.format(highlight(args.language))) + in_out.start('Enabling language {}'.format(highlight(args.language))) url = api.rest1('sys_Language/{}/active'.format(args.language)) put(url, 'true') diff --git a/mcmd/commands/give.py b/mcmd/commands/give.py index 3c0c0540..84f1f05c 100644 --- a/mcmd/commands/give.py +++ b/mcmd/commands/give.py @@ -10,8 +10,8 @@ from mcmd.core.command import command from mcmd.core.compatibility import version from mcmd.core.errors import McmdError -from mcmd.io import io -from mcmd.io.io import highlight +from mcmd.in_out import in_out +from mcmd.in_out.in_out import highlight from mcmd.molgenis.principals import PrincipalType, get_principal_type_from_args from mcmd.molgenis.resources import detect_resource_type, ensure_resource_exists, ResourceType from mcmd.molgenis.security import security @@ -127,7 +127,7 @@ def _validate_args(args): def _grant(principal_type: PrincipalType, principal_name: str, resource_type: ResourceType, entity_type_id: str, permission: Permission): - io.start('Giving %s %s permission to %s on %s %s' % (principal_type.value, + in_out.start('Giving %s %s permission to %s on %s %s' % (principal_type.value, highlight(principal_name), highlight(permission.value), resource_type.get_label().lower(), @@ -138,7 +138,7 @@ def _grant(principal_type: PrincipalType, principal_name: str, resource_type: Re def _grant_rls(principal_type: PrincipalType, principal_name: str, entity_type_id: str, entity_id: str, permission: Permission): - io.start('Giving %s %s permission to %s on row %s of entity type %s' % (principal_type.value, + in_out.start('Giving %s %s permission to %s on row %s of entity type %s' % (principal_type.value, highlight(principal_name), highlight(permission.value), highlight(entity_id), diff --git a/mcmd/commands/history.py b/mcmd/commands/history.py index c97f8486..44b88112 100644 --- a/mcmd/commands/history.py +++ b/mcmd/commands/history.py @@ -1,8 +1,8 @@ from mcmd.commands._registry import arguments from mcmd.core import history as hist from mcmd.core.command import command, CommandType -from mcmd.io import io -from mcmd.io.logging import get_logger +from mcmd.in_out import in_out +from mcmd.in_out.logging import get_logger # ========= @@ -38,15 +38,15 @@ def add_arguments(subparsers): @command def history(args): if args.clear: - io.start('Clearing history') + in_out.start('Clearing history') hist.clear() else: lines = hist.read(args.number, include_fails=True) if len(lines) == 0: log.info('History is empty.') for line in lines: - io.start(line[1]) + in_out.start(line[1]) if line[0]: - io.succeed() + in_out.succeed() else: - io.error(None) + in_out.error(None) diff --git a/mcmd/commands/import_.py b/mcmd/commands/import_.py index ff697a19..8474c38d 100644 --- a/mcmd/commands/import_.py +++ b/mcmd/commands/import_.py @@ -6,14 +6,14 @@ import requests import mcmd.config.config as config -import mcmd.io.ask +import mcmd.in_out.ask from mcmd.commands._registry import arguments from mcmd.core.command import command from mcmd.core.context import context from mcmd.core.errors import McmdError from mcmd.github import client as github -from mcmd.io import io -from mcmd.io.io import highlight +from mcmd.in_out import in_out +from mcmd.in_out.in_out import highlight from mcmd.molgenis import api from mcmd.molgenis.client import post_file, get, post from mcmd.utils import files @@ -107,7 +107,7 @@ def _choose_import_method(args): def _import_from_url(args): file_url = args.resource file_name = file_url.split("/")[-1] - io.start('Importing from URL %s' % highlight(file_url)) + in_out.start('Importing from URL %s' % highlight(file_url)) if args.import_action: action = args.import_action @@ -193,7 +193,7 @@ def _choose_attachment(attachments): attachment_map = _create_attachment_map(attachments) choices = list(attachment_map.keys()) - answer = mcmd.io.ask.multi_choice('Multiple attachments found. Choose which one to import:', choices) + answer = mcmd.in_out.ask.multi_choice('Multiple attachments found. Choose which one to import:', choices) return attachment_map[answer] @@ -203,11 +203,11 @@ def _download_attachment(attachment, issue_num): file_path = issue_folder.joinpath(attachment.name) if file_path.exists(): - overwrite = mcmd.io.ask.confirm('File %s already exists. Re-download?' % file_path.name) + overwrite = mcmd.in_out.ask.confirm('File %s already exists. Re-download?' % file_path.name) if not overwrite: return file_path - io.start('Downloading %s from GitHub issue %s' % (highlight(attachment.name), highlight('#' + issue_num))) + in_out.start('Downloading %s from GitHub issue %s' % (highlight(attachment.name), highlight('#' + issue_num))) try: r = requests.get(attachment.url) r.raise_for_status() @@ -215,12 +215,12 @@ def _download_attachment(attachment, issue_num): f.write(r.content) except (OSError, requests.RequestException, requests.HTTPError) as e: raise McmdError('Error downloading GitHub attachment: %s' % str(e)) - io.succeed() + in_out.succeed() return file_path def _do_import(file_path, package, entity_type_id, import_action): - io.start('Importing %s' % (highlight(file_path.name))) + in_out.start('Importing %s' % (highlight(file_path.name))) if import_action: action = import_action diff --git a/mcmd/commands/make.py b/mcmd/commands/make.py index 5625dc74..3689058a 100644 --- a/mcmd/commands/make.py +++ b/mcmd/commands/make.py @@ -19,8 +19,8 @@ from mcmd.core.command import command from mcmd.core.compatibility import version from mcmd.core.errors import McmdError -from mcmd.io import io, ask -from mcmd.io.io import highlight +from mcmd.in_out import in_out, ask +from mcmd.in_out.in_out import highlight from mcmd.molgenis import api from mcmd.molgenis.client import post, get, put from mcmd.molgenis.principals import to_role_name, get_principal_type_from_args, PrincipalType @@ -126,7 +126,7 @@ def _make_member_of_group_role(user: User, role: Role): membership = _get_group_membership(user, group) if membership: if membership.role.name == role.name: - io.info('User {} is already {} of group {}'.format(highlight(user.username), + in_out.info('User {} is already {} of group {}'.format(highlight(user.username), highlight(role.label), highlight(group.name))) else: @@ -143,19 +143,19 @@ def _make_member_of_group_role(user: User, role: Role): def _make_member_of_role(role, user): if _is_member(user, role): - io.info('User {} is already a member of role {}'.format(highlight(user.username), highlight(role.name))) + in_out.info('User {} is already a member of role {}'.format(highlight(user.username), highlight(role.name))) else: _add_role_membership(user, role) def _add_group_role_membership(user: User, group: Group, role: Role): - io.start('Making user {} a member of role {}'.format(highlight(user.username), highlight(role.name))) + in_out.start('Making user {} a member of role {}'.format(highlight(user.username), highlight(role.name))) url = api.member(group.name) post(url, data={'username': user.username, 'roleName': role.name}) def _update_group_role_membership(user: User, group: Group, role: Role): - io.start('Making user {} a member of role {}'.format(highlight(user.username), highlight(role.name))) + in_out.start('Making user {} a member of role {}'.format(highlight(user.username), highlight(role.name))) url = urljoin(api.member(group.name), user.username) put(url, data=json.dumps({'roleName': role.name})) @@ -164,7 +164,7 @@ def _add_role_membership(user: User, role: Role): """ Adds a membership manually because the identities API can't add memberships to non-group roles. """ - io.start('Making user {} a member of role {}'.format(highlight(user.username), highlight(role.name))) + in_out.start('Making user {} a member of role {}'.format(highlight(user.username), highlight(role.name))) membership = {'user': user.id, 'role': role.id, 'from': timestamp()} @@ -179,7 +179,7 @@ def _include_group_role(subject: Role, target_role: Role): if subject.name == target_role.name: raise McmdError("A role can't include itself") - io.start('Including role {} in role {}'.format(highlight(target_role.name), highlight(subject.name))) + in_out.start('Including role {} in role {}'.format(highlight(target_role.name), highlight(subject.name))) include = {'role': target_role.name} put(api.role(target_role.group.name, subject.name), data=json.dumps(include)) diff --git a/mcmd/commands/ping.py b/mcmd/commands/ping.py index 0512ee4d..17ce9436 100644 --- a/mcmd/commands/ping.py +++ b/mcmd/commands/ping.py @@ -4,7 +4,7 @@ from mcmd.commands._registry import arguments from mcmd.core.command import command from mcmd.core.errors import McmdError -from mcmd.io.io import highlight +from mcmd.in_out.in_out import highlight from mcmd.molgenis import version as molgenis_version diff --git a/mcmd/commands/run.py b/mcmd/commands/run.py index 901443a9..13acc639 100644 --- a/mcmd/commands/run.py +++ b/mcmd/commands/run.py @@ -6,7 +6,7 @@ from mcmd.core.command import command, CommandType from mcmd.core.context import context from mcmd.core.errors import McmdError -from mcmd.io import io +from mcmd.in_out import in_out from mcmd.script import script_runner from mcmd.script.model.script import Script from mcmd.script.options import ScriptOptions @@ -74,14 +74,14 @@ def _try_parse_script(lines: List[str]) -> Script: def _print_errors_and_exit(errors: List[ScriptValidationError]): - io.error('The script contains errors') - io.newline() + in_out.error('The script contains errors') + in_out.newline() errors.sort(key=lambda e: e.line_number) for error in errors: print(error.message) - io.newline() + in_out.newline() exit(1) diff --git a/mcmd/commands/script.py b/mcmd/commands/script.py index e32de774..e4d89358 100644 --- a/mcmd/commands/script.py +++ b/mcmd/commands/script.py @@ -1,13 +1,13 @@ -import mcmd.io.ask +import mcmd.in_out.ask from mcmd.commands._registry import arguments from mcmd.core.context import context from mcmd.core import history from mcmd.core.command import command, CommandType from mcmd.core.errors import McmdError -from mcmd.io import io -from mcmd.io.ask import confirm -from mcmd.io.io import highlight -from mcmd.io.logging import get_logger +from mcmd.in_out import in_out +from mcmd.in_out.ask import confirm +from mcmd.in_out.in_out import highlight +from mcmd.in_out.logging import get_logger # ========= @@ -71,7 +71,7 @@ def _remove_script(script_name): path = context().get_scripts_folder().joinpath(script_name) _check_script_exists(path) try: - io.start('Removing script %s' % highlight(script_name)) + in_out.start('Removing script %s' % highlight(script_name)) path.unlink() except OSError as e: raise McmdError('Error removing script: %s' % str(e)) @@ -101,7 +101,7 @@ def _create_script(args): return options = [line[1] for line in lines] - commands = mcmd.io.ask.checkbox('Pick the lines that will form the script:', options) + commands = mcmd.in_out.ask.checkbox('Pick the lines that will form the script:', options) file_name = _input_script_name() try: with open(str(context().get_scripts_folder().joinpath(file_name)), 'w') as script_file: @@ -119,7 +119,7 @@ def _check_script_exists(path): def _input_script_name(): file_name = '' while not file_name: - name = mcmd.io.ask.input_('Supply the name of the script:') + name = mcmd.in_out.ask.input_('Supply the name of the script:') if context().get_scripts_folder().joinpath(name).exists(): overwrite = confirm('%s already exists. Overwrite?' % name) if overwrite: diff --git a/mcmd/commands/set.py b/mcmd/commands/set.py index ad073d3e..4106ffc8 100644 --- a/mcmd/commands/set.py +++ b/mcmd/commands/set.py @@ -10,8 +10,8 @@ from mcmd.core.command import command from mcmd.core.context import context from mcmd.core.errors import McmdError -from mcmd.io import io -from mcmd.io.io import highlight +from mcmd.in_out import in_out +from mcmd.in_out.in_out import highlight from mcmd.molgenis import api from mcmd.molgenis.client import get, put from mcmd.utils import files @@ -122,12 +122,12 @@ def set_(args): if args.for_: entity = args.type row = args.for_ - io.start( + in_out.start( 'Updating {} of {} for id {} to {}'.format(highlight(args.attribute), highlight(args.type), highlight(args.for_), value_desc)) else: entity = _get_settings_entity(args.type) - io.start( + in_out.start( 'Updating {} of {} settings to {}'.format(highlight(args.attribute), highlight(args.type), value_desc)) row = _get_first_row_id(entity) diff --git a/mcmd/config/loader.py b/mcmd/config/loader.py index ccf442a1..064fd38a 100644 --- a/mcmd/config/loader.py +++ b/mcmd/config/loader.py @@ -15,11 +15,11 @@ from ruamel.yaml import YAML, YAMLError import mcmd.config.config as config -import mcmd.io.ask -import mcmd.io.io +import mcmd.in_out.ask +import mcmd.in_out.in_out from mcmd.core.context import context -from mcmd.io import io -from mcmd.io.io import highlight +from mcmd.in_out import in_out +from mcmd.in_out.in_out import highlight _DEFAULT_PROPERTIES = pkg_resources.resource_stream('mcmd.config', 'defaults.yaml') @@ -59,13 +59,13 @@ def _try_load_yaml(yaml: YAML, path: Path): try: return yaml.load(path) except YAMLError as e: - io.error("There's an error in the configuration file: {}".format(e)) + in_out.error("There's an error in the configuration file: {}".format(e)) exit(1) def _upgrade(default_config, user_config): - mcmd.io.io.info("Some properties haven't been configured yet. Let's take a moment to fix that.") - mcmd.io.io.newline() + mcmd.in_out.in_out.info("Some properties haven't been configured yet. Let's take a moment to fix that.") + mcmd.in_out.in_out.newline() for prop, configurer in property_configurers().items(): if prop not in user_config: @@ -73,38 +73,38 @@ def _upgrade(default_config, user_config): config.set_config(default_config, context().get_properties_file()) - mcmd.io.io.newline() - mcmd.io.io.info( + mcmd.in_out.in_out.newline() + mcmd.in_out.in_out.info( 'The configuration file has been updated successfully ({})'.format( highlight(str(context().get_properties_file())))) exit(0) def _install(default_config): - mcmd.io.io.info("Looks like this is your first time running {}!\n " + mcmd.in_out.in_out.info("Looks like this is your first time running {}!\n " "Let's take a moment to set things up. It's OK to leave some fields empty, you can always change " "them later.".format(highlight("Molgenis Commander"))) - mcmd.io.io.newline() + mcmd.in_out.in_out.newline() for configurer in property_configurers().values(): configurer(default_config) config.set_config(default_config, context().get_properties_file()) - mcmd.io.io.newline() - mcmd.io.io.info( + mcmd.in_out.in_out.newline() + mcmd.in_out.in_out.info( 'The configuration file has been created at {}'.format(highlight(str(context().get_properties_file())))) def _install_non_interactive(default_config): config.set_config(default_config, context().get_properties_file()) config.set_non_interactive(True) - mcmd.io.io.info( + mcmd.in_out.in_out.info( 'The configuration file has been created at {}'.format(highlight(str(context().get_properties_file())))) def _configure_git_root(config_): - git_root = mcmd.io.ask.input_( + git_root = mcmd.in_out.ask.input_( 'Enter the absolute path to your Molgenis git folder (e.g. /Users/me/git/molgenis/)') if len(git_root) > 0: config_['git']['root'] = git_root @@ -117,20 +117,20 @@ def _configure_host(values): def _configure_url(values): - host = mcmd.io.ask.input_('Enter the host name of your Molgenis (Default: http://localhost/)') + host = mcmd.in_out.ask.input_('Enter the host name of your Molgenis (Default: http://localhost/)') if len(host) > 0: values['host']['selected'] = host values['host']['auth'][0]['url'] = host def _configure_username(values): - username = mcmd.io.ask.input_('Enter the username of the super user (Default: admin)') + username = mcmd.in_out.ask.input_('Enter the username of the super user (Default: admin)') if len(username) > 0: values['host']['auth'][0]['username'] = username def _configure_password(values): - password = mcmd.io.ask.password( + password = mcmd.in_out.ask.password( 'Enter the password of the super user (Leave blank to use command line authentication)') if len(password) > 0: values['host']['auth'][0]['password'] = password diff --git a/mcmd/core/command.py b/mcmd/core/command.py index d5c5bab6..1b670f97 100644 --- a/mcmd/core/command.py +++ b/mcmd/core/command.py @@ -5,7 +5,7 @@ from mcmd.config import config from mcmd.core import history from mcmd.core.errors import McmdError, ScriptError -from mcmd.io import io +from mcmd.in_out import in_out from mcmd.molgenis import auth @@ -50,7 +50,7 @@ def wrapper(args, nested=False): else: _handle_error(error) else: - io.succeed() + in_out.succeed() finally: if args.write_to_history: history.write(args.arg_string, success=success) @@ -69,12 +69,12 @@ def _set_authentication(args): def _handle_error(error): - io.error(error.message) + in_out.error(error.message) if error.info: - io.info(error.info) + in_out.info(error.info) if isinstance(error, ScriptError): - io.info('Script failed at line {}'.format(io.highlight(str(error.line)))) + in_out.info('Script failed at line {}'.format(in_out.highlight(str(error.line)))) exit(1) diff --git a/mcmd/core/update_checker.py b/mcmd/core/update_checker.py index 343778ad..743e9605 100644 --- a/mcmd/core/update_checker.py +++ b/mcmd/core/update_checker.py @@ -8,7 +8,7 @@ from requests import RequestException from mcmd.core import store -from mcmd.io import io +from mcmd.in_out import in_out def check(): @@ -55,6 +55,6 @@ def _latest_version() -> Optional[Version]: def _show_update_message(current: Version, latest: Version): - io.warn( + in_out.warn( 'A new version of MOLGENIS Commander is available: {}! You are using {}.'.format(latest, current)) - io.info("To upgrade, run 'pip install --upgrade molgenis-commander'") + in_out.info("To upgrade, run 'pip install --upgrade molgenis-commander'") diff --git a/mcmd/io/__init__.py b/mcmd/in_out/__init__.py similarity index 100% rename from mcmd/io/__init__.py rename to mcmd/in_out/__init__.py diff --git a/mcmd/io/ask.py b/mcmd/in_out/ask.py similarity index 97% rename from mcmd/io/ask.py rename to mcmd/in_out/ask.py index 53f01a7a..3fb5f235 100644 --- a/mcmd/io/ask.py +++ b/mcmd/in_out/ask.py @@ -2,7 +2,7 @@ from mcmd.config import config from mcmd.core.errors import McmdError -from mcmd.io import io +from mcmd.in_out import in_out def multi_choice(message, choices): @@ -61,7 +61,7 @@ def _ask(question, validation=None): elif validation: result = validation(answer) if result is not True: - io.error(result) + in_out.error(result) return _ask(question, validation) return answer diff --git a/mcmd/io/io.py b/mcmd/in_out/in_out.py similarity index 97% rename from mcmd/io/io.py rename to mcmd/in_out/in_out.py index b5b7f6be..61a02b46 100644 --- a/mcmd/io/io.py +++ b/mcmd/in_out/in_out.py @@ -4,8 +4,8 @@ from halo import Halo import mcmd.config.config as config -from mcmd.io.kbhit import KBHit -from mcmd.io.logging import get_logger +from mcmd.in_out.kbhit import KBHit +from mcmd.in_out.logging import get_logger log = get_logger() diff --git a/mcmd/io/kbhit.py b/mcmd/in_out/kbhit.py similarity index 100% rename from mcmd/io/kbhit.py rename to mcmd/in_out/kbhit.py diff --git a/mcmd/io/logging.py b/mcmd/in_out/logging.py similarity index 100% rename from mcmd/io/logging.py rename to mcmd/in_out/logging.py diff --git a/mcmd/molgenis/auth.py b/mcmd/molgenis/auth.py index 9267bc4c..706911ae 100644 --- a/mcmd/molgenis/auth.py +++ b/mcmd/molgenis/auth.py @@ -8,10 +8,10 @@ import requests from requests import HTTPError -import mcmd.io.ask +import mcmd.in_out.ask from mcmd.config import config from mcmd.core.errors import McmdError, MolgenisOfflineError -from mcmd.io import io +from mcmd.in_out import in_out from mcmd.molgenis import api _username = None @@ -64,7 +64,7 @@ def _login(): _password = _ask_password() try: - io.debug('Logging in as user {}'.format(_username)) + in_out.debug('Logging in as user {}'.format(_username)) response = requests.post(api.login(), headers={'Content-Type': 'application/json'}, data=json.dumps({"username": _username, "password": _password})) @@ -81,7 +81,7 @@ def _login(): def _ask_password(): - io.pause() - password = mcmd.io.ask.password('Please enter the password for user {} on {}'.format(_username, config.url())) - io.unpause() + in_out.pause() + password = mcmd.in_out.ask.password('Please enter the password for user {} on {}'.format(_username, config.url())) + in_out.unpause() return password diff --git a/mcmd/molgenis/principals.py b/mcmd/molgenis/principals.py index e93f54fa..2027d331 100644 --- a/mcmd/molgenis/principals.py +++ b/mcmd/molgenis/principals.py @@ -2,8 +2,8 @@ from mcmd.core.compatibility import version from mcmd.core.errors import McmdError -from mcmd.io.ask import multi_choice -from mcmd.io.logging import get_logger +from mcmd.in_out.ask import multi_choice +from mcmd.in_out.logging import get_logger from mcmd.molgenis import api from mcmd.molgenis.client import get diff --git a/mcmd/molgenis/resources.py b/mcmd/molgenis/resources.py index 5f65e188..885243a0 100644 --- a/mcmd/molgenis/resources.py +++ b/mcmd/molgenis/resources.py @@ -3,8 +3,8 @@ from mcmd.molgenis import api from mcmd.molgenis.client import get -from mcmd.io.ask import multi_choice -from mcmd.io.logging import get_logger +from mcmd.in_out.ask import multi_choice +from mcmd.in_out.logging import get_logger from mcmd.core.errors import McmdError log = get_logger() diff --git a/mcmd/script/script_runner.py b/mcmd/script/script_runner.py index 5c6c656f..782191bb 100644 --- a/mcmd/script/script_runner.py +++ b/mcmd/script/script_runner.py @@ -7,9 +7,9 @@ from mcmd.args import parser as arg_parser from mcmd.args.errors import ArgumentSyntaxError from mcmd.core.errors import McmdError, ScriptError -from mcmd.io import io, ask -from mcmd.io.io import bold, dim -from mcmd.io.logging import get_logger +from mcmd.in_out import in_out, ask +from mcmd.in_out.in_out import bold, dim +from mcmd.in_out.logging import get_logger from mcmd.script.model.lines import ParsedLine from mcmd.script.model.script import Script from mcmd.script.model.statements import Value, Input, Wait, VisibleComment, Command, InvisibleComment, \ @@ -80,7 +80,7 @@ def _process_line(line: ParsedLine, state: _ScriptExecutionState): def _log_comment(comment: VisibleComment, state: _ScriptExecutionState): if state.options.log_comments: if len(comment.text.string) == 0: - io.newline() + in_out.newline() else: log.info(comment.text.render(state.values)) @@ -117,9 +117,9 @@ def _wait(wait: Wait, state: _ScriptExecutionState): text = '{}: {} {}'.format(bold('Waiting for user'), wait.message.render(state.values), dim('(Press enter to continue)')) - io.start(text) - io.wait_for_enter() - io.succeed() + in_out.start(text) + in_out.wait_for_enter() + in_out.succeed() def _handle_error(error: McmdError, line_number: int, state: _ScriptExecutionState): @@ -127,9 +127,9 @@ def _handle_error(error: McmdError, line_number: int, state: _ScriptExecutionSta raise ScriptError.from_error(error, line_number) else: sys.stderr.write('Error on line {}: '.format(str(line_number))) - io.error(error.message) + in_out.error(error.message) if error.info: - io.info(error.info) + in_out.info(error.info) def _run_command(command: Command, state: _ScriptExecutionState): diff --git a/mcmd/utils/files.py b/mcmd/utils/files.py index 3015e542..50d1fbc1 100644 --- a/mcmd/utils/files.py +++ b/mcmd/utils/files.py @@ -2,9 +2,9 @@ from pathlib import Path from typing import List -import mcmd.io.ask +import mcmd.in_out.ask from mcmd.core.errors import McmdError -from mcmd.io import io +from mcmd.in_out import in_out def get_file_name_from_path(file_path: str) -> str: @@ -25,7 +25,7 @@ def get_files(folders: List[Path]) -> List[Path]: files = list() for folder in folders: if not folder.is_dir(): - io.warn("Folder %s doesn't exist" % folder) + in_out.warn("Folder %s doesn't exist" % folder) for file in list(folder.glob('*.*')): files.append(file) @@ -107,5 +107,5 @@ def _choose_file(paths: List[Path], name: str): :return: the selected path """ choices = [str(file_path) for file_path in paths] - answer = mcmd.io.ask.multi_choice('Multiple files found for %s. Pick one:' % name, choices) + answer = mcmd.in_out.ask.multi_choice('Multiple files found for %s. Pick one:' % name, choices) return Path(answer) diff --git a/tests/integration/client/test_login.py b/tests/integration/client/test_login.py index bc1f0fb9..3e732b35 100644 --- a/tests/integration/client/test_login.py +++ b/tests/integration/client/test_login.py @@ -17,7 +17,7 @@ def test_login_password(set_token, session): @pytest.mark.integration -@patch('mcmd.io.ask.password') +@patch('mcmd.in_out.ask.password') @patch('mcmd.config.config._get_selected_host_auth') @patch('mcmd.config.config.set_token') def test_login_no_password(set_token_mock, host_mock, enter_password, session): diff --git a/tests/integration/commands/test_delete.py b/tests/integration/commands/test_delete.py index b0b77f87..41872e05 100644 --- a/tests/integration/commands/test_delete.py +++ b/tests/integration/commands/test_delete.py @@ -6,7 +6,7 @@ @pytest.mark.integration -@patch('mcmd.io.ask.confirm') +@patch('mcmd.in_out.ask.confirm') def test_delete_entity(are_you_sure, session, entity_type): are_you_sure.return_value = True run_commander('delete --entity-type {}'.format(entity_type)) @@ -15,7 +15,7 @@ def test_delete_entity(are_you_sure, session, entity_type): @pytest.mark.integration -@patch('mcmd.io.ask.confirm') +@patch('mcmd.in_out.ask.confirm') def test_delete_entity_cancel(are_you_sure, session, entity_type): are_you_sure.return_value = False run_commander('delete --entity-type {}'.format(entity_type)) @@ -24,7 +24,7 @@ def test_delete_entity_cancel(are_you_sure, session, entity_type): @pytest.mark.integration -@patch('mcmd.io.ask.confirm') +@patch('mcmd.in_out.ask.confirm') def test_delete_force(are_you_sure, session, package): run_commander('delete --force --package {}'.format(package)) @@ -40,7 +40,7 @@ def test_delete_entity_data(session, entity_type): @pytest.mark.integration -@patch('mcmd.io.ask.confirm') +@patch('mcmd.in_out.ask.confirm') def test_delete_entity_attribute(are_you_sure, session, entity_type): are_you_sure.return_value = True run_commander('delete --entity-type {} --attribute firstName'.format(entity_type)) diff --git a/tests/integration/commands/test_disable_rls.py b/tests/integration/commands/test_disable_rls.py index 7cfb0cac..4b2bc701 100644 --- a/tests/integration/commands/test_disable_rls.py +++ b/tests/integration/commands/test_disable_rls.py @@ -7,7 +7,7 @@ @pytest.mark.integration -@patch('mcmd.io.ask.confirm') +@patch('mcmd.in_out.ask.confirm') def test_disable_rls(are_you_sure, entity_type): are_you_sure.return_value = True run_commander('enable rls {}'.format(entity_type)) @@ -17,7 +17,7 @@ def test_disable_rls(are_you_sure, entity_type): @pytest.mark.integration -@patch('mcmd.io.ask.confirm') +@patch('mcmd.in_out.ask.confirm') def test_disable_rls_cancel(are_you_sure, entity_type): are_you_sure.return_value = False run_commander('enable rls {}'.format(entity_type)) diff --git a/tests/integration/commands/test_import.py b/tests/integration/commands/test_import.py index 0a2e0816..914ce830 100644 --- a/tests/integration/commands/test_import.py +++ b/tests/integration/commands/test_import.py @@ -97,7 +97,7 @@ def test_import_from_path_in_package(session, package): @pytest.mark.integration -@patch('mcmd.io.ask.multi_choice') +@patch('mcmd.in_out.ask.multi_choice') def test_import_from_issue(which_file_question, session): file_name = 'emx_package-only.xlsx' which_file_question.return_value = file_name diff --git a/tests/integration/commands/test_make.py b/tests/integration/commands/test_make.py index c7a0f20e..7f1e84d5 100644 --- a/tests/integration/commands/test_make.py +++ b/tests/integration/commands/test_make.py @@ -58,7 +58,7 @@ def test_make_group_member_explicit(session, user, group): # noinspection DuplicatedCode @pytest.mark.integration -@patch('mcmd.io.ask.confirm') +@patch('mcmd.in_out.ask.confirm') def test_make_group_member_update_cancel(update_yes_no, session, user, group): update_yes_no.return_value = False original_role_name = '{}_VIEWER'.format(group) @@ -74,7 +74,7 @@ def test_make_group_member_update_cancel(update_yes_no, session, user, group): # noinspection DuplicatedCode @pytest.mark.integration -@patch('mcmd.io.ask.confirm') +@patch('mcmd.in_out.ask.confirm') def test_make_group_member_update(update_yes_no, session, user, group): update_yes_no.return_value = True original_role_name = '{}_VIEWER'.format(group) diff --git a/tests/integration/commands/test_script.py b/tests/integration/commands/test_script.py index 6c85ebd0..3f9faa97 100644 --- a/tests/integration/commands/test_script.py +++ b/tests/integration/commands/test_script.py @@ -30,8 +30,8 @@ def test_script_read(caplog): @pytest.mark.integration -@patch('mcmd.io.ask.input_') -@patch('mcmd.io.ask.checkbox') +@patch('mcmd.in_out.ask.input_') +@patch('mcmd.in_out.ask.checkbox') @patch('mcmd.core.history.read') def test_script_create(history, which_lines, what_filename): history.return_value = _history_lines diff --git a/tests/unit/commands/import_test.py b/tests/unit/commands/import_test.py index c57e5b09..82617159 100644 --- a/tests/unit/commands/import_test.py +++ b/tests/unit/commands/import_test.py @@ -9,7 +9,7 @@ @pytest.mark.unit class ImportMethodsTest(unittest.TestCase): - @patch('mcmd.io.ask.multi_choice') + @patch('mcmd.in_out.ask.multi_choice') def test_choose_attachments(self, multi_choice): multi_choice.return_value = 'other_file.xlsx' a1 = Attachment('url/1234/file.xlsx') @@ -17,7 +17,7 @@ def test_choose_attachments(self, multi_choice): ret = import_._choose_attachment([a1, a2]) self.assertEqual(ret, a2) - @patch('mcmd.io.ask.multi_choice') + @patch('mcmd.in_out.ask.multi_choice') def test_choose_attachments_with_duplicates(self, multi_choice): multi_choice.return_value = '1234/file.xlsx' a1 = Attachment('url/1234/file.xlsx') diff --git a/tests/unit/script/script_runner_test.py b/tests/unit/script/script_runner_test.py index 7b058c52..b3d15bc0 100644 --- a/tests/unit/script/script_runner_test.py +++ b/tests/unit/script/script_runner_test.py @@ -14,9 +14,9 @@ class ScriptRunnerTest(unittest.TestCase): @staticmethod @log_capture() - @patch('mcmd.io.ask.input_') - @patch('mcmd.io.ask.confirm') - @patch('mcmd.io.ask.password') + @patch('mcmd.in_out.ask.input_') + @patch('mcmd.in_out.ask.confirm') + @patch('mcmd.in_out.ask.password') def test_script_runner(input_text, confirm_input, password_input, capture): input_text.return_value = 'text' confirm_input.return_value = 'true' @@ -60,7 +60,7 @@ def test_script_runner(input_text, confirm_input, password_input, capture): @staticmethod @log_capture() - @patch('mcmd.io.ask.input_') + @patch('mcmd.in_out.ask.input_') def test_line_dependencies(input_surname, capture): input_surname.return_value = 'achternaam' script_lines = ["$value name = 'henk'", diff --git a/tests/unit/utils/files_test.py b/tests/unit/utils/files_test.py index 7ee79b9a..b53cfd86 100644 --- a/tests/unit/utils/files_test.py +++ b/tests/unit/utils/files_test.py @@ -80,7 +80,7 @@ def test_select_path_with_extension(): assert selected_file == path1 - @patch('mcmd.io.ask.multi_choice') + @patch('mcmd.in_out.ask.multi_choice') def test_select_path_clash(self, multi_choice): with TemporaryDirectory() as temp_dir: path1 = Path(temp_dir).joinpath('tempfile.txt')