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

67 statements  

« prev     ^ index     » next       coverage.py v7.17.2, created at 2026-11-07 05:08 +0000

1# This file is part of the Apio project 

2# (C) 2016-present FPGAwars 

3# Project authors: 

4# * Jesús Arroyo (Jesus89) (2016-2019) 

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

6# * The Apio Team (2024-present) 

7# License: GPLv2 

8 

9"""Implementation of 'apio preferences' command""" 

10 

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 *, 

154 # -- Options 

155 theme_name: str, 

156 colors: bool, 

157 list_: bool, 

158): 

159 """Implements the apio preferences command.""" 

160 

161 # -- At most one of those. 

162 cmd_util.check_at_most_one_param( 

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

164 ) 

165 

166 # -- Handle theme setting. 

167 if theme_name: 

168 apio_ctx = ApioContext( 

169 project_policy=ProjectPolicy.NO_PROJECT, 

170 remote_config_policy=RemoteConfigPolicy.CACHED_OK, 

171 packages_policy=PackagesPolicy.ENSURE_PACKAGES, 

172 ) 

173 _set_theme(apio_ctx, theme_name) 

174 return 

175 

176 # -- Handle preferences settings. 

177 if list_: 

178 apio_ctx = ApioContext( 

179 project_policy=ProjectPolicy.NO_PROJECT, 

180 remote_config_policy=RemoteConfigPolicy.CACHED_OK, 

181 packages_policy=PackagesPolicy.ENSURE_PACKAGES, 

182 ) 

183 _list_preferences(apio_ctx) 

184 return 

185 

186 if colors: 

187 _list_themes_colors() 

188 return 

189 

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

191 click.echo(cmd_ctx.get_help())