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

67 statements  

« prev     ^ index     » next       coverage.py v7.16.1, created at 2026-09-23 03:53 +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 

10from io import StringIO 

11import click 

12from rich.console import Console 

13from rich.table import Table 

14from rich import box 

15from apio.commands import options 

16from apio.common import apio_themes 

17from apio.common.apio_console import cout, ctable 

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

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

20from apio.utils import cmd_util 

21from apio.apio_context import ( 

22 ApioContext, 

23 PackagesPolicy, 

24 ProjectPolicy, 

25 RemoteConfigPolicy, 

26) 

27from apio.utils.cmd_util import ApioCommand 

28 

29# --- apio preferences 

30 

31 

32def _list_themes_colors(): 

33 width = 16 

34 

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

36 # -- the current theme of apio_console. 

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

38 

39 # -- Print title lines. 

40 print() 

41 values = [] 

42 for theme_name in THEMES_NAMES: 

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

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

45 print(" ".join(values)) 

46 

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

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

49 values = [] 

50 for theme_name in THEMES_NAMES: 

51 theme = THEMES_TABLE[theme_name] 

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

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

54 # -- Format for a fixed with. 

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

56 # -- Install a capture buffer. 

57 cons.file = StringIO() 

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

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

60 # -- Get the captured output. 

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

62 # -- Print the line with style colors. 

63 print(" ".join(values)) 

64 

65 print() 

66 

67 

68def _list_preferences(apio_ctx: ApioContext): 

69 """Lists the preferences.""" 

70 

71 table = Table( 

72 show_header=True, 

73 show_lines=True, 

74 box=box.SQUARE, 

75 border_style=BORDER, 

76 title="Apio User Preferences", 

77 title_justify="left", 

78 padding=(0, 2), 

79 ) 

80 

81 # -- Add columns. 

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

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

84 

85 # -- Add rows. 

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

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

88 

89 # -- Render table. 

90 cout() 

91 ctable(table) 

92 

93 

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

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

96 

97 # -- Set the colors preference value. 

98 apio_ctx.profile.set_preferences_theme(theme_name) 

99 

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

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

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

103 

104 

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

106APIO_PREFERENCES_HELP = """ 

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

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

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

110apio projects. 

111 

112Examples:[code] 

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

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

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

116 apio preferences --list # List current preferences. 

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

118""" 

119 

120 

121theme_option = click.option( 

122 "theme_name", # Var name 

123 "-t", 

124 "--theme", 

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

126 help="Set colors theme name.", 

127 cls=cmd_util.ApioOption, 

128) 

129 

130colors_option = click.option( 

131 "colors", # Var name 

132 "-c", 

133 "--colors", 

134 is_flag=True, 

135 help="List themes colors.", 

136 cls=cmd_util.ApioOption, 

137) 

138 

139 

140@click.command( 

141 name="preferences", 

142 cls=ApioCommand, 

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

144 help=APIO_PREFERENCES_HELP, 

145) 

146@click.pass_context 

147@theme_option 

148@colors_option 

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

150def cli( 

151 cmd_ctx: click.Context, 

152 *, 

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 return 

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 return 

184 

185 if colors: 

186 _list_themes_colors() 

187 return 

188 

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

190 click.echo(cmd_ctx.get_help())