|
4 | 4 | import click |
5 | 5 | import importlib_resources |
6 | 6 | from tutor import hooks |
| 7 | +from tutor import config as tutor_config |
7 | 8 |
|
8 | 9 | from .__about__ import __version__ |
9 | 10 |
|
|
13 | 14 |
|
14 | 15 | hooks.Filters.CONFIG_DEFAULTS.add_items( |
15 | 16 | [ |
16 | | - # Add your new settings that have default values here. |
17 | | - # Each new setting is a pair: (setting_name, default_value). |
18 | | - # Prefix your setting names with 'PARAGON_'. |
| 17 | + # Plugin version (used for compatibility or debugging) |
19 | 18 | ("PARAGON_VERSION", __version__), |
| 19 | + # Directory where users will place style-dictionary source files |
| 20 | + # Each subfolder inside will represent a theme (e.g., "theme-abc/") |
| 21 | + ("PARAGON_THEME_SOURCES_PATH", "env/plugins/paragon/theme-sources"), |
| 22 | + # Directory where compiled CSS themes will be stored after transformation |
| 23 | + # One subfolder per compiled theme (e.g., "theme-abc/core.min.css") |
| 24 | + ("PARAGON_COMPILED_THEMES_PATH", "env/plugins/paragon/compiled-themes"), |
| 25 | + # List of enabled themes to compile and serve |
| 26 | + # Only themes listed here will be processed, even if others exist in sources |
| 27 | + ("PARAGON_ENABLED_THEMES", []), |
| 28 | + # Whether Tutor should expose the compiled themes to be served (e.g. via nginx, cady or static server) |
| 29 | + ("PARAGON_SERVE_COMPILED_THEMES", True), |
20 | 30 | ] |
21 | 31 | ) |
22 | 32 |
|
23 | | -hooks.Filters.CONFIG_UNIQUE.add_items( |
24 | | - [ |
25 | | - # Add settings that don't have a reasonable default for all users here. |
26 | | - # For instance: passwords, secret keys, etc. |
27 | | - # Each new setting is a pair: (setting_name, unique_generated_value). |
28 | | - # Prefix your setting names with 'PARAGON_'. |
29 | | - # For example: |
30 | | - ### ("PARAGON_SECRET_KEY", "{{ 24|random_string }}"), |
31 | | - ] |
32 | | -) |
33 | | - |
34 | | -hooks.Filters.CONFIG_OVERRIDES.add_items( |
35 | | - [ |
36 | | - # Danger zone! |
37 | | - # Add values to override settings from Tutor core or other plugins here. |
38 | | - # Each override is a pair: (setting_name, new_value). For example: |
39 | | - ### ("PLATFORM_NAME", "My platform"), |
40 | | - ] |
41 | | -) |
42 | 33 |
|
| 34 | +# Create directories for build and host |
| 35 | +@hooks.Actions.PROJECT_ROOT_READY.add() |
| 36 | +def create_paragon_folders(project_root: str) -> None: |
| 37 | + config = tutor_config.load(project_root) |
43 | 38 |
|
44 | | -######################################## |
45 | | -# INITIALIZATION TASKS |
46 | | -######################################## |
47 | | - |
48 | | -# To add a custom initialization task, create a bash script template under: |
49 | | -# tutorparagon/templates/paragon/tasks/ |
50 | | -# and then add it to the MY_INIT_TASKS list. Each task is in the format: |
51 | | -# ("<service>", ("<path>", "<to>", "<script>", "<template>")) |
52 | | -MY_INIT_TASKS: list[tuple[str, tuple[str, ...]]] = [ |
53 | | - # For example, to add LMS initialization steps, you could add the script template at: |
54 | | - # tutorparagon/templates/paragon/tasks/lms/init.sh |
55 | | - # And then add the line: |
56 | | - ### ("lms", ("paragon", "tasks", "lms", "init.sh")), |
57 | | -] |
58 | | - |
59 | | - |
60 | | -# For each task added to MY_INIT_TASKS, we load the task template |
61 | | -# and add it to the CLI_DO_INIT_TASKS filter, which tells Tutor to |
62 | | -# run it as part of the `init` job. |
63 | | -for service, template_path in MY_INIT_TASKS: |
64 | | - full_path: str = str( |
65 | | - importlib_resources.files("tutorparagon") |
66 | | - / os.path.join("templates", *template_path) |
| 39 | + # Paths from config (always have defaults) |
| 40 | + theme_sources_path = os.path.join( |
| 41 | + project_root, str(config["PARAGON_THEME_SOURCES_PATH"]) |
| 42 | + ) |
| 43 | + compiled_themes_path = os.path.join( |
| 44 | + project_root, str(config["PARAGON_COMPILED_THEMES_PATH"]) |
67 | 45 | ) |
68 | | - with open(full_path, encoding="utf-8") as init_task_file: |
69 | | - init_task: str = init_task_file.read() |
70 | | - hooks.Filters.CLI_DO_INIT_TASKS.add_item((service, init_task)) |
71 | | - |
72 | | - |
73 | | -######################################## |
74 | | -# DOCKER IMAGE MANAGEMENT |
75 | | -######################################## |
76 | | - |
77 | | - |
78 | | -# Images to be built by `tutor images build`. |
79 | | -# Each item is a quadruple in the form: |
80 | | -# ("<tutor_image_name>", ("path", "to", "build", "dir"), "<docker_image_tag>", "<build_args>") |
81 | | -hooks.Filters.IMAGES_BUILD.add_items( |
82 | | - [ |
83 | | - # To build `myimage` with `tutor images build myimage`, |
84 | | - # you would add a Dockerfile to templates/paragon/build/myimage, |
85 | | - # and then write: |
86 | | - ### ( |
87 | | - ### "myimage", |
88 | | - ### ("plugins", "paragon", "build", "myimage"), |
89 | | - ### "docker.io/myimage:{{ PARAGON_VERSION }}", |
90 | | - ### (), |
91 | | - ### ), |
92 | | - ] |
93 | | -) |
94 | 46 |
|
95 | | - |
96 | | -# Images to be pulled as part of `tutor images pull`. |
97 | | -# Each item is a pair in the form: |
98 | | -# ("<tutor_image_name>", "<docker_image_tag>") |
99 | | -hooks.Filters.IMAGES_PULL.add_items( |
100 | | - [ |
101 | | - # To pull `myimage` with `tutor images pull myimage`, you would write: |
102 | | - ### ( |
103 | | - ### "myimage", |
104 | | - ### "docker.io/myimage:{{ PARAGON_VERSION }}", |
105 | | - ### ), |
106 | | - ] |
107 | | -) |
108 | | - |
109 | | - |
110 | | -# Images to be pushed as part of `tutor images push`. |
111 | | -# Each item is a pair in the form: |
112 | | -# ("<tutor_image_name>", "<docker_image_tag>") |
113 | | -hooks.Filters.IMAGES_PUSH.add_items( |
114 | | - [ |
115 | | - # To push `myimage` with `tutor images push myimage`, you would write: |
116 | | - ### ( |
117 | | - ### "myimage", |
118 | | - ### "docker.io/myimage:{{ PARAGON_VERSION }}", |
119 | | - ### ), |
120 | | - ] |
121 | | -) |
| 47 | + for path, label in [ |
| 48 | + (theme_sources_path, "Theme Shources"), |
| 49 | + (compiled_themes_path, "Compiled Themes"), |
| 50 | + ]: |
| 51 | + if os.path.exists(path): |
| 52 | + print(f"[paragon] {label} folder already exists at: {path}") |
| 53 | + else: |
| 54 | + os.makedirs(path, exist_ok=True) |
| 55 | + print(f"[paragon] Created {label} folder at: {path}") |
122 | 56 |
|
123 | 57 |
|
124 | 58 | ######################################## |
|
158 | 92 | for path in glob(str(importlib_resources.files("tutorparagon") / "patches" / "*")): |
159 | 93 | with open(path, encoding="utf-8") as patch_file: |
160 | 94 | hooks.Filters.ENV_PATCHES.add_item((os.path.basename(path), patch_file.read())) |
161 | | - |
162 | | - |
163 | | -######################################## |
164 | | -# CUSTOM JOBS (a.k.a. "do-commands") |
165 | | -######################################## |
166 | | - |
167 | | -# A job is a set of tasks, each of which run inside a certain container. |
168 | | -# Jobs are invoked using the `do` command, for example: `tutor local do importdemocourse`. |
169 | | -# A few jobs are built in to Tutor, such as `init` and `createuser`. |
170 | | -# You can also add your own custom jobs: |
171 | | - |
172 | | - |
173 | | -# To add a custom job, define a Click command that returns a list of tasks, |
174 | | -# where each task is a pair in the form ("<service>", "<shell_command>"). |
175 | | -# For example: |
176 | | -### @click.command() |
177 | | -### @click.option("-n", "--name", default="plugin developer") |
178 | | -### def say_hi(name: str) -> list[tuple[str, str]]: |
179 | | -### """ |
180 | | -### An example job that just prints 'hello' from within both LMS and CMS. |
181 | | -### """ |
182 | | -### return [ |
183 | | -### ("lms", f"echo 'Hello from LMS, {name}!'"), |
184 | | -### ("cms", f"echo 'Hello from CMS, {name}!'"), |
185 | | -### ] |
186 | | - |
187 | | - |
188 | | -# Then, add the command function to CLI_DO_COMMANDS: |
189 | | -## hooks.Filters.CLI_DO_COMMANDS.add_item(say_hi) |
190 | | - |
191 | | -# Now, you can run your job like this: |
192 | | -# $ tutor local do say-hi --name="Alejandro Cardenas" |
193 | | - |
194 | | - |
195 | | -####################################### |
196 | | -# CUSTOM CLI COMMANDS |
197 | | -####################################### |
198 | | - |
199 | | -# Your plugin can also add custom commands directly to the Tutor CLI. |
200 | | -# These commands are run directly on the user's host computer |
201 | | -# (unlike jobs, which are run in containers). |
202 | | - |
203 | | -# To define a command group for your plugin, you would define a Click |
204 | | -# group and then add it to CLI_COMMANDS: |
205 | | - |
206 | | - |
207 | | -### @click.group() |
208 | | -### def paragon() -> None: |
209 | | -### pass |
210 | | - |
211 | | - |
212 | | -### hooks.Filters.CLI_COMMANDS.add_item(paragon) |
213 | | - |
214 | | - |
215 | | -# Then, you would add subcommands directly to the Click group, for example: |
216 | | - |
217 | | - |
218 | | -### @paragon.command() |
219 | | -### def example_command() -> None: |
220 | | -### """ |
221 | | -### This is helptext for an example command. |
222 | | -### """ |
223 | | -### print("You've run an example command.") |
224 | | - |
225 | | - |
226 | | -# This would allow you to run: |
227 | | -# $ tutor paragon example-command |
0 commit comments