33import os
44import os .path
55from glob import glob
6+ from typing import Iterable
67
7- import click
88import importlib_resources
99from tutor import config as tutor_config
1010from tutor import hooks
1111from tutormfe .hooks import MFE_APPS
12+ from tutormfe .plugin import CORE_MFE_APPS
1213
1314
1415from .__about__ import __version__
2324def validate_mfe_config (mfe_setting_name : str ):
2425 if mfe_setting_name .startswith ("MFE_" ) and mfe_setting_name .endswith ("_MFE_APP" ):
2526 return (
26- mfe_setting_name
27- .replace ("_MFE_APP" , "" )
27+ mfe_setting_name .replace ("_MFE_APP" , "" )
2828 .replace ("MFE_" , "" )
2929 .replace ("_" , "-" )
3030 .lower ()
3131 )
3232 return None
3333
34+
3435@MFE_APPS .add ()
3536def _manage_mfes_from_config (mfe_list ):
36- config = tutor_config .load ('.' )
37+ config = tutor_config .load ("." )
3738 for setting , value in config .items ():
3839 mfe_name = validate_mfe_config (setting )
3940 if not mfe_name :
@@ -54,6 +55,7 @@ def _manage_mfes_from_config(mfe_list):
5455
5556 return mfe_list
5657
58+
5759hooks .Filters .CONFIG_DEFAULTS .add_items (
5860 [
5961 # Add your new settings that have default values here.
@@ -65,104 +67,22 @@ def _manage_mfes_from_config(mfe_list):
6567 ]
6668)
6769
68- hooks .Filters .CONFIG_UNIQUE .add_items (
69- [
70- # Add settings that don't have a reasonable default for all users here.
71- # For instance: passwords, secret keys, etc.
72- # Each new setting is a pair: (setting_name, unique_generated_value).
73- # Prefix your setting names with 'MFE_EXTENSIONS_'.
74- # For example:
75- ### ("MFE_EXTENSIONS_SECRET_KEY", "{{ 24|random_string }}"),
76- ]
77- )
7870
79- hooks .Filters .CONFIG_OVERRIDES .add_items (
80- [
81- # Danger zone!
82- # Add values to override settings from Tutor core or other plugins here.
83- # Each override is a pair: (setting_name, new_value). For example:
84- (k ,v ) for k ,v in CORE_MFES_CONFIG .items ()
85- ]
86- )
71+ def iter_mfes_per_service (service : str = "" ) -> Iterable [str ]:
72+ """
73+ Return the list of MFEs that should be hosted via path in the
74+ same domain as each service.
8775
88- ########################################
89- # INITIALIZATION TASKS
90- ########################################
76+ """
77+ active_mfes = MFE_APPS .apply ({})
78+ cms_mfes = {"course-authoring" }
79+ lms_mfes = set (CORE_MFE_APPS ) - cms_mfes
9180
92- # To add a custom initialization task, create a bash script template under:
93- # tutormfe_extensions/templates/mfe_extensions/jobs/init/
94- # and then add it to the MY_INIT_TASKS list. Each task is in the format:
95- # ("<service>", ("<path>", "<to>", "<script>", "<template>"))
96- MY_INIT_TASKS : list [tuple [str , tuple [str , ...]]] = [
97- # For example, to add LMS initialization steps, you could add the script template at:
98- # tutormfe_extensions/templates/mfe_extensions/jobs/init/lms.sh
99- # And then add the line:
100- ### ("lms", ("mfe_extensions", "jobs", "init", "lms.sh")),
101- ]
102-
103-
104- # For each task added to MY_INIT_TASKS, we load the task template
105- # and add it to the CLI_DO_INIT_TASKS filter, which tells Tutor to
106- # run it as part of the `init` job.
107- for service , template_path in MY_INIT_TASKS :
108- full_path : str = str (
109- importlib_resources .files ("tutormfe_extensions" )
110- / os .path .join ("templates" , * template_path )
111- )
112- with open (full_path , encoding = "utf-8" ) as init_task_file :
113- init_task : str = init_task_file .read ()
114- hooks .Filters .CLI_DO_INIT_TASKS .add_item ((service , init_task ))
115-
116-
117- ########################################
118- # DOCKER IMAGE MANAGEMENT
119- ########################################
120-
121-
122- # Images to be built by `tutor images build`.
123- # Each item is a quadruple in the form:
124- # ("<tutor_image_name>", ("path", "to", "build", "dir"), "<docker_image_tag>", "<build_args>")
125- hooks .Filters .IMAGES_BUILD .add_items (
126- [
127- # To build `myimage` with `tutor images build myimage`,
128- # you would add a Dockerfile to templates/mfe_extensions/build/myimage,
129- # and then write:
130- ### (
131- ### "myimage",
132- ### ("plugins", "mfe_extensions", "build", "myimage"),
133- ### "docker.io/myimage:{{ MFE_EXTENSIONS_VERSION }}",
134- ### (),
135- ### ),
136- ]
137- )
138-
139-
140- # Images to be pulled as part of `tutor images pull`.
141- # Each item is a pair in the form:
142- # ("<tutor_image_name>", "<docker_image_tag>")
143- hooks .Filters .IMAGES_PULL .add_items (
144- [
145- # To pull `myimage` with `tutor images pull myimage`, you would write:
146- ### (
147- ### "myimage",
148- ### "docker.io/myimage:{{ MFE_EXTENSIONS_VERSION }}",
149- ### ),
150- ]
151- )
152-
153-
154- # Images to be pushed as part of `tutor images push`.
155- # Each item is a pair in the form:
156- # ("<tutor_image_name>", "<docker_image_tag>")
157- hooks .Filters .IMAGES_PUSH .add_items (
158- [
159- # To push `myimage` with `tutor images push myimage`, you would write:
160- ### (
161- ### "myimage",
162- ### "docker.io/myimage:{{ MFE_EXTENSIONS_VERSION }}",
163- ### ),
164- ]
165- )
81+ for mfe in active_mfes :
82+ if service == "lms" and mfe in lms_mfes :
83+ yield mfe
84+ if service == "cms" and mfe in cms_mfes :
85+ yield mfe
16686
16787
16888########################################
@@ -191,6 +111,12 @@ def _manage_mfes_from_config(mfe_list):
191111 ],
192112)
193113
114+ # Make the mfe_extensions functions available within templates
115+ hooks .Filters .ENV_TEMPLATE_VARIABLES .add_items (
116+ [
117+ ("iter_mfes_per_service" , iter_mfes_per_service ),
118+ ],
119+ )
194120
195121########################################
196122# PATCH LOADING
@@ -208,69 +134,3 @@ def _manage_mfes_from_config(mfe_list):
208134):
209135 with open (path , encoding = "utf-8" ) as patch_file :
210136 hooks .Filters .ENV_PATCHES .add_item ((os .path .basename (path ), patch_file .read ()))
211-
212-
213- ########################################
214- # CUSTOM JOBS (a.k.a. "do-commands")
215- ########################################
216-
217- # A job is a set of tasks, each of which run inside a certain container.
218- # Jobs are invoked using the `do` command, for example: `tutor local do importdemocourse`.
219- # A few jobs are built in to Tutor, such as `init` and `createuser`.
220- # You can also add your own custom jobs:
221-
222- # To add a custom job, define a Click command that returns a list of tasks,
223- # where each task is a pair in the form ("<service>", "<shell_command>").
224- # For example:
225- ### @click.command()
226- ### @click.option("-n", "--name", default="plugin developer")
227- ### def say_hi(name: str) -> list[tuple[str, str]]:
228- ### """
229- ### An example job that just prints 'hello' from within both LMS and CMS.
230- ### """
231- ### return [
232- ### ("lms", f"echo 'Hello from LMS, {name}!'"),
233- ### ("cms", f"echo 'Hello from CMS, {name}!'"),
234- ### ]
235-
236-
237- # Then, add the command function to CLI_DO_COMMANDS:
238- ## hooks.Filters.CLI_DO_COMMANDS.add_item(say_hi)
239-
240- # Now, you can run your job like this:
241- # $ tutor local do say-hi --name="Moisés González"
242-
243-
244- #######################################
245- # CUSTOM CLI COMMANDS
246- #######################################
247-
248- # Your plugin can also add custom commands directly to the Tutor CLI.
249- # These commands are run directly on the user's host computer
250- # (unlike jobs, which are run in containers).
251-
252- # To define a command group for your plugin, you would define a Click
253- # group and then add it to CLI_COMMANDS:
254-
255-
256- ### @click.group()
257- ### def mfe_extensions() -> None:
258- ### pass
259-
260-
261- ### hooks.Filters.CLI_COMMANDS.add_item(mfe_extensions)
262-
263-
264- # Then, you would add subcommands directly to the Click group, for example:
265-
266-
267- ### @mfe_extensions.command()
268- ### def example_command() -> None:
269- ### """
270- ### This is helptext for an example command.
271- ### """
272- ### print("You've run an example command.")
273-
274-
275- # This would allow you to run:
276- # $ tutor mfe_extensions example-command
0 commit comments