cfglint 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. cfglint-1.0.0/LICENSE +21 -0
  2. cfglint-1.0.0/PKG-INFO +561 -0
  3. cfglint-1.0.0/README.md +531 -0
  4. cfglint-1.0.0/pyproject.toml +59 -0
  5. cfglint-1.0.0/setup.cfg +4 -0
  6. cfglint-1.0.0/src/cfglint/__init__.py +3 -0
  7. cfglint-1.0.0/src/cfglint/ci.py +106 -0
  8. cfglint-1.0.0/src/cfglint/cli.py +363 -0
  9. cfglint-1.0.0/src/cfglint/config_loader.py +75 -0
  10. cfglint-1.0.0/src/cfglint/converter.py +68 -0
  11. cfglint-1.0.0/src/cfglint/differ.py +81 -0
  12. cfglint-1.0.0/src/cfglint/discovery.py +86 -0
  13. cfglint-1.0.0/src/cfglint/fixer.py +128 -0
  14. cfglint-1.0.0/src/cfglint/formatters/__init__.py +7 -0
  15. cfglint-1.0.0/src/cfglint/formatters/json_fmt.py +29 -0
  16. cfglint-1.0.0/src/cfglint/formatters/rich_fmt.py +121 -0
  17. cfglint-1.0.0/src/cfglint/formatters/sarif_fmt.py +105 -0
  18. cfglint-1.0.0/src/cfglint/formatters/text.py +81 -0
  19. cfglint-1.0.0/src/cfglint/linter.py +125 -0
  20. cfglint-1.0.0/src/cfglint/merger.py +61 -0
  21. cfglint-1.0.0/src/cfglint/models.py +161 -0
  22. cfglint-1.0.0/src/cfglint/parsers/__init__.py +19 -0
  23. cfglint-1.0.0/src/cfglint/parsers/base.py +83 -0
  24. cfglint-1.0.0/src/cfglint/parsers/env_parser.py +58 -0
  25. cfglint-1.0.0/src/cfglint/parsers/ini_parser.py +49 -0
  26. cfglint-1.0.0/src/cfglint/parsers/json_parser.py +21 -0
  27. cfglint-1.0.0/src/cfglint/parsers/toml_parser.py +46 -0
  28. cfglint-1.0.0/src/cfglint/parsers/yaml_parser.py +24 -0
  29. cfglint-1.0.0/src/cfglint/plugins.py +99 -0
  30. cfglint-1.0.0/src/cfglint/presets.py +77 -0
  31. cfglint-1.0.0/src/cfglint/rules/__init__.py +36 -0
  32. cfglint-1.0.0/src/cfglint/rules/base.py +111 -0
  33. cfglint-1.0.0/src/cfglint/rules/deprecation.py +85 -0
  34. cfglint-1.0.0/src/cfglint/rules/environment.py +141 -0
  35. cfglint-1.0.0/src/cfglint/rules/naming.py +146 -0
  36. cfglint-1.0.0/src/cfglint/rules/schema.py +69 -0
  37. cfglint-1.0.0/src/cfglint/rules/security.py +259 -0
  38. cfglint-1.0.0/src/cfglint/rules/structure.py +254 -0
  39. cfglint-1.0.0/src/cfglint/rules/types.py +132 -0
  40. cfglint-1.0.0/src/cfglint/stats.py +122 -0
  41. cfglint-1.0.0/src/cfglint/watcher.py +73 -0
  42. cfglint-1.0.0/src/cfglint.egg-info/PKG-INFO +561 -0
  43. cfglint-1.0.0/src/cfglint.egg-info/SOURCES.txt +45 -0
  44. cfglint-1.0.0/src/cfglint.egg-info/dependency_links.txt +1 -0
  45. cfglint-1.0.0/src/cfglint.egg-info/entry_points.txt +2 -0
  46. cfglint-1.0.0/src/cfglint.egg-info/requires.txt +12 -0
  47. cfglint-1.0.0/src/cfglint.egg-info/top_level.txt +1 -0
cfglint-1.0.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 JSLEEKR
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
cfglint-1.0.0/PKG-INFO ADDED
@@ -0,0 +1,561 @@
1
+ Metadata-Version: 2.4
2
+ Name: cfglint
3
+ Version: 1.0.0
4
+ Summary: Validate, lint, and diff configuration files with schema enforcement and security checks
5
+ Author-email: JSLEEKR <93jslee@gmail.com>
6
+ License: MIT
7
+ Keywords: config,lint,validation,yaml,json,toml,security
8
+ Classifier: Development Status :: 4 - Beta
9
+ Classifier: Environment :: Console
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.10
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Topic :: Software Development :: Quality Assurance
17
+ Requires-Python: >=3.10
18
+ Description-Content-Type: text/markdown
19
+ License-File: LICENSE
20
+ Requires-Dist: click>=8.1.0
21
+ Requires-Dist: pyyaml>=6.0
22
+ Requires-Dist: tomli>=2.0; python_version < "3.11"
23
+ Requires-Dist: jsonschema>=4.17.0
24
+ Requires-Dist: rich>=13.0.0
25
+ Provides-Extra: dev
26
+ Requires-Dist: pytest>=7.4.0; extra == "dev"
27
+ Requires-Dist: pytest-cov>=4.1.0; extra == "dev"
28
+ Requires-Dist: pytest-mock>=3.11.0; extra == "dev"
29
+ Dynamic: license-file
30
+
31
+ <div align="center">
32
+
33
+ # :gear: cfglint
34
+
35
+ ### Config file validator and linter for YAML, JSON, TOML, INI, and .env
36
+
37
+ [![GitHub Stars](https://img.shields.io/github/stars/JSLEEKR/cfglint?style=for-the-badge&logo=github&color=yellow)](https://github.com/JSLEEKR/cfglint/stargazers)
38
+ [![License](https://img.shields.io/badge/license-MIT-blue?style=for-the-badge)](LICENSE)
39
+ [![Python](https://img.shields.io/badge/Python-3.10+-3776AB?style=for-the-badge&logo=python&logoColor=white)](https://python.org)
40
+ [![Tests](https://img.shields.io/badge/tests-411%20passing-brightgreen?style=for-the-badge)](#)
41
+
42
+ <br/>
43
+
44
+ **Lint, validate, diff, and convert configuration files with 16 built-in rules and SARIF output**
45
+
46
+ [Quick Start](#quick-start) | [Rules](#built-in-rules-16) | [CLI](#cli-commands) | [API](#programmatic-api) | [Architecture](#architecture)
47
+
48
+ </div>
49
+
50
+ ---
51
+
52
+ ## Why This Exists
53
+
54
+ Configuration files are where secrets leak, debug flags get forgotten in production, and schema mismatches cause runtime crashes nobody can explain. Static analysis tools exist for code -- but config files are typically validated only at runtime, when it is already too late.
55
+
56
+ `cfglint` brings linting discipline to configuration files across every format your stack uses. Sixteen built-in rules catch hardcoded secrets, insecure protocols, duplicate keys, type mismatches, and deprecated fields before they reach production. SARIF output slots directly into GitHub Code Scanning, and the auto-fix engine corrects safe issues without manual edits.
57
+
58
+ - **Security-first rules** -- detects hardcoded API keys, GitHub tokens, AWS credentials, JWT secrets, and weak passwords with regex patterns
59
+ - **Multi-format support** -- YAML, JSON, TOML, INI, and .env files all go through the same rule engine
60
+ - **Auto-fix for safe issues** -- debug flags, null values, and insecure protocols can be corrected automatically
61
+
62
+ ## Requirements
63
+
64
+ - Python 3.10+
65
+ - Dependencies: `click`, `pyyaml`, `jsonschema`, `rich`
66
+ - Optional: `tomli` (for TOML on Python < 3.11)
67
+
68
+ ## Quick Start
69
+
70
+ ```bash
71
+ pip install cfglint
72
+ ```
73
+
74
+ ### Lint a Config File
75
+
76
+ ```bash
77
+ # Basic lint
78
+ cfglint lint config.yaml
79
+
80
+ # Lint with JSON output
81
+ cfglint lint config.yaml --format json
82
+
83
+ # Lint with production preset
84
+ cfglint lint config.yaml --preset production
85
+
86
+ # Lint with schema validation
87
+ cfglint lint config.yaml --schema schema.json
88
+ ```
89
+
90
+ ### Scan a Directory
91
+
92
+ ```bash
93
+ # Auto-discover and lint all config files
94
+ cfglint scan .
95
+
96
+ # Scan with ignore patterns
97
+ cfglint scan . --ignore "node_modules/**" --ignore "dist/**"
98
+ ```
99
+
100
+ ### Diff Two Configs
101
+
102
+ ```bash
103
+ cfglint diff config.dev.yaml config.prod.yaml
104
+ ```
105
+
106
+ ### Auto-Fix Issues
107
+
108
+ ```bash
109
+ # Fix debug flags, null values, insecure protocols
110
+ cfglint fix config.yaml
111
+
112
+ # Preview fixes without writing
113
+ cfglint fix config.yaml --dry-run
114
+ ```
115
+
116
+ ### Convert Formats
117
+
118
+ ```bash
119
+ # YAML to JSON
120
+ cfglint convert config.yaml --to json
121
+
122
+ # JSON to TOML
123
+ cfglint convert config.json --to toml
124
+ ```
125
+
126
+ ### Merge Configs
127
+
128
+ ```bash
129
+ # Merge with override strategy
130
+ cfglint merge base.yaml override.yaml -o merged.yaml
131
+
132
+ # Merge with deep strategy
133
+ cfglint merge base.yaml override.yaml --strategy deep -o merged.yaml
134
+ ```
135
+
136
+ ### Initialize Project
137
+
138
+ ```bash
139
+ # Create .cfglintrc with CI preset
140
+ cfglint init --preset ci
141
+ ```
142
+
143
+ ## How It Works
144
+
145
+ ```
146
+ Discover Parse Lint Report
147
+ ────────── ────────── ────────── ──────────
148
+ Glob/path → YAML/JSON/ → 16 rules → Rich/Text/
149
+ TOML/INI/ across 6 JSON/SARIF
150
+ .env categories
151
+ ```
152
+
153
+ 1. **Discover** -- find config files by glob pattern, extension, or explicit path
154
+ 2. **Parse** -- auto-detect format and parse into a normalized key-value tree
155
+ 3. **Lint** -- run 16 rules across security, structure, naming, type, environment, and deprecation categories
156
+ 4. **Report** -- output findings as colored terminal tables, plain text, JSON, or SARIF 2.1.0
157
+
158
+ ## Features
159
+
160
+ ### Multi-Format Parsing
161
+ - **YAML** -- full YAML 1.2 support via `pyyaml`
162
+ - **JSON** -- standard JSON with helpful parse error messages
163
+ - **TOML** -- TOML v1.0 support via `tomli` (stdlib on 3.11+)
164
+ - **INI** -- INI/cfg/conf files via `configparser`
165
+ - **.env** -- dotenv files with comment and quote handling
166
+ - **Auto-detection** -- format detected from file extension or name pattern
167
+
168
+ ### 16 Built-in Rules
169
+
170
+ #### Security (4 rules)
171
+ - **SEC001** -- Detect hardcoded secrets and credentials (API keys, tokens, AWS keys, OpenAI keys, JWT secrets)
172
+ - **SEC002** -- Detect weak or default passwords
173
+ - **SEC003** -- Detect insecure protocol URLs (http://, ftp://)
174
+ - **SEC004** -- Detect debug/verbose mode left enabled
175
+
176
+ #### Structure (4 rules)
177
+ - **STR001** -- Detect empty or null values
178
+ - **STR002** -- Detect duplicate keys
179
+ - **STR003** -- Detect excessively deep nesting (configurable depth)
180
+ - **STR004** -- Detect overly large config files
181
+
182
+ #### Naming (2 rules)
183
+ - **NAM001** -- Detect inconsistent key naming conventions (snake_case vs camelCase)
184
+ - **NAM002** -- Detect reserved or dangerous key names
185
+
186
+ #### Schema (1 rule)
187
+ - **SCH001** -- Validate against JSON Schema
188
+
189
+ #### Environment (2 rules)
190
+ - **ENV001** -- Check production config for development values (localhost, debug ports)
191
+ - **ENV002** -- Detect values that should use environment variables instead of hardcoding
192
+
193
+ #### Type (2 rules)
194
+ - **TYP001** -- Detect likely type mismatches (strings that look like numbers/booleans)
195
+ - **TYP002** -- Validate port numbers (1-65535)
196
+
197
+ #### Deprecation (1 rule)
198
+ - **DEP001** -- Detect deprecated keys and non-inclusive naming (master, slave, whitelist, blacklist)
199
+
200
+ ### Auto-Fix Engine
201
+ - **Debug flag fix** -- set `debug: false` and `verbose: false` automatically
202
+ - **Null value fix** -- replace null/empty values with safe defaults
203
+ - **Protocol fix** -- upgrade `http://` to `https://` where applicable
204
+ - **Dry-run mode** -- preview fixes without writing changes
205
+ - **Selective fixing** -- fix only specific rule categories
206
+
207
+ ### Config Diffing
208
+ - **Structural diff** -- compare two config files by key structure, not text
209
+ - **Change classification** -- added, removed, modified, type-changed
210
+ - **Cross-format diff** -- diff YAML against JSON, TOML against INI
211
+ - **Key path reporting** -- shows full dotted path to each changed key
212
+
213
+ ### Config Merging
214
+ - **Deep merge** -- recursively merge nested structures
215
+ - **Override strategy** -- second file wins on conflicts
216
+ - **Keep strategy** -- first file wins on conflicts
217
+ - **Output to file** -- write merged result in any supported format
218
+
219
+ ### Format Conversion
220
+ - **Any-to-any** -- convert between YAML, JSON, TOML, INI, and ENV
221
+ - **Preserves structure** -- maintains nested structure where format allows
222
+ - **CLI and API** -- available from command line and programmatically
223
+
224
+ ### Schema Validation
225
+ - **JSON Schema** -- validate any config format against a JSON Schema definition
226
+ - **Error reporting** -- schema violations reported as lint findings with paths
227
+ - **CLI integration** -- `--schema` flag on the `lint` command
228
+
229
+ ### File Discovery
230
+ - **Glob patterns** -- find config files matching `**/*.yaml`, `config.*`, etc.
231
+ - **Ignore rules** -- skip `node_modules`, `dist`, `.git` by default
232
+ - **Recursive scanning** -- scan entire directory trees automatically
233
+
234
+ ### Plugin System
235
+ - **Custom rules** -- write Python classes extending the `Rule` base class
236
+ - **Dynamic loading** -- load plugins from Python files at runtime
237
+ - **Full API access** -- plugins receive parsed data, file path, format, and raw content
238
+
239
+ ### Presets
240
+ - **strict** -- all rules enabled, warnings treated as errors
241
+ - **production** -- security + environment rules, strict severity
242
+ - **security** -- security rules only
243
+ - **ci** -- balanced set for CI pipelines
244
+ - **minimal** -- errors only, no warnings
245
+
246
+ ### File Watcher
247
+ - **Continuous linting** -- watch config files for changes and re-lint automatically
248
+ - **Directory watching** -- monitor entire directories for config file modifications
249
+ - **Debounced** -- avoids redundant runs on rapid file changes
250
+
251
+ ### CI/CD Integration
252
+ - **GitHub Actions generator** -- generate a workflow YAML for config linting
253
+ - **SARIF output** -- upload results to GitHub Code Scanning
254
+ - **Exit codes** -- 0 for clean, 1 for errors (or warnings in strict mode)
255
+ - **Non-interactive** -- all output formats work in headless CI environments
256
+
257
+ ### Statistics
258
+ - **Summary reporting** -- total files, findings by severity, rules triggered
259
+ - **Per-file breakdown** -- findings grouped by file path
260
+ - **Category analysis** -- findings grouped by rule category
261
+
262
+ ## CLI Commands
263
+
264
+ ```bash
265
+ # Core commands
266
+ cfglint lint <file> # Lint a config file
267
+ cfglint scan <dir> # Scan directory for config files
268
+ cfglint diff <file1> <file2> # Diff two config files
269
+ cfglint fix <file> # Auto-fix safe issues
270
+ cfglint convert <file> --to <format> # Convert between formats
271
+ cfglint merge <file1> <file2> -o <out> # Merge config files
272
+
273
+ # Utility commands
274
+ cfglint parse <file> # Parse and dump config structure
275
+ cfglint rules # List all available rules
276
+ cfglint presets # List available presets
277
+ cfglint init [--preset <name>] # Initialize .cfglintrc
278
+
279
+ # Common flags
280
+ --format text|json|rich|sarif # Output format (default: rich)
281
+ --severity error|warning|info # Minimum severity filter
282
+ --preset strict|production|security|ci|minimal
283
+ --schema <schema.json> # JSON Schema to validate against
284
+ --disable SEC001,STR001 # Disable specific rules
285
+ --ignore "pattern/**" # Ignore file patterns
286
+ ```
287
+
288
+ | Command | Description |
289
+ |---------|-------------|
290
+ | `cfglint lint <file>` | Lint a single config file |
291
+ | `cfglint scan <dir>` | Auto-discover and lint all config files in directory |
292
+ | `cfglint diff <a> <b>` | Structural diff between two config files |
293
+ | `cfglint fix <file>` | Auto-fix safe issues (debug, null, protocol) |
294
+ | `cfglint convert <file>` | Convert between YAML, JSON, TOML, INI, ENV |
295
+ | `cfglint merge <a> <b>` | Merge two config files with strategy |
296
+ | `cfglint parse <file>` | Parse and display config structure |
297
+ | `cfglint rules` | List all 16 built-in rules |
298
+ | `cfglint presets` | List available validation presets |
299
+ | `cfglint init` | Generate `.cfglintrc` project config |
300
+
301
+ ## Built-in Rules (16)
302
+
303
+ | Rule ID | Category | Severity | Description |
304
+ |---------|----------|----------|-------------|
305
+ | SEC001 | Security | error | Detect hardcoded secrets and credentials |
306
+ | SEC002 | Security | error | Detect weak or default passwords |
307
+ | SEC003 | Security | warning | Detect insecure protocol URLs |
308
+ | SEC004 | Security | warning | Detect debug/verbose mode enabled |
309
+ | STR001 | Structure | warning | Detect empty or null values |
310
+ | STR002 | Structure | error | Detect duplicate keys |
311
+ | STR003 | Structure | warning | Detect excessively deep nesting |
312
+ | STR004 | Structure | warning | Detect overly large config files |
313
+ | NAM001 | Naming | info | Detect inconsistent key naming conventions |
314
+ | NAM002 | Naming | warning | Detect reserved or dangerous key names |
315
+ | SCH001 | Schema | error | Validate against JSON Schema |
316
+ | ENV001 | Environment | warning | Check production config for dev values |
317
+ | ENV002 | Environment | info | Detect values that should use env vars |
318
+ | TYP001 | Type | info | Detect likely type mismatches |
319
+ | TYP002 | Type | warning | Validate port numbers (1-65535) |
320
+ | DEP001 | Deprecation | warning | Detect deprecated keys and inclusive naming |
321
+
322
+ ## Output Formats
323
+
324
+ ### Rich (default)
325
+
326
+ Colored terminal tables with severity highlighting, file paths, and suggestions.
327
+
328
+ ### Text
329
+
330
+ ```
331
+ [ERROR] SEC001: Hardcoded API key detected at database.password (config.yaml)
332
+ [WARN] SEC003: Insecure protocol URL at api.endpoint (config.yaml)
333
+ [INFO] NAM001: Inconsistent naming convention at myKey (config.yaml)
334
+ ```
335
+
336
+ ### JSON
337
+
338
+ ```json
339
+ {
340
+ "file": "config.yaml",
341
+ "format": "yaml",
342
+ "findings": [
343
+ {
344
+ "rule_id": "SEC001",
345
+ "severity": "error",
346
+ "message": "Hardcoded API key detected",
347
+ "key_path": "database.password",
348
+ "auto_fixable": false
349
+ }
350
+ ]
351
+ }
352
+ ```
353
+
354
+ ### SARIF 2.1.0
355
+
356
+ ```bash
357
+ cfglint lint config.yaml --format sarif > results.sarif
358
+ ```
359
+
360
+ Compatible with GitHub Code Scanning, VS Code SARIF Viewer, and other SARIF consumers.
361
+
362
+ ## Configuration
363
+
364
+ ### .cfglintrc (JSON)
365
+
366
+ ```json
367
+ {
368
+ "severity": "warning",
369
+ "disable": ["STR001"],
370
+ "ignore": ["node_modules/**", "dist/**"],
371
+ "enable": ["SEC001", "SEC002"],
372
+ "preset": "production"
373
+ }
374
+ ```
375
+
376
+ ### .cfglintrc.yaml
377
+
378
+ ```yaml
379
+ severity: warning
380
+ disable:
381
+ - STR001
382
+ ignore:
383
+ - "node_modules/**"
384
+ preset: ci
385
+ ```
386
+
387
+ Configuration is loaded from the nearest `.cfglintrc` or `.cfglintrc.yaml` file, traversing parent directories up to the filesystem root.
388
+
389
+ ## Programmatic API
390
+
391
+ ### Linting
392
+
393
+ ```python
394
+ from cfglint.linter import Linter
395
+ from cfglint.models import Severity
396
+
397
+ linter = Linter(
398
+ severity=Severity.WARNING,
399
+ disable=["STR001"],
400
+ )
401
+ result = linter.lint_file("config.yaml")
402
+
403
+ for finding in result.findings:
404
+ print(f"[{finding.severity.value}] {finding.rule_id}: {finding.message}")
405
+ ```
406
+
407
+ ### Custom Rules (Plugin System)
408
+
409
+ ```python
410
+ from cfglint.rules.base import Rule
411
+ from cfglint.models import FileFormat, LintFinding, Severity
412
+
413
+ class MaxPortRule(Rule):
414
+ @property
415
+ def rule_id(self) -> str:
416
+ return "CUSTOM001"
417
+
418
+ @property
419
+ def description(self) -> str:
420
+ return "Ports must be below 10000"
421
+
422
+ def check(self, data, file_path="", file_format=FileFormat.UNKNOWN, raw_content=""):
423
+ findings = []
424
+ # your validation logic here
425
+ return findings
426
+
427
+ # Load plugin
428
+ from cfglint.plugins import load_plugin
429
+ rules = load_plugin("my_rules.py")
430
+ ```
431
+
432
+ ### Config Diffing
433
+
434
+ ```python
435
+ from cfglint.differ import diff_configs
436
+
437
+ changes = diff_configs("config.dev.yaml", "config.prod.yaml")
438
+ for change in changes:
439
+ print(f"[{change.change_type}] {change.key_path}: {change.description}")
440
+ ```
441
+
442
+ ### Format Conversion
443
+
444
+ ```python
445
+ from cfglint.converter import convert_file
446
+
447
+ convert_file("config.yaml", "config.json")
448
+ ```
449
+
450
+ ### Config Merging
451
+
452
+ ```python
453
+ from cfglint.merger import merge_configs
454
+
455
+ merged = merge_configs("base.yaml", "override.yaml", strategy="deep")
456
+ ```
457
+
458
+ ### File Discovery
459
+
460
+ ```python
461
+ from cfglint.discovery import discover_config_files
462
+
463
+ files = discover_config_files(
464
+ ".",
465
+ patterns=["**/*.yaml", "**/*.json"],
466
+ ignore=["node_modules/**"],
467
+ )
468
+ ```
469
+
470
+ ### Schema Validation
471
+
472
+ ```python
473
+ from cfglint.linter import Linter
474
+
475
+ linter = Linter(schema_path="schema.json")
476
+ result = linter.lint_file("config.yaml")
477
+ # SCH001 findings included if schema violations found
478
+ ```
479
+
480
+ ## CI/CD Integration
481
+
482
+ ### GitHub Actions
483
+
484
+ ```yaml
485
+ name: Config Lint
486
+ on: [push, pull_request]
487
+
488
+ jobs:
489
+ cfglint:
490
+ runs-on: ubuntu-latest
491
+ steps:
492
+ - uses: actions/checkout@v4
493
+ - uses: actions/setup-python@v5
494
+ with:
495
+ python-version: "3.12"
496
+ - run: pip install cfglint
497
+ - run: cfglint scan . --format sarif > results.sarif
498
+ - uses: github/codeql-action/upload-sarif@v3
499
+ with:
500
+ sarif_file: results.sarif
501
+ ```
502
+
503
+ ### Pre-commit Hook
504
+
505
+ ```bash
506
+ #!/bin/sh
507
+ cfglint scan . --severity error || exit 1
508
+ ```
509
+
510
+ ### Exit Codes
511
+
512
+ | Code | Meaning |
513
+ |------|---------|
514
+ | 0 | No errors found |
515
+ | 1 | Errors found (or warnings in strict mode) |
516
+
517
+ ## Architecture
518
+
519
+ ```
520
+ src/cfglint/
521
+ __init__.py # Package version
522
+ cli.py # Click CLI (10 commands)
523
+ linter.py # Core linting engine
524
+ config_loader.py # .cfglintrc loader with directory traversal
525
+ models.py # Data models (Severity, FileFormat, LintFinding, LintResult)
526
+ differ.py # Structural config diffing
527
+ fixer.py # Auto-fix engine (debug, null, protocol)
528
+ merger.py # Config merge with deep/override/keep strategies
529
+ converter.py # Format conversion (any-to-any)
530
+ discovery.py # File discovery with glob and ignore
531
+ watcher.py # File watcher for continuous linting
532
+ plugins.py # Plugin loader for custom rules
533
+ presets.py # Validation presets (strict, production, security, ci, minimal)
534
+ stats.py # Statistics and summary reporting
535
+ ci.py # CI/CD integration helpers
536
+ parsers/
537
+ base.py # Format detection and parser dispatch
538
+ yaml_parser.py # YAML parser
539
+ json_parser.py # JSON parser
540
+ toml_parser.py # TOML parser
541
+ ini_parser.py # INI/cfg/conf parser
542
+ env_parser.py # .env parser
543
+ rules/
544
+ base.py # Rule abstract base class
545
+ security.py # SEC001-SEC004
546
+ structure.py # STR001-STR004
547
+ naming.py # NAM001-NAM002
548
+ schema.py # SCH001
549
+ environment.py # ENV001-ENV002
550
+ types.py # TYP001-TYP002
551
+ deprecation.py # DEP001
552
+ formatters/
553
+ text.py # Plain text formatter
554
+ json_fmt.py # JSON formatter
555
+ rich_fmt.py # Rich terminal formatter
556
+ sarif_fmt.py # SARIF 2.1.0 formatter
557
+ ```
558
+
559
+ ## License
560
+
561
+ MIT