| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193 |
- """Icon management for consistent CLI display."""
- from __future__ import annotations
- from pathlib import Path
- from typing import ClassVar
- class IconManager:
- """Centralized icon management system for consistent CLI display.
- This class provides standardized icons for file types, status indicators,
- and UI elements. Icons use Nerd Font glyphs for consistent display.
- Categories:
- - File types: .yaml, .j2, .json, .md, etc.
- - Status: success, warning, error, info, skipped
- - UI elements: folders, config, locks, etc.
- """
- # File Type Icons
- FILE_FOLDER = "\uf07b"
- FILE_DEFAULT = "\uf15b"
- FILE_YAML = "\uf15c"
- FILE_JSON = "\ue60b"
- FILE_MARKDOWN = "\uf48a"
- FILE_JINJA2 = "\ue235"
- FILE_DOCKER = "\uf308"
- FILE_COMPOSE = "\uf308"
- FILE_SHELL = "\uf489"
- FILE_PYTHON = "\ue73c"
- FILE_TEXT = "\uf15c"
- # Status Indicators
- STATUS_SUCCESS = "\uf00c" # (check)
- STATUS_ERROR = "\uf00d" # (times/x)
- STATUS_WARNING = "\uf071" # (exclamation-triangle)
- STATUS_INFO = "\uf05a" # (info-circle)
- STATUS_SKIPPED = "\uf05e" # (ban/circle-slash)
- # UI Elements
- UI_CONFIG = "\ue5fc"
- UI_LOCK = "\uf084"
- UI_SETTINGS = "\uf013"
- UI_ARROW_RIGHT = "\uf061" # (arrow-right)
- UI_BULLET = "\uf111" # (circle)
- UI_LIBRARY_GIT = "\uf418" # (git icon)
- UI_LIBRARY_STATIC = "\uf07c" # (folder icon)
- # Shortcode Mappings (emoji-style codes to Nerd Font icons)
- # Format: ":code:" -> "\uf000"
- #
- # Usage:
- # 1. In regular text: ":mycode: Some text" - icon replaces shortcode inline
- # 2. In markdown lists: "- :mycode: List item" - icon replaces bullet with color
- #
- # To add new shortcodes:
- # 1. Add entry to this dict: ":mycode:": "\uf000"
- # 2. Use in template descriptions or markdown content
- # 3. Shortcodes are automatically replaced when markdown is rendered
- # 4. List items starting with shortcodes get colored icons instead of bullets
- #
- # Find Nerd Font codes at: https://www.nerdfonts.com/cheat-sheet
- SHORTCODES: ClassVar[dict[str, str]] = {
- ":warning:": "\uf071", # (exclamation-triangle)
- ":info:": "\uf05a", # (info-circle)
- ":check:": "\uf00c", # (check)
- ":error:": "\uf00d", # (times/x)
- ":lock:": "\uf084", # (lock)
- ":folder:": "\uf07b", # (folder)
- ":file:": "\uf15b", # (file)
- ":gear:": "\uf013", # (settings/gear)
- ":rocket:": "\uf135", # (rocket)
- ":star:": "\uf005", # (star)
- ":lightning:": "\uf0e7", # (bolt/lightning)
- ":cloud:": "\uf0c2", # (cloud)
- ":database:": "\uf1c0", # (database)
- ":network:": "\uf6ff", # (network)
- ":docker:": "\uf308", # (docker)
- ":kubernetes:": "\ue287", # (kubernetes/helm)
- }
- @classmethod
- def get_file_icon(cls, file_path: str | Path) -> str:
- """Get the appropriate icon for a file based on its extension or name.
- Args:
- file_path: Path to the file (can be string or Path object)
- Returns:
- Unicode icon character for the file type
- Examples:
- >>> IconManager.get_file_icon("config.yaml")
- '\uf15c'
- >>> IconManager.get_file_icon("template.j2")
- '\ue235'
- """
- if isinstance(file_path, str):
- file_path = Path(file_path)
- file_name = file_path.name.lower()
- suffix = file_path.suffix.lower()
- # Check for Docker Compose files
- compose_names = {
- "docker-compose.yml",
- "docker-compose.yaml",
- "compose.yml",
- "compose.yaml",
- }
- if file_name in compose_names or file_name.startswith("docker-compose"):
- return cls.FILE_DOCKER
- # Check by extension
- extension_map = {
- ".yaml": cls.FILE_YAML,
- ".yml": cls.FILE_YAML,
- ".json": cls.FILE_JSON,
- ".md": cls.FILE_MARKDOWN,
- ".j2": cls.FILE_JINJA2,
- ".sh": cls.FILE_SHELL,
- ".py": cls.FILE_PYTHON,
- ".txt": cls.FILE_TEXT,
- }
- return extension_map.get(suffix, cls.FILE_DEFAULT)
- @classmethod
- def get_status_icon(cls, status: str) -> str:
- """Get the appropriate icon for a status indicator.
- Args:
- status: Status type (success, error, warning, info, skipped)
- Returns:
- Unicode icon character for the status
- Examples:
- >>> IconManager.get_status_icon("success")
- '✓'
- >>> IconManager.get_status_icon("warning")
- '⚠'
- """
- status_map = {
- "success": cls.STATUS_SUCCESS,
- "error": cls.STATUS_ERROR,
- "warning": cls.STATUS_WARNING,
- "info": cls.STATUS_INFO,
- "skipped": cls.STATUS_SKIPPED,
- }
- return status_map.get(status.lower(), cls.STATUS_INFO)
- @classmethod
- def folder(cls) -> str:
- """Get the folder icon."""
- return cls.FILE_FOLDER
- @classmethod
- def config(cls) -> str:
- """Get the config icon."""
- return cls.UI_CONFIG
- @classmethod
- def lock(cls) -> str:
- """Get the lock icon (for sensitive variables)."""
- return cls.UI_LOCK
- @classmethod
- def arrow_right(cls) -> str:
- """Get the right arrow icon (for showing transitions/changes)."""
- return cls.UI_ARROW_RIGHT
- @classmethod
- def replace_shortcodes(cls, text: str) -> str:
- """Replace emoji-style shortcodes with Nerd Font icons.
- Args:
- text: Text containing shortcodes like :warning:, :info:, etc.
- Returns:
- Text with shortcodes replaced by Nerd Font icons
- Examples:
- >>> IconManager.replace_shortcodes(":warning: This is a warning")
- ' This is a warning'
- >>> IconManager.replace_shortcodes(":docker: :kubernetes: Stack")
- ' Stack'
- """
- result = text
- for shortcode, icon in cls.SHORTCODES.items():
- result = result.replace(shortcode, icon)
- return result
|