1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
//! `tix lint`: validate frontmatter option values in every issue file
//! (`contracts/cli.md` §lint, FR-015..FR-018).
//!
//! Checks per issue (FR-016): `status` ∈ `tix.toml [columns]`, `priority` ∈
//! {low, medium, high}, `created`/`updated` parse as `YYYY-MM-DD`, `estimate`
//! absent or a readable duration (`3`, `3d`, `1 day`, `0.5-1 day`; non-estimate
//! comma-separated annotations are ignored), `number` integer. Unknown frontmatter
//! keys are never flagged.
//!
//! Lint walks the store itself (mirroring [`crate::storage::Store::list`]
//! layout: one segment level + flat root, skipping `.tix-tmp-*` dirs and
//! non-`.md` files) instead of calling [`Store::list`], because `list` abort
//! on the first malformed file. Lint must keep scanning and report each
//! broken file as a `missing`/`parse` diagnostic — never a panic (FR-018).
//!
//! Diagnostics render through `annotate-snippets` (C-004): one rustc-style
//! block per finding, and every block names the file, line, offending value
//! and valid set in a single reading (NFR-006). Diagnostics go to **stderr**;
//! stdout stays parseable and only carries the `Lint OK: N issues checked.`
//! summary on a healthy store. Exit semantics live at the CLI boundary
//! (`cli::run_lint`): `0` healthy, `1` findings, `2` usage/internal.
//!
//! **Only errors set the exit code** (#1361). A finding carries a
//! [`Severity`]: an unrecognised top-level frontmatter key is a *warning*,
//! because the key is preserved on write and the file is therefore valid. It is
//! rendered with `Level::WARNING` and a `W-` id so the output agrees with the
//! exit code, and `[custom_attributes]` in `tix.toml` silences it for keys the
//! project uses on purpose.
use BTreeMap;
use HashSet;
use fs;
use Range;
use ;
use crateplanner_for;
use crateConfig;
use crateDiagnostic;
use crate;
use crate;
use cratePlanner;
use crate;
use crate;
use crateStore;
use crate;
pub use *;
use *;
/// How much a finding should worry the reader.
///
/// Added for #1361. Everything that existed before is an [`Severity::Error`], and
/// the distinction is exactly one of consequence: only errors set the exit code.
/// A file carrying an unrecognised key is still a **valid** file — it parses, and
/// the key is now preserved on write — so failing a build over it would be
/// reporting a non-problem as a broken one.
/// One lint finding, carrying enough location to render a rustc-style
/// diagnostic (NFR-006). `line`/`column` are 1-based; file-level findings
/// (`missing`/`parse`) use `line == 0`.