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
3 changes: 0 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@
uses: "./.github/workflows/lint.yml"
variants:
uses: "./.github/workflows/variants.yml"
typecheck:
uses: "./.github/workflows/typecheck.yml"

# Always build & lint package.
build-package:
Expand All @@ -27,7 +25,6 @@
- lint
- tests
- variants
- typecheck
runs-on: ubuntu-latest
permissions:
attestations: write
Expand Down
28 changes: 0 additions & 28 deletions .github/workflows/typecheck.yml

This file was deleted.

7 changes: 7 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

## 2.2.0

- Feature: Add `qa.ty` domain for Astral's ty type checker.
ty is an extremely fast Python type checker (10-100x faster than mypy).
Registers with both CHECK_TARGETS and TYPECHECK_TARGETS for fast feedback.
[jensens]

## 2.1.0

- Enhancement: Use tables in the generated sphinx code for topic/domains.
Expand Down
181 changes: 53 additions & 128 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,9 @@
#: core.mxfiles
#: core.packages
#: docs.sphinx
#: qa.coverage
#: qa.isort
#: qa.mypy
#: qa.ruff
#: qa.test
#: qa.ty
#
# SETTINGS (ALL CHANGES MADE BELOW SETTINGS WILL BE LOST)
##############################################################################
Expand Down Expand Up @@ -111,12 +109,6 @@ MXMAKE?=-e .
# Default: src
RUFF_SRC?=src

## qa.isort

# Source folder to scan for Python files to run isort on.
# Default: src
ISORT_SRC?=src

## docs.sphinx

# Documentation source folder.
Expand Down Expand Up @@ -148,6 +140,17 @@ PROJECT_CONFIG?=mx.ini
# Default: false
PACKAGES_ALLOW_PRERELEASES?=false

## qa.ty

# Source folder for type checking.
# Default: src
TY_SRC?=src

# Target Python version for type checking (e.g., 3.12).
# Leave empty to use default detection.
# No default value.
TY_PYTHON_VERSION?=

## qa.test

# The command which gets executed. Defaults to the location the
Expand All @@ -164,23 +167,6 @@ TEST_REQUIREMENTS?=pytest
# No default value.
TEST_DEPENDENCY_TARGETS?=

## qa.coverage

# The command which gets executed. Defaults to the location the
# :ref:`run-coverage` template gets rendered to if configured.
# Default: .mxmake/files/run-coverage.sh
COVERAGE_COMMAND?=.mxmake/files/run-coverage.sh

## qa.mypy

# Source folder for code analysis.
# Default: src
MYPY_SRC?=src

# Mypy Python requirements to be installed (via pip).
# Default: types-setuptools
MYPY_REQUIREMENTS?=types-setuptools types-docutils types-PyYAML

## core.help

# Request to show all targets, descriptions and arguments for a given domain.
Expand Down Expand Up @@ -383,45 +369,6 @@ FORMAT_TARGETS+=ruff-format
DIRTY_TARGETS+=ruff-dirty
CLEAN_TARGETS+=ruff-clean

##############################################################################
# isort
##############################################################################

# Adjust ISORT_SRC to respect PROJECT_PATH_PYTHON if still at default
ifeq ($(ISORT_SRC),src)
ISORT_SRC:=$(PYTHON_PROJECT_PREFIX)src
endif

ISORT_TARGET:=$(SENTINEL_FOLDER)/isort.sentinel
$(ISORT_TARGET): $(MXENV_TARGET)
@echo "Install isort"
@$(PYTHON_PACKAGE_COMMAND) install isort
@touch $(ISORT_TARGET)

.PHONY: isort-check
isort-check: $(ISORT_TARGET)
@echo "Run isort check"
@isort --check $(ISORT_SRC)

.PHONY: isort-format
isort-format: $(ISORT_TARGET)
@echo "Run isort format"
@isort $(ISORT_SRC)

.PHONY: isort-dirty
isort-dirty:
@rm -f $(ISORT_TARGET)

.PHONY: isort-clean
isort-clean: isort-dirty
@test -e $(MXENV_PYTHON) && $(MXENV_PYTHON) -m pip uninstall -y isort || :

INSTALL_TARGETS+=$(ISORT_TARGET)
CHECK_TARGETS+=isort-check
FORMAT_TARGETS+=isort-format
DIRTY_TARGETS+=isort-dirty
CLEAN_TARGETS+=isort-clean

##############################################################################
# sphinx
##############################################################################
Expand Down Expand Up @@ -567,6 +514,47 @@ INSTALL_TARGETS+=packages
DIRTY_TARGETS+=packages-dirty
CLEAN_TARGETS+=packages-clean

##############################################################################
# ty
##############################################################################

# Adjust TY_SRC to respect PROJECT_PATH_PYTHON if still at default
ifeq ($(TY_SRC),src)
TY_SRC:=$(PYTHON_PROJECT_PREFIX)src
endif

# Build ty flags
TY_FLAGS:=
ifneq ($(TY_PYTHON_VERSION),)
TY_FLAGS+=--python-version $(TY_PYTHON_VERSION)
endif

TY_TARGET:=$(SENTINEL_FOLDER)/ty.sentinel
$(TY_TARGET): $(MXENV_TARGET)
@echo "Install ty"
@$(PYTHON_PACKAGE_COMMAND) install ty
@touch $(TY_TARGET)

.PHONY: ty
ty: $(PACKAGES_TARGET) $(TY_TARGET)
@echo "Run ty"
@ty check $(TY_FLAGS) $(TY_SRC)

.PHONY: ty-dirty
ty-dirty:
@rm -f $(TY_TARGET)

.PHONY: ty-clean
ty-clean: ty-dirty
@test -e $(MXENV_PYTHON) && $(MXENV_PYTHON) -m pip uninstall -y ty || :
@rm -rf .ty

INSTALL_TARGETS+=$(TY_TARGET)
CHECK_TARGETS+=ty
TYPECHECK_TARGETS+=ty
CLEAN_TARGETS+=ty-clean
DIRTY_TARGETS+=ty-dirty

##############################################################################
# test
##############################################################################
Expand Down Expand Up @@ -596,69 +584,6 @@ INSTALL_TARGETS+=$(TEST_TARGET)
CLEAN_TARGETS+=test-clean
DIRTY_TARGETS+=test-dirty

##############################################################################
# coverage
##############################################################################

COVERAGE_TARGET:=$(SENTINEL_FOLDER)/coverage.sentinel
$(COVERAGE_TARGET): $(TEST_TARGET)
@echo "Install Coverage"
@$(PYTHON_PACKAGE_COMMAND) install -U coverage
@touch $(COVERAGE_TARGET)

.PHONY: coverage
coverage: $(FILES_TARGET) $(SOURCES_TARGET) $(PACKAGES_TARGET) $(COVERAGE_TARGET)
@test -z "$(COVERAGE_COMMAND)" && echo "No coverage command defined" && exit 1 || :
@echo "Run coverage using $(COVERAGE_COMMAND)"
@/usr/bin/env bash -c "$(COVERAGE_COMMAND)"

.PHONY: coverage-dirty
coverage-dirty:
@rm -f $(COVERAGE_TARGET)

.PHONY: coverage-clean
coverage-clean: coverage-dirty
@test -e $(MXENV_PYTHON) && $(MXENV_PYTHON) -m pip uninstall -y coverage || :
@rm -rf .coverage htmlcov

INSTALL_TARGETS+=$(COVERAGE_TARGET)
DIRTY_TARGETS+=coverage-dirty
CLEAN_TARGETS+=coverage-clean

##############################################################################
# mypy
##############################################################################

# Adjust MYPY_SRC to respect PROJECT_PATH_PYTHON if still at default
ifeq ($(MYPY_SRC),src)
MYPY_SRC:=$(PYTHON_PROJECT_PREFIX)src
endif

MYPY_TARGET:=$(SENTINEL_FOLDER)/mypy.sentinel
$(MYPY_TARGET): $(MXENV_TARGET)
@echo "Install mypy"
@$(PYTHON_PACKAGE_COMMAND) install mypy $(MYPY_REQUIREMENTS)
@touch $(MYPY_TARGET)

.PHONY: mypy
mypy: $(PACKAGES_TARGET) $(MYPY_TARGET)
@echo "Run mypy"
@mypy $(MYPY_SRC)

.PHONY: mypy-dirty
mypy-dirty:
@rm -f $(MYPY_TARGET)

.PHONY: mypy-clean
mypy-clean: mypy-dirty
@test -e $(MXENV_PYTHON) && $(MXENV_PYTHON) -m pip uninstall -y mypy || :
@rm -rf .mypy_cache

INSTALL_TARGETS+=$(MYPY_TARGET)
TYPECHECK_TARGETS+=mypy
CLEAN_TARGETS+=mypy-clean
DIRTY_TARGETS+=mypy-dirty

##############################################################################
# help
##############################################################################
Expand Down
2 changes: 2 additions & 0 deletions src/mxmake/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ def list_command(args: argparse.Namespace):
sys.stdout.write(f"Requested domain not found: {args.domain}\n")
sys.exit(1)

assert domain is not None # type narrowing for ty

sys.stdout.write(f"Domain {topic.name}.{domain.name}:\n")
depends = ", ".join(domain.depends) if domain.depends else "No dependencies"
sys.stdout.write(f" Depends: {depends}\n")
Expand Down
12 changes: 8 additions & 4 deletions src/mxmake/templates.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,19 +58,23 @@ def __init__(
# XXX: if environment is None, default to ``get_template_environment``?
self.environment = environment

@abc.abstractproperty
@property
@abc.abstractmethod
def target_folder(self) -> Path:
"""Target folder for rendered template."""

@abc.abstractproperty
@property
@abc.abstractmethod
def target_name(self) -> str:
"""Target file name for rendered template."""

@abc.abstractproperty
@property
@abc.abstractmethod
def template_name(self) -> str:
"""Template name to use."""

@abc.abstractproperty
@property
@abc.abstractmethod
def template_variables(self) -> dict[str, typing.Any]:
"""Variables for template rendering."""

Expand Down
8 changes: 3 additions & 5 deletions src/mxmake/testing/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,6 @@ def __init__(


class RenderTestCase(unittest.TestCase):
class Example:
def __init__(self, want):
self.want = want + "\n"

class Failure(Exception):
pass

Expand All @@ -96,6 +92,8 @@ def checkOutput(self, want, got, optionflags=None):
if not success:
raise RenderTestCase.Failure(
self._checker.output_difference(
RenderTestCase.Example(want), got, optionflags
doctest.Example(source="", want=want + "\n"),
got,
optionflags,
)
)
2 changes: 1 addition & 1 deletion src/mxmake/tests/test_templates.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class Template(templates.Template):
def test_Template(self, tempdir: Path):
# cannot instantiate abstract template
with self.assertRaises(TypeError):
templates.Template() # type: ignore
templates.Template()

# create test template
class Template(templates.Template):
Expand Down
Loading