Coverage for apio/commands/apio_preferences.py: 100%

69 statements  

« prev     ^ index     » next       coverage.py v7.11.0, created at 2025-11-06 10:20 +0000

1# -*- coding: utf-8 -*- 

2# -- This file is part of the Apio project 

3# -- (C) 2016-2024 FPGAwars 

4# -- Authors 

5# -- * Jesús Arroyo (2016-2019) 

6# -- * Juan Gonzalez (obijuan) (2019-2024) 

7# -- License GPLv2 

8"""Implementation of 'apio preferences' command""" 

9 

10import sys 

11from io import StringIO 

12import click 

13from rich.console import Console 

14from rich.table import Table 

15from rich import box 

16from apio.commands import options 

17from apio.common import apio_themes 

18from apio.common.apio_console import cout, ctable 

19from apio.common.apio_styles import BORDER, EMPH1, SUCCESS 

20from apio.common.apio_themes import THEMES_TABLE, THEMES_NAMES, DEFAULT_THEME 

21from apio.utils import cmd_util 

22from apio.apio_context import ( 

23 ApioContext, 

24 PackagesPolicy, 

25 ProjectPolicy, 

26 RemoteConfigPolicy, 

27) 

28from apio.utils.cmd_util import ApioCommand 

29 

30# --- apio preferences 

31 

32 

33def _list_themes_colors(): 

34 width = 16 

35 

36 # -- For color styling we use an independent rich Console to bypass 

37 # -- the current theme of apio_console. 

38 cons = Console(color_system="auto", force_terminal=True) 

39 

40 # -- Print title lines. 

41 print() 

42 values = [] 

43 for theme_name in THEMES_NAMES: 

44 s = f"[{theme_name.upper()}]" 

45 values.append(f"{s:{width}}") 

46 print(" ".join(values)) 

47 

48 # -- Print a line for each style name. 

49 for style_name in DEFAULT_THEME.styles.keys(): 

50 values = [] 

51 for theme_name in THEMES_NAMES: 

52 theme = THEMES_TABLE[theme_name] 

53 # -- For themes with disabled colors we disable the color styling. 

54 style = theme.styles[style_name] if theme.colors_enabled else None 

55 # -- Format for a fixed with. 

56 s = f"{style_name:{width}}" 

57 # -- Install a capture buffer. 

58 cons.file = StringIO() 

59 # -- Output to buffer, with optional style. 

60 cons.out(s, style=style, end="") 

61 # -- Get the captured output. 

62 values.append(cons.file.getvalue()) 

63 # -- Print the line with style colors. 

64 print(" ".join(values)) 

65 

66 print() 

67 

68 

69def _list_preferences(apio_ctx: ApioContext): 

70 """Lists the preferences.""" 

71 

72 table = Table( 

73 show_header=True, 

74 show_lines=True, 

75 box=box.SQUARE, 

76 border_style=BORDER, 

77 title="Apio User Preferences", 

78 title_justify="left", 

79 padding=(0, 2), 

80 ) 

81 

82 # -- Add columns. 

83 table.add_column("ITEM", no_wrap=True) 

84 table.add_column("VALUE", no_wrap=True, style=EMPH1, min_width=30) 

85 

86 # -- Add rows. 

87 value = apio_ctx.profile.preferences.get("theme", "light") 

88 table.add_row("Theme name", value) 

89 

90 # -- Render table. 

91 cout() 

92 ctable(table) 

93 

94 

95def _set_theme(apio_ctx: ApioContext, theme_name: str): 

96 """Sets the colors theme to the given theme name.""" 

97 

98 # -- Set the colors preference value. 

99 apio_ctx.profile.set_preferences_theme(theme_name) 

100 

101 # -- Show the result. The new colors preference is already in effect. 

102 confirmed_theme = apio_ctx.profile.preferences["theme"] 

103 cout(f"Theme set to [{confirmed_theme}]", style=SUCCESS) 

104 

105 

106# -- Text in the rich-text format of the python rich library. 

107APIO_PREFERENCES_HELP = """ 

108The command 'apio preferences' allows to view and manage the setting of the \ 

109apio's user's preferences. These settings are stored in the 'profile.json' \ 

110file in the apio home directory (e.g. '~/.apio') and apply to all \ 

111apio projects. 

112 

113Examples:[code] 

114 apio preferences -t light # Colors for light backgrounds. 

115 apio preferences -t dark # Colors for dark backgrounds. 

116 apio preferences -t no-colors # No colors. 

117 apio preferences --list # List current preferences. 

118 apio pref -t dark # Using command shortcut.[/code] 

119""" 

120 

121 

122theme_option = click.option( 

123 "theme_name", # Var name 

124 "-t", 

125 "--theme", 

126 type=click.Choice(apio_themes.THEMES_NAMES, case_sensitive=True), 

127 help="Set colors theme name.", 

128 cls=cmd_util.ApioOption, 

129) 

130 

131colors_option = click.option( 

132 "colors", # Var name 

133 "-c", 

134 "--colors", 

135 is_flag=True, 

136 help="List themes colors.", 

137 cls=cmd_util.ApioOption, 

138) 

139 

140 

141@click.command( 

142 name="preferences", 

143 cls=ApioCommand, 

144 short_help="Manage the apio user preferences.", 

145 help=APIO_PREFERENCES_HELP, 

146) 

147@click.pass_context 

148@theme_option 

149@colors_option 

150@options.list_option_gen(short_help="List the preferences.") 

151def cli( 

152 cmd_ctx: click.Context, 

153 # -- Options 

154 theme_name: str, 

155 colors: bool, 

156 list_: bool, 

157): 

158 """Implements the apio preferences command.""" 

159 

160 # -- At most one of those. 

161 cmd_util.check_at_most_one_param( 

162 cmd_ctx, ["theme_name", "colors", "list_"] 

163 ) 

164 

165 # -- Handle theme setting. 

166 if theme_name: 

167 apio_ctx = ApioContext( 

168 project_policy=ProjectPolicy.NO_PROJECT, 

169 remote_config_policy=RemoteConfigPolicy.CACHED_OK, 

170 packages_policy=PackagesPolicy.ENSURE_PACKAGES, 

171 ) 

172 _set_theme(apio_ctx, theme_name) 

173 sys.exit(0) 

174 

175 # -- Handle preferences settings. 

176 if list_: 

177 apio_ctx = ApioContext( 

178 project_policy=ProjectPolicy.NO_PROJECT, 

179 remote_config_policy=RemoteConfigPolicy.CACHED_OK, 

180 packages_policy=PackagesPolicy.ENSURE_PACKAGES, 

181 ) 

182 _list_preferences(apio_ctx) 

183 sys.exit(0) 

184 

185 if colors: 

186 _list_themes_colors() 

187 sys.exit(0) 

188 

189 # -- If nothing to do then print help and exit 

190 click.echo(cmd_ctx.get_help()) 

191 sys.exit(0)