def table_print_cur_env_conflicts(conflicts, pretty=False): """ Print current conflicts in environment using terminaltables. """ ts = "No conflicts detected in environment" if conflicts: print_col("Conflicts in environment:", pretty=pretty, header=True) table_data = [['PACKAGE', 'DEPENDENCY', 'CONFLICT']] for conflict in conflicts: maglog.info(conflict) try: c_name = conflict[0][0] c_ver = conflict[0][1] c_dep = conflict[1] c_dep_dets = conflict[-1] t_row = [ " ".join([c_name, c_ver]), c_dep, _string_requirement_details(c_dep_dets) ] table_data.append(t_row) except Exception as e: maglog.exception(e) print("There was an error in printing output; check -v") ts = OutputTableType(table_data).table print_col(ts, pretty=pretty)
def table_print_cur_env_conflicts(conflicts, pretty=False): """ Print current conflicts in environment using terminaltables. """ ts = "No conflicts detected in environment" if conflicts: print_col("Conflicts in environment:", pretty=pretty, header=True) table_data = [['PACKAGE', 'DEPENDENCY', 'CONFLICT']] for conflict in conflicts: maglog.info(conflict) try: c_name = conflict[0][0] c_ver = conflict[0][1] c_dep = conflict[1] c_dep_dets = conflict[-1] t_row = [" ".join([c_name, c_ver]), c_dep, _string_requirement_details(c_dep_dets)] table_data.append(t_row) except Exception as e: maglog.exception(e) print("There was an error in printing output; check -v") ts = OutputTableType(table_data).table print_col(ts, pretty=pretty)
def _print_if(list_in, lead_in_text=None, tab_space=2, pretty=False): """ prints the list if it has items. :param list list_in: list of input items :param str lead_in_text: what to print before list print. :param int tab_space: indentation for prettiness. :param bool lead_nl: lead print with newline """ if list_in: if lead_in_text: print_col(" " * tab_space + lead_in_text, pretty=pretty) for item in list_in: if type(item) == tuple: _item = item[0] + " as " + _string_requirement_details(item[1]) else: _item = item print_col(" " * tab_space + "".join(_item), pretty=pretty)
def _print_if(list_in, lead_in_text=None, tab_space=2, pretty=False): """ prints the list if it has items. :param list list_in: list of input items :param str lead_in_text: what to print before list print. :param int tab_space: indentation for prettiness. :param bool lead_nl: lead print with newline """ if list_in: if lead_in_text: print_col(" "*tab_space + lead_in_text, pretty=pretty) for item in list_in: if type(item) == tuple: _item = item[0] + " as " + _string_requirement_details(item[1]) else: _item = item print_col(" "*tab_space + "".join(_item), pretty=pretty)
def pprint_dec_dict(descendant_dictionary, venv, pretty=False): """ Pretty prints ancestors dictionary to standard out. :param descendant_dictionary: :param venv: magellan.env_utils.Environment """ env_name = "the current environment" if not venv.name else venv.name for pk, p in descendant_dictionary.items(): if p: s = "{} depends on these packages in {}:"\ .format(venv.all_packages[pk].name, env_name) print_col(s, pretty=pretty, header=True) for a in p: try: print_col("{} {}".format(a[0], a[1]), pretty=pretty) except Exception as e: maglog.exception(e)
def acquire_and_display_dependencies(package_version_list, pretty=False): """ Gets the dependencies information by installing the package and version from PyPI """ for p in package_version_list: package = p[0] version = p[1] if not PyPIHelper.check_package_version_on_pypi(package, version): print_col("{} {} not found on PyPI.".format(package, version), pretty=pretty, header=True) continue requirements = DepTools.get_deps_for_package_version( package, version, vex_options=MagellanConfig.vex_options) maglog.debug(pformat(requirements)) _table_print_requirements(requirements, pretty)
def pprint_dec_dict(descendant_dictionary, venv, pretty=False): """ Pretty prints ancestors dictionary to standard out. :param descendant_dictionary: :param venv: magellan.env_utils.Environment """ env_name = "the current environment" if not venv.name else venv.name for pk, p in list(descendant_dictionary.items()): if p: s = "{} depends on these packages in {}:"\ .format(venv.all_packages[pk].name, env_name) print_col(s, pretty=pretty, header=True) for a in p: try: print_col("{} {}".format(a[0], a[1]), pretty=pretty) except Exception as e: maglog.exception(e)
def _table_print_requirements(requirements, pretty=False): """ Table print requirements to stdout for human consumption. :param dict requirements: dictionary of requirements from PyPI """ package = requirements.get('project_name') version = requirements.get('version') reqs = requirements.get('requires', {}) if not reqs: s = "{} {} appears to have no dependencies.".format(package, version) print_col(s, pretty=pretty, header=True) else: s = "Dependencies of {} {}:".format(package, version) print_col(s, pretty=pretty, header=True) table_data = [['PACKAGE', 'SPECS']] for r_key, r in reqs.items(): table_row = [r['project_name']] if r['specs']: spec_string = "" for s in r['specs']: spec_string += "{} {}\n".format(s[0], s[1]) table_row.append(spec_string) else: table_row.append('\n') table_data.append(table_row) table = OutputTableType(table_data) print_col(table.table, pretty=pretty)
def _table_print_requirements(requirements, pretty=False): """ Table print requirements to stdout for human consumption. :param dict requirements: dictionary of requirements from PyPI """ package = requirements.get('project_name') version = requirements.get('version') reqs = requirements.get('requires', {}) if not reqs: s = "{} {} appears to have no dependencies.".format(package, version) print_col(s, pretty=pretty, header=True) else: s = "Dependencies of {} {}:".format(package, version) print_col(s, pretty=pretty, header=True) table_data = [['PACKAGE', 'SPECS']] for r_key, r in list(reqs.items()): table_row = [r['project_name']] if r['specs']: spec_string = "" for s in r['specs']: spec_string += "{} {}\n".format(s[0], s[1]) table_row.append(spec_string) else: table_row.append('\n') table_data.append(table_row) table = OutputTableType(table_data) print_col(table.table, pretty=pretty)
def table_print_additional_package_conflicts(conflicts, pretty=False): """ Prints the upgrade conflicts to stdout in format easily digestible for people. :param conflicts: dict of upgrade conflicts """ print_col("Package Addition Conflicts:", pretty=pretty, header=True) for p_k, p in list(conflicts.items()): has_recs = p.get('requirements') if not has_recs: print_col("Requirements not found for {}, possible failure " "when installating package into temporary " "directory?".format(p_k), pretty=pretty) continue p_name = p.get('requirements').get('project_name') ver = p.get('requirements').get('version') print_col("{0} {1}:".format(p_name, ver), pretty=pretty, header=True) okay = p['may_be_okay'] up = p['may_try_upgrade'] new_ps = p['new_packages'] if not (okay or up or new_ps): s = (" No conflicts detected for the addition of {0} {1}.". format(p_name, ver)) print_col(s, pretty=pretty) _print_if(okay, "Should be okay:", pretty=pretty) _print_if(up, "May try to upgrade:", pretty=pretty) _print_if(new_ps, "New packages to add:", pretty=pretty) print("\n")
def table_print_additional_package_conflicts(conflicts, pretty=False): """ Prints the upgrade conflicts to stdout in format easily digestible for people. :param conflicts: dict of upgrade conflicts """ print_col("Package Addition Conflicts:", pretty=pretty, header=True) for p_k, p in conflicts.items(): has_recs = p.get('requirements') if not has_recs: print_col("Requirements not found for {}, possible failure " "when installating package into temporary " "directory?".format(p_k), pretty=pretty) continue p_name = p.get('requirements').get('project_name') ver = p.get('requirements').get('version') print_col("{0} {1}:".format(p_name, ver), pretty=pretty, header=True) okay = p['may_be_okay'] up = p['may_try_upgrade'] new_ps = p['new_packages'] if not (okay or up or new_ps): s = (" No conflicts detected for the addition of {0} {1}." .format(p_name, ver)) print_col(s, pretty=pretty) _print_if(okay, "Should be okay:", pretty=pretty) _print_if(up, "May try to upgrade:", pretty=pretty) _print_if(new_ps, "New packages to add:", pretty=pretty) print("\n")
def table_print_upgrade_conflicts(conflicts, dep_info, venv, pretty=False): """ Prints the upgrade conflicts to stdout in format easily digestible for people. :param dict conflicts: dict of upgrade conflicts :param dict dep_info: dependency information :param Environment venv: virtual environment """ if not conflicts: return print("\n") s = "Upgrade Conflicts:" print_col(s, pretty=pretty, header=True) for p_k, p in list(conflicts.items()): has_recs = dep_info.get(p_k).get('requirements') if not has_recs: print_col("Requirements not found for {}, possible failure " "when installating package into temporary " "directory?".format(p_k), pretty=pretty) continue p_name = dep_info[p_k]['requirements']['project_name'] ver = dep_info[p_k]['requirements']['version'] cur_ver = venv.all_packages[p_name.lower()].version if parse_version(cur_ver) < parse_version(ver): direction = "upgrade" else: direction = "downgrade" s = ("{} {}: {} from {} to {}.".format(p_name, ver, direction, cur_ver, ver)) print_col(s, pretty=pretty) missing_from_env = p['missing_packages'] new_dependencies = p['dep_set']['new_deps'] removed_dependencies = p['dep_set']['removed_deps'] broken_reqs = [ "{0}: {1}".format(x, v) for x, v in list(p['anc_dep'].items()) ] if not (missing_from_env or new_dependencies or removed_dependencies or broken_reqs): print_col("No conflicts detected", pretty=pretty) _print_if(missing_from_env, "Packages not in environment (to be installed):", pretty=pretty) _print_if(new_dependencies, "New dependencies of {}:".format(p_name), pretty=pretty) _print_if(removed_dependencies, "{} will no longer depend on:".format(p_name), pretty=pretty) _print_if(broken_reqs, "These packages will have their requirements broken:{}", pretty=pretty) print("\n")
def detect_upgrade_conflicts(packages, venv, pretty=False): """ Detect conflicts between packages in current environment when upgrading other packages. At present this routine will look at just the immediate connections to a graph in the environment. It does this in 3 major ways: 1. DEPENDENCY SET - check_changes_in_requirements_vs_env Checks the required dependencies of new version against current environment to see additions/removals BY NAME ONLY. 2. REQUIRED VERSIONS - check_req_deps_satisfied_by_current_env For all dependencies of new version, checks to see whether they are satisfied by current environment versions. 3. ANCESTOR DEPENDENCIES - check_if_ancestors_still_satisfied For all the ancestor nodes that depend on PACKAGE, it checks whether the dependency specs are satisfied by the new version. :param list packages: List of (package, desired_version)'s :param Environment venv: virtual environment """ uc_deps = {} conflicts = {} for u in packages: package = u[0] version = u[1] p_v = "{0}_{1}".format(package, version.replace('.', '_')) uc_deps[p_v] = {} p_key = package.lower() cur_ver = venv.all_packages[p_key].version if parse_version(cur_ver) == parse_version(version): s = ("{} version {} is same as current!".format( package, version)) print_col(s, 'red', 'black', pretty) continue if not PyPIHelper.check_package_version_on_pypi(package, version): continue uc_deps[p_v]['requirements'] = \ DepTools.get_deps_for_package_version( package, version, vex_options=MagellanConfig.vex_options) ancestors, descendants = Package.get_direct_links_to_any_package( package, venv.edges) # 1: DEPENDENCY SET - check_changes_in_requirements_vs_env uc_deps[p_v]['dependency_set'] = \ DepTools.check_changes_in_requirements_vs_env( uc_deps[p_v]['requirements'], descendants) # 2. REQUIRED VERSIONS - check_req_deps_satisfied_by_current_env uc_deps[p_v]['required_versions'] = \ DepTools.check_req_deps_satisfied_by_current_env( uc_deps[p_v]['requirements'], venv.nodes) # 3. ANCESTOR DEPENDENCIES - check_if_ancestors_still_satisfied uc_deps[p_v]['ancestor_dependencies'] = \ DepTools.check_if_ancestors_still_satisfied( package, version, ancestors, venv.package_requirements) conflicts[p_v] = {} try: conflicts[p_v]['dep_set'] = uc_deps[p_v]['dependency_set'] conflicts[p_v]['req_ver'] = \ uc_deps[p_v]['required_versions']['conflicts'] conflicts[p_v]['missing_packages'] = \ uc_deps[p_v]['required_versions']['missing'] conflicts[p_v]['anc_dep'] = \ uc_deps[p_v]['ancestor_dependencies']['conflicts'] except TypeError as e: maglog.debug( "Error when attempting to assess conflicts {}".format(e)) return conflicts, uc_deps
def table_print_upgrade_conflicts(conflicts, dep_info, venv, pretty=False): """ Prints the upgrade conflicts to stdout in format easily digestible for people. :param dict conflicts: dict of upgrade conflicts :param dict dep_info: dependency information :param Environment venv: virtual environment """ if not conflicts: return print("\n") s = "Upgrade Conflicts:" print_col(s, pretty=pretty, header=True) for p_k, p in conflicts.items(): has_recs = dep_info.get(p_k).get('requirements') if not has_recs: print_col("Requirements not found for {}, possible failure " "when installating package into temporary " "directory?".format(p_k), pretty=pretty) continue p_name = dep_info[p_k]['requirements']['project_name'] ver = dep_info[p_k]['requirements']['version'] cur_ver = venv.all_packages[p_name.lower()].version if parse_version(cur_ver) < parse_version(ver): direction = "upgrade" else: direction = "downgrade" s = ("{} {}: {} from {} to {}.".format( p_name, ver, direction, cur_ver, ver)) print_col(s, pretty=pretty) missing_from_env = p['missing_packages'] new_dependencies = p['dep_set']['new_deps'] removed_dependencies = p['dep_set']['removed_deps'] broken_reqs = ["{0}: {1}".format(x, v) for x, v in p['anc_dep'].items()] if not (missing_from_env or new_dependencies or removed_dependencies or broken_reqs): print_col("No conflicts detected", pretty=pretty) _print_if(missing_from_env, "Packages not in environment (to be installed):", pretty=pretty) _print_if(new_dependencies, "New dependencies of {}:".format(p_name), pretty=pretty) _print_if(removed_dependencies, "{} will no longer depend on:".format(p_name), pretty=pretty) _print_if(broken_reqs, "These packages will have their requirements broken:{}", pretty=pretty) print("\n")
def detail_version_info(version_info, package, version, pretty=False): """ Outputs to console the result of Package.check_latest_major_minor_versions """ print_col("Analysing {} {}".format(package, version), pretty=pretty, header=True) status = version_info.get("code") if status == -1: # Error print_col("There was an error, see [super] verbose output " "for details", pretty=pretty) elif status == 0: # Up to date print_col("Up to date.", pretty=pretty) elif status == 999: # beyond print_col("{} is BEYOND latest PyPI version {}".format( version, version_info.get("minor_version").get("latest")), pretty=pretty) else: maj_out = version_info.get("major_version").get("outdated") min_out = version_info.get("minor_version").get("outdated") if maj_out: print_col("Major version outdated {} > {}".format( version_info.get("major_version").get("latest"), version), pretty=pretty) if min_out: print_col("Minor version outdated {} > {}".format( version_info.get("minor_version").get("latest"), version), pretty=pretty)
def _print_req_env_comp_list(header, in_list, pretty=False): print_col(header, header=True, pretty=pretty) for line in in_list: print_col(str(line), pretty=pretty) if not in_list: print_col("None", pretty=pretty)
def detect_upgrade_conflicts(packages, venv, pretty=False): """ Detect conflicts between packages in current environment when upgrading other packages. At present this routine will look at just the immediate connections to a graph in the environment. It does this in 3 major ways: 1. DEPENDENCY SET - check_changes_in_requirements_vs_env Checks the required dependencies of new version against current environment to see additions/removals BY NAME ONLY. 2. REQUIRED VERSIONS - check_req_deps_satisfied_by_current_env For all dependencies of new version, checks to see whether they are satisfied by current environment versions. 3. ANCESTOR DEPENDENCIES - check_if_ancestors_still_satisfied For all the ancestor nodes that depend on PACKAGE, it checks whether the dependency specs are satisfied by the new version. :param list packages: List of (package, desired_version)'s :param Environment venv: virtual environment """ uc_deps = {} conflicts = {} for u in packages: package = u[0] version = u[1] p_v = "{0}_{1}".format(package, version.replace('.', '_')) uc_deps[p_v] = {} p_key = package.lower() cur_ver = venv.all_packages[p_key].version if parse_version(cur_ver) == parse_version(version): s = ("{} version {} is same as current!" .format(package, version)) print_col(s, 'red', 'black', pretty) continue if not PyPIHelper.check_package_version_on_pypi(package, version): continue uc_deps[p_v]['requirements'] = \ DepTools.get_deps_for_package_version( package, version, vex_options=MagellanConfig.vex_options) ancestors, descendants = Package.get_direct_links_to_any_package( package, venv.edges) # 1: DEPENDENCY SET - check_changes_in_requirements_vs_env uc_deps[p_v]['dependency_set'] = \ DepTools.check_changes_in_requirements_vs_env( uc_deps[p_v]['requirements'], descendants) # 2. REQUIRED VERSIONS - check_req_deps_satisfied_by_current_env uc_deps[p_v]['required_versions'] = \ DepTools.check_req_deps_satisfied_by_current_env( uc_deps[p_v]['requirements'], venv.nodes) # 3. ANCESTOR DEPENDENCIES - check_if_ancestors_still_satisfied uc_deps[p_v]['ancestor_dependencies'] = \ DepTools.check_if_ancestors_still_satisfied( package, version, ancestors, venv.package_requirements) conflicts[p_v] = {} try: conflicts[p_v]['dep_set'] = uc_deps[p_v]['dependency_set'] conflicts[p_v]['req_ver'] = \ uc_deps[p_v]['required_versions']['conflicts'] conflicts[p_v]['missing_packages'] = \ uc_deps[p_v]['required_versions']['missing'] conflicts[p_v]['anc_dep'] = \ uc_deps[p_v]['ancestor_dependencies']['conflicts'] except TypeError as e: maglog.debug("Error when attempting to assess conflicts {}" .format(e)) return conflicts, uc_deps