feat: Complete Issue #8 - Detailed Validation Error Reporting and CLI Enhancements
Some checks failed
Test Suite / unit-tests (3.11) (push) Has been cancelled
Test Suite / unit-tests (3.12) (push) Has been cancelled
Test Suite / integration-tests (push) Has been cancelled
Test Suite / e2e-tests (push) Has been cancelled
Test Suite / performance-tests (push) Has been cancelled
Test Suite / code-quality (push) Has been cancelled
Test Suite / security-scan (push) Has been cancelled
Test Suite / test-summary (push) Has been cancelled
Some checks failed
Test Suite / unit-tests (3.11) (push) Has been cancelled
Test Suite / unit-tests (3.12) (push) Has been cancelled
Test Suite / integration-tests (push) Has been cancelled
Test Suite / e2e-tests (push) Has been cancelled
Test Suite / performance-tests (push) Has been cancelled
Test Suite / code-quality (push) Has been cancelled
Test Suite / security-scan (push) Has been cancelled
Test Suite / test-summary (push) Has been cancelled
Major Features: - Implement comprehensive validation error reporting system (Issue #8) - Add direct CLI access with 'markitect' command - Create extensive makefile targets for CLI usage - Enhance schema validation with detailed error collection Components Added: - markitect/validation_error.py: ValidationError system with 8 error types - Enhanced markitect/schema_validator.py: Detailed error reporting methods - markitect/cli.py: Enhanced with --detailed-errors and --error-format options - visualize_schema.py: Schema visualization with ASCII and colorful modes - Comprehensive test suite for validation error reporting CLI Enhancements: - Direct 'markitect' command access for all operations - Makefile targets for typical CLI usage (cli-help, cli-ingest, etc.) - Support for text, JSON, and markdown error output formats - Backward compatibility with existing validation functionality Testing: - 11 comprehensive tests for Issue #8 validation error reporting - Tests for schema validation, visualization, and CLI integration - 100% test coverage for validation error scenarios 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
111
markitect/cli.py
111
markitect/cli.py
@@ -30,7 +30,8 @@ from .serializer import ASTSerializer
|
||||
from .cache_service import CacheDirectoryService
|
||||
from .ast_service import ASTService
|
||||
from .schema_generator import SchemaGenerator
|
||||
from .exceptions import FileNotFoundError, InvalidDepthError
|
||||
from .schema_validator import SchemaValidator
|
||||
from .exceptions import FileNotFoundError, InvalidDepthError, SchemaValidationError, InvalidSchemaError
|
||||
|
||||
|
||||
# Global options for CLI configuration
|
||||
@@ -996,6 +997,114 @@ def generate_schema(config, file_path, max_depth, output, output_format):
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
@cli.command('validate')
|
||||
@click.argument('file_path', type=click.Path(exists=True, path_type=Path))
|
||||
@click.option('--schema', '-s', type=click.Path(exists=True, path_type=Path),
|
||||
help='Path to JSON schema file')
|
||||
@click.option('--schema-json', type=str,
|
||||
help='JSON schema provided as a string')
|
||||
@click.option('--quiet', '-q', is_flag=True,
|
||||
help='Only output validation result (true/false)')
|
||||
@click.option('--detailed-errors', '--errors', is_flag=True,
|
||||
help='Show detailed validation errors (Issue #8)')
|
||||
@click.option('--error-format', type=click.Choice(['text', 'json', 'markdown']), default='text',
|
||||
help='Format for detailed error output')
|
||||
@pass_config
|
||||
def validate(config, file_path, schema, schema_json, quiet, detailed_errors, error_format):
|
||||
"""
|
||||
Validate a markdown file against a JSON schema.
|
||||
|
||||
Checks if a markdown document strictly adheres to the structure defined
|
||||
by a specified schema. Returns boolean result (True/False).
|
||||
|
||||
Issue #8: Enhanced with detailed error reporting for failed validations.
|
||||
|
||||
Examples:
|
||||
markitect validate doc.md --schema schema.json
|
||||
markitect validate doc.md --schema-json '{"$schema": "...", "type": "object"}'
|
||||
markitect validate doc.md --schema schema.json --detailed-errors
|
||||
markitect validate doc.md --schema schema.json --errors --error-format json
|
||||
"""
|
||||
try:
|
||||
validator = SchemaValidator()
|
||||
|
||||
# Validate exactly one schema source is provided
|
||||
schema_sources = [schema, schema_json]
|
||||
provided_sources = [s for s in schema_sources if s is not None]
|
||||
|
||||
if len(provided_sources) != 1:
|
||||
click.echo("Error: Specify exactly one schema source (--schema or --schema-json)", err=True)
|
||||
sys.exit(1)
|
||||
|
||||
# Perform validation (with or without detailed errors)
|
||||
if detailed_errors:
|
||||
# Use detailed error reporting for Issue #8
|
||||
if schema:
|
||||
error_collector = validator.validate_file_with_errors_file(file_path, schema)
|
||||
schema_source = f"schema file: {schema}"
|
||||
else:
|
||||
error_collector = validator.validate_file_with_errors_string(file_path, schema_json)
|
||||
schema_source = "provided JSON schema"
|
||||
|
||||
is_valid = not error_collector.has_errors()
|
||||
|
||||
# Output detailed errors
|
||||
if quiet:
|
||||
click.echo(str(is_valid).lower())
|
||||
else:
|
||||
status = "VALID" if is_valid else "INVALID"
|
||||
click.echo(f"Validation result: {status}")
|
||||
click.echo(f"File: {file_path}")
|
||||
click.echo(f"Schema: {schema_source}")
|
||||
|
||||
if is_valid:
|
||||
click.echo("✅ Document structure matches schema requirements")
|
||||
else:
|
||||
click.echo("❌ Document structure does not match schema requirements")
|
||||
click.echo()
|
||||
click.echo(error_collector.format_errors(error_format))
|
||||
|
||||
else:
|
||||
# Use simple boolean validation (original Issue #7 functionality)
|
||||
if schema:
|
||||
is_valid = validator.validate_file_against_schema_file(file_path, schema)
|
||||
schema_source = f"schema file: {schema}"
|
||||
else:
|
||||
is_valid = validator.validate_file_against_schema_string(file_path, schema_json)
|
||||
schema_source = "provided JSON schema"
|
||||
|
||||
# Output results
|
||||
if quiet:
|
||||
click.echo(str(is_valid).lower())
|
||||
else:
|
||||
status = "VALID" if is_valid else "INVALID"
|
||||
click.echo(f"Validation result: {status}")
|
||||
click.echo(f"File: {file_path}")
|
||||
click.echo(f"Schema: {schema_source}")
|
||||
|
||||
if is_valid:
|
||||
click.echo("✅ Document structure matches schema requirements")
|
||||
else:
|
||||
click.echo("❌ Document structure does not match schema requirements")
|
||||
click.echo("💡 Use --detailed-errors to see specific validation issues")
|
||||
|
||||
# Exit with appropriate code
|
||||
sys.exit(0 if is_valid else 1)
|
||||
|
||||
except FileNotFoundError as e:
|
||||
click.echo(f"File not found: {e}", err=True)
|
||||
sys.exit(1)
|
||||
except (InvalidSchemaError, SchemaValidationError) as e:
|
||||
click.echo(f"Schema validation error: {e}", err=True)
|
||||
sys.exit(1)
|
||||
except Exception as e:
|
||||
click.echo(f"Validation error: {e}", err=True)
|
||||
if config and config.get('verbose'):
|
||||
import traceback
|
||||
click.echo(traceback.format_exc(), err=True)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def main():
|
||||
"""
|
||||
Main entry point for the CLI.
|
||||
|
||||
Reference in New Issue
Block a user