def status(analysis_id: typing.Optional[str] = None, output_format: typing.Optional[str] = None): """Get status of an analysis. If ANALYSIS_ID is not provided, there will be used last analysis id, if noted by Thamos. """ if not analysis_id: with workdir(): status_dict = get_status() else: status_dict = get_status(analysis_id) if not output_format or output_format == "table": table = Table() for key in status_dict.keys(): table.add_column( key.replace("_", " ").capitalize(), style="cyan", overflow="fold", ) table.add_row(*status_dict.values()) console = Console() console.print(table, justify="center") return elif output_format == "json": output = json.dumps(status_dict, indent=2) elif output_format == "yaml": output = yaml.safe_dump(status_dict, default_flow_style=False) else: raise NotImplementedError(f"Unknown output format {output_format}") click.echo(output)
def show(output_format: str, runtime_environment: Optional[str] = None) -> None: """Show details for configured runtime environments. Examples: thamos show --runtime-environment "development" """ with workdir(configuration.CONFIG_NAME): environments = configuration.list_runtime_environments() if not runtime_environment: if not environments: _LOGGER.error("No runtime environments found") sys.exit(1) to_show = environments if runtime_environment: for env in environments: if env.get("name") == runtime_environment: to_show = env break else: raise NoRuntimeEnvironmentError( f"Runtime environment {runtime_environment!r} not found") if output_format == "json": output = json.dumps(to_show, indent=2) elif output_format == "yaml": output = yaml.safe_dump(to_show, default_flow_style=False) else: raise NotImplementedError(f"Unknown output format {output_format}") click.echo(output)
def list_() -> None: """List available runtime environments configured.""" with workdir(configuration.CONFIG_NAME): environments = configuration.list_runtime_environments() if not environments: _LOGGER.error("No runtime environments found") sys.exit(1) for env in environments: click.echo(env.get("name"))
def log(analysis_id: str = None): """Get log of running or finished analysis. If ANALYSIS_ID is not provided, there will be used last analysis id, if noted by Thamos. """ if not analysis_id: with workdir(): log_str = get_log() else: log_str = get_log(analysis_id) click.echo(log_str)
def log(analysis_id: typing.Optional[str] = None): """Get log of running or finished analysis. If ANALYSIS_ID is not provided, the last request is used by default. """ if not analysis_id: with workdir(): log_str = get_log() else: log_str = get_log(analysis_id) click.echo(log_str)
def install(dev: bool) -> None: """Install dependencies as stated in Pipfile.lock or requirements.txt. This command assumes requirements files are present and dependencies are already resolved. If that's not the case, issue `thamos advise` before calling this. """ with workdir(): method = ("pipenv" if configuration.requirements_format == "pipenv" else "requirements") if not dev and method == "pipenv": _LOGGER.warning( "Development dependencies will not be installed - see %s", jl("no_dev")) micropipenv.install(method=method, deploy=True, dev=dev)
def provenance_check( debug: bool = False, no_wait: bool = False, json_output: bool = False, force: bool = False, ): """Check provenance of installed packages.""" with workdir(): if configuration.requirements_format != "pipenv": raise ValueError( "Provenance checks are available only for requirements managed by Pipenv" ) pipfile, pipfile_lock = _load_files("pipenv") if not pipfile_lock: _LOGGER.error( "No Pipfile.lock found - provenance cannot be checked") sys.exit(3) results = thoth_provenance_check(pipfile, pipfile_lock, debug=debug, nowait=no_wait, force=force) if not results: sys.exit(2) if no_wait: # Echo the analysis id to user when nowait. click.echo(results) sys.exit(0) report, error = results if report: _print_report(report, json_output=json_output, title="Provenance check report") else: _LOGGER.info("Provenance check passed!") if error: sys.exit(5) if any(item.get("type") == "ERROR" for item in report): sys.exit(4) return 0
def provenance_check( debug: bool = False, no_wait: bool = False, json_output: bool = False, force: bool = False, ): """Check provenance of installed packages.""" with workdir(): pipfile, pipfile_lock = _load_pipfiles() if not pipfile_lock: _LOGGER.error( "No Pipfile.lock found - provenance cannot be checked") sys.exit(3) results = thoth_provenance_check(pipfile, pipfile_lock, debug=debug, nowait=no_wait, force=force) if not results: sys.exit(2) if no_wait: # Echo the analysis id to user when nowait. click.echo(results) sys.exit(0) report, error = results _print_report(report, json_output=json_output ) if report else _LOGGER.info("Provenance check passed!") if error: sys.exit(5) if any(item.get("type") == "ERROR" for item in report): sys.exit(4) return 0
def status(analysis_id: str = None, output_format: str = None): """Get status of an analysis. If ANALYSIS_ID is not provided, there will be used last analysis id, if noted by Thamos. """ if not analysis_id: with workdir(): status_dict = get_status() else: status_dict = get_status(analysis_id) if not output_format or output_format == "table": table = Texttable(max_width=get_terminal_size().columns) table.set_deco(Texttable.VLINES) table.add_rows(list(status_dict.items()), header=False) output = table.draw() elif output_format == "json": output = json.dumps(status_dict, indent=2) elif output_format == "yaml": output = yaml.safe_dump(status_dict, default_flow_style=False) else: raise NotImplementedError(f"Unknown output format {output_format}") click.echo(output)
def advise( debug: bool = False, no_write: bool = False, recommendation_type: str = None, runtime_environment: str = None, no_wait: bool = False, no_static_analysis: bool = False, json_output: bool = False, limit_latest_versions: int = None, force: bool = False, ): """Ask Thoth for recommendations on application stack.""" with workdir(): pipfile, pipfile_lock = _load_pipfiles() # In CLI we always call to obtain only the best software stack (count is implicitly set to 1). results = thoth_advise( pipfile, pipfile_lock, recommendation_type=recommendation_type, runtime_environment_name=runtime_environment, debug=debug, nowait=no_wait, force=force, limit_latest_versions=limit_latest_versions, no_static_analysis=no_static_analysis, ) if not results: return sys.exit(2) if no_wait: # Echo the analysis id to user when not waiting. click.echo(results) sys.exit(0) result, error = results if not no_write: # Print report of the best one - thus index zero. if result["report"] and result["report"][0][0]: _print_header("Recommended stack report") _print_report(result["report"][0][0], json_output=json_output) if result["stack_info"]: _print_header("Application stack guidance") _print_report(result["stack_info"], json_output=json_output) if not error: pipfile = result["report"][0][1]["requirements"] pipfile_lock = result["report"][0][1]["requirements_locked"] _write_configuration(result["advised_configuration"], recommendation_type, limit_latest_versions) _write_pipfiles(pipfile, pipfile_lock) else: click.echo(json.dumps(result, indent=2)) if error: sys.exit(4) sys.exit(0)
def advise( debug: bool = False, no_write: bool = False, recommendation_type: str = None, runtime_environment: str = None, no_wait: bool = False, no_static_analysis: bool = False, json_output: bool = False, force: bool = False, dev: bool = False, no_user_stack: bool = False, install: bool = False, write_advised_manifest_changes: Optional[str] = None, ): """Ask Thoth for recommendations on application stack.""" if install and no_wait: _LOGGER.error("Cannot install dependencies as --no-wait was provided") sys.exit(1) if install and no_write: _LOGGER.error( "Cannot install dependencies if lock files are not written") sys.exit(1) with workdir(): if not dev and configuration.requirements_format == "pipenv": _LOGGER.warning( "Development dependencies will not be considered during the resolution process - see %s", jl("no_dev"), ) # In CLI we always call to obtain only the best software stack (count is implicitly set to 1). results = thoth_advise_here( recommendation_type=recommendation_type, runtime_environment_name=runtime_environment, debug=debug, nowait=no_wait, force=force, source_type=ThothAdviserIntegrationEnum.CLI, no_static_analysis=no_static_analysis, dev=dev, no_user_stack=no_user_stack, ) if not results: return sys.exit(2) if no_wait: # Echo the analysis id to user when not waiting. click.echo(results) sys.exit(0) result, error = results if error: if json_output: json.dump(result, sys.stdout, indent=2) else: stack_info = (result.get("report") or {}).get("stack_info") if stack_info: _print_report( stack_info, json_output=json_output, title="Application stack guidance", ) print( result.get("error_msg") or "No error message was provided by the service.") sys.exit(4) if not no_write: if result["report"] and result["report"]["stack_info"]: _print_report( result["report"]["stack_info"], json_output=json_output, title="Application stack guidance", ) # Print report of the best one - thus index zero. if result["report"] and result["report"]["products"]: if result["report"]["products"][0]["justification"]: _print_report( result["report"]["products"][0]["justification"], json_output=json_output, title="Recommended stack report", ) else: click.echo( "No justification was made for the recommended stack") pipfile = result["report"]["products"][0]["project"][ "requirements"] pipfile_lock = result["report"]["products"][0]["project"][ "requirements_locked"] _write_configuration( result["report"]["products"][0]["advised_runtime_environment"], recommendation_type, dev, ) _write_files(pipfile, pipfile_lock, configuration.requirements_format) # type: ignore if write_advised_manifest_changes: advised_manifest_changes = result["report"]["products"][0][ "project"].get("advised_manifest_changes") with open(write_advised_manifest_changes, "w") as advised_manifest_changes_file: json.dump(advised_manifest_changes or {}, advised_manifest_changes_file) advised_manifest_changes_file.write("\n") if install: method = ("pipenv" if configuration.requirements_format == "pipenv" else "requirements") micropipenv.install(method=method, deploy=True, dev=dev) else: click.echo(json.dumps(result, indent=2)) sys.exit(0)