-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 79e39a1
Showing
14 changed files
with
1,046 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
name: Run tests | ||
|
||
on: | ||
pull_request: | ||
branches: [master] | ||
|
||
jobs: | ||
tests: | ||
runs-on: ubuntu-latest | ||
strategy: | ||
matrix: | ||
python-version: ['3.8', '3.12'] | ||
steps: | ||
- uses: actions/checkout@v3 | ||
- name: Set up Python ${{ matrix.python-version }} | ||
uses: actions/setup-python@v5 | ||
with: | ||
python-version: ${{ matrix.python-version }} | ||
- name: Upgrade pip | ||
run: python -m pip install --upgrade pip | ||
- name: Install dependencies | ||
run: | | ||
pip install .[dev] | ||
- name: Test lint, types, and format | ||
run: make test |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
.*.swp | ||
!.gitignore | ||
TODO | ||
__pycache__ | ||
*.egg-info/ | ||
/build/ | ||
/dist/ |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
recursive-include tutorpicasso/patches * | ||
recursive-include tutorpicasso/templates * |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
.DEFAULT_GOAL := help | ||
.PHONY: docs | ||
SRC_DIRS = ./tutorpicasso | ||
BLACK_OPTS = --exclude templates ${SRC_DIRS} | ||
|
||
# Warning: These checks are not necessarily run on every PR. | ||
test: test-lint test-types test-format # Run some static checks. | ||
|
||
test-format: ## Run code formatting tests | ||
black --check --diff $(BLACK_OPTS) | ||
|
||
test-lint: ## Run code linting tests | ||
pylint --errors-only --enable=unused-import,unused-argument --ignore=templates --ignore=docs/_ext ${SRC_DIRS} | ||
|
||
test-types: ## Run type checks. | ||
mypy --exclude=templates --ignore-missing-imports --implicit-reexport --strict ${SRC_DIRS} | ||
|
||
format: ## Format code automatically | ||
black $(BLACK_OPTS) | ||
|
||
isort: ## Sort imports. This target is not mandatory because the output may be incompatible with black formatting. Provided for convenience purposes. | ||
isort --skip=templates ${SRC_DIRS} | ||
|
||
ESCAPE = | ||
help: ## Print this help | ||
@grep -E '^([a-zA-Z_-]+:.*?## .*|######* .+)$$' Makefile \ | ||
| sed 's/######* \(.*\)/@ $(ESCAPE)[1;31m\1$(ESCAPE)[0m/g' | tr '@' '\n' \ | ||
| awk 'BEGIN {FS = ":.*?## "}; {printf "\033[33m%-30s\033[0m %s\n", $$1, $$2}' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
picasso plugin for `Tutor <https://docs.tutor.edly.io>`__ | ||
######################################################### | ||
|
||
picasso plugin for Tutor | ||
|
||
|
||
Installation | ||
************ | ||
|
||
.. code-block:: bash | ||
pip install git+https://github.com/eduNEXT/tutor-contrib-picasso | ||
Usage | ||
***** | ||
|
||
.. code-block:: bash | ||
tutor plugins enable picasso | ||
License | ||
******* | ||
|
||
This software is licensed under the terms of the AGPLv3. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import io | ||
import os | ||
|
||
from setuptools import find_packages, setup | ||
|
||
HERE = os.path.abspath(os.path.dirname(__file__)) | ||
|
||
|
||
def load_readme(): | ||
with io.open(os.path.join(HERE, "README.rst"), "rt", encoding="utf8") as f: | ||
return f.read() | ||
|
||
|
||
def load_about(): | ||
about = {} | ||
with io.open( | ||
os.path.join(HERE, "tutorpicasso", "__about__.py"), | ||
"rt", | ||
encoding="utf-8", | ||
) as f: | ||
exec(f.read(), about) # pylint: disable=exec-used | ||
return about | ||
|
||
|
||
ABOUT = load_about() | ||
|
||
|
||
setup( | ||
name="tutor-contrib-picasso", | ||
version=ABOUT["__version__"], | ||
url="https://github.com/eduNEXT/tutor-contrib-picasso", | ||
project_urls={ | ||
"Code": "https://github.com/eduNEXT/tutor-contrib-picasso", | ||
"Issue tracker": "https://github.com/eduNEXT/tutor-contrib-picasso/issues", | ||
}, | ||
license="AGPLv3", | ||
author="eduNEXT", | ||
description="Picasso plugin for Tutor", | ||
long_description=load_readme(), | ||
long_description_content_type="text/x-rst", | ||
packages=find_packages(exclude=["tests*"]), | ||
include_package_data=True, | ||
python_requires=">=3.8", | ||
install_requires=["tutor>=18.0.0,<19.0.0"], | ||
extras_require={ | ||
"dev": [ | ||
"tutor[dev]>=18.0.0,<19.0.0", | ||
] | ||
}, | ||
entry_points={ | ||
"tutor.plugin.v1": [ | ||
"picasso = tutorpicasso.plugin" | ||
] | ||
}, | ||
classifiers=[ | ||
"Development Status :: 3 - Alpha", | ||
"Intended Audience :: Developers", | ||
"License :: OSI Approved :: GNU Affero General Public License v3", | ||
"Operating System :: OS Independent", | ||
"Programming Language :: Python", | ||
"Programming Language :: Python :: 3.8", | ||
"Programming Language :: Python :: 3.9", | ||
"Programming Language :: Python :: 3.10", | ||
"Programming Language :: Python :: 3.11", | ||
"Programming Language :: Python :: 3.12", | ||
], | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
__version__ = "18.0.0" |
Empty file.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,229 @@ | ||
from __future__ import annotations | ||
|
||
import os | ||
from glob import glob | ||
|
||
import click | ||
import importlib_resources | ||
from tutor import hooks | ||
|
||
from .__about__ import __version__ | ||
|
||
######################################## | ||
# CONFIGURATION | ||
######################################## | ||
|
||
hooks.Filters.CONFIG_DEFAULTS.add_items( | ||
[ | ||
# Add your new settings that have default values here. | ||
# Each new setting is a pair: (setting_name, default_value). | ||
# Prefix your setting names with 'PICASSO_'. | ||
("PICASSO_VERSION", __version__), | ||
] | ||
) | ||
|
||
hooks.Filters.CONFIG_UNIQUE.add_items( | ||
[ | ||
# Add settings that don't have a reasonable default for all users here. | ||
# For instance: passwords, secret keys, etc. | ||
# Each new setting is a pair: (setting_name, unique_generated_value). | ||
# Prefix your setting names with 'PICASSO_'. | ||
# For example: | ||
### ("PICASSO_SECRET_KEY", "{{ 24|random_string }}"), | ||
] | ||
) | ||
|
||
hooks.Filters.CONFIG_OVERRIDES.add_items( | ||
[ | ||
# Danger zone! | ||
# Add values to override settings from Tutor core or other plugins here. | ||
# Each override is a pair: (setting_name, new_value). For example: | ||
### ("PLATFORM_NAME", "My platform"), | ||
] | ||
) | ||
|
||
|
||
######################################## | ||
# INITIALIZATION TASKS | ||
######################################## | ||
|
||
# To add a custom initialization task, create a bash script template under: | ||
# tutorpicasso/templates/picasso/tasks/ | ||
# and then add it to the MY_INIT_TASKS list. Each task is in the format: | ||
# ("<service>", ("<path>", "<to>", "<script>", "<template>")) | ||
MY_INIT_TASKS: list[tuple[str, tuple[str, ...]]] = [ | ||
# For example, to add LMS initialization steps, you could add the script template at: | ||
# tutorpicasso/templates/picasso/tasks/lms/init.sh | ||
# And then add the line: | ||
### ("lms", ("picasso", "tasks", "lms", "init.sh")), | ||
] | ||
|
||
|
||
# For each task added to MY_INIT_TASKS, we load the task template | ||
# and add it to the CLI_DO_INIT_TASKS filter, which tells Tutor to | ||
# run it as part of the `init` job. | ||
for service, template_path in MY_INIT_TASKS: | ||
full_path: str = str( | ||
importlib_resources.files("tutorpicasso") | ||
/ os.path.join("templates", *template_path) | ||
) | ||
with open(full_path, encoding="utf-8") as init_task_file: | ||
init_task: str = init_task_file.read() | ||
hooks.Filters.CLI_DO_INIT_TASKS.add_item((service, init_task)) | ||
|
||
|
||
######################################## | ||
# DOCKER IMAGE MANAGEMENT | ||
######################################## | ||
|
||
|
||
# Images to be built by `tutor images build`. | ||
# Each item is a quadruple in the form: | ||
# ("<tutor_image_name>", ("path", "to", "build", "dir"), "<docker_image_tag>", "<build_args>") | ||
hooks.Filters.IMAGES_BUILD.add_items( | ||
[ | ||
# To build `myimage` with `tutor images build myimage`, | ||
# you would add a Dockerfile to templates/picasso/build/myimage, | ||
# and then write: | ||
### ( | ||
### "myimage", | ||
### ("plugins", "picasso", "build", "myimage"), | ||
### "docker.io/myimage:{{ PICASSO_VERSION }}", | ||
### (), | ||
### ), | ||
] | ||
) | ||
|
||
|
||
# Images to be pulled as part of `tutor images pull`. | ||
# Each item is a pair in the form: | ||
# ("<tutor_image_name>", "<docker_image_tag>") | ||
hooks.Filters.IMAGES_PULL.add_items( | ||
[ | ||
# To pull `myimage` with `tutor images pull myimage`, you would write: | ||
### ( | ||
### "myimage", | ||
### "docker.io/myimage:{{ PICASSO_VERSION }}", | ||
### ), | ||
] | ||
) | ||
|
||
|
||
# Images to be pushed as part of `tutor images push`. | ||
# Each item is a pair in the form: | ||
# ("<tutor_image_name>", "<docker_image_tag>") | ||
hooks.Filters.IMAGES_PUSH.add_items( | ||
[ | ||
# To push `myimage` with `tutor images push myimage`, you would write: | ||
### ( | ||
### "myimage", | ||
### "docker.io/myimage:{{ PICASSO_VERSION }}", | ||
### ), | ||
] | ||
) | ||
|
||
|
||
######################################## | ||
# TEMPLATE RENDERING | ||
# (It is safe & recommended to leave | ||
# this section as-is :) | ||
######################################## | ||
|
||
hooks.Filters.ENV_TEMPLATE_ROOTS.add_items( | ||
# Root paths for template files, relative to the project root. | ||
[ | ||
str(importlib_resources.files("tutorpicasso") / "templates"), | ||
] | ||
) | ||
|
||
hooks.Filters.ENV_TEMPLATE_TARGETS.add_items( | ||
# For each pair (source_path, destination_path): | ||
# templates at ``source_path`` (relative to your ENV_TEMPLATE_ROOTS) will be | ||
# rendered to ``source_path/destination_path`` (relative to your Tutor environment). | ||
# For example, ``tutorpicasso/templates/picasso/build`` | ||
# will be rendered to ``$(tutor config printroot)/env/plugins/picasso/build``. | ||
[ | ||
("picasso/build", "plugins"), | ||
("picasso/apps", "plugins"), | ||
], | ||
) | ||
|
||
|
||
######################################## | ||
# PATCH LOADING | ||
# (It is safe & recommended to leave | ||
# this section as-is :) | ||
######################################## | ||
|
||
# For each file in tutorpicasso/patches, | ||
# apply a patch based on the file's name and contents. | ||
for path in glob(str(importlib_resources.files("tutorpicasso") / "patches" / "*")): | ||
with open(path, encoding="utf-8") as patch_file: | ||
hooks.Filters.ENV_PATCHES.add_item((os.path.basename(path), patch_file.read())) | ||
|
||
|
||
######################################## | ||
# CUSTOM JOBS (a.k.a. "do-commands") | ||
######################################## | ||
|
||
# A job is a set of tasks, each of which run inside a certain container. | ||
# Jobs are invoked using the `do` command, for example: `tutor local do importdemocourse`. | ||
# A few jobs are built in to Tutor, such as `init` and `createuser`. | ||
# You can also add your own custom jobs: | ||
|
||
|
||
# To add a custom job, define a Click command that returns a list of tasks, | ||
# where each task is a pair in the form ("<service>", "<shell_command>"). | ||
# For example: | ||
### @click.command() | ||
### @click.option("-n", "--name", default="plugin developer") | ||
### def say_hi(name: str) -> list[tuple[str, str]]: | ||
### """ | ||
### An example job that just prints 'hello' from within both LMS and CMS. | ||
### """ | ||
### return [ | ||
### ("lms", f"echo 'Hello from LMS, {name}!'"), | ||
### ("cms", f"echo 'Hello from CMS, {name}!'"), | ||
### ] | ||
|
||
|
||
# Then, add the command function to CLI_DO_COMMANDS: | ||
## hooks.Filters.CLI_DO_COMMANDS.add_item(say_hi) | ||
|
||
# Now, you can run your job like this: | ||
# $ tutor local do say-hi --name="eduNEXT" | ||
|
||
|
||
####################################### | ||
# CUSTOM CLI COMMANDS | ||
####################################### | ||
|
||
# Your plugin can also add custom commands directly to the Tutor CLI. | ||
# These commands are run directly on the user's host computer | ||
# (unlike jobs, which are run in containers). | ||
|
||
# To define a command group for your plugin, you would define a Click | ||
# group and then add it to CLI_COMMANDS: | ||
|
||
|
||
### @click.group() | ||
### def picasso() -> None: | ||
### pass | ||
|
||
|
||
### hooks.Filters.CLI_COMMANDS.add_item(picasso) | ||
|
||
|
||
# Then, you would add subcommands directly to the Click group, for example: | ||
|
||
|
||
### @picasso.command() | ||
### def example_command() -> None: | ||
### """ | ||
### This is helptext for an example command. | ||
### """ | ||
### print("You've run an example command.") | ||
|
||
|
||
# This would allow you to run: | ||
# $ tutor picasso example-command |
Empty file.
Empty file.
Empty file.