Esempio n. 1
0
def remove_trailing_whitespaces_for_file(file: str, session: nox.Session,
                                         check_only: bool) -> bool:
    try:
        with open(file, "rb") as fp:
            lines = fp.readlines()
            new_lines = lines[:]

        for i in range(len(new_lines)):
            line = lines[i].rstrip(b"\n\r \t")
            line += b"\n"
            new_lines[i] = line

        if lines == new_lines:
            return False

        if check_only:
            session.log(f"Trailing whitespaces found in {file}")
            return True

        session.log(f"Removing trailing whitespaces present in {file}")

        with open(file, "wb") as fp:
            fp.writelines(new_lines)

        if GIT is not None:
            result = subprocess.check_call([GIT, "add", file, "-vf"],
                                           stdout=subprocess.PIPE,
                                           stderr=subprocess.PIPE,
                                           stdin=None)
            assert result == 0, f"`git add {file} -v' exited with code {result}"

        return True
    except Exception as ex:
        print("Failed to check", file, "because", type(ex).__name__, ex)
        return False
Esempio n. 2
0
def pytest(session: nox.Session) -> None:
    """Run unit tests and measure code coverage.

    Coverage can be disabled with the `--skip-coverage` flag.
    """
    session.install("-r", "requirements.txt", "-r", "dev-requirements.txt")
    _pytest(session)
Esempio n. 3
0
def _pytest(session: nox.Session, *py_flags: str) -> None:
    try:
        os.remove(".coverage")
    except:
        # Ignore errors
        pass
    session.run("python", *py_flags, "-m", "pytest", *FLAGS, *session.posargs, config.TEST_PACKAGE)
Esempio n. 4
0
def pytest_speedups(session: nox.Session) -> None:
    """Run unit tests and measure code coverage, using speedup modules.

    Coverage can be disabled with the `--skip-coverage` flag.
    """
    session.install("-r", "requirements.txt", "-r", "speedup-requirements.txt",
                    "-r", "dev-requirements.txt")
    _pytest(session, "-OO")
Esempio n. 5
0
def reformat_code(session: nox.Session) -> None:
    """Remove trailing whitespace in source, run isort and then run black code formatter."""
    session.install("-r", "dev-requirements.txt")

    remove_trailing_whitespaces()

    session.run("isort", *REFORMATING_PATHS)
    session.run("black", *REFORMATING_PATHS)
Esempio n. 6
0
def _pytest(session: nox.Session, *py_flags: str) -> None:
    if "--skip-coverage" in session.posargs:
        session.posargs.remove("--skip-coverage")
        flags = RUN_FLAGS
    else:
        flags = [*RUN_FLAGS, *COVERAGE_FLAGS]

    session.run("python", *py_flags, "-m", "pytest", *flags, *session.posargs,
                config.TEST_PACKAGE)
Esempio n. 7
0
def mypy(session: nox.Session) -> None:
    """Perform static type analysis on Python source code."""
    session.install("-r", "requirements.txt", "-r", "dev-requirements.txt")
    session.run(
        "mypy",
        "-p",
        config.MAIN_PACKAGE,
        "--config",
        config.MYPY_INI,
    )
Esempio n. 8
0
def verify_types(session: nox.Session) -> None:
    """Verify the "type completeness" of types exported by the library using Pyright."""
    session.install("-r", "dev-requirements.txt")
    session.install(".")
    # session.env["PYRIGHT_PYTHON_GLOBAL_NODE"] = "off"
    session.env["PYRIGHT_PYTHON_FORCE_VERSION"] = config.PYRIGHT_VERSION
    session.run("python", "-m", "pyright", "--version")
    session.run("python", "-m", "pyright", "--verifytypes", "hikari", "--ignoreexternal")
Esempio n. 9
0
def flake8(session: nox.Session) -> None:
    """Run code linting, SAST, and analysis."""
    session.install("-r", "requirements.txt", "-r", "flake8-requirements.txt")
    session.run(
        "flake8",
        "--statistics",
        "--show-source",
        "--benchmark",
        "--tee",
        config.MAIN_PACKAGE,
        config.TEST_PACKAGE,
    )
Esempio n. 10
0
def flake8_html(session: nox.Session) -> None:
    """Run code linting, SAST, and analysis and generate an HTML report."""
    session.install("-r", "requirements.txt", "-r", "flake8-requirements.txt")
    session.run(
        "flake8",
        "--format=html",
        f"--htmldir={config.FLAKE8_REPORT}",
        "--statistics",
        "--show-source",
        "--benchmark",
        "--tee",
        config.MAIN_PACKAGE,
        config.TEST_PACKAGE,
    )
Esempio n. 11
0
def _generate_stubs(session: nox.Session) -> None:
    session.run("stubgen", *STUBGEN_GENERATE, "-o", ".", "--include-private", "--no-import")

    stub_paths = [path + "i" for path in STUBGEN_GENERATE]

    session.run("isort", *stub_paths)
    session.run("black", *stub_paths)

    for stub_path in stub_paths:
        with open(stub_path, "r") as fp:
            content = fp.read()

        with open(stub_path, "w") as fp:
            fp.write("# DO NOT MANUALLY EDIT THIS FILE!\n")
            fp.write("# This file was automatically generated by `nox -s generate-stubs`\n\n")
            fp.write(content)
Esempio n. 12
0
def reformat_code(session: nox.Session) -> None:
    """Remove trailing whitespace in source, run isort and then run black code formatter."""
    remove_trailing_whitespaces()

    # isort
    session.install(f"isort=={ISORT_VERSION}")
    session.run("isort", *REFORMATING_PATHS)

    # black
    session.install(f"black=={BLACK_VERSION}")
    session.run("black", *REFORMATING_PATHS)
Esempio n. 13
0
def pdoc3(session: nox.Session) -> None:
    """Generate documentation with pdoc."""
    session.install("-r", "requirements.txt", "-r", "dev-requirements.txt")
    session.env["PDOC3_GENERATING"] = "1"

    session.run(
        "python",
        "docs/patched_pdoc.py",
        config.MAIN_PACKAGE,
        "--html",
        "--output-dir",
        config.ARTIFACT_DIRECTORY,
        "--template-dir",
        config.DOCUMENTATION_DIRECTORY,
        "--force",
    )
    shutil.copyfile(
        os.path.join(config.DOCUMENTATION_DIRECTORY, config.LOGO_SOURCE),
        os.path.join(config.ARTIFACT_DIRECTORY, config.LOGO_SOURCE),
    )
Esempio n. 14
0
def reformat_code(session: nox.Session) -> None:
    """Remove trailing whitespace in source, run isort, codespell and then run black code formatter."""
    session.install("-r", "dev-requirements.txt")

    remove_trailing_whitespaces(session)

    session.run("isort", *config.PYTHON_REFORMATTING_PATHS)
    session.run("black", *config.PYTHON_REFORMATTING_PATHS)
    session.run("codespell", "-w", *config.FULL_REFORMATTING_PATHS)
Esempio n. 15
0
def mypy(session: nox.Session) -> None:
    """Perform static type analysis on Python source code."""
    session.install("-r", "requirements.txt", "-r", "speedup-requirements.txt",
                    "-r", "dev-requirements.txt")

    _generate_stubs(session)

    session.run("mypy", "-p", config.MAIN_PACKAGE, "--config",
                config.PYPROJECT_TOML)
    session.run("mypy", "-p", config.EXAMPLE_SCRIPTS, "--config",
                config.PYPROJECT_TOML)
Esempio n. 16
0
def remove_trailing_whitespaces(session: nox.Session,
                                check_only: bool = False) -> None:
    session.log(
        f"Searching for stray trailing whitespaces in files ending in {config.REFORMATTING_FILE_EXTS}"
    )

    count = 0
    total = 0

    start = time.perf_counter()
    for path in config.FULL_REFORMATTING_PATHS:
        if os.path.isfile(path):
            total += 1
            count += remove_trailing_whitespaces_for_file(
                path, session, check_only)

        for root, dirs, files in os.walk(path, topdown=True,
                                         followlinks=False):
            for file in files:
                if file.casefold().endswith(config.REFORMATTING_FILE_EXTS):
                    total += 1
                    count += remove_trailing_whitespaces_for_file(
                        os.path.join(root, file), session, check_only)

                i = len(dirs) - 1
                while i >= 0:
                    if dirs[i] == "__pycache__":
                        del dirs[i]
                    i -= 1

    end = time.perf_counter()

    remark = "Good job! " if not count else ""
    message = "Had to fix" if not check_only else "Found issues in"
    session.log(
        f"{message} {count} file(s). "
        f"{remark}Took {1_000 * (end - start):.2f}ms to check {total} files in this project.",
    )

    if check_only and count:
        session.error(
            "Trailing whitespaces found. Try running 'nox -s reformat-code' to fix them"
        )
Esempio n. 17
0
def pytest(session: nox.Session) -> None:
    """Run unit tests and measure code coverage."""
    session.install("-r", "requirements.txt", "-r", "dev-requirements.txt")
    _pytest(session)
Esempio n. 18
0
def slotscheck(session: nox.Session) -> None:
    """Check for common slotting mistakes."""
    session.install(".", "-r", "dev-requirements.txt")
    session.run("slotscheck", "-m", config.MAIN_PACKAGE)
Esempio n. 19
0
def coveralls(session: nox.Session) -> None:
    """Run coveralls. This has little effect outside TravisCI."""
    session.install("-U", "python-coveralls")
    session.run("coveralls")
Esempio n. 20
0
def _generate_stubs(session: nox.Session) -> None:
    session.run("stubgen", *STUBGEN_GENERATE, "-o", ".", "--include-private",
                "--no-import")
Esempio n. 21
0
def pages(session: nox.Session) -> None:
    """Generate website pages."""
    if not os.path.exists(config.ARTIFACT_DIRECTORY):
        os.mkdir(config.ARTIFACT_DIRECTORY)

    # Static
    print("Copying static objects...")
    copy_from_in(config.PAGES_DIRECTORY, config.ARTIFACT_DIRECTORY)

    # Documentation
    session.install("-r", "requirements.txt", "-r", "dev-requirements.txt")
    session.env["PDOC3_GENERATING"] = "1"

    print("Building documentation...")
    session.run(
        "python",
        "docs/patched_pdoc.py",
        config.MAIN_PACKAGE,
        "--html",
        "--output-dir",
        config.ARTIFACT_DIRECTORY,
        "--template-dir",
        config.DOCUMENTATION_DIRECTORY,
        "--force",
    )

    # Rename `hikari` into `documentation`
    # print("Renaming output dir...")
    # print(f"{config.ARTIFACT_DIRECTORY}/{config.MAIN_PACKAGE} -> {config.ARTIFACT_DIRECTORY}/documentation")
    # shutil.rmtree(f"{config.ARTIFACT_DIRECTORY}/documentation", ignore_errors=True)
    # shutil.move(f"{config.ARTIFACT_DIRECTORY}/{config.MAIN_PACKAGE}", f"{config.ARTIFACT_DIRECTORY}/documentation")

    # Pre-generated indexes
    if shutil.which("npm") is None:
        message = "'npm' not installed, can't prebuild index"
        if "CI" in os.environ:
            session.error(message)

        session.skip(message)

    print("Prebuilding index...")
    session.run("npm", "install", "[email protected]", external=True)
    session.run(
        "node",
        "scripts/prebuild_index.js",
        f"{config.ARTIFACT_DIRECTORY}/hikari/index.json",
        f"{config.ARTIFACT_DIRECTORY}/hikari/prebuilt_index.json",
        external=True,
    )
Esempio n. 22
0
def generate_stubs(session: nox.Session) -> None:
    """Generate the stubs for the package."""
    session.install("-r", "dev-requirements.txt")
    _generate_stubs(session)
Esempio n. 23
0
def safety(session: nox.Session) -> None:
    """Perform dependency scanning."""
    # Temporary addition to avoid safety erroring due to https://github.com/pypa/pip/pull/9827
    session.install("--upgrade", "pip")
    session.install("-r", "requirements.txt", "-r", "dev-requirements.txt")
    session.run("safety", "check", "--full-report")
Esempio n. 24
0
def verify_types(session: nox.Session) -> None:
    """Verify the "type completeness" of types exported by the library using Pyright."""
    session.install("-r", "dev-requirements.txt")
    session.install(".")
    session.run("python", "-m", "pyright", "--verifytypes", config.MAIN_PACKAGE, "--ignoreexternal")
Esempio n. 25
0
def codespell(session: nox.Session) -> None:
    """Run codespell to check for spelling mistakes."""
    session.install("-r", "dev-requirements.txt")
    session.run("codespell", *config.FULL_REFORMATTING_PATHS)
Esempio n. 26
0
def pytest_speedups(session: nox.Session) -> None:
    """Run unit tests and measure code coverage, using speedup modules."""
    session.install("-r", "requirements.txt", "-r", "speedup-requirements.txt", "-r", "dev-requirements.txt")
    _pytest(session, "-OO")
Esempio n. 27
0
def _pytest(session: nox.Session, *py_flags: str) -> None:
    shutil.rmtree(".coverage", ignore_errors=True)
    session.run("python", *py_flags, "-m", "pytest", *FLAGS, *session.posargs, config.TEST_PACKAGE)
Esempio n. 28
0
def twemoji_test(session: nox.Session):
    """Brute-force test all possible Twemoji mappings for Discord unicode emojis."""
    session.install("-U", "-e", ".", "requests")
    session.run("python", "scripts/test_twemoji_mapping.py")
Esempio n. 29
0
def safety(session: nox.Session) -> None:
    """Perform dependency scanning."""
    session.install("-r", "requirements.txt", "-r", "dev-requirements.txt")
    session.run("safety", "check", "--full-report")