Mercurial > piecrust2
comparison piecrust/commands/builtin/themes.py @ 488:a00750896316
themes: Improve CLI, add `deactivate` command.
* `link` command renamed to `activate`.
* `deactivate` command removes the active theme.
* `info` command shows information about the active theme. Runs by default
when doing `chef themes`.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Wed, 22 Jul 2015 21:32:54 -0700 |
parents | d5885c6d64bd |
children | 5336e146ac8d |
comparison
equal
deleted
inserted
replaced
487:61508ae67488 | 488:a00750896316 |
---|---|
21 if app.root_dir is None: | 21 if app.root_dir is None: |
22 return | 22 return |
23 | 23 |
24 subparsers = parser.add_subparsers() | 24 subparsers = parser.add_subparsers() |
25 p = subparsers.add_parser( | 25 p = subparsers.add_parser( |
26 'info', | |
27 help="Provides information about the current theme.") | |
28 p.set_defaults(sub_func=self._info) | |
29 | |
30 p = subparsers.add_parser( | |
26 'create', | 31 'create', |
27 help="Create a new theme for the current website.") | 32 help="Create a new theme for the current website.") |
28 p.add_argument( | 33 p.add_argument( |
29 '--from-default', | 34 '--from-default', |
30 action='store_true', | 35 action='store_true', |
39 'override', | 44 'override', |
40 help="Copies a theme to the website for customization.") | 45 help="Copies a theme to the website for customization.") |
41 p.set_defaults(sub_func=self._overrideTheme) | 46 p.set_defaults(sub_func=self._overrideTheme) |
42 | 47 |
43 p = subparsers.add_parser( | 48 p = subparsers.add_parser( |
44 'link', | 49 'activate', |
45 help="Installs a theme as a link to an already existing " | 50 help="Makes a given theme the active one for the current " |
46 "theme on disk.") | 51 "website by creating a symbolic link to it from the " |
52 "'theme' directory. If a symbolic link can't be created " | |
53 "the theme will be copied to the 'theme' directory.") | |
47 p.add_argument( | 54 p.add_argument( |
48 'theme_dir', | 55 'theme_dir', |
49 help="The directory of the theme to link.") | 56 help="The directory of the theme to link.") |
50 p.set_defaults(sub_func=self._linkTheme) | 57 p.add_argument( |
58 '--link-only', | |
59 action='store_true', | |
60 help="Abort the activation if a symbolic link can't be " | |
61 "created") | |
62 p.set_defaults(sub_func=self._activateTheme) | |
63 | |
64 p = subparsers.add_parser( | |
65 'deactivate', | |
66 help="Removes the currently active theme for the website. " | |
67 "This removes the symbolic link to the theme, if any, or " | |
68 "deletes the theme folder if it was copied locally.") | |
69 p.set_defaults(sub_func=self._deactivateTheme) | |
51 | 70 |
52 def checkedRun(self, ctx): | 71 def checkedRun(self, ctx): |
53 if not hasattr(ctx.args, 'sub_func'): | 72 if not hasattr(ctx.args, 'sub_func'): |
54 ctx.parser.parse_args(['themes', '--help']) | 73 ctx.args = ctx.parser.parse_args(['themes', 'info']) |
55 return | |
56 ctx.args.sub_func(ctx) | 74 ctx.args.sub_func(ctx) |
75 | |
76 def _info(self, ctx): | |
77 theme_dir = os.path.join(ctx.app.root_dir, THEME_DIR) | |
78 if not os.path.exists(theme_dir): | |
79 logger.info("Using default theme, from: %s" % ctx.app.theme_dir) | |
80 elif os.path.islink(theme_dir): | |
81 target = os.readlink(theme_dir) | |
82 target = os.path.join(os.path.dirname(theme_dir), target) | |
83 logger.info("Using theme, from: %s" % target) | |
84 else: | |
85 logger.info("Using local theme.") | |
57 | 86 |
58 def _createTheme(self, ctx): | 87 def _createTheme(self, ctx): |
59 theme_dir = os.path.join(ctx.app.root_dir, THEME_DIR) | 88 theme_dir = os.path.join(ctx.app.root_dir, THEME_DIR) |
60 if os.path.exists(theme_dir): | 89 if os.path.exists(theme_dir): |
61 logger.warning("A theme already exists, and will be overwritten. " | 90 logger.warning("A theme already exists, and will be overwritten. " |
138 logger.info(os.path.relpath(c[1], app_dir)) | 167 logger.info(os.path.relpath(c[1], app_dir)) |
139 if not os.path.exists(os.path.dirname(c[1])): | 168 if not os.path.exists(os.path.dirname(c[1])): |
140 os.makedirs(os.path.dirname(c[1])) | 169 os.makedirs(os.path.dirname(c[1])) |
141 shutil.copy2(c[0], c[1]) | 170 shutil.copy2(c[0], c[1]) |
142 | 171 |
143 def _linkTheme(self, ctx): | 172 def _activateTheme(self, ctx): |
144 if not os.path.isdir(ctx.args.theme_dir): | 173 if not os.path.isdir(ctx.args.theme_dir): |
145 logger.error("Invalid theme directory: %s" % ctx.args.theme_dir) | 174 logger.error("Invalid theme directory: %s" % ctx.args.theme_dir) |
146 return 1 | 175 return 1 |
147 | 176 |
148 theme_dir = os.path.join(ctx.app.root_dir, THEME_DIR) | 177 theme_dir = os.path.join(ctx.app.root_dir, THEME_DIR) |
157 if len(ans) > 0 and ans.lower() not in ['y', 'yes']: | 186 if len(ans) > 0 and ans.lower() not in ['y', 'yes']: |
158 return 1 | 187 return 1 |
159 | 188 |
160 shutil.rmtree(theme_dir) | 189 shutil.rmtree(theme_dir) |
161 | 190 |
162 os.symlink(ctx.args.theme_dir, theme_dir) | 191 try: |
163 | 192 os.symlink(ctx.args.theme_dir, theme_dir) |
193 except (NotImplementedError, OSError) as ex: | |
194 if ctx.args.link_only: | |
195 logger.error("Couldn't symlink the theme: %s" % ex) | |
196 return 1 | |
197 | |
198 # pre-Vista Windows, or unprivileged user... gotta copy the | |
199 # theme the old fashioned way. | |
200 logging.warning("Can't create a symbolic link... copying the " | |
201 "theme directory instead.") | |
202 ignore = shutil.ignore_patterns('.git*', '.hg*', '.svn', '.bzr') | |
203 shutil.copytree(ctx.args.theme_dir, theme_dir, ignore=ignore) | |
204 | |
205 def _deactivateTheme(self, ctx): | |
206 theme_dir = os.path.join(ctx.app.root_dir, THEME_DIR) | |
207 | |
208 if os.path.islink(theme_dir): | |
209 logger.debug("Unlinking: %s" % theme_dir) | |
210 os.unlink(theme_dir) | |
211 elif os.path.isdir(theme_dir): | |
212 logger.warning("The active theme is local. Are you sure you want " | |
213 "to delete the theme directory? [Y/n]") | |
214 ans = input() | |
215 if len(ans) > 0 and ans.lower() not in ['y', 'yes']: | |
216 return 1 | |
217 | |
218 shutil.rmtree(theme_dir) | |
219 else: | |
220 logger.info("No currently active theme.") | |
221 |