display_icons.py 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. """Icon management for consistent CLI display."""
  2. from __future__ import annotations
  3. from pathlib import Path
  4. from typing import ClassVar
  5. class IconManager:
  6. """Centralized icon management system for consistent CLI display.
  7. This class provides standardized icons for file types, status indicators,
  8. and UI elements. Icons use Nerd Font glyphs for consistent display.
  9. Categories:
  10. - File types: .yaml, .j2, .json, .md, etc.
  11. - Status: success, warning, error, info, skipped
  12. - UI elements: folders, config, locks, etc.
  13. """
  14. # File Type Icons
  15. FILE_FOLDER = "\uf07b"
  16. FILE_DEFAULT = "\uf15b"
  17. FILE_YAML = "\uf15c"
  18. FILE_JSON = "\ue60b"
  19. FILE_MARKDOWN = "\uf48a"
  20. FILE_JINJA2 = "\ue235"
  21. FILE_DOCKER = "\uf308"
  22. FILE_COMPOSE = "\uf308"
  23. FILE_SHELL = "\uf489"
  24. FILE_PYTHON = "\ue73c"
  25. FILE_TEXT = "\uf15c"
  26. # Status Indicators
  27. STATUS_SUCCESS = "\uf00c" # (check)
  28. STATUS_ERROR = "\uf00d" # (times/x)
  29. STATUS_WARNING = "\uf071" # (exclamation-triangle)
  30. STATUS_INFO = "\uf05a" # (info-circle)
  31. STATUS_SKIPPED = "\uf05e" # (ban/circle-slash)
  32. # UI Elements
  33. UI_CONFIG = "\ue5fc"
  34. UI_LOCK = "\uf084"
  35. UI_SETTINGS = "\uf013"
  36. UI_ARROW_RIGHT = "\uf061" # (arrow-right)
  37. UI_BULLET = "\uf111" # (circle)
  38. UI_LIBRARY_GIT = "\uf418" # (git icon)
  39. UI_LIBRARY_STATIC = "\uf07c" # (folder icon)
  40. # Shortcode Mappings (emoji-style codes to Nerd Font icons)
  41. # Format: ":code:" -> "\uf000"
  42. # To add new shortcodes:
  43. # 1. Add entry to this dict: ":mycode:": "\uf000"
  44. # 2. Use in template descriptions: ":mycode: Some text"
  45. # 3. Shortcode will be automatically replaced when markdown is rendered
  46. # Find Nerd Font codes at: https://www.nerdfonts.com/cheat-sheet
  47. SHORTCODES: ClassVar[dict[str, str]] = {
  48. ":warning:": "\uf071", # (exclamation-triangle)
  49. ":info:": "\uf05a", # (info-circle)
  50. ":check:": "\uf00c", # (check)
  51. ":error:": "\uf00d", # (times/x)
  52. ":lock:": "\uf084", # (lock)
  53. ":folder:": "\uf07b", # (folder)
  54. ":file:": "\uf15b", # (file)
  55. ":gear:": "\uf013", # (settings/gear)
  56. ":rocket:": "\uf135", # (rocket)
  57. ":star:": "\uf005", # (star)
  58. ":lightning:": "\uf0e7", # (bolt/lightning)
  59. ":cloud:": "\uf0c2", # (cloud)
  60. ":database:": "\uf1c0", # (database)
  61. ":network:": "\uf6ff", # (network)
  62. ":docker:": "\uf308", # (docker)
  63. ":kubernetes:": "\ue287", # (kubernetes/helm)
  64. }
  65. @classmethod
  66. def get_file_icon(cls, file_path: str | Path) -> str:
  67. """Get the appropriate icon for a file based on its extension or name.
  68. Args:
  69. file_path: Path to the file (can be string or Path object)
  70. Returns:
  71. Unicode icon character for the file type
  72. Examples:
  73. >>> IconManager.get_file_icon("config.yaml")
  74. '\uf15c'
  75. >>> IconManager.get_file_icon("template.j2")
  76. '\ue235'
  77. """
  78. if isinstance(file_path, str):
  79. file_path = Path(file_path)
  80. file_name = file_path.name.lower()
  81. suffix = file_path.suffix.lower()
  82. # Check for Docker Compose files
  83. compose_names = {
  84. "docker-compose.yml",
  85. "docker-compose.yaml",
  86. "compose.yml",
  87. "compose.yaml",
  88. }
  89. if file_name in compose_names or file_name.startswith("docker-compose"):
  90. return cls.FILE_DOCKER
  91. # Check by extension
  92. extension_map = {
  93. ".yaml": cls.FILE_YAML,
  94. ".yml": cls.FILE_YAML,
  95. ".json": cls.FILE_JSON,
  96. ".md": cls.FILE_MARKDOWN,
  97. ".j2": cls.FILE_JINJA2,
  98. ".sh": cls.FILE_SHELL,
  99. ".py": cls.FILE_PYTHON,
  100. ".txt": cls.FILE_TEXT,
  101. }
  102. return extension_map.get(suffix, cls.FILE_DEFAULT)
  103. @classmethod
  104. def get_status_icon(cls, status: str) -> str:
  105. """Get the appropriate icon for a status indicator.
  106. Args:
  107. status: Status type (success, error, warning, info, skipped)
  108. Returns:
  109. Unicode icon character for the status
  110. Examples:
  111. >>> IconManager.get_status_icon("success")
  112. '✓'
  113. >>> IconManager.get_status_icon("warning")
  114. '⚠'
  115. """
  116. status_map = {
  117. "success": cls.STATUS_SUCCESS,
  118. "error": cls.STATUS_ERROR,
  119. "warning": cls.STATUS_WARNING,
  120. "info": cls.STATUS_INFO,
  121. "skipped": cls.STATUS_SKIPPED,
  122. }
  123. return status_map.get(status.lower(), cls.STATUS_INFO)
  124. @classmethod
  125. def folder(cls) -> str:
  126. """Get the folder icon."""
  127. return cls.FILE_FOLDER
  128. @classmethod
  129. def config(cls) -> str:
  130. """Get the config icon."""
  131. return cls.UI_CONFIG
  132. @classmethod
  133. def lock(cls) -> str:
  134. """Get the lock icon (for sensitive variables)."""
  135. return cls.UI_LOCK
  136. @classmethod
  137. def arrow_right(cls) -> str:
  138. """Get the right arrow icon (for showing transitions/changes)."""
  139. return cls.UI_ARROW_RIGHT
  140. @classmethod
  141. def replace_shortcodes(cls, text: str) -> str:
  142. """Replace emoji-style shortcodes with Nerd Font icons.
  143. Args:
  144. text: Text containing shortcodes like :warning:, :info:, etc.
  145. Returns:
  146. Text with shortcodes replaced by Nerd Font icons
  147. Examples:
  148. >>> IconManager.replace_shortcodes(":warning: This is a warning")
  149. ' This is a warning'
  150. >>> IconManager.replace_shortcodes(":docker: :kubernetes: Stack")
  151. ' Stack'
  152. """
  153. result = text
  154. for shortcode, icon in cls.SHORTCODES.items():
  155. result = result.replace(shortcode, icon)
  156. return result