- 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>
123 lines
3.7 KiB
Python
123 lines
3.7 KiB
Python
"""
|
|
Version information for MarkiTect.
|
|
|
|
This module provides version and release information for the MarkiTect package.
|
|
Version information is sourced from pyproject.toml and git metadata when available.
|
|
"""
|
|
|
|
import os
|
|
import subprocess
|
|
from pathlib import Path
|
|
from typing import Optional
|
|
|
|
# Base version from pyproject.toml
|
|
__version__ = "0.1.0"
|
|
|
|
def get_git_commit_hash() -> Optional[str]:
|
|
"""Get the current git commit hash if available."""
|
|
try:
|
|
result = subprocess.run(
|
|
['git', 'rev-parse', '--short', 'HEAD'],
|
|
capture_output=True,
|
|
text=True,
|
|
check=True,
|
|
cwd=Path(__file__).parent.parent
|
|
)
|
|
return result.stdout.strip()
|
|
except (subprocess.CalledProcessError, FileNotFoundError):
|
|
return None
|
|
|
|
def get_git_branch() -> Optional[str]:
|
|
"""Get the current git branch if available."""
|
|
try:
|
|
result = subprocess.run(
|
|
['git', 'branch', '--show-current'],
|
|
capture_output=True,
|
|
text=True,
|
|
check=True,
|
|
cwd=Path(__file__).parent.parent
|
|
)
|
|
return result.stdout.strip()
|
|
except (subprocess.CalledProcessError, FileNotFoundError):
|
|
return None
|
|
|
|
def get_git_tag() -> Optional[str]:
|
|
"""Get the current git tag if available."""
|
|
try:
|
|
result = subprocess.run(
|
|
['git', 'describe', '--tags', '--exact-match'],
|
|
capture_output=True,
|
|
text=True,
|
|
check=True,
|
|
cwd=Path(__file__).parent.parent
|
|
)
|
|
return result.stdout.strip()
|
|
except (subprocess.CalledProcessError, FileNotFoundError):
|
|
return None
|
|
|
|
def is_development_version() -> bool:
|
|
"""Check if this is a development version (has uncommitted changes)."""
|
|
try:
|
|
result = subprocess.run(
|
|
['git', 'status', '--porcelain'],
|
|
capture_output=True,
|
|
text=True,
|
|
check=True,
|
|
cwd=Path(__file__).parent.parent
|
|
)
|
|
return bool(result.stdout.strip())
|
|
except (subprocess.CalledProcessError, FileNotFoundError):
|
|
return False
|
|
|
|
def get_version_info() -> dict:
|
|
"""Get comprehensive version information."""
|
|
git_commit = get_git_commit_hash()
|
|
git_branch = get_git_branch()
|
|
git_tag = get_git_tag()
|
|
is_dev = is_development_version()
|
|
|
|
# Build version string
|
|
version_parts = [__version__]
|
|
|
|
if git_tag and git_tag != f"v{__version__}":
|
|
# If we have a different tag, use it
|
|
version_parts = [git_tag.lstrip('v')]
|
|
|
|
if git_commit:
|
|
if is_dev:
|
|
version_parts.append(f"dev+{git_commit}")
|
|
elif not git_tag:
|
|
version_parts.append(f"+{git_commit}")
|
|
|
|
if is_dev and not git_commit:
|
|
version_parts.append("dev")
|
|
|
|
full_version = ".".join(version_parts)
|
|
|
|
return {
|
|
"version": __version__,
|
|
"full_version": full_version,
|
|
"git_commit": git_commit,
|
|
"git_branch": git_branch,
|
|
"git_tag": git_tag,
|
|
"is_development": is_dev,
|
|
"is_git_repo": git_commit is not None
|
|
}
|
|
|
|
def get_release_info() -> dict:
|
|
"""Get release information."""
|
|
version_info = get_version_info()
|
|
|
|
release_type = "development" if version_info["is_development"] else "release"
|
|
if version_info["git_tag"]:
|
|
release_type = "tagged-release"
|
|
elif version_info["git_commit"] and not version_info["is_development"]:
|
|
release_type = "commit-build"
|
|
|
|
return {
|
|
"release_type": release_type,
|
|
"build_from": version_info["git_branch"] or "unknown",
|
|
"commit": version_info["git_commit"] or "unknown",
|
|
"clean_build": not version_info["is_development"],
|
|
**version_info
|
|
} |