Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ jobs:
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install sass
run: npm install -g sass
- name: Install dependencies
run: |
pip install .[dev]
Expand Down
2 changes: 1 addition & 1 deletion .hatch_build.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,5 @@ def load_about() -> dict[str, str]:
with open(
os.path.join(HERE, "tutordeck", "__about__.py"), "rt", encoding="utf-8"
) as f:
exec(f.read(), about) # pylint: disable=exec-used
exec(f.read(), about)
return about
22 changes: 15 additions & 7 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
.DEFAULT_GOAL := help
.PHONY: docs
SRC_DIRS = ./tutordeck
BLACK_OPTS = --exclude templates ${SRC_DIRS}

runserver: ## Run a development server
tutor deck runserver --dev
Expand All @@ -13,29 +12,38 @@ scss-watch: ## Compile SCSS files to CSS and watch for changes
$(MAKE) scss SASS_OPTS="--watch"

# Warning: These checks are not necessarily run on every PR.
test: test-lint test-types test-format # Run some static checks.
test: test-lint test-types test-format test-pythonpackage # Run some static checks.

test-format: ## Run code formatting tests
black --check --diff $(BLACK_OPTS)
ruff format --check --diff ${SRC_DIRS}

test-lint: ## Run code linting tests
pylint --errors-only --enable=unused-import,unused-argument --ignore=templates --ignore=docs/_ext ${SRC_DIRS}
ruff check ${SRC_DIRS}

test-types: ## Run type checks.
mypy --exclude=templates --ignore-missing-imports --implicit-reexport --strict ${SRC_DIRS}

build-pythonpackage: ## Build the "tutor-deck" python package for upload to pypi
python -m build --sdist

test-pythonpackage: build-pythonpackage ## Test that package can be uploaded to pypi
twine check dist/tutor_deck-$(shell make version).tar.gz

format: ## Format code automatically
black $(BLACK_OPTS)
ruff format ${SRC_DIRS}

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}
fix-lint: ## Fix lint errors automatically
ruff check --fix ${SRC_DIRS}

changelog-entry: ## Create a new changelog entry.
scriv create

changelog: ## Collect changelog entries in the CHANGELOG.md file.
scriv collect

version: ## Print the current tutor-deck version
@python -c 'import io, os; about = {}; exec(io.open(os.path.join("tutordeck", "__about__.py"), "rt", encoding="utf-8").read(), about); print(about["__version__"])'

ESCAPE = 
help: ## Print this help
@grep -E '^([a-zA-Z_-]+:.*?## .*|######* .+)$$' Makefile \
Expand Down
2 changes: 2 additions & 0 deletions changelog.d/20250808_150533_muhammad.labeeb_release.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- [Improvement] Migrate from pylint and black to ruff. (by @mlabeeb03)
- [Improvement] Test python package distribution build when running make test. (by @mlabeeb03)
19 changes: 17 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,7 @@ dev = [
"tutor[dev]>=20.0.0,<21.0.0",
"types-aiofiles",
"types-Markdown",
"pylint",
"black",
"ruff",
]

[project.entry-points."tutor.plugin.v1"]
Expand Down Expand Up @@ -75,3 +74,19 @@ path = ".hatch_build.py"

[tool.hatch.build.targets.wheel]
packages = ["tutordeck"]

[tool.ruff]
exclude = ["templates", "docs/_ext"]

[tool.ruff.lint]
# E: pycodestyle errors
# I: isort
# N: pep8-naming
select = ["E", "I", "N"]

# F401: unused-import
# F841: unused-variable
# W292: missing-newline-at-end-of-file
extend-select = ["F401", "F841", "W292"]

[tool.ruff.format]
Comment thread
mlabeeb03 marked this conversation as resolved.
14 changes: 7 additions & 7 deletions tutordeck/server/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,13 @@
url_for,
)
from quart.typing import ResponseTypes
from werkzeug.sansio.response import Response as BaseResponse
from tutor.plugins.v1 import discover_package
from werkzeug.sansio.response import Response as BaseResponse

from tutordeck.server.utils import current_page_plugins, pagination_context

from . import constants, tutorclient


app = Quart(
__name__,
static_url_path="/static",
Expand Down Expand Up @@ -372,8 +371,9 @@ async def process_config_update_request() -> None:
cmd = ["config", "save"]
for key, value in form.items():
if value.startswith("{{"):
# Templated values that start with {{ should be explicitely converted to string
# Otherwise there will be a parsing error because it might be considered a dictionary
# Templated values that start with {{ should be explicitely
# converted to string otherwise there will be a parsing
# error because it might be considered a dictionary
value = f"'{value}'"
cmd.extend(["--set", f"{key}={value}"])
tutorclient.CliPool.run_sequential(cmd)
Expand Down Expand Up @@ -489,9 +489,9 @@ def update_plugins_requiring_launch(
response: Response, add: t.Optional[str] = None, remove: t.Optional[str] = None
) -> None:
"""
Store the list of plugins for which a recent set of changes require running "local launch".

This list is stored as a "+"-separated string in a cookie. Note that flask will automatically put the content in quotes.
Store the list of plugins for which a recent set of changes require
running "local launch". This list is stored as a "+"-separated string
in a cookie. Note that flask will automatically put the content in quotes.
"""
# Note that comma, colon and semi-colon are not supported in cookie values
separator = "+"
Expand Down
8 changes: 5 additions & 3 deletions tutordeck/server/tutorclient.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@ def get_config(cls) -> Config:
@classmethod
def get_user_config(cls) -> Config:
"""
TODO load config dynamically from root anytime it is changed on disk? Maybe take the chance to clear sys.modules cache on reload?
TODO
Load config dynamically from root anytime it is changed on disk?
Maybe take the chance to clear sys.modules cache on reload?
"""
return tutor.config.get_user(cls.ROOT)

Expand Down Expand Up @@ -131,8 +133,8 @@ async def iter_logs(self) -> t.AsyncGenerator[str, None]:
The first item is the log file path. Second item is the running command.

This will handle gracefully file deletion. Note however that if the file is
truncated, all contents added to the beginning until the current position will be
missed.
truncated, all contents added to the beginning until the current position
will be missed.
"""
yield f"$ {self.command}\n"
async with aiofiles.open(self.log_path, "rb") as f:
Expand Down