feat: implement markitect installer with version/release commands (issue #80)

- Add comprehensive version information system with git integration
- Add `markitect version` and `markitect release` commands with multiple output formats
- Add global `--version` flag for quick version checking
- Create Python installer script with advanced options (install.py)
- Create shell installer wrapper for easy installation (install.sh)
- Add comprehensive installation documentation (INSTALL.md)
- Support user and system-wide installations with virtual environments
- Include development mode installation with test dependencies
- Add installation status checking and uninstall functionality

Commands added:
- `markitect --version` - Quick version display
- `markitect version [--short]` - Detailed version information
- `markitect release [--format text|json|yaml]` - Release information

Installer features:
- Automatic virtual environment creation
- Symbolic link management for global access
- Custom installation paths and prefixes
- Development mode with test dependencies
- Installation validation and troubleshooting

Resolves #80

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-10-03 05:47:02 +02:00
parent 3231bd291a
commit 8e6ba272ca
6 changed files with 1237 additions and 0 deletions

View File

@@ -27,6 +27,7 @@ import builtins
from .database import DatabaseManager
from .legacy_compat import LegacyMode, emit_deprecation_warning, legacy_switch_option
from .__version__ import get_version_info, get_release_info
# Import legacy system components for advanced management
try:
@@ -175,10 +176,20 @@ def format_output(data, output_format):
return format_output(data, 'table')
def print_version(ctx, param, value):
"""Callback to print version and exit."""
if not value or ctx.resilient_parsing:
return
version_info = get_version_info()
click.echo(version_info['full_version'])
ctx.exit()
@click.group()
@click.option('--verbose', '-v', is_flag=True, help='Enable verbose output')
@click.option('--config', 'config_file', type=click.Path(exists=True), help='Configuration file path')
@click.option('--database', type=click.Path(), help='Database file path')
@click.option('--version', is_flag=True, expose_value=False, is_eager=True,
callback=print_version, help='Show version and exit')
@pass_config
def cli(config, verbose, database, config_file):
"""
@@ -218,6 +229,63 @@ def cli(config, verbose, database, config_file):
# Issue management commands removed - use dedicated 'issue' CLI or 'tddai' CLI instead
# Version and release information commands
@cli.command()
@click.option('--short', is_flag=True, help='Show only version number')
def version(short):
"""Show MarkiTect version information."""
version_info = get_version_info()
if short:
click.echo(version_info['full_version'])
else:
click.echo("MarkiTect Version Information")
click.echo("============================")
click.echo(f"Version: {version_info['full_version']}")
click.echo(f"Base Version: {version_info['version']}")
if version_info['is_git_repo']:
click.echo(f"Git Commit: {version_info['git_commit'] or 'N/A'}")
click.echo(f"Git Branch: {version_info['git_branch'] or 'N/A'}")
if version_info['git_tag']:
click.echo(f"Git Tag: {version_info['git_tag']}")
click.echo(f"Development Build: {'Yes' if version_info['is_development'] else 'No'}")
else:
click.echo("Git Repository: Not available")
@cli.command()
@click.option('--format', 'output_format', default='text',
type=click.Choice(['text', 'json', 'yaml']),
help='Output format (text, json, yaml)')
def release(output_format):
"""Show MarkiTect release information."""
release_info = get_release_info()
if output_format == 'json':
import json
click.echo(json.dumps(release_info, indent=2))
elif output_format == 'yaml':
import yaml
click.echo(yaml.dump(release_info, default_flow_style=False))
else:
# Text format
click.echo("MarkiTect Release Information")
click.echo("============================")
click.echo(f"Version: {release_info['full_version']}")
click.echo(f"Release Type: {release_info['release_type']}")
click.echo(f"Build From: {release_info['build_from']}")
click.echo(f"Commit: {release_info['commit']}")
click.echo(f"Clean Build: {'Yes' if release_info['clean_build'] else 'No'}")
if release_info['is_git_repo']:
click.echo(f"Git Repository: Available")
if release_info['git_tag']:
click.echo(f"Tagged Release: {release_info['git_tag']}")
else:
click.echo("Git Repository: Not available")
@cli.command()
@click.argument('file_path', type=click.Path(exists=True))