brazier/lint

Types

A src/ module allowed to fold text in Unicode, and the reason its text is Unicode by design rather than ASCII by grammar.

pub type CaseFoldingAllowance {
  CaseFoldingAllowance(path: String, reason: String)
}

Constructors

  • CaseFoldingAllowance(path: String, reason: String)

A lint violation found in a source file.

pub type Violation {
  Violation(
    file: String,
    location: String,
    rule: String,
    message: String,
  )
}

Constructors

  • Violation(
      file: String,
      location: String,
      rule: String,
      message: String,
    )

    Arguments

    file

    The file path where the violation was found.

    location

    The line/byte offset of the violation.

    rule

    The rule that was violated.

    message

    Human-readable description.

Values

pub const allow_discard_marker: String

The comment that opts a single let _ = out of the discard rule. It must sit on the line directly above the assignment and carry a reason:

// lint:allow-discard the decrement returns the new count, which is unused
let _ = connection_tracker_decrement()
pub const case_folding_allowed: List(CaseFoldingAllowance)

The modules in src/ allowed string.lowercase, string.uppercase and string.capitalise, each with its reason.

Those functions fold in Unicode: the Kelvin sign U+212A lowercases to k, U+0130 to i plus a combining dot, ß uppercases to SS. Almost all text the framework folds is ASCII by grammar: HTTP field names and tokens (RFC 9110 §5.1, §5.6.2), URL schemes (WHATWG URL), HTML and SVG attribute names, media types, file extensions and Gleam names (glexer’s [A-Z][A-Za-z0-9]*). Unicode folding of such text lets a non-ASCII lookalike pass a check that compares against an ASCII name, so it is folded with brazier/internal/ascii instead.

The list is empty: no module in src/ folds text that is Unicode by design. A module that does (say, a search that matches user text without case) is added here with the reason, which the rule requires to be non-empty.

pub fn lint_case_folding(
  file_path: String,
  source: String,
  allowed: List(CaseFoldingAllowance),
) -> List(Violation)

Run only the unicode-case-folding rule over source, with allowed in place of case_folding_allowed. lint_source runs it with case_folding_allowed; this entry point lets a test exercise an allow-list the source tree does not need.

pub fn lint_directory(dir: String) -> List(Violation)

Lint a directory of Gleam source files. Returns a list of violations found.

pub fn lint_doc_source(
  file_path: String,
  source: String,
) -> List(Violation)
pub fn lint_docs_directory(dir: String) -> List(Violation)

Lint Markdown documentation for stale public model language. Every file named PROGRESS.md, at any depth, is excluded: these are progress logs that record old names on purpose. The exclusion is by file name, not by directory: docs/archive/PROGRESS.md is skipped because it is named PROGRESS.md, and any other file under docs/archive/ is linted like the rest of docs/.

pub fn lint_file(path: String) -> List(Violation)

Lint a single Gleam source file.

pub fn lint_names_directory(dir: String) -> List(Violation)

Lint every text file under dir, at any depth, for the project’s pre-rename name (see lint_stale_names). main runs it over src, test and examples.

pub fn lint_source(
  file_path: String,
  source: String,
) -> List(Violation)

Lint source code from a string. A file that does not parse is itself a violation: the linter cannot vouch for code it cannot read.

pub fn lint_stale_names(
  file_path: String,
  source: String,
) -> List(Violation)

Flag every line of source that uses the project’s pre-rename name, in any case. The uses allowed are the ones that keep the rename safe, each only where it belongs:

  • src/brazier/config.gleam refuses old-named environment variables (<OLD>_ENV, …) by their prefix (the string "<OLD>_") and the old published dev secret, and its comment names the rename (`<old>` to `brazier`);
  • tests under test/ set those variables and that secret to check the refusals.

Nothing else may keep the old name: not an alias, a comment or a log line. gleam.toml’s repository is outside the linted directories.

pub fn main() -> Nil

Main entry point for CLI: gleam run -m brazier/lint

pub fn violation_to_string(v: Violation) -> String

Format a lint violation as a human-readable string. Format: file:location [rule] message

✨ Search Document