Esempio n. 1
0
    def test_cli_overwrite_prompt_and_behavior(self, res_path, scratch_path,
                                               misc_info, run_cmdline_test):
        """Confirm overwrite prompt works properly."""
        src_path_1 = res_path / "objects_attrs.inv"
        src_path_2 = res_path / "objects_sarge.inv"
        dst_path = scratch_path / (misc_info.FNames.INIT +
                                   misc_info.Extensions.DEC)
        dst_path.unlink()

        args = ["convert", "plain", None, str(dst_path)]

        # Initial decompress
        args[2] = str(src_path_1)
        with stdio_mgr() as (in_, out_, err_):
            run_cmdline_test(args)

            assert "converted" in err_.getvalue()
            assert "(plain)" in err_.getvalue()

        # First overwrite, declining clobber
        args[2] = str(src_path_2)
        with stdio_mgr("n\n") as (in_, out_, err_):
            run_cmdline_test(args)

            assert "(Y/N)? n" in out_.getvalue()

        assert "attrs" == Inventory(str(dst_path)).project

        # Second overwrite, with clobber
        with stdio_mgr("y\n") as (in_, out_, err_):
            run_cmdline_test(args)

            assert "(Y/N)? y" in out_.getvalue()

        assert "Sarge" == Inventory(str(dst_path)).project
def inv(pytestconfig):
    inv_dict = pytestconfig.cache.get('python/objects.inv', None)
    if inv_dict is not None:
        return Inventory(inv_dict)
    print("Downloading objects.inv")
    url = 'https://docs.python.org/{v.major}.{v.minor}/objects.inv'.format(
        v=sys.version_info)
    inv = Inventory(url=url)
    pytestconfig.cache.set('python/objects.inv', inv.json_dict())
    return inv
Esempio n. 3
0
    def test_cli_convert_cycle_formats(
        self,
        testall_inv_path,
        res_path,
        scratch_path,
        run_cmdline_test,
        misc_info,
        pytestconfig,
        check,
    ):
        """Confirm conversion in a loop, reading/writing all formats."""
        res_src_path = res_path / testall_inv_path
        plain_path = scratch_path / (misc_info.FNames.MOD +
                                     misc_info.Extensions.DEC)
        json_path = scratch_path / (misc_info.FNames.MOD +
                                    misc_info.Extensions.JSON)
        zlib_path = scratch_path / (misc_info.FNames.MOD +
                                    misc_info.Extensions.CMP)

        if (not pytestconfig.getoption("--testall")
                and testall_inv_path.name != "objects_attrs.inv"):
            pytest.skip("'--testall' not specified")

        run_cmdline_test(
            ["convert", "plain",
             str(res_src_path),
             str(plain_path)])
        run_cmdline_test(["convert", "json", str(plain_path), str(json_path)])
        run_cmdline_test(["convert", "zlib", str(json_path), str(zlib_path)])

        invs = {
            "orig": Inventory(str(res_src_path)),
            "plain": Inventory(str(plain_path)),
            "zlib": Inventory(str(zlib_path)),
            "json": Inventory(json.loads(json_path.read_text())),
        }

        for fmt, attrib in product(
            ("plain", "zlib", "json"),
            (
                HeaderFields.Project.value,
                HeaderFields.Version.value,
                HeaderFields.Count.value,
            ),
        ):
            check.equal(getattr(invs[fmt], attrib),
                        getattr(invs["orig"], attrib))
Esempio n. 4
0
    def test_cli_json_export_import(self, res_cmp, scratch_path, misc_info,
                                    run_cmdline_test, sphinx_load_test):
        """Confirm JSON sent to stdout from local source imports ok."""
        mod_path = scratch_path / (misc_info.FNames.MOD +
                                   misc_info.Extensions.CMP)

        with stdio_mgr() as (in_, out_, err_):
            run_cmdline_test(["convert", "json", str(res_cmp.resolve()), "-"])

            data = out_.getvalue()

        with stdio_mgr(data) as (in_, out_, err_):
            run_cmdline_test(["convert", "zlib", "-", str(mod_path.resolve())])

        assert Inventory(json.loads(data))
        assert Inventory(mod_path)
        sphinx_load_test(mod_path)
Esempio n. 5
0
    def test_cli_stdio_output(self, scratch_path, res_cmp, run_cmdline_test,
                              format_arg):
        """Confirm that inventory data can be written to stdout."""
        with stdio_mgr() as (in_, out_, err_):
            run_cmdline_test(
                ["convert", format_arg,
                 str(res_cmp.resolve()), "-"])

            result = out_.getvalue()

        inv1 = Inventory(res_cmp)

        if format_arg == "plain":
            inv2 = Inventory(result.encode("utf-8"))
        elif format_arg == "json":
            inv2 = Inventory(json.loads(result))
        else:  # pragma: no cover
            raise ValueError("Invalid parametrized format arg")

        assert inv1 == inv2
Esempio n. 6
0
    def test_cli_stdin_clobber(self, res_path, scratch_path, misc_info,
                               run_cmdline_test):
        """Confirm clobber with stdin data only with --overwrite."""
        src_path_sarge = res_path / "objects_sarge.inv"
        dst_path = scratch_path / (misc_info.FNames.INIT +
                                   misc_info.Extensions.CMP)

        assert "attrs" == Inventory(dst_path).project

        data = json.dumps(Inventory(src_path_sarge).json_dict())

        args = ["convert", "plain", "-", str(dst_path)]
        with stdio_mgr(data):
            run_cmdline_test(args)
        assert "attrs" == Inventory(dst_path).project

        args.append("-o")
        with stdio_mgr(data):
            run_cmdline_test(args)
        assert "Sarge" == Inventory(dst_path).project
Esempio n. 7
0
    def test_cli_stdio_input(self, scratch_path, res_cmp, misc_info,
                             run_cmdline_test, data_format):
        """Confirm that inventory data can be read on stdin."""
        inv1 = Inventory(res_cmp)

        if data_format is SourceTypes.DictJSON:
            input_data = json.dumps(inv1.json_dict())
        elif data_format is SourceTypes.BytesPlaintext:
            input_data = inv1.data_file().decode("utf-8")

        out_path = scratch_path / (misc_info.FNames.MOD +
                                   misc_info.Extensions.DEC)

        with stdio_mgr(input_data) as (in_, out_, err_):
            run_cmdline_test(
                ["convert", "plain", "-",
                 str(out_path.resolve())])

        inv2 = Inventory(out_path)

        assert inv1 == inv2
Esempio n. 8
0
def inv_stdin(params):
    """Create |Inventory| from contents of stdin.

    Due to stdin's encoding and formatting assumptions, only
    text-based inventory formats can be sanely parsed.

    Thus, only plaintext and JSON inventory formats can be
    used as inputs here.

    Parameters
    ----------
    params

        |dict| -- Parameters/values mapping from the active subparser

    Returns
    -------
    inv

        |Inventory| -- Object representation of the inventory
        provided at stdin

    """
    data = sys.stdin.read()

    try:
        return Inventory(dict_json=json.loads(data))
    except (JSONDecodeError, ValidationError):
        pass

    try:
        return Inventory(plaintext=data)
    except (AttributeError, UnicodeEncodeError, TypeError):
        pass

    log_print("Invalid plaintext or JSON inventory format.", params)
    sys.exit(1)
Esempio n. 9
0
def import_infile(in_path):
    """Attempt import of indicated file.

    Convenience function wrapping attempts to load an
    |Inventory| from a local path.

    Parameters
    ----------
    in_path

        |str| -- Path to input file

    Returns
    -------
    inv

        |Inventory| or |None| -- If instantiation with the file at
        `in_path` succeeds, the resulting |Inventory| instance;
        otherwise, |None|

    """
    # Try general import, for zlib or plaintext files
    try:
        inv = Inventory(in_path)
    except AttributeError:
        pass  # Punt to JSON attempt
    else:
        return inv

    # Maybe it's JSON
    try:
        inv = Inventory(readjson(in_path))
    except JSONDecodeError:
        return None
    else:
        return inv
Esempio n. 10
0
    async def setup_inventories(self):
        if self.object_map is not None:
            return

        self.object_map = {}
        self.inventories = []
        async with aiohttp.ClientSession() as session:
            for iurl in self.config['inventories']:
                obj_url = urljoin(iurl, "objects.inv")
                async with session.get(obj_url) as resp:
                    inv = Inventory(await resp.read())
                    self.inventories.append(inv)
                self.object_map.update(
                    {i.name: urljoin(iurl, i.uri)
                     for i in inv.objects})
Esempio n. 11
0
def inv_url(params):
    """Create |Inventory| from file downloaded from URL.

    Initially, treats |cli:INFILE| as a download URL to be passed to
    the `url` initialization argument
    of :class:`~sphobjinv.inventory.Inventory`.

    If an inventory is not found at that exact URL, progressively
    searches the directory tree of the URL for |objects.inv|.

    Injects the URL at which an inventory was found into `params`
    under the |cli:FOUND_URL| key.

    Calls :func:`sys.exit` internally in error-exit situations.

    Parameters
    ----------
    params

        |dict| -- Parameters/values mapping from the active subparser

    Returns
    -------
    inv

        |Inventory| -- Object representation of the inventory
        at |cli:INFILE|

    ret_path

        |str| -- URL from |cli:INFILE| used to construct `inv`.
        If URL is longer than 45 characters, the central portion is elided.

    """
    in_file = params[PrsConst.INFILE]

    # Disallow --url mode on local files
    if in_file.startswith("file:/"):
        log_print("\nError: URL mode on local file is invalid", params)
        sys.exit(1)

    # Need to initialize the inventory variable
    inv = None

    # Try URL as provided
    try:
        inv = Inventory(url=in_file)
    except (HTTPError, ValueError, VersionError, URLError):
        log_print("No inventory at provided URL.", params)
    else:
        log_print("Remote inventory found.", params)
        url = in_file

    # Keep searching if inv not found yet
    if not inv:
        for url in urlwalk(in_file):
            log_print(f'Attempting "{url}" ...', params)
            try:
                inv = Inventory(url=url)
            except (ValueError, HTTPError):
                pass
            else:
                log_print("Remote inventory found.", params)
                break

    # Cosmetic line break
    log_print(" ", params)

    # Success or no?
    if not inv:
        log_print("No inventory found!", params)
        sys.exit(1)

    params.update({PrsConst.FOUND_URL: url})
    if len(url) > 45:
        ret_path = url[:20] + "[...]" + url[-20:]
    else:  # pragma: no cover
        ret_path = url

    return inv, ret_path
Esempio n. 12
0
def main():
    settings = Settings(_env_file=".github/actions/changelog/.env")
    inventory = Inventory(url=docs_url + "objects.inv")
    github = Github(settings.input_token.get_secret_value())
    repo = github.get_repo(settings.github_repository)
    docs_changelog = repo.get_contents(
        "docs/changelog.rst", settings.github_ref.split("/")[-1]
    )

    content = docs_changelog.decoded_content.decode()
    new_content = content
    directives: typing.List[re.Match] = list(
        re.finditer(r":(\w+):`(.+?)`", content)
    )
    links: typing.List[str] = []

    for directive in directives:
        if directive[1] == "ref":
            links.append("`{} <{}>`__".format(*refs[directive[2]]))
        else:
            role = roles.get(directive[1], directive[1])
            try:
                index = [
                    i
                    for _, i in inventory.suggest(
                        f":py:{role}:`codingame.{directive[2]}`",
                        with_index=True,
                        thresh=90,
                    )
                ][0]
            except IndexError:
                print(
                    "::warning file=CHANGELOG.rst:: "
                    f":py:{role}:`codingame.{directive[2]}` not found"
                )
                links.append(f"``{directive[2]}``")
                continue

            obj = inventory.objects[index]
            links.append(
                f"`{obj.dispname_expanded[len('codingame.'):]} "
                f"<{docs_url + obj.uri_expanded}>`__"
            )

    for directive, link in zip(directives[::-1], links[::-1]):
        new_content = (
            new_content[: directive.start()]
            + link
            + new_content[directive.end() :]  # noqa: E203
        )

    new_content = new_content[
        len(".. currentmodule:: codingame\n\n") :  # noqa: E203
    ]

    changelog = repo.get_contents(
        "CHANGELOG.rst", settings.github_ref.split("/")[-1]
    )
    if new_content != changelog.decoded_content.decode():
        repo.update_file(
            changelog.path,
            "Update CHANGELOG.rst",
            new_content,
            changelog.sha,
            branch=settings.github_ref.split("/")[-1],
        )
Esempio n. 13
0
    def test_cli_suggest_many_results_stdin(self, res_cmp, run_cmdline_test):
        """Confirm suggest from stdin doesn't choke on a long list."""
        data = json.dumps(Inventory(res_cmp).json_dict())

        with stdio_mgr(data) as (in_, out_, err_):
            run_cmdline_test(["suggest", "-", "py", "-t", "1"])