|
| 1 | +import os |
| 2 | +import sys |
| 3 | +import shlex |
| 4 | + |
| 5 | +from invoke import Collection, task |
| 6 | + |
| 7 | +HAS_COLORS: bool = (sys.stderr.isatty() or os.getenv("CLICOLOR_FORCE")) and not os.getenv("NO_COLOR") |
| 8 | + |
| 9 | + |
| 10 | +def apply_colors(msg: object, /, *, code: str) -> str: |
| 11 | + if HAS_COLORS: |
| 12 | + return f"\x1b[{code}m{msg}\x1b[0m" |
| 13 | + else: |
| 14 | + return str(msg) |
| 15 | + |
| 16 | + |
| 17 | +def log_info(msg: object): |
| 18 | + print( |
| 19 | + apply_colors("INFO:", code="1;32"), |
| 20 | + apply_colors(msg, code="1"), |
| 21 | + ) |
| 22 | + |
| 23 | + |
| 24 | +@task |
| 25 | +def test(ctx): |
| 26 | + check(ctx, format=False) |
| 27 | + ctx.run("cargo nextest run --workspace", pty=True) |
| 28 | + miri(ctx) |
| 29 | + run_format(ctx, check=True) |
| 30 | + |
| 31 | +@task |
| 32 | +def coverage(ctx): |
| 33 | + check(ctx, format=False) |
| 34 | + ctx.run("cargo +nightly llvm-cov nextest --all-features", pty=True) |
| 35 | + run_format(ctx, check=True) |
| 36 | + |
| 37 | + |
| 38 | +@task |
| 39 | +def miri(ctx): |
| 40 | + # https://docs.pyinvoke.org/en/3.0/concepts/invoking-tasks.html#wrapper-tasks |
| 41 | + ctx.run(f"cargo +nightly miri nextest run --all-features {ctx.remainder}", pty=True) |
| 42 | + |
| 43 | +@task |
| 44 | +def bench(ctx, basic=False): |
| 45 | + args = shlex.split(ctx.remainder) |
| 46 | + if basic: |
| 47 | + args.append("--bench=basic") |
| 48 | + ctx.run(shlex.join([ |
| 49 | + *shlex.split("cargo +nightly bench -p benchmark-biasedrc --all-features"), |
| 50 | + *args |
| 51 | + ]), pty=True) |
| 52 | + |
| 53 | +@task |
| 54 | +def check(ctx, format=True): |
| 55 | + clippy(ctx) |
| 56 | + doc(ctx) |
| 57 | + # by default, check formatting as well |
| 58 | + if format: |
| 59 | + run_format(ctx, check=True) |
| 60 | + |
| 61 | +@task |
| 62 | +def clippy(ctx): |
| 63 | + ctx.run("cargo +nightly clippy --workspace --all-targets", pty=True) |
| 64 | + ctx.run("cargo +nightly clippy --workspace --all-targets", pty=True) |
| 65 | + |
| 66 | +@task |
| 67 | +def doc(ctx): |
| 68 | + """Build documentation and check for issues""" |
| 69 | + ctx.run("cargo doc --workspace --document-private-items --no-deps", pty=True) |
| 70 | + |
| 71 | +@task(name="format") |
| 72 | +def run_format(ctx, check=False): |
| 73 | + verb = "Checking" if check else "Fixing" |
| 74 | + log_info(f"{verb} formatting") |
| 75 | + maybe_check = " --check" if check else "" |
| 76 | + maybe_fix = " --fix" if not check else "" |
| 77 | + ctx.run("cargo +nightly fmt --all" + maybe_check) |
| 78 | + ctx.run("taplo format" + maybe_check) |
| 79 | + ctx.run("cargo sort --grouped --no-format --workspace" + maybe_check) |
| 80 | + |
| 81 | + # need python format for invoke.py |
| 82 | + ctx.run("ruff format" + maybe_check) |
| 83 | + ctx.run("ruff check --select=I" + maybe_fix) # works like isort |
| 84 | + check_spelling(ctx, fix=False) |
| 85 | + |
| 86 | + |
| 87 | +TYPOS_VER = "1.46" # pinned to avoid update breakage |
| 88 | + |
| 89 | + |
| 90 | +@task(name="typos") |
| 91 | +def check_spelling(ctx, fix=False): |
| 92 | + maybe_write = " --write-changes" if fix else "" |
| 93 | + ctx.run(f"uvx typos@{TYPOS_VER}" + maybe_write) |
| 94 | + |
| 95 | + |
| 96 | +ns = Collection(test, coverage, miri, bench, check, clippy, doc, run_format, check_spelling) |
| 97 | +ns.configure( |
| 98 | + { |
| 99 | + "run": { |
| 100 | + "echo": True, |
| 101 | + "env": { |
| 102 | + "CLICOLOR_FORCE": "1" if HAS_COLORS else "0", |
| 103 | + "RUST_BACKTRACE": "1", |
| 104 | + # Due to header arithmetic, we had problems with stacked borrows in the past. |
| 105 | + # Right now it seems to be working. If problems come up switch back to -Zmiri-tree-borrows. |
| 106 | + "MIRIFLAGS": "-Zmiri-strict-provenance -Zmiri-env-forward=RUST_BACKTRACE", |
| 107 | + }, |
| 108 | + } |
| 109 | + } |
| 110 | +) |
0 commit comments