makeapp 2.1.0__tar.gz → 2.2.0__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.
- {makeapp-2.1.0 → makeapp-2.2.0}/LICENSE +1 -1
- {makeapp-2.1.0 → makeapp-2.2.0}/PKG-INFO +14 -3
- {makeapp-2.1.0 → makeapp-2.2.0}/README.md +11 -1
- {makeapp-2.1.0 → makeapp-2.2.0}/pyproject.toml +3 -15
- makeapp-2.2.0/src/makeapp/__init__.py +3 -0
- makeapp-2.2.0/src/makeapp/app_templates/__default__/.github/workflows/python-package.yml +41 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/__default__/pyproject.toml +2 -17
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/django/.github/workflows/python-package.yml +5 -6
- makeapp-2.2.0/src/makeapp/app_templates/django/pyproject.toml +13 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/appmaker.py +2 -1
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/apptools.py +31 -8
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/cli.py +21 -1
- makeapp-2.2.0/src/makeapp/helpers/__init__.py +0 -0
- makeapp-2.2.0/src/makeapp/helpers/tests.py +123 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/helpers/venvs.py +1 -1
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/rendering.py +1 -1
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/utils.py +9 -26
- makeapp-2.1.0/src/makeapp/__init__.py +0 -3
- makeapp-2.1.0/src/makeapp/app_templates/__default__/tests/__init__.py +0 -12
- makeapp-2.1.0/src/makeapp/app_templates/django/pyproject.toml +0 -19
- {makeapp-2.1.0 → makeapp-2.2.0}/.gitignore +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/__default__/.gitignore +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/__default__/AUTHORS.md +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/__default__/CHANGELOG.md +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/__default__/CONTRIBUTING.md +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/__default__/INSTALL.md +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/__default__/README.md +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/__default__/docs/index.md +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/__default__/docs/quickstart.md +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/__default__/mkdocs.yml +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/__default__/ruff.toml +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/__default__/src/__package_name__/__init__.py +0 -0
- {makeapp-2.1.0/src/makeapp/app_templates/django/src/__package_name__/management/commands → makeapp-2.2.0/src/makeapp/app_templates/__default__/tests}/__init__.py +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/__default__/tests/test_basic.py +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/click/makeappconf.py +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/click/pyproject.toml +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/click/src/__package_name__/cli.py +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/console/pyproject.toml +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/console/src/__package_name__/cli.py +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/django/makeappconf.py +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/django/src/__package_name__/__init__.py +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/django/src/__package_name__/admin.py +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/django/src/__package_name__/apps.py +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/django/src/__package_name__/locale/empty +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/django/src/__package_name__/management/__init__.py +0 -0
- {makeapp-2.1.0/src/makeapp/app_templates/webscaff/src/__package_name__/settings → makeapp-2.2.0/src/makeapp/app_templates/django/src/__package_name__/management/commands}/__init__.py +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/django/src/__package_name__/models.py +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/django/src/__package_name__/templates/empty +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/django/src/__package_name__/templatetags/empty +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/django/src/__package_name__/tests/__init__.py +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/django/src/__package_name__/tests/conftest.py +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/django/src/__package_name__/tests/test_basic.py +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/django/src/__package_name__/views.py +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/pytestplugin/pyproject.toml +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/pytestplugin/src/__package_name__/entry.py +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/pytestplugin/tests/test_basic.py +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/webscaff/.gitignore +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/webscaff/conf/__package_name__-certbot-hook.sh +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/webscaff/conf/__package_name__.service +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/webscaff/conf/env_production.py +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/webscaff/makeappconf.py +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/webscaff/pyproject.toml +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/webscaff/requirements.txt +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/webscaff/src/__package_name__/core/uwsgiinit.py +0 -0
- {makeapp-2.1.0/src/makeapp/helpers → makeapp-2.2.0/src/makeapp/app_templates/webscaff/src/__package_name__/settings}/__init__.py +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/webscaff/src/__package_name__/settings/auto.py +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/webscaff/src/__package_name__/settings/base.py +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/webscaff/src/__package_name__/settings/env_development.py +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/webscaff/src/__package_name__/settings/env_testing.py +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/webscaff/src/__package_name__/settings/sub_paths.py +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/webscaff/src/__package_name__/uwsgicfg.py +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/webscaff/state/certbot/empty +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/webscaff/state/dumps/empty +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/webscaff/state/media/empty +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/webscaff/state/spool/empty +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/webscaff/state/static/empty +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/webscaff/tests/conftest.py +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/webscaff/tests/requirements.txt +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/webscaff/tests/test_module.py +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/webscaff/wscaff.yml +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/appconfig.py +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/apptemplate.py +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/exceptions.py +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/helpers/dist.py +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/helpers/files.py +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/helpers/vcs.py +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/license_templates/apache2 +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/license_templates/apache2_src +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/license_templates/bsd2cl +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/license_templates/bsd3cl +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/license_templates/gpl2 +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/license_templates/gpl2_src +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/license_templates/gpl3 +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/license_templates/gpl3_src +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/license_templates/mit +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/license_templates/no +0 -0
- {makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/license_templates/no_src +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: makeapp
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.2.0
|
|
4
4
|
Summary: Simplifies routine Python application development processes.
|
|
5
5
|
Project-URL: Homepage, https://github.com/idlesign/makeapp
|
|
6
6
|
Project-URL: Documentation, https://makeapp.readthedocs.io/
|
|
@@ -8,9 +8,10 @@ Author-email: Igor Starikov <idlesign@yandex.ru>
|
|
|
8
8
|
License-Expression: BSD-3-Clause
|
|
9
9
|
License-File: LICENSE
|
|
10
10
|
Keywords: development,scaffolding
|
|
11
|
-
Requires-Python: >=3.
|
|
11
|
+
Requires-Python: >=3.11
|
|
12
12
|
Requires-Dist: click
|
|
13
13
|
Requires-Dist: jinja2~=3.1
|
|
14
|
+
Requires-Dist: pyyaml
|
|
14
15
|
Requires-Dist: requests
|
|
15
16
|
Description-Content-Type: text/markdown
|
|
16
17
|
|
|
@@ -37,6 +38,7 @@ https://github.com/idlesign/makeapp
|
|
|
37
38
|
* Easily bootstrap your development environment.
|
|
38
39
|
* Build and local serve the docs.
|
|
39
40
|
* Run code styling/linting.
|
|
41
|
+
* Run tests in different environments.
|
|
40
42
|
|
|
41
43
|
## Application scaffolding
|
|
42
44
|
|
|
@@ -111,7 +113,6 @@ Apply code style with `style` command:
|
|
|
111
113
|
ma style
|
|
112
114
|
```
|
|
113
115
|
|
|
114
|
-
|
|
115
116
|
## Build/serve docs
|
|
116
117
|
|
|
117
118
|
Use `docs` command:
|
|
@@ -120,6 +121,16 @@ Use `docs` command:
|
|
|
120
121
|
ma docs
|
|
121
122
|
```
|
|
122
123
|
|
|
124
|
+
|
|
125
|
+
## Run tests
|
|
126
|
+
|
|
127
|
+
Use `tests` command:
|
|
128
|
+
|
|
129
|
+
``` bash
|
|
130
|
+
ma tests
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
|
|
123
134
|
## Documentation
|
|
124
135
|
|
|
125
136
|
https://makeapp.readthedocs.io/
|
|
@@ -21,6 +21,7 @@ https://github.com/idlesign/makeapp
|
|
|
21
21
|
* Easily bootstrap your development environment.
|
|
22
22
|
* Build and local serve the docs.
|
|
23
23
|
* Run code styling/linting.
|
|
24
|
+
* Run tests in different environments.
|
|
24
25
|
|
|
25
26
|
## Application scaffolding
|
|
26
27
|
|
|
@@ -95,7 +96,6 @@ Apply code style with `style` command:
|
|
|
95
96
|
ma style
|
|
96
97
|
```
|
|
97
98
|
|
|
98
|
-
|
|
99
99
|
## Build/serve docs
|
|
100
100
|
|
|
101
101
|
Use `docs` command:
|
|
@@ -104,6 +104,16 @@ Use `docs` command:
|
|
|
104
104
|
ma docs
|
|
105
105
|
```
|
|
106
106
|
|
|
107
|
+
|
|
108
|
+
## Run tests
|
|
109
|
+
|
|
110
|
+
Use `tests` command:
|
|
111
|
+
|
|
112
|
+
``` bash
|
|
113
|
+
ma tests
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
|
|
107
117
|
## Documentation
|
|
108
118
|
|
|
109
119
|
https://makeapp.readthedocs.io/
|
|
@@ -8,12 +8,13 @@ authors = [
|
|
|
8
8
|
readme = "README.md"
|
|
9
9
|
license = "BSD-3-Clause"
|
|
10
10
|
license-files = ["LICENSE"]
|
|
11
|
-
requires-python = ">=3.
|
|
11
|
+
requires-python = ">=3.11"
|
|
12
12
|
keywords = ["scaffolding", "development"]
|
|
13
13
|
dependencies = [
|
|
14
14
|
"requests",
|
|
15
15
|
"click",
|
|
16
16
|
"jinja2~=3.1",
|
|
17
|
+
"pyyaml",
|
|
17
18
|
]
|
|
18
19
|
|
|
19
20
|
[project.urls]
|
|
@@ -38,6 +39,7 @@ linters = [
|
|
|
38
39
|
]
|
|
39
40
|
tests = [
|
|
40
41
|
"pytest",
|
|
42
|
+
"pytest-datafixtures",
|
|
41
43
|
]
|
|
42
44
|
|
|
43
45
|
[build-system]
|
|
@@ -75,17 +77,3 @@ exclude_also = [
|
|
|
75
77
|
"if TYPE_CHECKING:",
|
|
76
78
|
]
|
|
77
79
|
|
|
78
|
-
[tool.tox]
|
|
79
|
-
skip_missing_interpreters = true
|
|
80
|
-
env_list = [
|
|
81
|
-
"py310",
|
|
82
|
-
"py311",
|
|
83
|
-
"py312",
|
|
84
|
-
"py313",
|
|
85
|
-
]
|
|
86
|
-
|
|
87
|
-
[tool.tox.env_run_base]
|
|
88
|
-
dependency_groups = ["tests"]
|
|
89
|
-
commands = [
|
|
90
|
-
["pytest", { replace = "posargs", default = ["tests"], extend = true }],
|
|
91
|
-
]
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
name: Python package
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ master ]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [ master ]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
build:
|
|
11
|
+
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
strategy:
|
|
14
|
+
fail-fast: false
|
|
15
|
+
matrix:
|
|
16
|
+
python-version: [3.11, 3.12, 3.13, 3.14]
|
|
17
|
+
|
|
18
|
+
steps:
|
|
19
|
+
{% raw %}
|
|
20
|
+
- uses: actions/checkout@v4
|
|
21
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
22
|
+
uses: actions/setup-python@v5
|
|
23
|
+
with:
|
|
24
|
+
python-version: ${{ matrix.python-version }}
|
|
25
|
+
- name: Setup uv
|
|
26
|
+
uses: astral-sh/setup-uv@v6
|
|
27
|
+
- name: Install deps
|
|
28
|
+
run: |
|
|
29
|
+
uv sync --only-group tests
|
|
30
|
+
uv pip install coveralls
|
|
31
|
+
- uses: astral-sh/ruff-action@v3
|
|
32
|
+
with:
|
|
33
|
+
version: 0.13.1
|
|
34
|
+
args: check
|
|
35
|
+
- name: Run tests
|
|
36
|
+
env:
|
|
37
|
+
GITHUB_TOKEN: ${{ secrets.github_token }}
|
|
38
|
+
{% endraw %}
|
|
39
|
+
run: |
|
|
40
|
+
uv run coverage run -m pytest
|
|
41
|
+
uv run coveralls --service=github
|
|
@@ -89,26 +89,11 @@ exclude_also = [
|
|
|
89
89
|
"if TYPE_CHECKING:",
|
|
90
90
|
]
|
|
91
91
|
|
|
92
|
-
[tool.
|
|
93
|
-
skip_missing_interpreters = true
|
|
94
|
-
env_list = [
|
|
95
|
-
{% block tox_envlist %}
|
|
96
|
-
"py310",
|
|
97
|
-
"py311",
|
|
98
|
-
"py312",
|
|
99
|
-
"py313",
|
|
100
|
-
{% endblock %}
|
|
101
|
-
]
|
|
102
|
-
|
|
103
|
-
[tool.tox.env_run_base]
|
|
104
|
-
dependency_groups = ["tests"]
|
|
92
|
+
[tool.makeapp.tests]
|
|
105
93
|
deps = [
|
|
106
|
-
{% block
|
|
94
|
+
{% block deps_matests %}
|
|
107
95
|
{% endblock %}
|
|
108
96
|
]
|
|
109
|
-
commands = [
|
|
110
|
-
["pytest", { replace = "posargs", default = ["tests"], extend = true }],
|
|
111
|
-
]
|
|
112
97
|
|
|
113
98
|
{% block tools_ext %}
|
|
114
99
|
{% endblock %}
|
|
@@ -5,7 +5,6 @@ on:
|
|
|
5
5
|
branches: [ master ]
|
|
6
6
|
pull_request:
|
|
7
7
|
branches: [ master ]
|
|
8
|
-
workflow_dispatch:
|
|
9
8
|
|
|
10
9
|
jobs:
|
|
11
10
|
build:
|
|
@@ -14,12 +13,12 @@ jobs:
|
|
|
14
13
|
strategy:
|
|
15
14
|
fail-fast: false
|
|
16
15
|
matrix:
|
|
17
|
-
python-version: [3.11, 3.12, 3.13]
|
|
18
|
-
django-version: [4.2, 5.1, 5.2]
|
|
16
|
+
python-version: [3.11, 3.12, 3.13, 3.14]
|
|
17
|
+
django-version: [4.2, 5.1, 5.2, 6.0]
|
|
19
18
|
|
|
20
19
|
exclude:
|
|
21
|
-
- python-version: 3.
|
|
22
|
-
django-version:
|
|
20
|
+
- python-version: 3.11
|
|
21
|
+
django-version: 6.0
|
|
23
22
|
|
|
24
23
|
steps:
|
|
25
24
|
{% raw %}
|
|
@@ -33,7 +32,7 @@ jobs:
|
|
|
33
32
|
- name: Install deps
|
|
34
33
|
run: |
|
|
35
34
|
uv sync --only-group tests
|
|
36
|
-
uv pip install coveralls "
|
|
35
|
+
uv pip install coveralls "django~=${{ matrix.django-version }}.0"
|
|
37
36
|
- uses: astral-sh/ruff-action@v3
|
|
38
37
|
with:
|
|
39
38
|
version: 0.13.1
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{% extends parent_template %}
|
|
2
|
+
|
|
3
|
+
{% block deps_tests %}{{ super() }}
|
|
4
|
+
"pytest-djangoapp>=1.7.0",
|
|
5
|
+
{% endblock %}
|
|
6
|
+
|
|
7
|
+
{% block cov_omit %}{{ super() }}
|
|
8
|
+
"src/{{ package_name }}/migrations/*",
|
|
9
|
+
{% endblock %}
|
|
10
|
+
|
|
11
|
+
{% block deps_matests %}{{ super() }}
|
|
12
|
+
"django~={%raw%}${{ django-version }}{% endraw %}.0",
|
|
13
|
+
{% endblock %}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
import os
|
|
3
3
|
import re
|
|
4
|
+
from contextlib import chdir
|
|
4
5
|
from datetime import date
|
|
5
6
|
from pathlib import Path
|
|
6
7
|
from typing import Any
|
|
@@ -12,7 +13,7 @@ from .exceptions import AppMakerException
|
|
|
12
13
|
from .helpers.vcs import VcsHelper
|
|
13
14
|
from .helpers.venvs import VenvHelper
|
|
14
15
|
from .rendering import Renderer
|
|
15
|
-
from .utils import PYTHON_VERSION,
|
|
16
|
+
from .utils import PYTHON_VERSION, configure_logging, get_user_dir, read_ini
|
|
16
17
|
|
|
17
18
|
RE_UNKNOWN_MARKER = re.compile(r'{{ [^}]+ }}')
|
|
18
19
|
BASE_PATH = os.path.dirname(__file__)
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
import os
|
|
3
|
+
import tomllib
|
|
4
|
+
from contextlib import chdir
|
|
3
5
|
from datetime import datetime
|
|
4
6
|
from pathlib import Path
|
|
5
7
|
|
|
6
8
|
from .exceptions import ProjectorExeption
|
|
7
9
|
from .helpers.dist import DistHelper
|
|
8
10
|
from .helpers.files import FileHelper
|
|
11
|
+
from .helpers.tests import TestsHelper
|
|
9
12
|
from .helpers.vcs import VcsHelper
|
|
10
13
|
from .helpers.venvs import VenvHelper
|
|
11
|
-
from .utils import
|
|
14
|
+
from .utils import MkDocs, Ruff, Uv, configure_logging
|
|
12
15
|
|
|
13
16
|
LOG = logging.getLogger(__name__)
|
|
14
17
|
|
|
@@ -362,6 +365,7 @@ class Project:
|
|
|
362
365
|
self.changelog: ChangelogData | None = None
|
|
363
366
|
self.vcs = VcsHelper.get(project_path)
|
|
364
367
|
self.venv = VenvHelper(project_path)
|
|
368
|
+
self._setting = {}
|
|
365
369
|
|
|
366
370
|
def configure_logging(self, verbosity_lvl: int = None, format: str = '%(message)s'):
|
|
367
371
|
"""Switches on logging at a given level.
|
|
@@ -372,6 +376,25 @@ class Project:
|
|
|
372
376
|
"""
|
|
373
377
|
configure_logging(verbosity_lvl, logger=LOG, format=format)
|
|
374
378
|
|
|
379
|
+
def get_settings(self) -> dict | None:
|
|
380
|
+
"""Returns project settings from pyproject.toml (with default) or None if file not found."""
|
|
381
|
+
|
|
382
|
+
settings = self._setting
|
|
383
|
+
|
|
384
|
+
if not settings:
|
|
385
|
+
|
|
386
|
+
path = Path("pyproject.toml")
|
|
387
|
+
if not path.exists():
|
|
388
|
+
raise ProjectorExeption('No `pyproject.toml` file found in the current directory.')
|
|
389
|
+
|
|
390
|
+
with path.open("rb") as f:
|
|
391
|
+
data = tomllib.load(f)
|
|
392
|
+
|
|
393
|
+
settings = data.get("tool", {}).get("makeapp", {})
|
|
394
|
+
self._setting = settings
|
|
395
|
+
|
|
396
|
+
return settings
|
|
397
|
+
|
|
375
398
|
def _gather_data(self):
|
|
376
399
|
"""Gathers data relevant for project related functions."""
|
|
377
400
|
|
|
@@ -383,11 +406,7 @@ class Project:
|
|
|
383
406
|
|
|
384
407
|
LOG.debug(f'Gathering info from `{project_path}` directory ...')
|
|
385
408
|
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
if not os.path.isfile(marker_file):
|
|
389
|
-
raise ProjectorExeption(f'No `{marker_file}` file found in the current directory.')
|
|
390
|
-
|
|
409
|
+
self.get_settings()
|
|
391
410
|
self.vcs.check()
|
|
392
411
|
|
|
393
412
|
parent_dirname = project_path.parent.name
|
|
@@ -506,6 +525,11 @@ class Project:
|
|
|
506
525
|
self.vcs.push()
|
|
507
526
|
DistHelper.upload()
|
|
508
527
|
|
|
528
|
+
def run_tests(self, *, only: list[str] | None = None) -> dict[str, list[str]]:
|
|
529
|
+
LOG.info('Running tests ...')
|
|
530
|
+
helper = TestsHelper(settings=self.get_settings().get('tests', {}), only=only)
|
|
531
|
+
return helper.run_tests()
|
|
532
|
+
|
|
509
533
|
def style(self):
|
|
510
534
|
LOG.info('Styling ...')
|
|
511
535
|
Ruff.check()
|
|
@@ -523,13 +547,12 @@ class Project:
|
|
|
523
547
|
LOG.info(f'{"Upgrading" if upgrade else "Bootstrapping"} development tools ...')
|
|
524
548
|
|
|
525
549
|
tools_default = [
|
|
526
|
-
'tox',
|
|
527
550
|
'ruff==0.13.1',
|
|
528
551
|
]
|
|
529
552
|
|
|
530
553
|
method = Uv.tool_upgrade if upgrade else Uv.tool_install
|
|
531
554
|
|
|
532
|
-
LOG.info(
|
|
555
|
+
LOG.info('Processing uv ...')
|
|
533
556
|
|
|
534
557
|
if upgrade:
|
|
535
558
|
Uv.upgrade()
|
|
@@ -5,13 +5,14 @@ from pathlib import Path
|
|
|
5
5
|
|
|
6
6
|
import click
|
|
7
7
|
|
|
8
|
+
from makeapp.helpers.tests import TestsHelper
|
|
9
|
+
|
|
8
10
|
from .exceptions import MakeappException
|
|
9
11
|
|
|
10
12
|
try:
|
|
11
13
|
from . import VERSION
|
|
12
14
|
from .appmaker import AppMaker
|
|
13
15
|
from .apptools import VERSION_NUMBER_CHUNKS, Project
|
|
14
|
-
from .utils import configure_logging
|
|
15
16
|
|
|
16
17
|
except MakeappException as e:
|
|
17
18
|
click.secho(f'{e}', err=True, fg='red')
|
|
@@ -234,6 +235,25 @@ def style(debug):
|
|
|
234
235
|
click.secho('Done', fg='green')
|
|
235
236
|
|
|
236
237
|
|
|
238
|
+
@entry_point.command()
|
|
239
|
+
@option_debug
|
|
240
|
+
@click.option('-o', '--only', multiple=True, help='Run only certain tests. E.g. -o "py314_django600"')
|
|
241
|
+
def tests(debug, only):
|
|
242
|
+
"""Run tests."""
|
|
243
|
+
project = Project(log_level=logging.DEBUG if debug else logging.INFO)
|
|
244
|
+
stats = project.run_tests(only=only)
|
|
245
|
+
|
|
246
|
+
key_ok = TestsHelper.KEY_OK
|
|
247
|
+
key_fail = TestsHelper.KEY_FAIL
|
|
248
|
+
|
|
249
|
+
for status, color, err in ((key_ok, 'green', False), (key_fail, 'red', True)):
|
|
250
|
+
if items := stats[status]:
|
|
251
|
+
items = "\n ".join(items)
|
|
252
|
+
click.secho(f'Tests {status}:\n {items}', err=err, fg=color)
|
|
253
|
+
|
|
254
|
+
click.secho('Done', fg='green')
|
|
255
|
+
|
|
256
|
+
|
|
237
257
|
@entry_point.command()
|
|
238
258
|
@option_debug
|
|
239
259
|
@click.option(
|
|
File without changes
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import re
|
|
2
|
+
from functools import partial
|
|
3
|
+
from itertools import product
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from pprint import pformat
|
|
6
|
+
from sys import version_info
|
|
7
|
+
|
|
8
|
+
import yaml
|
|
9
|
+
|
|
10
|
+
from ..exceptions import CommandError
|
|
11
|
+
from ..utils import LOG, Uv
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class TestsHelper:
|
|
15
|
+
|
|
16
|
+
_RE_VAR = re.compile(r'\$\{\{\s*([\w-]+)\s*\}\}')
|
|
17
|
+
_RE_VALID_IDENT = re.compile(r'[^a-zA-Z0-9]')
|
|
18
|
+
|
|
19
|
+
KEY_OK = 'OK'
|
|
20
|
+
KEY_FAIL = 'FAIL'
|
|
21
|
+
|
|
22
|
+
def __init__(self, *, settings: dict, only: list[str] | None = None):
|
|
23
|
+
self._settings = settings
|
|
24
|
+
self._only = set(only or [])
|
|
25
|
+
|
|
26
|
+
@classmethod
|
|
27
|
+
def apply_context(cls, text: str, context: dict) -> str:
|
|
28
|
+
"""Apply context to a text (resolves variables).
|
|
29
|
+
|
|
30
|
+
:param text:
|
|
31
|
+
:param context:
|
|
32
|
+
"""
|
|
33
|
+
def replace(match):
|
|
34
|
+
var_name = match.group(1)
|
|
35
|
+
return f'{context.get(var_name, match.group(0))}'
|
|
36
|
+
|
|
37
|
+
return cls._RE_VAR.sub(replace, text)
|
|
38
|
+
|
|
39
|
+
@classmethod
|
|
40
|
+
def get_matrix_github(cls, fpath: Path):
|
|
41
|
+
with fpath.open() as f:
|
|
42
|
+
config = yaml.safe_load(f)
|
|
43
|
+
|
|
44
|
+
jobs = config.get('jobs', {})
|
|
45
|
+
job_name = list(jobs.keys())[0]
|
|
46
|
+
matrix = jobs[job_name].get('strategy', {}).get('matrix', {})
|
|
47
|
+
exclusions = matrix.pop('exclude', [])
|
|
48
|
+
keys = matrix.keys()
|
|
49
|
+
values = matrix.values()
|
|
50
|
+
combinations = []
|
|
51
|
+
|
|
52
|
+
for combined in product(*values):
|
|
53
|
+
combination = dict(zip(keys, combined, strict=False))
|
|
54
|
+
is_excluded = False
|
|
55
|
+
for exclusion in exclusions:
|
|
56
|
+
if all(f'{combination.get(key)}' == f'{val}' for key, val in exclusion.items()):
|
|
57
|
+
is_excluded = True
|
|
58
|
+
break
|
|
59
|
+
|
|
60
|
+
if not is_excluded:
|
|
61
|
+
combinations.append(combination)
|
|
62
|
+
|
|
63
|
+
return combinations
|
|
64
|
+
|
|
65
|
+
def run_tests(self) -> dict[str, list[str]]:
|
|
66
|
+
settings = self._settings
|
|
67
|
+
|
|
68
|
+
workflow_github = Path(settings.get('workflow_github') or 'python-package.yml')
|
|
69
|
+
if len(workflow_github.parts) == 1:
|
|
70
|
+
workflow_github = Path('.github', 'workflows', workflow_github)
|
|
71
|
+
|
|
72
|
+
matrix = self.get_matrix_github(workflow_github)
|
|
73
|
+
apply_ctx = self.apply_context
|
|
74
|
+
make_valid_ident = partial(self._RE_VALID_IDENT.sub, '')
|
|
75
|
+
deps = settings.get('deps') or []
|
|
76
|
+
only = self._only
|
|
77
|
+
|
|
78
|
+
matrix_lines = '\n '.join(' '.join(f"{key}:{value}" for key, value in line.items()) for line in matrix)
|
|
79
|
+
LOG.info(f'Test matrix:\n {matrix_lines}')
|
|
80
|
+
|
|
81
|
+
stats = {
|
|
82
|
+
self.KEY_OK: [],
|
|
83
|
+
self.KEY_FAIL: [],
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
for combination in matrix:
|
|
87
|
+
|
|
88
|
+
python_version = combination.get('python-version') or f"{version_info.major}.{version_info.minor}"
|
|
89
|
+
ident_chunks = [make_valid_ident(f'py{python_version}')]
|
|
90
|
+
deps_resolved = []
|
|
91
|
+
for dep in deps:
|
|
92
|
+
dep = apply_ctx(dep, combination)
|
|
93
|
+
deps_resolved.append(f'"{dep}"')
|
|
94
|
+
ident_chunks.append(make_valid_ident(dep))
|
|
95
|
+
|
|
96
|
+
ident = "_".join(ident_chunks)
|
|
97
|
+
|
|
98
|
+
if not only or ident in only:
|
|
99
|
+
LOG.info(f'Running: {ident}: {combination} ...')
|
|
100
|
+
|
|
101
|
+
venv_dir = f'.venv_ma/{ident}'
|
|
102
|
+
execute = partial(Uv.exec, env={
|
|
103
|
+
'VIRTUAL_ENV': venv_dir,
|
|
104
|
+
'UV_PROJECT_ENVIRONMENT': venv_dir,
|
|
105
|
+
})
|
|
106
|
+
status = self.KEY_OK
|
|
107
|
+
|
|
108
|
+
try:
|
|
109
|
+
execute(f'sync --only-group tests --python {python_version}')
|
|
110
|
+
|
|
111
|
+
if deps_resolved := ' '.join(deps_resolved):
|
|
112
|
+
execute(f'pip install {deps_resolved} --python {venv_dir}')
|
|
113
|
+
|
|
114
|
+
execute('run pytest')
|
|
115
|
+
|
|
116
|
+
except CommandError:
|
|
117
|
+
status = self.KEY_FAIL
|
|
118
|
+
continue
|
|
119
|
+
|
|
120
|
+
finally:
|
|
121
|
+
stats[status].append(ident)
|
|
122
|
+
|
|
123
|
+
return stats
|
|
@@ -49,23 +49,6 @@ def read_ini(fpath: Path) -> ConfigParser:
|
|
|
49
49
|
return cfg
|
|
50
50
|
|
|
51
51
|
|
|
52
|
-
@contextmanager
|
|
53
|
-
def chdir(target_path):
|
|
54
|
-
"""Context manager.
|
|
55
|
-
|
|
56
|
-
Temporarily switches the current working directory.
|
|
57
|
-
|
|
58
|
-
"""
|
|
59
|
-
curr_dir = os.getcwd()
|
|
60
|
-
os.chdir(target_path)
|
|
61
|
-
|
|
62
|
-
try:
|
|
63
|
-
yield
|
|
64
|
-
|
|
65
|
-
finally:
|
|
66
|
-
os.chdir(curr_dir)
|
|
67
|
-
|
|
68
|
-
|
|
69
52
|
@contextmanager
|
|
70
53
|
def temp_dir() -> Generator[str, None, None]:
|
|
71
54
|
"""Context manager to temporarily create a directory."""
|
|
@@ -107,10 +90,10 @@ def check_command(command: str, *, hint: str):
|
|
|
107
90
|
try:
|
|
108
91
|
run_command(f'type {command}')
|
|
109
92
|
|
|
110
|
-
except CommandError:
|
|
93
|
+
except CommandError as e:
|
|
111
94
|
raise CommandError(
|
|
112
95
|
f"Failed to execute '{command}' command. "
|
|
113
|
-
f"Check {hint} is installed and available.")
|
|
96
|
+
f"Check {hint} is installed and available.") from e
|
|
114
97
|
|
|
115
98
|
|
|
116
99
|
def run_command(command: str, *, err_msg: str = '', env: dict | None = None, capture: bool = True) -> list[str]:
|
|
@@ -159,7 +142,7 @@ class Ruff:
|
|
|
159
142
|
return run_command(f'ruff {cmd}', capture=False)
|
|
160
143
|
|
|
161
144
|
@classmethod
|
|
162
|
-
def check(cls, fix: bool = True) -> list[str]:
|
|
145
|
+
def check(cls, *, fix: bool = True) -> list[str]:
|
|
163
146
|
return cls._run(f'check{" --fix" if fix else ""}')
|
|
164
147
|
|
|
165
148
|
|
|
@@ -183,24 +166,24 @@ class Uv:
|
|
|
183
166
|
"""Uv wrapper."""
|
|
184
167
|
|
|
185
168
|
@classmethod
|
|
186
|
-
def
|
|
187
|
-
return run_command(f'uv {cmd}', capture=False)
|
|
169
|
+
def exec(cls, cmd: str, env: dict | None = None) -> list[str]:
|
|
170
|
+
return run_command(f'uv {cmd}', env=env, capture=False)
|
|
188
171
|
|
|
189
172
|
@classmethod
|
|
190
173
|
def upgrade(cls) -> list[str]:
|
|
191
|
-
return cls.
|
|
174
|
+
return cls.exec('self update')
|
|
192
175
|
|
|
193
176
|
@classmethod
|
|
194
177
|
def tool_install(cls, name: str) -> list[str]:
|
|
195
|
-
return cls.
|
|
178
|
+
return cls.exec(f'tool install {name}')
|
|
196
179
|
|
|
197
180
|
@classmethod
|
|
198
181
|
def tool_upgrade(cls, name: str) -> list[str]:
|
|
199
|
-
return cls.
|
|
182
|
+
return cls.exec(f'tool upgrade {name} --reinstall')
|
|
200
183
|
|
|
201
184
|
@classmethod
|
|
202
185
|
def sync(cls) -> list[str]:
|
|
203
|
-
return cls.
|
|
186
|
+
return cls.exec('sync')
|
|
204
187
|
|
|
205
188
|
@classmethod
|
|
206
189
|
def install(cls):
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
import sys
|
|
3
|
-
import unittest
|
|
4
|
-
|
|
5
|
-
DIR_CURRENT = os.path.abspath(os.path.dirname(__file__))
|
|
6
|
-
DIR_PARENT = os.path.dirname(DIR_CURRENT)
|
|
7
|
-
|
|
8
|
-
sys.path.insert(0, DIR_PARENT)
|
|
9
|
-
|
|
10
|
-
tests_loader = unittest.TestLoader()
|
|
11
|
-
test_suit = tests_loader.discover(DIR_CURRENT)
|
|
12
|
-
unittest.TextTestRunner().run(test_suit)
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
{% extends parent_template %}
|
|
2
|
-
|
|
3
|
-
{% block deps_tests %}{{ super() }}
|
|
4
|
-
"pytest-djangoapp>=1.6.0",
|
|
5
|
-
{% endblock %}
|
|
6
|
-
|
|
7
|
-
{% block cov_omit %}{{ super() }}
|
|
8
|
-
"src/{{ package_name }}/migrations/*",
|
|
9
|
-
{% endblock %}
|
|
10
|
-
|
|
11
|
-
{% block tox_envlist %}
|
|
12
|
-
"py{310,311,312,313}-dj{42,51,52}",
|
|
13
|
-
{% endblock %}
|
|
14
|
-
|
|
15
|
-
{% block tox_deps %}{{ super() }}
|
|
16
|
-
"dj42: Django>=4.1,<4.2",
|
|
17
|
-
"dj51: Django>=5.1,<5.2",
|
|
18
|
-
"dj52: Django>=5.2,<5.3",
|
|
19
|
-
{% endblock %}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/console/src/__package_name__/cli.py
RENAMED
|
File without changes
|
|
File without changes
|
{makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/django/src/__package_name__/__init__.py
RENAMED
|
File without changes
|
{makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/django/src/__package_name__/admin.py
RENAMED
|
File without changes
|
{makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/django/src/__package_name__/apps.py
RENAMED
|
File without changes
|
{makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/django/src/__package_name__/locale/empty
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/django/src/__package_name__/models.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/django/src/__package_name__/views.py
RENAMED
|
File without changes
|
|
File without changes
|
{makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/pytestplugin/src/__package_name__/entry.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/webscaff/conf/__package_name__.service
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{makeapp-2.1.0 → makeapp-2.2.0}/src/makeapp/app_templates/webscaff/src/__package_name__/uwsgicfg.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|