示例#1
0
def status(obj, long_format, plugins):
    """Print information about (successfully) installed plugins."""
    host = obj["host"]
    plugins_local_dir = obj["plugins_local_dir"]
    local_versions = PluginInfos.make_from_local_store(
        plugins_local_dir).filter_to_latest()
    plugin_infos = PluginInfos.make_from_encapsia(host)
    if plugins:
        specs = PluginSpecs.make_from_spec_strings(plugins)
        plugin_infos = specs.filter(plugin_infos)

    headers = ["name*", "version**", "available**", "installed"]
    if long_format:
        headers.extend(["description", "plugin-tags"])

    info = []
    for pi in plugin_infos:
        pi_info = [
            pi.name_and_variant(),
            pi.formatted_version(),
            _get_available_from_local_store(local_versions, pi),
            pi.extras["installed"],
        ]
        if long_format:
            pi_info.extend(
                [pi.extras["description"], pi.extras["plugin-tags"]])
        info.append(pi_info)
    lib.log(tabulate(info, headers=headers))
    _log_message_explaining_headers()
示例#2
0
 def test_filter_to_latest(self, plugininfo_list):
     pis = PluginInfos(plugininfo_list)
     expected = [
         PluginInfo.make_from_name_variant_version(*nvv)
         for nvv in [
             ("bar", "", "1.0.0"),
             ("bar", "trial", "1.0.0"),
             ("foo", "", "2.0.0"),
             ("foo", "trial", "1.0.0"),
             ("foo", "zzz", "1.0.0"),
         ]
     ]
     assert sorted(pis.filter_to_latest()) == expected
示例#3
0
def add(obj, versions, latest_existing, plugins):
    """Add plugin(s) to local store from file, URL, or S3."""
    plugins_local_dir = obj["plugins_local_dir"]
    plugins_s3_buckets = obj["plugins_s3_buckets"]
    plugins_force = obj["plugins_force"]
    host = obj["host"]

    specs_to_search_in_s3 = []
    to_download_from_s3 = []
    s3_versions = None  # For performance, only fetch if/when first needed.
    added_from_file_or_uri = False
    for plugin in plugins:
        if Path(plugin).is_file():
            _add_to_local_store_from_uri(
                plugins_local_dir,
                Path(plugin).resolve().as_uri(),
                plugins_force,
            )
            added_from_file_or_uri = True
        elif urllib.parse.urlparse(plugin).scheme != "":
            _add_to_local_store_from_uri(plugins_local_dir, plugin,
                                         plugins_force)
            added_from_file_or_uri = True
        else:
            specs_to_search_in_s3.append(PluginSpec.make_from_string(plugin))
    if versions:
        specs_to_search_in_s3.extend(
            PluginSpecs.make_from_version_dict(
                lib.read_toml(Path(versions).expanduser())))
    if latest_existing:
        specs_to_search_in_s3.extend(
            PluginSpecs.make_from_plugininfos(
                PluginInfos.make_from_encapsia(host)))
    if specs_to_search_in_s3:
        s3_versions = PluginInfos.make_from_s3_buckets(plugins_s3_buckets)
        to_download_from_s3.extend(pi for spec in specs_to_search_in_s3 if (
            pi := s3_versions.latest_version_matching_spec(spec)) is not None)
    if to_download_from_s3:
        for pi in to_download_from_s3:
            _add_to_local_store_from_s3(pi,
                                        plugins_local_dir,
                                        force=plugins_force)
    else:
        if not added_from_file_or_uri:
            lib.log("Nothing to do!")
示例#4
0
 def test_filter(self, plugininfo_list):
     pis = PluginInfos(plugininfo_list)
     expected = [
         PluginInfo.make_from_name_variant_version(*nvv)
         for nvv in [
             ("bar", "", "1.0.0"),
             ("bar", "trial", "1.0.0"),
             ("foo", "", "2.0.0"),
         ]
     ]
     assert sorted(PluginSpecs(["foo-2", "bar-ANY"]).filter(pis)) == expected
示例#5
0
def _get_available_from_local_store(local_versions: PluginInfos,
                                    pi: PluginInfo) -> str:
    available_pi = local_versions.latest_version_matching_spec(
        # filter for name-and-variant
        PluginSpec(pi.name, pi.variant))
    if available_pi:
        available_version = available_pi.formatted_version()
        available = ("<same>" if available_version == pi.formatted_version()
                     else available_version)
    else:
        available = ""
    return available
示例#6
0
def upstream(obj, plugins, all_versions):
    """Print information about plugins on S3.

    By default, only includes latest versions.
    """
    plugins_s3_buckets = obj["plugins_s3_buckets"]
    lib.log(
        f"Searching for plugins in S3 bucket(s): {', '.join(plugins_s3_buckets)}"
    )
    plugin_infos = PluginInfos.make_from_s3_buckets(plugins_s3_buckets)
    if plugins:
        plugin_infos = PluginSpecs.make_from_spec_strings(plugins).filter(
            plugin_infos)
    if not all_versions:
        plugin_infos = plugin_infos.filter_to_latest()
    info = ([
        r.name_and_variant(),
        r.formatted_version(),
        r.get_s3_bucket(),
        r.get_s3_path(),
    ] for r in sorted(plugin_infos))
    lib.log(tabulate(info, headers=["name*", "version**", "bucket", "path"]))
    _log_message_explaining_headers()
示例#7
0
def ls(obj, all_versions, long_format, plugins):
    """Print information about plugins in local store.

    By default, only includes latest versions.
    """
    plugins_local_dir = obj["plugins_local_dir"]
    plugin_infos = PluginInfos.make_from_local_store(plugins_local_dir)
    if not all_versions:
        plugin_infos = plugin_infos.filter_to_latest()
    if plugins:
        plugin_infos = PluginSpecs.make_from_spec_strings(plugins).filter(
            plugin_infos)

    def _read_description(pi):
        filename = plugins_local_dir / pi.get_filename()
        try:
            with lib.temp_directory() as tmp_dir:
                lib.extract_targz(filename, tmp_dir)
                manifests = list(tmp_dir.glob("**/plugin.toml"))
                return lib.read_toml(manifests[0])["description"]
        except Exception:
            lib.log_error(f"Malformed? Unable to read: {filename}")
            return "N/A"

    if long_format:
        info = ([
            pi.name_and_variant(),
            pi.formatted_version(),
            _read_description(pi)
        ] for pi in sorted(plugin_infos))
        lib.log(tabulate(info, headers=["name*", "version**", "description"]))
    else:
        info = ([pi.name_and_variant(),
                 pi.formatted_version()] for pi in sorted(plugin_infos))
        lib.log(tabulate(info, headers=["name*", "version**"]))
    _log_message_explaining_headers()
示例#8
0
def install(obj, versions, show_logs, latest_existing, plugins):
    """Install/upgrade plugins by name, from files, or from a versions.toml file.

    Plugins provided as files are put in the local store before being installed.

    When described by name alone, the latest plugin of that name in the local store will be used.

    Plugins specified in the versions.toml file will be taken from the local store.

    """
    plugins_local_dir = obj["plugins_local_dir"]
    plugins_force = obj["plugins_force"]
    host = obj["host"]

    # Create a list of installation candidates.
    to_install_candidates = []
    for plugin in plugins:
        plugin_filename = Path(plugin).resolve()
        if plugin_filename.is_file():
            # If it looks like a file then just add it.
            _add_to_local_store_from_uri(plugins_local_dir,
                                         plugin_filename.as_uri(),
                                         force=True)
            to_install_candidates.append(
                PluginInfo.make_from_filename(plugin_filename))
        else:
            # Else assume it is a spec for a plugin already in the local store.
            to_install_candidates.append(PluginSpec.make_from_string(plugin))
    if versions:
        # Assume plugins already present in local store.
        to_install_candidates.extend(
            PluginSpecs.make_from_version_dict(
                lib.read_toml(Path(versions).expanduser())))
    if latest_existing:
        to_install_candidates.extend(
            PluginSpec(pi.name, pi.variant)
            for pi in PluginInfos.make_from_encapsia(host))

    # Work out and list installation plan.
    # to_install_candidates = sorted(PluginInfos(to_install_candidates))
    installed = PluginInfos.make_from_encapsia(host)
    local_store = PluginInfos.make_from_local_store(plugins_local_dir)
    plan = _create_install_plan(to_install_candidates,
                                installed,
                                local_store,
                                force_install=plugins_force)
    to_install = [i[0] for i in plan if i[4] != "skip"]
    headers = ["name*", "existing version**", "new version**", "action"]
    lib.log(tabulate([i[1:] for i in plan], headers=headers))
    _log_message_explaining_headers()

    # Seek confirmation unless force.
    if to_install and not plugins_force:
        click.confirm(
            "Do you wish to proceed with the above plan?",
            abort=True,
        )

    # Install them.
    lib.log("")
    if to_install:
        api = lib.get_api(**obj)
        for pi in to_install:
            success = _install_plugin(api,
                                      plugins_local_dir / pi.get_filename(),
                                      print_output=show_logs)
        if not success:
            lib.log_error("Some plugins failed to install.", abort=True)
    else:
        lib.log("Nothing to do!")
示例#9
0
def freeze(obj):
    """Print currently installed plugins as versions TOML."""
    versions = PluginSpecs.make_from_plugininfos(
        PluginInfos.make_from_encapsia(obj["host"])).as_version_dict()
    lib.log_output(toml.dumps(versions))
示例#10
0
 def test_filter(self, plugininfo_list, spec, expected):
     pis = PluginInfos(plugininfo_list)
     expected = [PluginInfo.make_from_name_variant_version(*nvv) for nvv in expected]
     assert sorted(PluginSpec.make_from_string(spec).filter(pis)) == expected
示例#11
0
 def test_latest_version_matching_spec_none(self, plugininfo_list, spec):
     pis = PluginInfos(plugininfo_list)
     assert pis.latest_version_matching_spec(spec) is None
示例#12
0
 def test_latest_version_matching_spec(self, plugininfo_list, spec, expected_nvv):
     pis = PluginInfos(plugininfo_list)
     expected = PluginInfo.make_from_name_variant_version(*expected_nvv)
     assert pis.latest_version_matching_spec(spec) == expected
示例#13
0
 def test_latest(self, plugininfo_list):
     pis = PluginInfos(plugininfo_list)
     assert pis.latest() == PluginInfo.make_from_name_variant_version(
         "foo", "zzz", "1.0.0"
     )
示例#14
0
 def test_plugininfos_sorted(self, plugininfo_list, presorted_plugininfo_list):
     pis = PluginInfos(plugininfo_list)
     sorted_pis = sorted(pis)
     assert sorted_pis == presorted_plugininfo_list
示例#15
0
 def test_plugininfos_iterable(self, plugininfo_list):
     pis = PluginInfos(plugininfo_list)
     assert list(pis) == plugininfo_list