PyProd 0.3.0__tar.gz → 0.5.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.
- {pyprod-0.3.0 → pyprod-0.5.0}/.gitignore +3 -1
- {pyprod-0.3.0 → pyprod-0.5.0}/PKG-INFO +13 -6
- {pyprod-0.3.0 → pyprod-0.5.0}/README.rst +11 -5
- pyprod-0.5.0/docs/commandline.rst +23 -0
- {pyprod-0.3.0 → pyprod-0.5.0}/docs/conf.py +1 -1
- {pyprod-0.3.0 → pyprod-0.5.0}/docs/index.rst +32 -2
- {pyprod-0.3.0 → pyprod-0.5.0}/docs/prodfile.rst +84 -34
- pyprod-0.5.0/docs/releasenotes.rst +22 -0
- {pyprod-0.3.0 → pyprod-0.5.0}/pyproject.toml +8 -2
- {pyprod-0.3.0/sample → pyprod-0.5.0/samples}/build-c/Makefile +1 -1
- pyprod-0.3.0/sample/build-c/PRODFILE.py → pyprod-0.5.0/samples/build-c/Prodfile.py +6 -3
- pyprod-0.3.0/sample/generate-doc/PRODFILE.py → pyprod-0.5.0/samples/generate-doc/Prodfile.py +5 -2
- {pyprod-0.3.0/sample → pyprod-0.5.0/samples}/md-to-pdf/Prodfile.py +7 -1
- {pyprod-0.3.0/sample → pyprod-0.5.0/samples}/s3files/Prodfile.py +7 -3
- pyprod-0.5.0/src/pyprod/__init__.py +1 -0
- {pyprod-0.3.0 → pyprod-0.5.0}/src/pyprod/main.py +28 -8
- {pyprod-0.3.0 → pyprod-0.5.0}/src/pyprod/prod.py +248 -135
- {pyprod-0.3.0 → pyprod-0.5.0}/src/pyprod/utils.py +5 -3
- {pyprod-0.3.0 → pyprod-0.5.0}/src/pyprod/venv.py +13 -4
- pyprod-0.5.0/tests/conftest.py +11 -0
- pyprod-0.5.0/tests/test_prod.py +344 -0
- {pyprod-0.3.0 → pyprod-0.5.0}/tests/test_prodfuncs.py +35 -3
- {pyprod-0.3.0 → pyprod-0.5.0}/tests/test_rule.py +23 -41
- pyprod-0.5.0/tests/utils.py +13 -0
- pyprod-0.3.0/.python-version +0 -1
- pyprod-0.3.0/.readthedocs.yaml +0 -20
- pyprod-0.3.0/docs/commandline.rst +0 -20
- pyprod-0.3.0/docs/releasenotes.rst +0 -9
- pyprod-0.3.0/sample/generate-doc/.gitignore +0 -2
- pyprod-0.3.0/tests/__init__.py +0 -0
- pyprod-0.3.0/tests/conftest.py +0 -3
- pyprod-0.3.0/tests/test_prod.py +0 -217
- pyprod-0.3.0/uv.lock +0 -723
- {pyprod-0.3.0 → pyprod-0.5.0}/.github/workflows/publish.yml +0 -0
- {pyprod-0.3.0 → pyprod-0.5.0}/.github/workflows/test.yml +0 -0
- {pyprod-0.3.0 → pyprod-0.5.0}/LICENSE +0 -0
- {pyprod-0.3.0 → pyprod-0.5.0}/docs/Makefile +0 -0
- {pyprod-0.3.0 → pyprod-0.5.0}/docs/make.bat +0 -0
- {pyprod-0.3.0 → pyprod-0.5.0}/docs/pyprod2.png +0 -0
- {pyprod-0.3.0 → pyprod-0.5.0}/docs/quickstart.rst +0 -0
- {pyprod-0.3.0 → pyprod-0.5.0}/docs/requirements.txt +0 -0
- {pyprod-0.3.0 → pyprod-0.5.0}/pyprod.webp +0 -0
- {pyprod-0.3.0 → pyprod-0.5.0}/pyprod2.png +0 -0
- {pyprod-0.3.0/sample → pyprod-0.5.0/samples}/build-c/hello.c +0 -0
- {pyprod-0.3.0/sample → pyprod-0.5.0/samples}/build-c/hello.h +0 -0
- {pyprod-0.3.0/sample → pyprod-0.5.0/samples}/build-c/main.c +0 -0
- {pyprod-0.3.0/sample → pyprod-0.5.0/samples}/generate-doc/a.txt +0 -0
- {pyprod-0.3.0/sample → pyprod-0.5.0/samples}/generate-doc/b.txt +0 -0
- {pyprod-0.3.0/sample → pyprod-0.5.0/samples}/generate-doc/c.txt +0 -0
- {pyprod-0.3.0/sample → pyprod-0.5.0/samples}/generate-doc/inc1.txt +0 -0
- {pyprod-0.3.0/sample → pyprod-0.5.0/samples}/generate-doc/inc2.txt +0 -0
- {pyprod-0.3.0/sample → pyprod-0.5.0/samples}/md-to-pdf/doc.md +0 -0
- {pyprod-0.3.0/sample → pyprod-0.5.0/samples}/md-to-pdf/md_to_html.py +0 -0
- {pyprod-0.3.0/sample → pyprod-0.5.0/samples}/md-to-pdf/template.html +0 -0
- {pyprod-0.3.0/sample → pyprod-0.5.0/samples}/s3files/S3TEST.txt +0 -0
- {pyprod-0.3.0/sample → pyprod-0.5.0/samples}/tutorial-1/Prodfile.py +0 -0
- {pyprod-0.3.0/sample → pyprod-0.5.0/samples}/tutorial-2/Prodfile.py +0 -0
- {pyprod-0.3.0 → pyprod-0.5.0}/src/pyprod/__main__.py +0 -0
- {pyprod-0.3.0/src/pyprod → pyprod-0.5.0/tests}/__init__.py +0 -0
@@ -1,3 +1,5 @@
|
|
1
|
+
.*
|
2
|
+
!.github
|
1
3
|
# Byte-compiled / optimized / DLL files
|
2
4
|
__pycache__/
|
3
5
|
*.py[cod]
|
@@ -98,7 +100,7 @@ ipython_config.py
|
|
98
100
|
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
|
99
101
|
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
100
102
|
# commonly ignored for libraries.
|
101
|
-
|
103
|
+
uv.lock
|
102
104
|
|
103
105
|
# poetry
|
104
106
|
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: PyProd
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.5.0
|
4
4
|
Summary: PyProd: More Makeable than Make
|
5
5
|
Project-URL: Homepage, https://github.com/atsuoishimoto/pyprod
|
6
6
|
Project-URL: Documentation, https://pyprod.readthedocs.io/en/latest/
|
@@ -12,12 +12,13 @@ Classifier: Operating System :: OS Independent
|
|
12
12
|
Classifier: Programming Language :: Python :: 3
|
13
13
|
Classifier: Topic :: Software Development :: Build Tools
|
14
14
|
Requires-Python: >=3.10
|
15
|
+
Requires-Dist: python-dateutil
|
15
16
|
Description-Content-Type: text/x-rst
|
16
17
|
|
17
18
|
PyProd - More Makeable than Make
|
18
19
|
=================================
|
19
20
|
|
20
|
-
PyProd is a Python script that can be used as an alternative to Makefile. By leveraging Python's versatility, it enables you to define build rules and dependencies programmatically, allowing for dynamic configurations, integration with existing Python libraries, and custom build logic not easily achievable with traditional Makefiles. For detailed documentation, please refer to the `official documentation <https://pyprod.readthedocs.io/en/
|
21
|
+
PyProd is a Python script that can be used as an alternative to Makefile. By leveraging Python's versatility, it enables you to define build rules and dependencies programmatically, allowing for dynamic configurations, integration with existing Python libraries, and custom build logic not easily achievable with traditional Makefiles. For detailed documentation, please refer to the `official documentation <https://pyprod.readthedocs.io/en/stable/>`_.
|
21
22
|
|
22
23
|
|
23
24
|
Features
|
@@ -42,22 +43,26 @@ With PyProd, a traditional Makefile for C can be expressed as a Python script li
|
|
42
43
|
.. code-block:: python
|
43
44
|
|
44
45
|
CC = "gcc"
|
45
|
-
CFLAGS = "-I."
|
46
|
+
CFLAGS = "-c -I."
|
46
47
|
DEPS = "hello.h"
|
47
48
|
OBJS = "hello.o main.o".split()
|
49
|
+
EXE = "hello.exe"
|
48
50
|
|
49
51
|
@rule("%.o", depends=("%.c", DEPS))
|
50
52
|
def compile(target, src, *deps):
|
51
|
-
run(CC, "-
|
53
|
+
run(CC, "-o", target, src, CFLAGS)
|
52
54
|
|
53
|
-
@rule(
|
55
|
+
@rule(EXE, depends=OBJS)
|
54
56
|
def link(target, *objs):
|
55
57
|
run(CC, "-o", target, objs)
|
56
58
|
|
59
|
+
@task
|
57
60
|
def clean():
|
58
61
|
run("rm -f", OBJS, "hello.exe")
|
59
62
|
|
60
|
-
|
63
|
+
@task
|
64
|
+
def rebuild():
|
65
|
+
build(clean, EXE)
|
61
66
|
|
62
67
|
|
63
68
|
To run the build script, simply execute:
|
@@ -67,6 +72,8 @@ To run the build script, simply execute:
|
|
67
72
|
$ cd project
|
68
73
|
$ pyprod
|
69
74
|
|
75
|
+
Other examples can be found in the `samples <https://github.com/atsuoishimoto/pyprod/tree/main/samples>`_ directory.
|
76
|
+
|
70
77
|
License
|
71
78
|
-------
|
72
79
|
PyProd is licensed under the MIT License. See the `LICENSE <LICENSE>`_ file for more details.
|
@@ -1,7 +1,7 @@
|
|
1
1
|
PyProd - More Makeable than Make
|
2
2
|
=================================
|
3
3
|
|
4
|
-
PyProd is a Python script that can be used as an alternative to Makefile. By leveraging Python's versatility, it enables you to define build rules and dependencies programmatically, allowing for dynamic configurations, integration with existing Python libraries, and custom build logic not easily achievable with traditional Makefiles. For detailed documentation, please refer to the `official documentation <https://pyprod.readthedocs.io/en/
|
4
|
+
PyProd is a Python script that can be used as an alternative to Makefile. By leveraging Python's versatility, it enables you to define build rules and dependencies programmatically, allowing for dynamic configurations, integration with existing Python libraries, and custom build logic not easily achievable with traditional Makefiles. For detailed documentation, please refer to the `official documentation <https://pyprod.readthedocs.io/en/stable/>`_.
|
5
5
|
|
6
6
|
|
7
7
|
Features
|
@@ -26,22 +26,26 @@ With PyProd, a traditional Makefile for C can be expressed as a Python script li
|
|
26
26
|
.. code-block:: python
|
27
27
|
|
28
28
|
CC = "gcc"
|
29
|
-
CFLAGS = "-I."
|
29
|
+
CFLAGS = "-c -I."
|
30
30
|
DEPS = "hello.h"
|
31
31
|
OBJS = "hello.o main.o".split()
|
32
|
+
EXE = "hello.exe"
|
32
33
|
|
33
34
|
@rule("%.o", depends=("%.c", DEPS))
|
34
35
|
def compile(target, src, *deps):
|
35
|
-
run(CC, "-
|
36
|
+
run(CC, "-o", target, src, CFLAGS)
|
36
37
|
|
37
|
-
@rule(
|
38
|
+
@rule(EXE, depends=OBJS)
|
38
39
|
def link(target, *objs):
|
39
40
|
run(CC, "-o", target, objs)
|
40
41
|
|
42
|
+
@task
|
41
43
|
def clean():
|
42
44
|
run("rm -f", OBJS, "hello.exe")
|
43
45
|
|
44
|
-
|
46
|
+
@task
|
47
|
+
def rebuild():
|
48
|
+
build(clean, EXE)
|
45
49
|
|
46
50
|
|
47
51
|
To run the build script, simply execute:
|
@@ -51,6 +55,8 @@ To run the build script, simply execute:
|
|
51
55
|
$ cd project
|
52
56
|
$ pyprod
|
53
57
|
|
58
|
+
Other examples can be found in the `samples <https://github.com/atsuoishimoto/pyprod/tree/main/samples>`_ directory.
|
59
|
+
|
54
60
|
License
|
55
61
|
-------
|
56
62
|
PyProd is licensed under the MIT License. See the `LICENSE <LICENSE>`_ file for more details.
|
@@ -0,0 +1,23 @@
|
|
1
|
+
|
2
|
+
.. _commandline:
|
3
|
+
|
4
|
+
Command line options
|
5
|
+
------------------------
|
6
|
+
|
7
|
+
|
8
|
+
usage: pyprod [-h] [-C DIRECTORY] [-f FILE] [-j JOB] [-r] [-g] [-v] [targets ...]
|
9
|
+
|
10
|
+
PyProd - More makable than make
|
11
|
+
|
12
|
+
positional arguments:
|
13
|
+
targets Build targets
|
14
|
+
|
15
|
+
options:
|
16
|
+
-h, --help show this help message and exit
|
17
|
+
-C, --directory DIRECTORY
|
18
|
+
Change to DIRECTORY before performing any operations
|
19
|
+
-f, --file FILE Use FILE as the Prodfile (default: 'Prodfile.py')
|
20
|
+
-j, --job JOB Allow up to N jobs to run simultaneously (default: 1)
|
21
|
+
-r, --rebuild Rebuild all
|
22
|
+
-g, --use-git Get file timestamps from Git
|
23
|
+
-v Increase verbosity level (default: 0)
|
@@ -7,7 +7,7 @@
|
|
7
7
|
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
|
8
8
|
|
9
9
|
project = "PyProd"
|
10
|
-
copyright = "2024, Atsuo Ishimoto"
|
10
|
+
copyright = "2024-2025, Atsuo Ishimoto"
|
11
11
|
author = "Atsuo Ishimoto"
|
12
12
|
|
13
13
|
# -- General configuration ---------------------------------------------------
|
@@ -1,17 +1,47 @@
|
|
1
1
|
PyProd - More Makeable than Make
|
2
2
|
============================================
|
3
|
-
|
4
3
|
PyProd is a Python script that can be used as an alternative to Makefile. By leveraging Python's versatility, it enables you to define build rules and dependencies programmatically, allowing for dynamic configurations, integration with existing Python libraries, and custom build logic not easily achievable with traditional Makefiles.
|
5
4
|
|
6
5
|
Features
|
7
6
|
--------
|
8
|
-
|
9
7
|
- Define build rules in Python: Use Python functions to create clear and concise build logic.
|
10
8
|
- Specify dependencies for each rule: Automatically track and resolve dependencies between files, such as source files and headers.
|
11
9
|
- Easily extendable with custom Python functions: Integrate custom logic for specialized tasks, like code linting or deployment.
|
12
10
|
- Manages virtual environments: Automatically create and manage virtual environments for each project, ensuring a clean and isolated build environment.
|
13
11
|
|
14
12
|
|
13
|
+
Example
|
14
|
+
-------
|
15
|
+
With PyProd, a traditional Makefile for C can be expressed as a Python script like this:
|
16
|
+
|
17
|
+
.. code-block:: python
|
18
|
+
|
19
|
+
CC = "gcc"
|
20
|
+
CFLAGS = "-c -I."
|
21
|
+
DEPS = "hello.h"
|
22
|
+
OBJS = "hello.o main.o".split()
|
23
|
+
EXE = "hello.exe"
|
24
|
+
|
25
|
+
@rule("%.o", depends=("%.c", DEPS))
|
26
|
+
def compile(target, src, *deps):
|
27
|
+
run(CC, "-o", target, src, CFLAGS)
|
28
|
+
|
29
|
+
@rule(EXE, depends=OBJS)
|
30
|
+
def link(target, *objs):
|
31
|
+
run(CC, "-o", target, objs)
|
32
|
+
|
33
|
+
@task
|
34
|
+
def clean():
|
35
|
+
run("rm -f", OBJS, "hello.exe")
|
36
|
+
|
37
|
+
@task
|
38
|
+
def rebuild():
|
39
|
+
build(clean, EXE)
|
40
|
+
|
41
|
+
|
42
|
+
|
43
|
+
Other examples can be found in the `samples <https://github.com/atsuoishimoto/pyprod/tree/main/samples>`_ directory.
|
44
|
+
|
15
45
|
Table of Contents
|
16
46
|
--------------------
|
17
47
|
|
@@ -10,12 +10,12 @@ Rule definition
|
|
10
10
|
|
11
11
|
A rule is defined using the ``@rule`` decorator, which takes the target file as an argument. The target file is the output of the rule, and the function that follows the decorator is the build logic that generates the target file.
|
12
12
|
|
13
|
-
.. py:function:: @rule(
|
13
|
+
.. py:function:: @rule(targets, pattern=None, *, depends=(), uses=())
|
14
14
|
|
15
15
|
Defines rule to build target files.
|
16
16
|
|
17
|
-
:param
|
18
|
-
:type target: str | Path|list[str | Path]
|
17
|
+
:param targets: The target file or files to be generated by the rule. Wildcards can be used in filenames, and exactly one % must be included in the filename.
|
18
|
+
:type target: str | Path | list[str | Path]
|
19
19
|
|
20
20
|
:param pattern: Specify the pattern used to extract the stem of the target filename.
|
21
21
|
|
@@ -85,8 +85,8 @@ The rule decorator can also be used as a standalone function without being tied
|
|
85
85
|
|
86
86
|
.. code-block:: python
|
87
87
|
|
88
|
-
rule(
|
89
|
-
rule(
|
88
|
+
rule(targets=("file1", "file2"), depends="inc1")
|
89
|
+
rule(targets=("file3", "file4"), uses="inc2")
|
90
90
|
|
91
91
|
|
92
92
|
|
@@ -97,12 +97,12 @@ Checker definition
|
|
97
97
|
PyProd provides default checkers for common file types for files and directories. For non-file targets requiring specialized checks, you can define a custom checker to determine whether a build is needed.
|
98
98
|
A checker is defined using the ``@check`` decorator, which takes the target file as an argument.
|
99
99
|
|
100
|
-
.. py:function:: @check(
|
100
|
+
.. py:function:: @check(targets)
|
101
101
|
|
102
102
|
Defines a checker to get last modified time of the target.
|
103
103
|
|
104
|
-
:param
|
105
|
-
|
104
|
+
:param targets: The target file or files to be checked. Wildcards can be used.
|
105
|
+
:type target: str | Path | list[str | Path]
|
106
106
|
|
107
107
|
:return: Last modified time of the file if the target exists. Returns false or raise FileNotFoundError if the target does not exist.
|
108
108
|
:rtype: false|float|datetime.datetime
|
@@ -137,6 +137,37 @@ For example, a checker to retrieve the last modified timestamp of a file on Amaz
|
|
137
137
|
return
|
138
138
|
raise
|
139
139
|
|
140
|
+
Task definition
|
141
|
+
^^^^^^^^^^^^^^^^^^
|
142
|
+
|
143
|
+
A task is similar to a rule but does not have a target and is always executed when it is depended upon.
|
144
|
+
|
145
|
+
.. py:function:: @task(*, name=None, uses=(), default=False)
|
146
|
+
|
147
|
+
Defines a task to be executed.
|
148
|
+
|
149
|
+
:param name: The name of the task. Defaults to the function name.
|
150
|
+
:type name: str
|
151
|
+
|
152
|
+
:param uses: Specify the dependencies of the target file.
|
153
|
+
:type uses: str | Path | list[str | Path]
|
154
|
+
|
155
|
+
:param default: If True, this task will be executed when no target is specified in the command-line arguments.
|
156
|
+
|
157
|
+
.. code-block:: python
|
158
|
+
|
159
|
+
@task(depends=("file1", "file2"))
|
160
|
+
def my_task(*files):
|
161
|
+
print("Task executed", files)
|
162
|
+
|
163
|
+
|
164
|
+
`@task` can be used without any arguments if no dependencies are specified.
|
165
|
+
|
166
|
+
.. code-block:: python
|
167
|
+
|
168
|
+
@task
|
169
|
+
def my_task(*files):
|
170
|
+
print("Task executed", files)
|
140
171
|
|
141
172
|
|
142
173
|
|
@@ -148,18 +179,31 @@ In addition to the ``@rule`` and ``@check`` decorators, PyProd provides several
|
|
148
179
|
The following built-ins are available:
|
149
180
|
|
150
181
|
|
182
|
+
.. py:function:: build(*deps)
|
183
|
+
|
184
|
+
Schedule dependencies. The specified deps are built sequentially after the current build completes.
|
185
|
+
|
186
|
+
:param deps: name of dependencies to be built.
|
187
|
+
|
188
|
+
Example:
|
189
|
+
|
190
|
+
.. code-block:: python
|
191
|
+
|
192
|
+
@task
|
193
|
+
def rebuild():
|
194
|
+
build(clean, EXE)
|
195
|
+
|
151
196
|
.. py:function:: pip(*args)
|
152
197
|
|
153
198
|
Install Python packages. It creates a virtual environment if one does not already exist and installs the specified packages.
|
154
199
|
|
155
200
|
:param args: Arguments to pass to the pip install command.
|
156
|
-
:type target: str
|
157
201
|
|
158
|
-
Example:
|
202
|
+
Example:
|
159
203
|
|
160
|
-
.. code-block:: python
|
204
|
+
.. code-block:: python
|
161
205
|
|
162
|
-
|
206
|
+
pip("numpy", "pandas")
|
163
207
|
|
164
208
|
.. _run:
|
165
209
|
|
@@ -196,14 +240,14 @@ Example:
|
|
196
240
|
.. code-block:: python
|
197
241
|
|
198
242
|
run(["echo", "Hello, World!"]) # list style args
|
199
|
-
run(
|
200
|
-
run(
|
243
|
+
run("echo Hello, World") # Shell style args
|
244
|
+
run("echo", "Hello,", "World") # Shell style args (automactic concatenation)
|
201
245
|
run("echo", ["hello", ["world"]]) # Shell style args (automactic flattening)
|
202
246
|
|
203
247
|
files = run("ls", stdout=True).stdout # Capture output
|
204
248
|
|
205
249
|
|
206
|
-
.. py:function::
|
250
|
+
.. py:function:: capture(*args, echo=True, cwd=None, check=True, text=True, shell=None)
|
207
251
|
|
208
252
|
Execute a command and capture the output. This function is a wrapper around
|
209
253
|
:ref:`run <run>`.
|
@@ -211,10 +255,10 @@ Example:
|
|
211
255
|
:param args: Command and arguments to execute. If first argument is a list, the first element is the command and the rest are arguments. Sequences specified for args are automatically flattened.
|
212
256
|
:type args: str | Path | list[str | Path]
|
213
257
|
|
214
|
-
:echo: Print the command before executing it (default ``True``).
|
258
|
+
:param echo: Print the command before executing it (default ``True``).
|
215
259
|
:type echo: bool
|
216
260
|
|
217
|
-
:cwd: Change the current working directory before executing the command.
|
261
|
+
:param cwd: Change the current working directory before executing the command.
|
218
262
|
:type shell: str | Path | None
|
219
263
|
|
220
264
|
:param check: Raise an exception if the command returns a non-zero exit code (default ``True``).
|
@@ -235,7 +279,7 @@ Example:
|
|
235
279
|
msg = capture("echo Hello, World!")
|
236
280
|
|
237
281
|
|
238
|
-
.. py:function:: read(filename)
|
282
|
+
.. py:function:: read(filename)
|
239
283
|
|
240
284
|
Read the contents of a file.
|
241
285
|
|
@@ -245,7 +289,7 @@ Example:
|
|
245
289
|
:return: The contents of the file.
|
246
290
|
:rtype: str
|
247
291
|
|
248
|
-
.. py:function:: write(filename, txt, append=False)
|
292
|
+
.. py:function:: write(filename, txt, append=False)
|
249
293
|
|
250
294
|
Write text to a file.
|
251
295
|
|
@@ -258,7 +302,7 @@ Example:
|
|
258
302
|
:param append: Append to the file instead of overwriting it (default ``False``).
|
259
303
|
:type append: bool
|
260
304
|
|
261
|
-
.. py:function:: makedirs(path)
|
305
|
+
.. py:function:: makedirs(path)
|
262
306
|
|
263
307
|
Create a directory along with any necessary parent directories if they do not already exist. This function wraps `os.makedirs() <https://docs.python.org/3/library/os.html#os.makedirs>`_ with the ``exists_ok`` parameter set to ``True``.
|
264
308
|
|
@@ -285,27 +329,34 @@ Example:
|
|
285
329
|
|
286
330
|
SRCFILES = glob("**/*.c")
|
287
331
|
|
288
|
-
.. py:function:: quote(s)
|
289
|
-
.. py:function:: q(s)
|
332
|
+
.. py:function:: quote(*s)
|
333
|
+
.. py:function:: q(*s)
|
290
334
|
|
291
|
-
|
335
|
+
Quote strings in ``s``. Each ``s`` is flattend.
|
292
336
|
|
293
337
|
:param s: The string to quote.
|
294
|
-
:type s: str
|
338
|
+
:type s: str | list
|
295
339
|
|
296
|
-
:return: The quoted
|
297
|
-
:rtype: str
|
340
|
+
:return: The list of quoted strings.
|
341
|
+
:rtype: list[str]
|
298
342
|
|
299
|
-
.. py:function:: squote(
|
300
|
-
.. py:function:: sq(
|
343
|
+
.. py:function:: squote(s)
|
344
|
+
.. py:function:: sq(s)
|
301
345
|
|
302
|
-
|
346
|
+
Convert ``s`` to string and quote for use as a shell command argument. This function is a wrapper around `shlex.quote() <https://docs.python.org/3/library/shlex.html#shlex.quote>`_.
|
303
347
|
|
304
|
-
:param s: The string to quote.
|
348
|
+
:param s: The string to quote. If ``s`` is sequence, it is flattened and joined with space.
|
305
349
|
:type s: str | list
|
306
350
|
|
307
|
-
:return: The
|
308
|
-
:rtype:
|
351
|
+
:return: The quoted string.
|
352
|
+
:rtype: str
|
353
|
+
|
354
|
+
.. py:function:: use_git(use)
|
355
|
+
|
356
|
+
Enable or disable git support. If enabled, PyProd retrieves the last modified time of the files from the git log.
|
357
|
+
|
358
|
+
:param use: Enable or disable git support.
|
359
|
+
:type bool: bool
|
309
360
|
|
310
361
|
.. py:class:: Path
|
311
362
|
|
@@ -316,8 +367,7 @@ Example:
|
|
316
367
|
|
317
368
|
.. py:data:: shutil
|
318
369
|
|
319
|
-
|
320
|
-
|
370
|
+
An alias for the Python Standard Library's `shutil <https://docs.python.org/3/library/shutil.html>`_ module. This module provides a higher-level interface for file operations than the built-in `os <https://docs.python.org/3/library/os.html>`_ module.
|
321
371
|
|
322
372
|
.. py:data:: env
|
323
373
|
|
@@ -0,0 +1,22 @@
|
|
1
|
+
Release Notes
|
2
|
+
================
|
3
|
+
|
4
|
+
0.5.0 (2025-2-12)
|
5
|
+
-----------------------------
|
6
|
+
|
7
|
+
- Added ``default`` to the ``@task``.
|
8
|
+
- Removed ``depends`` from thr ``@task``.
|
9
|
+
- Added --use-git commandline option.
|
10
|
+
|
11
|
+
0.4.0 (2025-1-17)
|
12
|
+
-------------------------
|
13
|
+
- Swapped the behavior of quote() and squote() to make their naming more intuitive.
|
14
|
+
- Add @task decorator.
|
15
|
+
- Change the parameter name target to targets.
|
16
|
+
- Added --rebuild option.
|
17
|
+
|
18
|
+
0.3.0 (2025-01-03)
|
19
|
+
------------------
|
20
|
+
- Arguments for build and check function are converted to string.
|
21
|
+
- Add built-in functions.
|
22
|
+
- Validate rule dependencies.
|
@@ -1,6 +1,6 @@
|
|
1
1
|
[project]
|
2
2
|
name = "PyProd"
|
3
|
-
|
3
|
+
dynamic = ["version"]
|
4
4
|
description = "PyProd: More Makeable than Make"
|
5
5
|
readme = "README.rst"
|
6
6
|
requires-python = ">=3.10"
|
@@ -12,7 +12,9 @@ classifiers = [
|
|
12
12
|
"Environment :: Console",
|
13
13
|
"Topic :: Software Development :: Build Tools",
|
14
14
|
]
|
15
|
-
dependencies = [
|
15
|
+
dependencies = [
|
16
|
+
"python-dateutil",
|
17
|
+
]
|
16
18
|
|
17
19
|
[project.urls]
|
18
20
|
Homepage = "https://github.com/atsuoishimoto/pyprod"
|
@@ -25,10 +27,14 @@ pyprod = "pyprod.main:main"
|
|
25
27
|
requires = ["hatchling"]
|
26
28
|
build-backend = "hatchling.build"
|
27
29
|
|
30
|
+
[tool.hatch.version]
|
31
|
+
path = "src/pyprod/__init__.py"
|
32
|
+
|
28
33
|
[dependency-groups]
|
29
34
|
dev = [
|
30
35
|
"pytest>=8.3.4",
|
31
36
|
"pytest-asyncio>=0.25.0",
|
37
|
+
"pytest-mock>=3.14.0",
|
32
38
|
"ruff>=0.8.4",
|
33
39
|
"sphinx>=8.1.3",
|
34
40
|
"sphinx-autobuild>=2024.10.3",
|
@@ -3,7 +3,7 @@
|
|
3
3
|
|
4
4
|
APP = "hello.exe"
|
5
5
|
CC = "gcc"
|
6
|
-
CFLAGS = "-I."
|
6
|
+
CFLAGS = "-c -I."
|
7
7
|
DEPS = "hello.h"
|
8
8
|
OBJS = "hello.o main.o".split()
|
9
9
|
|
@@ -15,11 +15,14 @@ def link(target, *src):
|
|
15
15
|
|
16
16
|
@rule("%.o", depends=("%.c", DEPS))
|
17
17
|
def compile(target, src, *deps):
|
18
|
-
run(CC, "-
|
18
|
+
run(CC, "-o", target, src, CFLAGS)
|
19
19
|
|
20
20
|
|
21
|
+
@task
|
21
22
|
def clean():
|
22
23
|
run("rm", "-rf", OBJS, APP)
|
23
24
|
|
24
25
|
|
25
|
-
|
26
|
+
@task
|
27
|
+
def rebuild():
|
28
|
+
build(clean, APP)
|
pyprod-0.3.0/sample/generate-doc/PRODFILE.py → pyprod-0.5.0/samples/generate-doc/Prodfile.py
RENAMED
@@ -15,7 +15,7 @@ def build_app(target, *src):
|
|
15
15
|
|
16
16
|
@rule(BUILDDIR)
|
17
17
|
def build_dir(target):
|
18
|
-
run("mkdir", target)
|
18
|
+
run("mkdir -p", target)
|
19
19
|
|
20
20
|
|
21
21
|
@rule(BUILDDIR / "%.o", depends=("%.txt", COMMON), uses=BUILDDIR)
|
@@ -23,8 +23,11 @@ def build_c(target, src, *commons):
|
|
23
23
|
run("cat", *commons, src, ">", target)
|
24
24
|
|
25
25
|
|
26
|
+
@task
|
26
27
|
def clean():
|
27
28
|
run("rm", "-rf", BUILDDIR, BUILDFILES, DOC)
|
28
29
|
|
29
30
|
|
30
|
-
|
31
|
+
@task
|
32
|
+
def rebuild():
|
33
|
+
build(clean, DOC)
|
@@ -39,9 +39,15 @@ def make_html(target, src, template, *_):
|
|
39
39
|
# create outputs directory
|
40
40
|
@rule(BUILD)
|
41
41
|
def builds(target):
|
42
|
-
os.makedirs(target)
|
42
|
+
os.makedirs(target, exist_ok=True)
|
43
43
|
|
44
44
|
|
45
|
+
@task
|
45
46
|
def clean():
|
46
47
|
shutil.rmtree(BUILD, ignore_errors=True)
|
47
48
|
PDF.unlink(missing_ok=True)
|
49
|
+
|
50
|
+
|
51
|
+
@task
|
52
|
+
def rebuild():
|
53
|
+
build(clean, PDF)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# ruff: NOQA
|
2
2
|
# type: ignore
|
3
3
|
|
4
|
-
pip("boto3") # install boto3
|
4
|
+
pip("boto3", "-q") # install boto3
|
5
5
|
|
6
6
|
import boto3, botocore
|
7
7
|
from urllib.parse import urlparse
|
@@ -17,7 +17,7 @@ def parse_s3url(s3url):
|
|
17
17
|
return parsed.netloc, parsed.path.lstrip("/")
|
18
18
|
|
19
19
|
|
20
|
-
@rule(
|
20
|
+
@rule(targets=TARGET, pattern="*/%.txt", depends="%.txt")
|
21
21
|
def copyfile(target, src):
|
22
22
|
"""Copies a file to an S3 bucket."""
|
23
23
|
bucket, key = parse_s3url(target)
|
@@ -36,16 +36,20 @@ def check_s3file(s3url):
|
|
36
36
|
raise
|
37
37
|
|
38
38
|
|
39
|
+
@task
|
39
40
|
def clean():
|
40
41
|
"""Deletes an S3 file."""
|
41
42
|
bucket, key = parse_s3url(TARGET)
|
42
43
|
s3.delete_object(Bucket=bucket, Key=key)
|
43
44
|
|
44
45
|
|
46
|
+
@task
|
45
47
|
def ls():
|
46
48
|
"""Lists the contents of an S3 bucket."""
|
47
49
|
bucket, key = parse_s3url(TARGET)
|
48
50
|
run("aws s3 ls", bucket)
|
49
51
|
|
50
52
|
|
51
|
-
|
53
|
+
@task
|
54
|
+
def rebuild():
|
55
|
+
build(clean, TARGET)
|
@@ -0,0 +1 @@
|
|
1
|
+
__version__ = "0.5.0"
|