tux
¶
Tux Discord Bot Package Initialization.
This module handles version detection for the Tux Discord bot using a robust fallback strategy that works across different deployment scenarios including development, Docker containers, and PyPI installations.
Notes
The version detection follows this priority order: 1. TUX_VERSION environment variable (runtime override) 2. VERSION file (Docker builds and deployments) 3. Git tags (development environments) 4. Package metadata (PyPI installations) 5. Fallback to "dev" if all methods fail
This approach ensures reliable version reporting regardless of how the bot is deployed or executed.
Modules:
Name | Description |
---|---|
app | TuxApp: Orchestration and lifecycle management for the Tux Discord bot. |
bot | Tux Discord bot core implementation. |
cli | Command-line interface for Tux development tools. |
cog_loader | |
cogs | |
database | |
handlers | |
help | Help command system for Tux. |
main | Entrypoint for the Tux Discord bot application. |
ui | |
utils | |
wrappers | |
Functions¶
_get_version() -> str
¶
Retrieve the application version using multiple fallback strategies.
This function attempts to determine the version using several methods in priority order, ensuring version detection works in all deployment scenarios.
Returns:
Type | Description |
---|---|
str | The detected version string, or "dev" if detection fails. |
Notes
Fallback Strategy: 1. Environment variable (TUX_VERSION) - Allows runtime version override 2. VERSION file - Created during Docker builds for consistent versioning 3. Git describe - Uses git tags for development environments 4. Package metadata - Standard approach for PyPI installations 5. "dev" fallback - Ensures a version is always returned
This function is designed to never raise exceptions. All errors are silently handled to ensure the application can start even if version detection encounters issues.
Source code in tux/__init__.py
def _get_version() -> str:
"""
Retrieve the application version using multiple fallback strategies.
This function attempts to determine the version using several methods in
priority order, ensuring version detection works in all deployment scenarios.
Returns
-------
str
The detected version string, or "dev" if detection fails.
Notes
-----
Fallback Strategy:
1. Environment variable (TUX_VERSION) - Allows runtime version override
2. VERSION file - Created during Docker builds for consistent versioning
3. Git describe - Uses git tags for development environments
4. Package metadata - Standard approach for PyPI installations
5. "dev" fallback - Ensures a version is always returned
This function is designed to never raise exceptions. All errors are
silently handled to ensure the application can start even if version
detection encounters issues.
"""
root = Path(__file__).parent.parent
def from_env() -> str:
"""
Retrieve version from TUX_VERSION environment variable.
This method provides the highest priority for version detection,
allowing runtime override of the version string.
Returns
-------
str
Environment variable value, or empty string if not set.
Notes
-----
Useful for:
- Testing with specific version strings
- Deployment environments with custom versioning
- CI/CD pipelines that need to override detected versions
"""
return os.environ.get("TUX_VERSION", "").strip()
def from_file() -> str:
"""
Retrieve version from VERSION file in the project root.
This method reads a VERSION file that is typically created during
Docker builds or deployment processes. It provides consistent
versioning for containerized deployments where git history may
not be available.
Returns
-------
str
Contents of VERSION file, or empty string if file doesn't exist.
Notes
-----
The VERSION file is typically created during Docker builds and contains
a single line with the version string. This method is preferred for
containerized deployments where git history is not available.
"""
version_file = root / "VERSION"
return version_file.read_text().strip() if version_file.exists() else ""
def from_git() -> str:
"""
Retrieve version from git tags using git describe.
This method uses git describe to generate version strings from git tags,
making it ideal for development environments where the full git history
is available.
Returns
-------
str
Git-generated version string with 'v' prefix removed,
or empty string if git is unavailable or fails.
Notes
-----
The version includes:
- Exact tag name for released versions
- Tag + commit count + SHA for development builds
- "--dirty" suffix for uncommitted changes
Only attempts git operations if .git directory exists to avoid
unnecessary subprocess calls in non-git environments.
"""
# Only attempt git operations if .git directory exists
if not (root / ".git").exists():
return ""
# Execute git describe with comprehensive flags
result = subprocess.run(
["git", "describe", "--tags", "--always", "--dirty"],
capture_output=True,
text=True,
cwd=root,
timeout=5, # Prevent hanging on network-mounted git repos
check=False, # Don't raise on non-zero exit codes
)
# Validate git command succeeded and produced output
if result.returncode != 0 or not result.stdout.strip():
return ""
version = result.stdout.strip()
# Remove common 'v' prefix from version tags (e.g., 'v1.0.0' -> '1.0.0')
return version.removeprefix("v")
def from_metadata() -> str:
"""
Retrieve version from package metadata.
This method uses Python's importlib.metadata to read the version
from the installed package's metadata. This is the standard approach
for packages installed via pip from PyPI or local wheels.
Returns
-------
str
Package version from metadata.
Raises
------
PackageNotFoundError
If the package is not installed or metadata is unavailable.
AttributeError
If metadata module is not available (Python < 3.8).
Various other exceptions
If package metadata is corrupted or inaccessible.
Notes
-----
All exceptions are handled by the caller to ensure robust version
detection that never crashes the application startup process.
"""
return metadata.version("tux")
# Attempt each version detection method in priority order
# Stop at the first method that returns a non-empty version string
for getter in (from_env, from_file, from_git, from_metadata):
try:
version = getter()
except Exception:
# Silently continue to next method on any error
# This ensures version detection is robust and never crashes
continue
if version:
return version
# Fallback version when all detection methods fail
# Indicates development/unknown version rather than causing errors
return "dev"