prepare-assignment 0.4.0__tar.gz → 0.4.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/.github/workflows/test.yml +49 -0
  2. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/PKG-INFO +1 -1
  3. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/prepare_assignment/cli/main.py +1 -2
  4. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/prepare_assignment/cli/task.py +1 -2
  5. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/pyproject.toml +1 -1
  6. prepare_assignment-0.4.1/tests/test_dependencies.py +48 -0
  7. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  8. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  9. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/.github/dependabot.yml +0 -0
  10. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/.github/workflows/pr-title.yml +0 -0
  11. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/.github/workflows/pypi-publish.yml +0 -0
  12. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/.github/workflows/release.yml +0 -0
  13. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/.github/workflows/semantic-release.yml +0 -0
  14. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/.gitignore +0 -0
  15. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/.releaserc.json +0 -0
  16. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/LICENSE +0 -0
  17. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/README.md +0 -0
  18. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/prepare_assignment/__init__.py +0 -0
  19. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/prepare_assignment/__main__.py +0 -0
  20. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/prepare_assignment/cli/__init__.py +0 -0
  21. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/prepare_assignment/cli/tasks.py +0 -0
  22. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/prepare_assignment/core/__init__.py +0 -0
  23. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/prepare_assignment/core/check.py +0 -0
  24. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/prepare_assignment/core/command.py +0 -0
  25. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/prepare_assignment/core/expression.py +0 -0
  26. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/prepare_assignment/core/main.py +0 -0
  27. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/prepare_assignment/core/preparer.py +0 -0
  28. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/prepare_assignment/core/runner.py +0 -0
  29. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/prepare_assignment/core/shell.py +0 -0
  30. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/prepare_assignment/core/subsituter.py +0 -0
  31. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/prepare_assignment/core/task_handler.py +0 -0
  32. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/prepare_assignment/core/validator.py +0 -0
  33. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/prepare_assignment/core/versions.py +0 -0
  34. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/prepare_assignment/data/__init__.py +0 -0
  35. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/prepare_assignment/data/config.py +0 -0
  36. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/prepare_assignment/data/constants.py +0 -0
  37. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/prepare_assignment/data/errors.py +0 -0
  38. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/prepare_assignment/data/job_environment.py +0 -0
  39. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/prepare_assignment/data/prepare.py +0 -0
  40. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/prepare_assignment/data/task_definition.py +0 -0
  41. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/prepare_assignment/data/task_properties.py +0 -0
  42. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/prepare_assignment/data/types.py +0 -0
  43. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/prepare_assignment/schemas/config.schema.json +0 -0
  44. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/prepare_assignment/schemas/prepare.schema.json +0 -0
  45. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/prepare_assignment/schemas/task.schema.json +0 -0
  46. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/prepare_assignment/utils/__init__.py +0 -0
  47. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/prepare_assignment/utils/config.py +0 -0
  48. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/prepare_assignment/utils/default_validator.py +0 -0
  49. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/prepare_assignment/utils/dependency.py +0 -0
  50. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/prepare_assignment/utils/files.py +0 -0
  51. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/prepare_assignment/utils/logger.py +0 -0
  52. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/prepare_assignment/utils/paths.py +0 -0
  53. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/prepare_assignment/utils/resources.py +0 -0
  54. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/prepare_assignment/utils/tasks.py +0 -0
  55. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/prepare_assignment/utils/virtual_env.py +0 -0
  56. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/prepare_assignment/utils/yml_loader.py +0 -0
  57. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/tests/__init__.py +0 -0
  58. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/tests/core/__init__.py +0 -0
  59. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/tests/core/test_check.py +0 -0
  60. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/tests/core/test_command.py +0 -0
  61. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/tests/core/test_expression.py +0 -0
  62. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/tests/core/test_preparer.py +0 -0
  63. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/tests/core/test_resolve_version.py +0 -0
  64. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/tests/core/test_runner.py +0 -0
  65. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/tests/core/test_runner_process.py +0 -0
  66. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/tests/core/test_shell.py +0 -0
  67. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/tests/core/test_substituter.py +0 -0
  68. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/tests/core/test_task_handler.py +0 -0
  69. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/tests/core/test_validator.py +0 -0
  70. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/tests/data/__init__.py +0 -0
  71. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/tests/data/test_prepare.py +0 -0
  72. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/tests/data/test_types.py +0 -0
  73. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/tests/test_main.py +0 -0
  74. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/tests/testproject/prepare.yml +0 -0
  75. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/tests/testproject/solution/pom.xml +0 -0
  76. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/tests/testproject/solution/src/main/java/gradelist/AssessmentResult.java +0 -0
  77. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/tests/testproject/solution/src/main/java/gradelist/GradeList.java +0 -0
  78. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/tests/testproject/solution/src/main/java/gradelist/Test.java +0 -0
  79. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/tests/testproject/solution/src/test/java/gradelist/AssessmentResultTest.java +0 -0
  80. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/tests/testproject/solution/src/test/java/gradelist/GradeListTest.java +0 -0
  81. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/tests/utils/__init__.py +0 -0
  82. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/tests/utils/test_config.py +0 -0
  83. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/tests/utils/test_default_validator.py +0 -0
  84. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/tests/utils/test_files.py +0 -0
  85. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/tests/utils/test_logger.py +0 -0
  86. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/tests/utils/test_paths.py +0 -0
  87. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/tests/utils/test_resources.py +0 -0
  88. {prepare_assignment-0.4.0 → prepare_assignment-0.4.1}/uv.lock +0 -0
@@ -11,7 +11,39 @@ on:
11
11
  branches: [ "main" ]
12
12
 
13
13
  jobs:
14
+ # Skip the tests if a PR only changes documentation. The jobs are skipped instead of the whole workflow
15
+ # (paths-ignore), because a required check that never reports blocks the PR, see the 'tests' job.
16
+ changes:
17
+ runs-on: ubuntu-latest
18
+ permissions:
19
+ contents: read
20
+ pull-requests: read
21
+ outputs:
22
+ code: ${{ steps.filter.outputs.code }}
23
+ steps:
24
+ - id: filter
25
+ env:
26
+ GH_TOKEN: ${{ github.token }}
27
+ PR: ${{ github.event.pull_request.number }}
28
+ REPO: ${{ github.repository }}
29
+ run: |
30
+ files=$(gh pr diff "$PR" --name-only --repo "$REPO")
31
+ echo "Changed files:"
32
+ echo "$files"
33
+ code=false
34
+ # Fail safe: run the tests if the changed files cannot be determined
35
+ [ -z "$files" ] && code=true
36
+ while IFS= read -r file; do
37
+ case "$file" in
38
+ *.md|LICENSE|.github/ISSUE_TEMPLATE/*) ;;
39
+ *) code=true ;;
40
+ esac
41
+ done <<< "$files"
42
+ echo "code=$code" >> "$GITHUB_OUTPUT"
43
+
14
44
  test:
45
+ needs: changes
46
+ if: needs.changes.outputs.code == 'true'
15
47
  strategy:
16
48
  fail-fast: false
17
49
  matrix:
@@ -44,6 +76,8 @@ jobs:
44
76
  report_paths: tests.xml
45
77
 
46
78
  typecheck:
79
+ needs: changes
80
+ if: needs.changes.outputs.code == 'true'
47
81
  strategy:
48
82
  matrix:
49
83
  python-version: [ "3.12" ]
@@ -61,3 +95,18 @@ jobs:
61
95
  run: uv sync --locked --group test
62
96
  - name: Type checker
63
97
  run: uv run mypy prepare_assignment
98
+
99
+ # The only required check (next to the PR title): succeeds if all tests passed or were skipped because only
100
+ # documentation changed. Skipped matrix jobs don't report their individual checks (e.g. 'test (3.12, ...)').
101
+ tests:
102
+ if: always()
103
+ needs: [changes, test, typecheck]
104
+ runs-on: ubuntu-latest
105
+ steps:
106
+ - name: All tests passed or were skipped
107
+ env:
108
+ FAILED: ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') }}
109
+ RESULTS: ${{ toJSON(needs) }}
110
+ run: |
111
+ echo "$RESULTS"
112
+ [ "$FAILED" = "false" ]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: prepare-assignment
3
- Version: 0.4.0
3
+ Version: 0.4.1
4
4
  Summary: Prepare assignment
5
5
  Author-email: Bonajo <m.bonajo@fontys.nl>
6
6
  License: MIT
@@ -1,10 +1,9 @@
1
1
  import os.path
2
2
  import sys
3
3
  from pathlib import Path
4
- from typing import Dict, List, Optional
4
+ from typing import Annotated, Dict, List, Optional
5
5
 
6
6
  import typer
7
- from typing_extensions import Annotated
8
7
 
9
8
  from prepare_assignment import __version__
10
9
  from prepare_assignment.cli.task import app as task_app
@@ -1,8 +1,7 @@
1
1
  import logging
2
- from typing import Optional
2
+ from typing import Annotated, Optional
3
3
 
4
4
  import typer
5
- from typing_extensions import Annotated
6
5
 
7
6
  from prepare_assignment.core.task_handler import info, remove, update, add
8
7
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "prepare-assignment"
3
- version = "0.4.0"
3
+ version = "0.4.1"
4
4
  description = "Prepare assignment"
5
5
  authors = [{name = "Bonajo", email = "m.bonajo@fontys.nl"}]
6
6
  license = {text = "MIT"}
@@ -0,0 +1,48 @@
1
+ import ast
2
+ import sys
3
+ from importlib.metadata import packages_distributions, requires
4
+ from pathlib import Path
5
+ from typing import Set
6
+
7
+ from packaging.requirements import Requirement
8
+ from packaging.utils import canonicalize_name
9
+
10
+ PACKAGE = Path(__file__).parent.parent / "prepare_assignment"
11
+
12
+
13
+ def _imported_modules() -> Set[str]:
14
+ modules: Set[str] = set()
15
+ for file in PACKAGE.rglob("*.py"):
16
+ tree = ast.parse(file.read_text(encoding="utf-8"))
17
+ for node in ast.walk(tree):
18
+ if isinstance(node, ast.Import):
19
+ modules.update(alias.name.split(".")[0] for alias in node.names)
20
+ elif isinstance(node, ast.ImportFrom) and node.level == 0 and node.module is not None:
21
+ modules.add(node.module.split(".")[0])
22
+ return {module for module in modules
23
+ if module not in sys.stdlib_module_names and module != "prepare_assignment"}
24
+
25
+
26
+ def _declared_dependencies() -> Set[str]:
27
+ declared: Set[str] = set()
28
+ for line in requires("prepare-assignment") or []:
29
+ requirement = Requirement(line)
30
+ # Skip optional dependencies (extras)
31
+ if requirement.marker is None or requirement.marker.evaluate({"extra": ""}):
32
+ declared.add(canonicalize_name(requirement.name))
33
+ return declared
34
+
35
+
36
+ def test_all_imports_are_declared_dependencies() -> None:
37
+ """
38
+ A module that is only installed as a dependency of a (test) dependency works in development, but not for users.
39
+ typer 0.27 dropped its typing-extensions dependency, which broke the released 0.4.0.
40
+ """
41
+ distributions = packages_distributions()
42
+ declared = _declared_dependencies()
43
+ undeclared = {}
44
+ for module in sorted(_imported_modules()):
45
+ names = {canonicalize_name(name) for name in distributions.get(module, [])}
46
+ if not names & declared:
47
+ undeclared[module] = sorted(names) or ["not installed"]
48
+ assert undeclared == {}, f"Imported, but not declared in pyproject.toml dependencies: {undeclared}"