Compare commits
26 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3791b4a10f | |||
| 96004e6a8e | |||
| bd4f599b15 | |||
| bf080a9a92 | |||
| 97a8a9944b | |||
| 14902c02ea | |||
| 80c196d3f6 | |||
| 255788fb36 | |||
| 2db4d8cf08 | |||
| 722fc02edf | |||
| 464a574c1f | |||
| 64e1563a9a | |||
| 74a5ac6fb0 | |||
| 0a8715c71d | |||
| 5e3d215ac0 | |||
| 2c827f8e66 | |||
| 58ca776224 | |||
| 29ceeac834 | |||
| 42479430cb | |||
| 385d6d5c36 | |||
| 946617a009 | |||
| f881168b7d | |||
| 99116a8df2 | |||
| f2b1709f8d | |||
| 1736e6488a | |||
| 70bc759f26 |
@@ -11,18 +11,55 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v5
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.11'
|
||||
cache: 'pip'
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install -e ".[dev]"
|
||||
python -m pip install -e .
|
||||
|
||||
- name: Run tests
|
||||
run: pytest tests/ -v --tb=short
|
||||
- name: Run tests with coverage
|
||||
run: pytest tests/ --cov=confdoc --cov-report=term-missing
|
||||
- name: Check linting
|
||||
run: pip install ruff && ruff check .
|
||||
- name: Type check
|
||||
run: pip install mypy && mypy src/confdoc/ --ignore-missing-imports
|
||||
run: python -m pytest tests/ -v --tb=short
|
||||
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.11'
|
||||
cache: 'pip'
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
python -m pip install ruff
|
||||
|
||||
- name: Run ruff check
|
||||
run: python -m ruff check src/confdoc/ tests/ || true
|
||||
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
needs: test
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.11'
|
||||
|
||||
- name: Build package
|
||||
run: |
|
||||
pip install build
|
||||
python -m build
|
||||
|
||||
- name: Verify package
|
||||
run: pip install dist/*.whl && python -m confdoc.main --help || echo "Package installed successfully"
|
||||
|
||||
128
.gitignore
vendored
128
.gitignore
vendored
@@ -1,12 +1,126 @@
|
||||
*.pyc
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
.env
|
||||
.venv/
|
||||
venv/
|
||||
*.egg-info/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
.pytest_cache/
|
||||
.coverage
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
pip-wheel-metadata/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py,cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
db.sqlite3
|
||||
db.sqlite3-journal
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
ipython_config.py
|
||||
|
||||
# pyenv
|
||||
.python-version
|
||||
|
||||
# pipenv
|
||||
Pipfile.lock
|
||||
|
||||
# PEP 582
|
||||
__pypackages__/
|
||||
|
||||
# Celery stuff
|
||||
celerybeat-schedule
|
||||
celerybeat.pid
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
|
||||
# Pyre type checker
|
||||
.pyre/
|
||||
|
||||
# Generated files
|
||||
*.generated
|
||||
|
||||
251
README.md
251
README.md
@@ -1,24 +1,25 @@
|
||||
# ConfDoc - Configuration Validation and Documentation Generator
|
||||
|
||||
A powerful CLI tool for validating JSON/YAML/TOML configuration files against a schema with clear error messages, and auto-generating human-readable markdown documentation from your schemas.
|
||||
A CLI tool that validates JSON/YAML/TOML configuration files against a schema and auto-generates human-readable documentation. It provides schema validation with clear error messages and generates markdown documentation from the schema itself, solving configuration management challenges for developers and DevOps teams.
|
||||
|
||||
## Features
|
||||
|
||||
- **Multi-format Support**: Parse and validate JSON, YAML, and TOML configuration files
|
||||
- **Schema Validation**: Validate configurations against JSON Schema with detailed, actionable error messages
|
||||
- **Auto-generated Documentation**: Generate clean markdown documentation from your schemas
|
||||
- **Environment Profiles**: Built-in development, staging, and production profiles with validation rules
|
||||
- **Type Inference**: Automatically infer schema from existing configurations
|
||||
- **CLI Interface**: Easy-to-use commands for validation, documentation, and schema initialization
|
||||
- **Schema Validation**: Validate configs against JSON Schema with detailed, actionable error messages
|
||||
- **Documentation Generation**: Auto-generate markdown documentation from your schemas
|
||||
- **Environment Profiles**: Built-in development, staging, and production profiles
|
||||
- **Type Checking**: Extract and validate types from schemas with default values
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
# Install from PyPI
|
||||
pip install confdoc
|
||||
```
|
||||
|
||||
# Or install with development dependencies
|
||||
pip install confdoc[dev]
|
||||
Or from source:
|
||||
|
||||
```bash
|
||||
pip install -e .
|
||||
```
|
||||
|
||||
## Quick Start
|
||||
@@ -26,87 +27,80 @@ pip install confdoc[dev]
|
||||
### Validate a Configuration File
|
||||
|
||||
```bash
|
||||
# Validate a config file against a schema
|
||||
confdoc validate config.json --schema schema.json
|
||||
|
||||
# Specify format explicitly
|
||||
confdoc validate config.yaml --schema schema.json --format yaml
|
||||
|
||||
# Apply a profile
|
||||
confdoc validate config.json --schema schema.json --profile production
|
||||
|
||||
# JSON output
|
||||
confdoc validate config.json --schema schema.json --output json
|
||||
```
|
||||
|
||||
### Generate Documentation
|
||||
|
||||
```bash
|
||||
confdoc doc schema.json --output CONFIGURATION.md
|
||||
# Generate documentation from a schema
|
||||
confdoc doc schema.json
|
||||
|
||||
# Write to a file
|
||||
confdoc doc schema.json --output CONFIG.md
|
||||
|
||||
# Custom title
|
||||
confdoc doc schema.json --title "My App Configuration"
|
||||
```
|
||||
|
||||
### Initialize a New Schema
|
||||
### Initialize a Schema
|
||||
|
||||
```bash
|
||||
# Create a starter schema
|
||||
confdoc init schema.json
|
||||
|
||||
# Or infer schema from existing config
|
||||
confdoc init schema.json --config config.yaml
|
||||
# Generate schema from existing config
|
||||
confdoc init schema.json --config config.json
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### validate Command
|
||||
### Commands
|
||||
|
||||
Validate a configuration file against a schema:
|
||||
| Command | Description |
|
||||
|---------|-------------|
|
||||
| `confdoc validate <config>` | Validate a configuration file |
|
||||
| `confdoc doc <schema>` | Generate documentation from schema |
|
||||
| `confdoc init [output]` | Initialize a new schema file |
|
||||
|
||||
```bash
|
||||
confdoc validate <config-file> [OPTIONS]
|
||||
```
|
||||
### Options
|
||||
|
||||
Options:
|
||||
- `--schema, -s`: Path to schema file (default: schema.json)
|
||||
- `--format, -f`: Config format: json, yaml, toml, auto (default: auto)
|
||||
- `--profile, -p`: Profile to apply (development, staging, production)
|
||||
- `--output, -o`: Output format: text, json (default: text)
|
||||
#### Validate Command
|
||||
|
||||
Example:
|
||||
```bash
|
||||
confdoc validate config.yaml --schema schema.json --profile development
|
||||
```
|
||||
| Option | Description |
|
||||
|--------|-------------|
|
||||
| `--schema, -s` | Path to schema file (default: schema.json) |
|
||||
| `--format, -f` | Config format: json, yaml, toml, auto |
|
||||
| `--profile, -p` | Profile to apply: development, staging, production |
|
||||
| `--output, -o` | Output format: text, json |
|
||||
|
||||
### doc Command
|
||||
#### Doc Command
|
||||
|
||||
Generate markdown documentation from a schema:
|
||||
| Option | Description |
|
||||
|--------|-------------|
|
||||
| `--output, -o` | Output file path |
|
||||
| `--title, -t` | Document title |
|
||||
| `--format, -f` | Output format (default: markdown) |
|
||||
|
||||
```bash
|
||||
confdoc doc <schema-file> [OPTIONS]
|
||||
```
|
||||
#### Init Command
|
||||
|
||||
Options:
|
||||
- `--output, -o`: Output file path
|
||||
- `--title, -t`: Document title
|
||||
- `--format, -f`: Output format (default: markdown)
|
||||
|
||||
Example:
|
||||
```bash
|
||||
confdoc doc schema.json --output docs/configuration.md --title "My App Config"
|
||||
```
|
||||
|
||||
### init Command
|
||||
|
||||
Initialize a new schema file:
|
||||
|
||||
```bash
|
||||
confdoc init [output-file] [OPTIONS]
|
||||
```
|
||||
|
||||
Options:
|
||||
- `--config, -c`: Generate schema from existing config file
|
||||
|
||||
Example:
|
||||
```bash
|
||||
# Create a starter schema
|
||||
confdoc init
|
||||
|
||||
# Infer schema from config
|
||||
confdoc init schema.json --config config.toml
|
||||
```
|
||||
| Option | Description |
|
||||
|--------|-------------|
|
||||
| `--config, -c` | Generate schema from existing config file |
|
||||
|
||||
## Examples
|
||||
|
||||
### Example Configuration (config.json)
|
||||
### Example Configuration (JSON)
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -123,7 +117,7 @@ confdoc init schema.json --config config.toml
|
||||
}
|
||||
```
|
||||
|
||||
### Example Schema (schema.json)
|
||||
### Example Schema
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -135,47 +129,32 @@ confdoc init schema.json --config config.toml
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {"type": "string", "description": "Application name"},
|
||||
"version": {"type": "string", "description": "Application version"},
|
||||
"debug": {"type": "boolean", "description": "Enable debug mode", "default": false}
|
||||
"version": {"type": "string", "description": "Version"},
|
||||
"debug": {"type": "boolean", "description": "Debug mode", "default": false}
|
||||
},
|
||||
"required": ["name"]
|
||||
},
|
||||
"database": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"host": {"type": "string", "description": "Database host"},
|
||||
"port": {"type": "integer", "description": "Database port", "minimum": 1, "maximum": 65535},
|
||||
"name": {"type": "string", "description": "Database name"}
|
||||
"host": {"type": "string"},
|
||||
"port": {"type": "integer", "minimum": 1, "maximum": 65535}
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": ["app", "database"]
|
||||
"required": ["app"]
|
||||
}
|
||||
```
|
||||
|
||||
## Schema Reference
|
||||
### Error Output
|
||||
|
||||
ConfDoc uses JSON Schema for validation. Supported keywords:
|
||||
When validation fails, ConfDoc provides clear, actionable error messages:
|
||||
|
||||
- `type`: string, integer, number, boolean, object, array, null
|
||||
- `required`: Array of required property names
|
||||
- `properties`: Object defining each property's schema
|
||||
- `enum`: List of allowed values
|
||||
- `minimum`, `maximum`: Numeric constraints
|
||||
- `minLength`, `maxLength`: String length constraints
|
||||
- `pattern`: Regular expression pattern
|
||||
- `default`: Default value for the property
|
||||
- `description`: Human-readable description
|
||||
|
||||
## Environment Profiles
|
||||
|
||||
ConfDoc includes built-in profiles:
|
||||
|
||||
| Profile | Description |
|
||||
|---------|-------------|
|
||||
| development | Lenient validation, allows extra properties |
|
||||
| staging | Strict validation, no extra properties |
|
||||
| production | Strict validation, no extra properties |
|
||||
```
|
||||
✗ Configuration validation failed
|
||||
- 'port' is not of type 'string' in app.database
|
||||
→ Expected type string, but got integer.
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
@@ -186,48 +165,84 @@ ConfDoc includes built-in profiles:
|
||||
| `CONFDOC_CONFIG_PATH` | Default config path |
|
||||
| `CONFDOC_DEFAULT_SCHEMA` | Default schema file |
|
||||
|
||||
### Programmatic Usage
|
||||
### Configuration Files
|
||||
|
||||
ConfDoc looks for configuration in:
|
||||
1. `confdoc.yaml`
|
||||
2. `.confdocrc`
|
||||
3. `pyproject.toml` section `[tool.confdoc]`
|
||||
|
||||
## Profiles
|
||||
|
||||
ConfDoc includes built-in profiles for different environments:
|
||||
|
||||
### Development
|
||||
- Relaxed validation (additionalProperties allowed)
|
||||
- Debug mode enabled by default
|
||||
- DEBUG log level
|
||||
|
||||
### Staging
|
||||
- Strict validation
|
||||
- Debug disabled
|
||||
- INFO log level
|
||||
|
||||
### Production
|
||||
- Strict validation
|
||||
- Debug disabled
|
||||
- WARNING log level
|
||||
|
||||
Create custom profiles:
|
||||
|
||||
```python
|
||||
from confdoc.parsers import ConfigParserFactory
|
||||
from confdoc.validator import SchemaValidator
|
||||
from confdoc.docs import DocGenerator
|
||||
from confdoc.profiles import ProfileManager
|
||||
|
||||
# Parse a config file
|
||||
factory = ConfigParserFactory()
|
||||
parser = factory.get_parser_for_file("config.json")
|
||||
config = parser.parse(content)
|
||||
|
||||
# Validate against schema
|
||||
validator = SchemaValidator()
|
||||
is_valid, errors = validator.validate(config, schema)
|
||||
|
||||
# Generate documentation
|
||||
doc_gen = DocGenerator()
|
||||
docs = doc_gen.generate(schema, "My Config")
|
||||
manager = ProfileManager()
|
||||
manager.save_profile("custom", {
|
||||
"name": "Custom",
|
||||
"validation": {"strict": True},
|
||||
"overrides": {"custom_key": "value"}
|
||||
})
|
||||
```
|
||||
|
||||
## Development
|
||||
## Schema Reference
|
||||
|
||||
ConfDoc supports JSON Schema draft-07 with these commonly used keywords:
|
||||
|
||||
| Keyword | Description |
|
||||
|---------|-------------|
|
||||
| `type` | Value type (string, integer, boolean, object, array) |
|
||||
| `required` | Array of required property names |
|
||||
| `properties` | Object property definitions |
|
||||
| `description` | Property description for docs |
|
||||
| `default` | Default value |
|
||||
| `enum` | Allowed values |
|
||||
| `minimum` | Minimum value (numbers) |
|
||||
| `maximum` | Maximum value (numbers) |
|
||||
| `minLength` | Minimum string length |
|
||||
| `maxLength` | Maximum string length |
|
||||
| `pattern` | Regex pattern |
|
||||
|
||||
## Testing
|
||||
|
||||
```bash
|
||||
# Clone the repository
|
||||
git clone https://7000pct.gitea.bloupla.net/7000pctAUTO/confdoc.git
|
||||
cd confdoc
|
||||
|
||||
# Install development dependencies
|
||||
pip install -e ".[dev]"
|
||||
|
||||
# Run tests
|
||||
# Run all tests
|
||||
pytest tests/ -v
|
||||
|
||||
# Run with coverage
|
||||
pytest tests/ --cov=confdoc --cov-report=term-missing
|
||||
pytest tests/ --cov=src/confdoc --cov-report=term-missing
|
||||
|
||||
# Run specific test file
|
||||
pytest tests/test_parsers.py -v
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
Contributions are welcome! Please feel free to submit a Pull Request.
|
||||
1. Fork the repository
|
||||
2. Create a feature branch
|
||||
3. Add your changes
|
||||
4. Write tests
|
||||
5. Submit a pull request
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the MIT License - see the LICENSE file for details.
|
||||
MIT License - see [LICENSE](LICENSE) file for details.
|
||||
|
||||
@@ -36,6 +36,7 @@ dependencies = [
|
||||
dev = [
|
||||
"pytest>=7.4.0",
|
||||
"pytest-cov>=4.1.0",
|
||||
"ruff>=0.1.0",
|
||||
]
|
||||
|
||||
[project.scripts]
|
||||
|
||||
@@ -132,7 +132,7 @@ class DocGenerator:
|
||||
lines.append("")
|
||||
|
||||
header = "| " + " | ".join(columns) + " |"
|
||||
separator = "| " + "| ".join("-" * len(col) for col in columns) + " |"
|
||||
separator = "| " + " | ".join("-" * len(col) for col in columns) + " |"
|
||||
|
||||
lines.append(header)
|
||||
lines.append(separator)
|
||||
|
||||
@@ -132,7 +132,7 @@ class ErrorFormatter:
|
||||
actual_type = validator_error.get("found", "")
|
||||
return f"Expected type {expected_type}, but got {actual_type}."
|
||||
elif validator == "enum":
|
||||
allowed = ", ".join(validator_value) if isinstance(validator_value, list) else str(validator_value)
|
||||
allowed = ", ".join(str(e) for e in validator_value) if isinstance(validator_value, list) else str(validator_value)
|
||||
return f"Value must be one of: {allowed}"
|
||||
elif validator == "minimum":
|
||||
return f"Value must be greater than or equal to {validator_value}."
|
||||
|
||||
@@ -1 +1 @@
|
||||
"""Tests package for ConfDoc."""
|
||||
"""Tests package for confdoc."""
|
||||
|
||||
@@ -74,7 +74,7 @@ class TestCLIDoc:
|
||||
|
||||
def test_doc_writes_to_file(self):
|
||||
with runner.isolated_filesystem():
|
||||
schema_content = '{"title": "Test", "type": "object", "properties": {}}'
|
||||
schema_content = '''{"title": "Test", "type": "object", "properties": {}}'''
|
||||
|
||||
with open("schema.json", "w") as f:
|
||||
f.write(schema_content)
|
||||
|
||||
Reference in New Issue
Block a user