feat: enhance validate command with semantic validation
Integrates SemanticValidator into CLI validate command: New Options: - --semantic/--no-semantic (default: True) - Enable/disable semantic validation - --check-links - Enable link validation (requires semantic validation) - --strict - Treat warnings as errors (fail on WARNING-level issues) Features: - Automatically detects x-markitect extensions in schema - Runs semantic validation alongside structural validation - Combines results with clear separation in output - Maintains full backward compatibility (--no-semantic for classic mode) - Supports .md schema files with embedded JSON - Graceful degradation: semantic validation errors don't crash command Example Usage: # Full validation (structural + semantic) markitect validate doc.md --schema manpage-schema-v1.0.md # Strict mode (warnings = errors) markitect validate doc.md --schema schema.md --strict # Classic mode (structural only) markitect validate doc.md --schema schema.json --no-semantic Output Format: - Shows structural validation results first - Then semantic validation results (sections, content) - Clear summary with error/warning counts - Exit codes: 0=pass, 1=fail (respects --strict flag) Integration: cli.py:1493-1668 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1493,7 +1493,7 @@ def generate_schema(config, file_path, max_depth, output, outfile, output_format
|
||||
@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')
|
||||
help='Path to JSON schema file (.json or .md)')
|
||||
@click.option('--schema-json', type=str,
|
||||
help='JSON schema provided as a string')
|
||||
@click.option('--quiet', '-q', is_flag=True,
|
||||
@@ -1502,21 +1502,38 @@ def generate_schema(config, file_path, max_depth, output, outfile, output_format
|
||||
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')
|
||||
@click.option('--semantic/--no-semantic', default=True,
|
||||
help='Enable/disable semantic validation (sections, patterns, quality)')
|
||||
@click.option('--check-links', is_flag=True,
|
||||
help='Enable link validation (may be slow, requires --semantic)')
|
||||
@click.option('--strict', is_flag=True,
|
||||
help='Treat warnings as errors')
|
||||
@pass_config
|
||||
def validate(config, file_path, schema, schema_json, quiet, detailed_errors, error_format):
|
||||
def validate(config, file_path, schema, schema_json, quiet, detailed_errors, error_format,
|
||||
semantic, check_links, strict):
|
||||
"""
|
||||
Validate a markdown file against a JSON schema.
|
||||
|
||||
ENHANCED: Now includes semantic validation of x-markitect extensions:
|
||||
- Section classifications (required, recommended, optional, discouraged, improper)
|
||||
- Content patterns (required_patterns, forbidden_patterns)
|
||||
- Quality metrics (min_words, max_words, min_sentences)
|
||||
|
||||
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"}'
|
||||
# Structural + semantic validation (default)
|
||||
markitect validate doc.md --schema manpage-schema-v1.0.md
|
||||
|
||||
# Only structural validation
|
||||
markitect validate doc.md --schema schema.json --no-semantic
|
||||
|
||||
# Strict mode (warnings become errors)
|
||||
markitect validate doc.md --schema schema.json --strict
|
||||
|
||||
# Legacy detailed errors
|
||||
markitect validate doc.md --schema schema.json --detailed-errors
|
||||
markitect validate doc.md --schema schema.json --errors --error-format json
|
||||
"""
|
||||
try:
|
||||
validator = SchemaValidator()
|
||||
@@ -1594,6 +1611,46 @@ def validate(config, file_path, schema, schema_json, quiet, detailed_errors, err
|
||||
click.echo("❌ Document structure does not match schema requirements")
|
||||
click.echo("💡 Use --detailed-errors to see specific validation issues")
|
||||
|
||||
# Semantic validation (if enabled and schema has x-markitect extensions)
|
||||
semantic_report = None
|
||||
if semantic and schema:
|
||||
try:
|
||||
from .semantic_validator import SemanticValidator, load_schema_from_path
|
||||
|
||||
# Load schema (supports .md and .json)
|
||||
schema_dict = load_schema_from_path(schema)
|
||||
|
||||
# Check if schema has x-markitect extensions
|
||||
has_extensions = ('x-markitect-sections' in schema_dict or
|
||||
'x-markitect-content-control' in schema_dict)
|
||||
|
||||
if has_extensions:
|
||||
sem_validator = SemanticValidator(schema_dict)
|
||||
semantic_report = sem_validator.validate(file_path, check_links=check_links)
|
||||
|
||||
# Combine with structural validation result
|
||||
if semantic_report and not quiet:
|
||||
click.echo("")
|
||||
click.echo("=" * 60)
|
||||
click.echo("Semantic Validation Results:")
|
||||
click.echo("=" * 60)
|
||||
click.echo(semantic_report.format_text())
|
||||
|
||||
# Update validity based on semantic validation
|
||||
if semantic_report:
|
||||
if semantic_report.has_errors():
|
||||
is_valid = False
|
||||
elif strict and semantic_report.has_warnings():
|
||||
is_valid = False
|
||||
|
||||
except Exception as e:
|
||||
# Semantic validation failure doesn't fail the whole command
|
||||
# unless strict mode is enabled
|
||||
if not quiet:
|
||||
click.echo(f"\n⚠️ Semantic validation error: {e}", err=True)
|
||||
if strict:
|
||||
is_valid = False
|
||||
|
||||
# Exit with appropriate code
|
||||
sys.exit(0 if is_valid else 1)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user