{"id":30873054,"url":"https://github.com/alexeev-prog/configdoctor","last_synced_at":"2026-01-20T16:52:31.122Z","repository":{"id":313635404,"uuid":"1052097983","full_name":"alexeev-prog/ConfigDoctor","owner":"alexeev-prog","description":"A universal, plugin-based linter for all your configuration files","archived":false,"fork":false,"pushed_at":"2025-09-17T14:08:23.000Z","size":130,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-09-24T18:59:06.627Z","etag":null,"topics":["cli","config","configs","configuration","configuration-files","configuration-management","docker","docker-compose","python","utility"],"latest_commit_sha":null,"homepage":"https://alexeev-prog.github.io/ConfigDoctor/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-2.1","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/alexeev-prog.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-07T11:59:17.000Z","updated_at":"2025-09-17T14:08:27.000Z","dependencies_parsed_at":"2025-09-07T14:30:25.899Z","dependency_job_id":"d4fa5e3c-e0c4-4aea-807a-df24c421d021","html_url":"https://github.com/alexeev-prog/ConfigDoctor","commit_stats":null,"previous_names":["alexeev-prog/configdoctor"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/alexeev-prog/ConfigDoctor","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexeev-prog%2FConfigDoctor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexeev-prog%2FConfigDoctor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexeev-prog%2FConfigDoctor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexeev-prog%2FConfigDoctor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alexeev-prog","download_url":"https://codeload.github.com/alexeev-prog/ConfigDoctor/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexeev-prog%2FConfigDoctor/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279014025,"owners_count":26085345,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-13T02:00:06.723Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","config","configs","configuration","configuration-files","configuration-management","docker","docker-compose","python","utility"],"created_at":"2025-09-07T22:48:00.735Z","updated_at":"2025-10-13T02:21:35.419Z","avatar_url":"https://github.com/alexeev-prog.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ConfigDoctor\n\u003ca id=\"readme-top\"\u003e\u003c/a\u003e\n\n\u003cdiv align=\"center\"\u003e\n  \u003cp align=\"center\"\u003e\n    A universal, plugin-based linter for all your configuration files\n    \u003cbr /\u003e\n    \u003ca href=\"https://alexeev-prog.github.io/configdoctor/\"\u003e\u003cstrong\u003eExplore the docs »\u003c/strong\u003e\u003c/a\u003e\n    \u003cbr /\u003e\n    \u003cbr /\u003e\n    \u003ca href=\"#-getting-started\"\u003eGetting Started\u003c/a\u003e\n    ·\n    \u003ca href=\"#-usage-examples\"\u003eBasic Usage\u003c/a\u003e\n    ·\n    \u003ca href=\"https://alexeev-prog.github.io/configdoctor/\"\u003eDocumentation\u003c/a\u003e\n    ·\n    \u003ca href=\"https://github.com/alexeev-prog/configdoctor/blob/main/LICENSE\"\u003eLicense\u003c/a\u003e\n  \u003c/p\u003e\n\u003c/div\u003e\n\u003cbr\u003e\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"https://img.shields.io/github/languages/top/alexeev-prog/configdoctor?style=for-the-badge\"\u003e\n    \u003cimg src=\"https://img.shields.io/github/languages/count/alexeev-prog/configdoctor?style=for-the-badge\"\u003e\n    \u003cimg src=\"https://img.shields.io/github/license/alexeev-prog/configdoctor?style=for-the-badge\"\u003e\n    \u003cimg src=\"https://img.shields.io/github/stars/alexeev-prog/configdoctor?style=for-the-badge\"\u003e\n    \u003cimg src=\"https://img.shields.io/github/issues/alexeev-prog/configdoctor?style=for-the-badge\"\u003e\n    \u003cimg src=\"https://img.shields.io/github/last-commit/alexeev-prog/configdoctor?style=for-the-badge\"\u003e\n    \u003cimg src=\"https://img.shields.io/pypi/wheel/configdoctor?style=for-the-badge\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/coverage-100%25-100%25?style=for-the-badge\" alt=\"Coverage\"\u003e\n    \u003cimg alt=\"PyPI - Downloads\" src=\"https://img.shields.io/pypi/dm/configdoctor?style=for-the-badge\"\u003e\n    \u003cimg alt=\"PyPI - Version\" src=\"https://img.shields.io/pypi/v/configdoctor?style=for-the-badge\"\u003e\n    \u003cimg alt=\"PyPI - Python Version\" src=\"https://img.shields.io/pypi/pyversions/configdoctor?style=for-the-badge\"\u003e\n    \u003cimg alt=\"GitHub contributors\" src=\"https://img.shields.io/github/contributors/alexeev-prog/configdoctor?style=for-the-badge\"\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"https://raw.githubusercontent.com/alexeev-prog/configdoctor/refs/heads/main/docs/pallet-0.png\"\u003e\n\u003c/p\u003e\n\nConfigDoctor is a powerful, unified linter for configuration files (YAML, TOML, Docker, etc.). It enforces best practices, security, and style guidelines across your projects. Its plugin-based architecture allows for deep customization and easy integration into any CI/CD pipeline. Replace a collection of disparate linters with a single, configurable tool that provides clear, actionable feedback to keep your configs clean, secure, and consistent.\n\n\u003e [!CAUTION]\n\u003e configdoctor is currently in active alpha development. While core functionality is stable, some advanced features are still evolving. Production use requires thorough testing.\n\n## Config Specification\nConfigDoctor utilizes a TOML-based configuration file (typically named `.configdoctor.toml`) to control all aspects of the linter's behavior. This configuration enables granular control over file selection, rule configuration, output formatting, and plugin management.\n\n### General Settings\n```toml\n[general]\n# Output verbosity level: \"quiet\", \"normal\", or \"verbose\"\nverbosity = \"normal\"\n\n# Output format: \"human\" (colored console), \"json\", or \"github\" (GitHub Actions annotations)\noutput_format = \"human\"\n\n# Enable/disable colored output (only applicable to \"human\" format)\ncolor = true\n\n# Attempt to automatically fix fixable issues where possible\napply_fixes = false\n```\n\n### File Selection\n```toml\n[files]\n# Glob patterns to include in analysis\ninclude = [\n    \"**/*.yaml\",\n    \"**/*.yml\",\n    \"**/*.toml\",\n    # ... additional patterns\n]\n\n# Glob patterns to exclude from analysis\nexclude = [\n    \"**/node_modules/**\",\n    \"**/.git/**\",\n    # ... additional patterns\n]\n```\n\n### Parser Configuration\n```toml\n[parsers]\n# Use safe YAML loading (recommended for security)\nyaml_safe_load = true\n\n# Allow duplicate keys in YAML (generally not recommended)\nyaml_allow_duplicates = false\n\n# Allow YAML anchors and aliases\nyaml_allow_anchors = true\n```\n\n### Rules Configuration\n```toml\n[rules]\n# List of rule IDs to disable globally\ndisable = [\n    \"yaml::format::line-length\",\n    # ... additional rule IDs\n]\n\n# List of rule IDs to enable globally (overrides disable for these rules)\nenable = [\n    \"general::security::no-secrets\",\n    # ... additional rule IDs\n]\n\n# Rule-specific configuration options\n[rules.options]\n    # Configure line-length rule\n    [rules.options.\"general::format::line-length\"]\n    max = 120\n    ignore_comments = true\n    \n    # Configure Dockerfile rule\n    [rules.options.\"dockerfile::security::avoid-latest-tag\"]\n    allowed_images = [\"nginx\", \"alpine\"]\n    \n    # Configure compose rule\n    [rules.options.\"compose::best-practices::pin-version\"]\n    mode = \"warning\"\n    ignore_services = [\"local-dev-service\"]\n```\n\n### Plugin Management\n```toml\n[plugins]\n# Additional paths to search for custom plugins\ncustom_paths = [\"./devops/configdoctor_plugins\"]\n\n# Plugin-specific configuration\n[plugins.dockerfile]\nallowed_run_commands = [\"apt-get update \u0026\u0026 apt-get install -y my-package\"]\n\n[plugins.yaml]\nrequire_explicit_version = false\n\n[plugins.compose]\ntarget_version = \"3.8\"\n```\n\n### Output Configuration\n```toml\n[output]\n# Group results by \"file\" or by \"rule\"\ngroup_by = \"file\"\n\n# Human-readable output settings\n[output.human]\nshow_documentation_link = true\nshow_suggestion = true\n\n# JSON output settings\n[output.json]\ninclude_source_code = false\npretty = true\n\n# GitHub Actions output settings\n[output.github]\nuse_workflow_commands = true\n```\n\n### Profiles\n```toml\n[profiles]\n# Define a strict profile\n[profiles.strict]\ndescription = \"Maximum strictness for production environments\"\nenable = [\n    \"dockerfile::security::*\",\n    \"compose::best-practices::*\",\n]\n[profiles.strict.rules.options]\n    [profiles.strict.rules.options.\"general::format::line-length\"]\n    max = 100\n\n# Define a development profile\n[profiles.dev]\ndescription = \"Relaxed rules for development\"\ndisable = [\n    \"dockerfile::security::avoid-latest-tag\",\n    \"compose::best-practices::pin-version\",\n]\n```\n\n### File-Specific Overrides\n```toml\n# Override rules for development environments\n[[overrides]]\nfiles = [\"**/dev/**\", \"**/staging/**\"]\n[overrides.rules]\ndisable = [\"yaml::security::no-ssh-urls\"]\n[overrides.rules.options]\n    [overrides.rules.options.\"dockerfile::security::avoid-latest-tag\"]\n    mode = \"warning\"\n\n# Override rules for production environments\n[[overrides]]\nfiles = [\"**/production/**\"]\n[overrides.rules]\nenable = [\"*::security::*\"]\n[overrides.rules.options]\n    [overrides.rules.options.\"dockerfile::security::avoid-latest-tag\"]\n    mode = \"error\"\n```\n\n### Rule ID Format\n\nRules follow a consistent naming convention:\n```\n\u003cdomain\u003e::\u003ccategory\u003e::\u003crule-name\u003e\n```\n\nWhere:\n- `domain`: The technology or format (e.g., `yaml`, `dockerfile`, `compose`)\n- `category`: The rule category (e.g., `format`, `security`, `best-practices`)\n- `rule-name`: A descriptive name for the specific rule\n\nExamples:\n- `yaml::format::line-length`\n- `dockerfile::security::avoid-latest-tag`\n- `compose::best-practices::pin-version`\n\n### Configuration Precedence\n\nConfigDoctor applies configuration settings in the following order of precedence (from highest to lowest):\n\n1. Command-line arguments\n2. File-specific overrides (matching the current file path)\n3. Active profile settings\n4. Global rules configuration\n5. Default rule settings\n\n### Configuration Validation\n\nThe configuration file is validated against a strict schema. Invalid configuration keys or values will result in errors with detailed messages about what needs to be corrected.\n\n### Environment Variables\n\nConfiguration values can be overridden using environment variables with the `CONFIGDOCTOR_` prefix following the structure of the configuration file:\n\nExample:\n```bash\nexport CONFIGDOCTOR_GENERAL_VERBOSITY=verbose\nexport CONFIGDOCTOR_RULES_OPTIONS_GENERAL__FORMAT__LINE_LENGTH_MAX=150\n```\n\nEnvironment variables take precedence over all other configuration sources.\n\n### Multiple Configuration Files\n\nConfigDoctor will search for configuration files in the following locations (in order of precedence):\n\n1. `.configdoctor.toml` in the current directory\n2. `.configdoctor.toml` in the user's home directory\n3. Default built-in configuration\n\nSettings are merged with later files overriding earlier ones.\n\n## Contributing\n\nWe welcome contributions! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines. Key areas for contribution include:\n- Additional test cases for thread-local scenarios\n- Performance optimization proposals\n- Extended version format support\n- IDE integration plugins\n\n## License \u0026 Support\n\nThis project is licensed under **GNU LGPL 2.1 License** - see [LICENSE](https://github.com/alexeev-prog/configdoctor/blob/main/LICENSE). For commercial support and enterprise features, contact [alexeev.dev@mail.ru](mailto:alexeev.dev@mail.ru).\n\n[Explore Documentation](https://alexeev-prog.github.io/configdoctor) |\n[Report Issue](https://github.com/alexeev-prog/configdoctor/issues) |\n[View Examples](./examples)\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#readme-top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n---\nA universal, plugin-based linter for all your configuration files\n\nCopyright © 2025 Alexeev Bronislav. Distributed under GNU LGPL 2.1 license.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexeev-prog%2Fconfigdoctor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falexeev-prog%2Fconfigdoctor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexeev-prog%2Fconfigdoctor/lists"}