# alint://bundled/hygiene/no-tracked-artifacts@v1
#
# The set of paths/files that essentially no repository should
# track: build outputs, dependency caches, editor/OS junk,
# secrets-shaped files, oversized blobs. All rules ship with
# reasonable defaults at unambiguous severities; use field-level
# override to tweak.
#
# Each `dir_absent` rule walks the *tracked* tree (respecting
# `.gitignore`), so a properly-gitignored directory trivially
# passes — these checks catch the case where someone committed
# an artifact AND forgot the `.gitignore` entry.

version: 1

rules:
  # --- Dependency caches ----------------------------------------------
  - id: hygiene-no-node-modules
    kind: dir_absent
    paths: "**/node_modules"
    level: error
    message: "`node_modules/` must not be committed. Add it to .gitignore."

  - id: hygiene-no-python-cache
    kind: dir_absent
    paths: ["**/__pycache__", "**/.venv", "**/venv", "**/.mypy_cache", "**/.pytest_cache", "**/.ruff_cache"]
    level: error
    message: "Python caches and virtualenvs must not be committed."

  - id: hygiene-no-ruby-bundler-cache
    kind: dir_absent
    paths: ["**/.bundle", "**/vendor/bundle"]
    level: warning

  # --- Build outputs --------------------------------------------------
  - id: hygiene-no-cargo-target
    # Rust's build output, which is large and host-specific.
    kind: dir_absent
    paths: "**/target"
    level: error

  - id: hygiene-no-js-build-outputs
    # Common JS/TS bundler output dirs. Some teams legitimately
    # commit `dist/` for published packages — disable this rule
    # on those repos.
    #
    # v0.9.18: gated on `has_ancestor: package.json` so the rule
    # only fires inside JS-package contexts. Without this gate, the
    # rule produced false positives in 8 polyglot monorepos
    # (k8s `build/`, golang/go `src/cmd/dist`, dotnet `bin/`,
    # bazel `tools/build_defs/`, vscode `extensions/*/build/`,
    # nixpkgs `pkgs/development/python-modules/build`,
    # deno `tests/testdata/dist/`, angular `dev-infra/.../build/`)
    # — directories literally named `build`/`dist`/etc. in non-JS
    # contexts.
    kind: dir_absent
    paths: ["**/dist", "**/build", "**/out", "**/.next", "**/.nuxt", "**/.svelte-kit", "**/.turbo", "**/coverage"]
    scope_filter:
      has_ancestor: package.json
    level: warning

  - id: hygiene-no-go-build-cache
    kind: dir_absent
    paths: ["**/.go-build"]
    level: info

  # --- OS / editor junk -----------------------------------------------
  - id: hygiene-no-macos-junk
    kind: file_absent
    paths: ["**/.DS_Store", "**/._*"]
    level: error
    message: "macOS Finder metadata must not be committed."
    fix:
      file_remove: {}

  - id: hygiene-no-windows-junk
    kind: file_absent
    paths: ["**/Thumbs.db", "**/desktop.ini"]
    level: error
    message: "Windows shell metadata must not be committed."
    fix:
      file_remove: {}

  - id: hygiene-no-editor-backups
    # Emacs (*~), Vim (*.swp, *.swo), JetBrains (.idea/workspace.xml
    # — but .idea/ as a whole is project-specific), generic *.bak.
    kind: file_absent
    paths: ["**/*~", "**/*.swp", "**/*.swo", "**/*.bak", "**/*.orig"]
    level: warning
    message: "Editor backup or merge-conflict-orig files must not be committed."
    fix:
      file_remove: {}

  # --- Secrets-shaped files -------------------------------------------
  - id: hygiene-no-env-files
    # Canonical .env + the *.local variants. `.env.example` /
    # `.env.template` are explicitly allowed (via the include
    # list) because they're the convention for documenting what
    # env vars a project expects.
    kind: file_absent
    paths:
      - "**/.env"
      - "**/.env.local"
      - "**/.env.*.local"
      - "**/.env.development"
      - "**/.env.production"
      - "**/.env.staging"
    level: error
    message: >-
      Environment files containing real values must not be
      committed. Use `.env.example` (or similar) for shared
      non-secret defaults.

  # --- Size gate ------------------------------------------------------
  - id: hygiene-no-huge-files
    # Conservative default. Binary fixtures / large test inputs
    # are the main legitimate exception — override or disable on
    # those repos.
    kind: file_max_size
    paths: "**"
    max_bytes: 10485760   # 10 MiB
    level: warning
    message: "Committed files larger than 10 MiB should be reviewed. Consider Git LFS for binaries."
