Skip to main content

Find retired and broken status badges in Markdown that link checkers miss

Project description

badgevet

CI crates.io clispec

Find retired and broken status badges in Markdown that link checkers miss.

A retired shields.io badge returns HTTP 200 with a valid SVG whose title reads retired badge, so ordinary link checkers (lychee, markdown-link-check) mark it OK. badgevet fetches each badge and reads the rendered SVG title instead, so it can tell a dead badge from a healthy one.

Install

cargo install badgevet
# or a prebuilt binary, no recompile:
cargo binstall badgevet

Usage

badgevet                    # scan README.md in the current directory
badgevet docs/ README.md    # scan files and directories (dirs recurse for *.md)
badgevet ~/Projects/mine    # one command scans every README under all your local repos
badgevet --only-broken .    # report only permanently broken badges
badgevet | jq .             # JSON when piped

Check every repo you own

Point badgevet at an owner and it checks the canonical published README of each of their repositories - no cloning needed. It reads the same README GitHub shows the world, so it catches badge rot even in repos you rarely touch.

badgevet --github rvben              # all your public, non-fork, non-archived repos
badgevet --github rvben --only-broken

Set GITHUB_TOKEN (or GH_TOKEN) to lift GitHub's unauthenticated rate limit; required for --include-private. Widen the default scope with --include-forks, --include-archived, --include-private.

Example:

STATE        PROVIDER               LOCATION                   BADGE
broken       shields.io             README.md:3                Version
             -> https://vsmarketplacebadges.dev/version/rvben.rumdl.svg

3 checked · 2 ok · 1 broken · 0 unconfirmed

How it classifies

Each badge lands in one of three states:

State Meaning Fails CI?
ok The badge renders a real value. no
broken A deterministic dead state (retired, deprecated). yes (exit 1)
unconfirmed Could not be verified: an ambiguous invalid / inaccessible / empty title, or a transient network failure. Retried with backoff first. no (unless --strict)

The distinction is the point. shields.io renders invalid both for a genuinely bad badge and when its upstream API is merely rate-limiting, so unconfirmed never fails your build by default. Only an explicit, permanent dead state does.

When a known-dead pattern has a modern replacement (e.g. shields.io's retired Visual Studio Marketplace routes), badgevet prints the suggested URL.

Fixing

scan never touches your files. The separate fix command applies those suggestions in place:

badgevet fix              # rewrite broken badges in README.md
badgevet fix docs/        # ...or across a directory of Markdown

It swaps only the badge image URL (leaving the surrounding link untouched), changes only broken badges that have a known replacement, and is idempotent. Broken badges with no known replacement are left alone and reported as unfixable (exit 1). fix is local-only; it does not work with --github. Since scan is read-only and fix mutates, they are separate commands with honest mutating markers in the schema.

Options

Flag Default Description
--github <owner> - Scan an owner's GitHub repos instead of local paths.
--include-forks off With --github: include forks.
--include-archived off With --github: include archived repos.
--include-private off With --github: include private repos (needs a token).
--only-broken off Report only permanently broken badges.
--strict off Also exit 1 on unconfirmed badges.
--retries <n> 2 Re-fetch an ambiguous badge before giving up.
--timeout <secs> 10 Per-request HTTP timeout.
-o, --output <fmt> auto auto (text on a TTY, JSON when piped), json, text.

Exit codes

code meaning
0 no broken badges
1 at least one badge is permanently broken (or, with --strict, unconfirmed)
2 a path could not be read, or the HTTP client failed to build
3 usage error

Exit 1 is an outcome, not an error: stdout still carries the full report and no error envelope is written. This makes badgevet a natural CI or pre-commit gate.

For agents (clispec)

badgevet follows The CLI Spec: structured output on stdout, structured error envelopes on the last line of stderr, and a schema subcommand whose output validates against clispec.dev/schema/v0.2.json (checked by the test suite).

badgevet schema

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

badgevet-0.1.0.tar.gz (47.3 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

badgevet-0.1.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.9 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ x86-64

badgevet-0.1.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (1.9 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ ARM64

badgevet-0.1.0-py3-none-macosx_11_0_arm64.whl (1.7 MB view details)

Uploaded Python 3macOS 11.0+ ARM64

badgevet-0.1.0-py3-none-macosx_10_12_x86_64.whl (1.9 MB view details)

Uploaded Python 3macOS 10.12+ x86-64

File details

Details for the file badgevet-0.1.0.tar.gz.

File metadata

  • Download URL: badgevet-0.1.0.tar.gz
  • Upload date:
  • Size: 47.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for badgevet-0.1.0.tar.gz
Algorithm Hash digest
SHA256 819646bf08d877ffccf9ee401599181a88dd8f779324206a8d0d526a03c957b1
MD5 6cf6639bbddfcab673445e7101b4430b
BLAKE2b-256 9995d39e669214264c410966bfdaf94347379230e0401836851cf227ebb7ec2a

See more details on using hashes here.

File details

Details for the file badgevet-0.1.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

  • Download URL: badgevet-0.1.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
  • Upload date:
  • Size: 1.9 MB
  • Tags: Python 3, manylinux: glibc 2.17+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for badgevet-0.1.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 4e18dd2277e40ac0620d55f3e5334f71e40ec15998f2150754dd7887c1b6367c
MD5 ca0706307eafbfbbaa7d8a0adc9fd5fb
BLAKE2b-256 2be4216e99e96df5b040a52014b9be87e3015326b92904fcac0be853e0a9b6ef

See more details on using hashes here.

File details

Details for the file badgevet-0.1.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

  • Download URL: badgevet-0.1.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
  • Upload date:
  • Size: 1.9 MB
  • Tags: Python 3, manylinux: glibc 2.17+ ARM64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for badgevet-0.1.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 bcfb60abb1d481c71a6f48d2ec23360043121eee5458a63c205dd828b776bdaf
MD5 38091944c00f4fc85789f3876dd93c91
BLAKE2b-256 d5377ceb5d4d1f0580e81b576285d3e32525f9b265652c3ee7366b673b89194a

See more details on using hashes here.

File details

Details for the file badgevet-0.1.0-py3-none-macosx_11_0_arm64.whl.

File metadata

  • Download URL: badgevet-0.1.0-py3-none-macosx_11_0_arm64.whl
  • Upload date:
  • Size: 1.7 MB
  • Tags: Python 3, macOS 11.0+ ARM64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for badgevet-0.1.0-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 a9b1492d68845635bd0b5c1e6f5c235d376f2698582f57d3f5c89282fddc13c3
MD5 1e62dca9b6876a40b1de5f38a210145d
BLAKE2b-256 f10e4a623ec4fcfa8991adae27cb852fda1b051d116edc8aadf18d0aa2ef1782

See more details on using hashes here.

File details

Details for the file badgevet-0.1.0-py3-none-macosx_10_12_x86_64.whl.

File metadata

  • Download URL: badgevet-0.1.0-py3-none-macosx_10_12_x86_64.whl
  • Upload date:
  • Size: 1.9 MB
  • Tags: Python 3, macOS 10.12+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for badgevet-0.1.0-py3-none-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 c108a395308d4f6ec18587382fbe592cce9975d43dc53de6822d6f593dca54eb
MD5 65c20d9adede0027e11b629663189428
BLAKE2b-256 66b8d550de2bccd52ae72eb60608c435243447c635e735d3cd83b63d006141e4

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page