ppqs 2.0.2__tar.gz → 2.1.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.
- {ppqs-2.0.2/src/ppqs.egg-info → ppqs-2.1.0}/PKG-INFO +26 -14
- {ppqs-2.0.2 → ppqs-2.1.0}/README.md +25 -13
- {ppqs-2.0.2 → ppqs-2.1.0}/pyproject.toml +1 -1
- {ppqs-2.0.2 → ppqs-2.1.0/src/ppqs.egg-info}/PKG-INFO +26 -14
- {ppqs-2.0.2 → ppqs-2.1.0}/src/py_proj_quick_scripts/__init__.py +18 -4
- {ppqs-2.0.2 → ppqs-2.1.0}/test/test_cli.py +40 -2
- {ppqs-2.0.2 → ppqs-2.1.0}/test/test_parse_scripts.py +32 -1
- {ppqs-2.0.2 → ppqs-2.1.0}/LICENSE +0 -0
- {ppqs-2.0.2 → ppqs-2.1.0}/setup.cfg +0 -0
- {ppqs-2.0.2 → ppqs-2.1.0}/src/ppqs.egg-info/SOURCES.txt +0 -0
- {ppqs-2.0.2 → ppqs-2.1.0}/src/ppqs.egg-info/dependency_links.txt +0 -0
- {ppqs-2.0.2 → ppqs-2.1.0}/src/ppqs.egg-info/entry_points.txt +0 -0
- {ppqs-2.0.2 → ppqs-2.1.0}/src/ppqs.egg-info/requires.txt +0 -0
- {ppqs-2.0.2 → ppqs-2.1.0}/src/ppqs.egg-info/top_level.txt +0 -0
- {ppqs-2.0.2 → ppqs-2.1.0}/test/test_find_pyproject.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ppqs
|
|
3
|
-
Version: 2.0
|
|
3
|
+
Version: 2.1.0
|
|
4
4
|
Summary: Python project quick scripts
|
|
5
5
|
Author-email: Karl Wette <karl.wette@anu.edu.au>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -100,17 +100,30 @@ $ ppqs print-something Hi
|
|
|
100
100
|
Hi
|
|
101
101
|
```
|
|
102
102
|
|
|
103
|
-
The following only applies to scripts defined as lists of lists:
|
|
104
|
-
argument is itself a list, it is concatenated into a path appropriate for the
|
|
105
|
-
current operating system. For example,
|
|
103
|
+
The following only applies to scripts defined as lists of lists:
|
|
106
104
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
```
|
|
105
|
+
* If a command argument is itself a list, it is concatenated into a path
|
|
106
|
+
appropriate for the current operating system. For example,
|
|
107
|
+
|
|
108
|
+
```toml
|
|
109
|
+
[tool.ppqs.scripts]
|
|
110
|
+
do-something = [["do-something-to", ["subdir", "afile"]]]
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
would run the command `do-something-to subdir/afile` on a Unix-based operating
|
|
114
|
+
system.
|
|
115
|
+
|
|
116
|
+
If the last element of the path contains a wildcard (`*`), the path is
|
|
117
|
+
expanded at runtime into a list of files/directories matching the wildcard
|
|
118
|
+
expression. For example, if the directory `subdir/` contained the files
|
|
119
|
+
`file1.txt`, `file2.txt`, and `file3.dat`, then:
|
|
120
|
+
|
|
121
|
+
```toml
|
|
122
|
+
[tool.ppqs.scripts]
|
|
123
|
+
do-something = [["do-something-to", ["subdir", "*.txt"]]]
|
|
124
|
+
```
|
|
111
125
|
|
|
112
|
-
would run the command `do-something-to subdir/
|
|
113
|
-
system.
|
|
126
|
+
would run the command `do-something-to subdir/file1.txt subdir/file2.txt`
|
|
114
127
|
|
|
115
128
|
Scripts may also be defined in their own section, which permit a few options:
|
|
116
129
|
|
|
@@ -146,10 +159,9 @@ The default value of some options may be overridden in the
|
|
|
146
159
|
print-header = true
|
|
147
160
|
```
|
|
148
161
|
|
|
149
|
-
Note that commands are *not* passed to the shell, so shell features
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
then be called by `ppqs` as:
|
|
162
|
+
Note that commands are *not* passed to the shell, so shell features are not
|
|
163
|
+
available. The recommended solution is to write a helper script,
|
|
164
|
+
e.g. `scripts/lots-to-do.py`, which may then be called by `ppqs` as:
|
|
153
165
|
|
|
154
166
|
```toml
|
|
155
167
|
[tool.ppqs.scripts]
|
|
@@ -84,17 +84,30 @@ $ ppqs print-something Hi
|
|
|
84
84
|
Hi
|
|
85
85
|
```
|
|
86
86
|
|
|
87
|
-
The following only applies to scripts defined as lists of lists:
|
|
88
|
-
argument is itself a list, it is concatenated into a path appropriate for the
|
|
89
|
-
current operating system. For example,
|
|
87
|
+
The following only applies to scripts defined as lists of lists:
|
|
90
88
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
```
|
|
89
|
+
* If a command argument is itself a list, it is concatenated into a path
|
|
90
|
+
appropriate for the current operating system. For example,
|
|
91
|
+
|
|
92
|
+
```toml
|
|
93
|
+
[tool.ppqs.scripts]
|
|
94
|
+
do-something = [["do-something-to", ["subdir", "afile"]]]
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
would run the command `do-something-to subdir/afile` on a Unix-based operating
|
|
98
|
+
system.
|
|
99
|
+
|
|
100
|
+
If the last element of the path contains a wildcard (`*`), the path is
|
|
101
|
+
expanded at runtime into a list of files/directories matching the wildcard
|
|
102
|
+
expression. For example, if the directory `subdir/` contained the files
|
|
103
|
+
`file1.txt`, `file2.txt`, and `file3.dat`, then:
|
|
104
|
+
|
|
105
|
+
```toml
|
|
106
|
+
[tool.ppqs.scripts]
|
|
107
|
+
do-something = [["do-something-to", ["subdir", "*.txt"]]]
|
|
108
|
+
```
|
|
95
109
|
|
|
96
|
-
would run the command `do-something-to subdir/
|
|
97
|
-
system.
|
|
110
|
+
would run the command `do-something-to subdir/file1.txt subdir/file2.txt`
|
|
98
111
|
|
|
99
112
|
Scripts may also be defined in their own section, which permit a few options:
|
|
100
113
|
|
|
@@ -130,10 +143,9 @@ The default value of some options may be overridden in the
|
|
|
130
143
|
print-header = true
|
|
131
144
|
```
|
|
132
145
|
|
|
133
|
-
Note that commands are *not* passed to the shell, so shell features
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
then be called by `ppqs` as:
|
|
146
|
+
Note that commands are *not* passed to the shell, so shell features are not
|
|
147
|
+
available. The recommended solution is to write a helper script,
|
|
148
|
+
e.g. `scripts/lots-to-do.py`, which may then be called by `ppqs` as:
|
|
137
149
|
|
|
138
150
|
```toml
|
|
139
151
|
[tool.ppqs.scripts]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ppqs
|
|
3
|
-
Version: 2.0
|
|
3
|
+
Version: 2.1.0
|
|
4
4
|
Summary: Python project quick scripts
|
|
5
5
|
Author-email: Karl Wette <karl.wette@anu.edu.au>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -100,17 +100,30 @@ $ ppqs print-something Hi
|
|
|
100
100
|
Hi
|
|
101
101
|
```
|
|
102
102
|
|
|
103
|
-
The following only applies to scripts defined as lists of lists:
|
|
104
|
-
argument is itself a list, it is concatenated into a path appropriate for the
|
|
105
|
-
current operating system. For example,
|
|
103
|
+
The following only applies to scripts defined as lists of lists:
|
|
106
104
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
```
|
|
105
|
+
* If a command argument is itself a list, it is concatenated into a path
|
|
106
|
+
appropriate for the current operating system. For example,
|
|
107
|
+
|
|
108
|
+
```toml
|
|
109
|
+
[tool.ppqs.scripts]
|
|
110
|
+
do-something = [["do-something-to", ["subdir", "afile"]]]
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
would run the command `do-something-to subdir/afile` on a Unix-based operating
|
|
114
|
+
system.
|
|
115
|
+
|
|
116
|
+
If the last element of the path contains a wildcard (`*`), the path is
|
|
117
|
+
expanded at runtime into a list of files/directories matching the wildcard
|
|
118
|
+
expression. For example, if the directory `subdir/` contained the files
|
|
119
|
+
`file1.txt`, `file2.txt`, and `file3.dat`, then:
|
|
120
|
+
|
|
121
|
+
```toml
|
|
122
|
+
[tool.ppqs.scripts]
|
|
123
|
+
do-something = [["do-something-to", ["subdir", "*.txt"]]]
|
|
124
|
+
```
|
|
111
125
|
|
|
112
|
-
would run the command `do-something-to subdir/
|
|
113
|
-
system.
|
|
126
|
+
would run the command `do-something-to subdir/file1.txt subdir/file2.txt`
|
|
114
127
|
|
|
115
128
|
Scripts may also be defined in their own section, which permit a few options:
|
|
116
129
|
|
|
@@ -146,10 +159,9 @@ The default value of some options may be overridden in the
|
|
|
146
159
|
print-header = true
|
|
147
160
|
```
|
|
148
161
|
|
|
149
|
-
Note that commands are *not* passed to the shell, so shell features
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
then be called by `ppqs` as:
|
|
162
|
+
Note that commands are *not* passed to the shell, so shell features are not
|
|
163
|
+
available. The recommended solution is to write a helper script,
|
|
164
|
+
e.g. `scripts/lots-to-do.py`, which may then be called by `ppqs` as:
|
|
153
165
|
|
|
154
166
|
```toml
|
|
155
167
|
[tool.ppqs.scripts]
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import glob
|
|
1
2
|
import os
|
|
2
3
|
import re
|
|
3
4
|
import shutil
|
|
@@ -12,7 +13,7 @@ else: # pragma: no cover
|
|
|
12
13
|
import tomli as tomllib
|
|
13
14
|
|
|
14
15
|
__author__ = "Karl Wette"
|
|
15
|
-
__version__ = "2.0
|
|
16
|
+
__version__ = "2.1.0"
|
|
16
17
|
|
|
17
18
|
|
|
18
19
|
class MissingPyProjectError(Exception):
|
|
@@ -151,11 +152,14 @@ def parse_scripts(pyproject_path):
|
|
|
151
152
|
|
|
152
153
|
# List arguments are treated as paths
|
|
153
154
|
arg_path = Path(*arg)
|
|
155
|
+
if any("*" in a for a in arg[:-1]):
|
|
156
|
+
msg2 = f"path argument '{arg_path}' may contain wildcards only in the last element"
|
|
157
|
+
raise InvalidScriptError(pyproject_path, msg2)
|
|
154
158
|
if arg_path.is_absolute():
|
|
155
159
|
msg2 = f"path argument '{arg_path}' must be a relative path"
|
|
156
160
|
raise InvalidScriptError(pyproject_path, msg2)
|
|
157
161
|
|
|
158
|
-
script_line.append(
|
|
162
|
+
script_line.append(arg_path)
|
|
159
163
|
|
|
160
164
|
else:
|
|
161
165
|
script_line.append(arg)
|
|
@@ -211,7 +215,16 @@ def run_script(script_name, script, argv, cwd):
|
|
|
211
215
|
cmd = []
|
|
212
216
|
|
|
213
217
|
for arg in command:
|
|
214
|
-
if arg
|
|
218
|
+
if isinstance(arg, Path):
|
|
219
|
+
if "*" in arg.parts[-1]:
|
|
220
|
+
|
|
221
|
+
# Expand wildcards in last path element
|
|
222
|
+
cmd.extend(sorted(glob.glob(str(arg), recursive=False)))
|
|
223
|
+
|
|
224
|
+
else:
|
|
225
|
+
cmd.append(str(arg))
|
|
226
|
+
|
|
227
|
+
elif arg == "...":
|
|
215
228
|
|
|
216
229
|
# Replace "..." in command with arguments
|
|
217
230
|
cmd.extend(argv)
|
|
@@ -222,7 +235,8 @@ def run_script(script_name, script, argv, cwd):
|
|
|
222
235
|
# Print header
|
|
223
236
|
if script["print-header"]:
|
|
224
237
|
cmd_str = " ".join(cmd)
|
|
225
|
-
|
|
238
|
+
header = f"*** ppqs {script_name}: {cmd_str} ***".center(col_width, "*")
|
|
239
|
+
print(header, flush=True)
|
|
226
240
|
|
|
227
241
|
# Run command
|
|
228
242
|
retn = subprocess.run(cmd, stdin=subprocess.DEVNULL, shell=False, cwd=cwd)
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
1
3
|
import pytest
|
|
2
4
|
|
|
3
5
|
from py_proj_quick_scripts import InvalidScriptError, cli
|
|
@@ -24,6 +26,14 @@ def pyproject_path(tmp_path):
|
|
|
24
26
|
script = [
|
|
25
27
|
["python", "-c", "import sys; print(*sys.argv[1:])", "..."],
|
|
26
28
|
]
|
|
29
|
+
[tool.ppqs.scripts.echo-path]
|
|
30
|
+
script = [
|
|
31
|
+
["python", "-c", "import sys; print(*sys.argv[1:])", ["afile"], ["subdir", "bfile"]],
|
|
32
|
+
]
|
|
33
|
+
[tool.ppqs.scripts.echo-wildcard]
|
|
34
|
+
script = [
|
|
35
|
+
["python", "-c", "import sys; print(*sys.argv[1:])", ["subdir", "*.txt"]],
|
|
36
|
+
]
|
|
27
37
|
"""
|
|
28
38
|
|
|
29
39
|
write_file(pyproject_path, pyproject_toml)
|
|
@@ -53,7 +63,7 @@ def test_notest(pyproject_path):
|
|
|
53
63
|
|
|
54
64
|
def test_exit(pyproject_path):
|
|
55
65
|
"""
|
|
56
|
-
Test exit
|
|
66
|
+
Test `exit` script.
|
|
57
67
|
"""
|
|
58
68
|
|
|
59
69
|
with in_dir(pyproject_path.parent):
|
|
@@ -63,7 +73,7 @@ def test_exit(pyproject_path):
|
|
|
63
73
|
|
|
64
74
|
def test_echo(pyproject_path, capfd):
|
|
65
75
|
"""
|
|
66
|
-
Test echo
|
|
76
|
+
Test `echo` script.
|
|
67
77
|
"""
|
|
68
78
|
|
|
69
79
|
with in_dir(pyproject_path.parent):
|
|
@@ -71,3 +81,31 @@ def test_echo(pyproject_path, capfd):
|
|
|
71
81
|
captured = capfd.readouterr()
|
|
72
82
|
assert captured.out == "Hello\n"
|
|
73
83
|
assert captured.err == ""
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def test_echo_path(pyproject_path, capfd):
|
|
87
|
+
"""
|
|
88
|
+
Test `echo-path` script.
|
|
89
|
+
"""
|
|
90
|
+
|
|
91
|
+
with in_dir(pyproject_path.parent):
|
|
92
|
+
cli("echo-path")
|
|
93
|
+
captured = capfd.readouterr()
|
|
94
|
+
assert captured.out == "afile subdir/bfile\n".replace("/", os.sep)
|
|
95
|
+
assert captured.err == ""
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def test_echo_wildcard(pyproject_path, capfd):
|
|
99
|
+
"""
|
|
100
|
+
Test `echo-wildcard` script.
|
|
101
|
+
"""
|
|
102
|
+
|
|
103
|
+
with in_dir(pyproject_path.parent) as wd:
|
|
104
|
+
subdir = wd / "subdir"
|
|
105
|
+
subdir.mkdir()
|
|
106
|
+
write_file(subdir / "a.txt", "Some text")
|
|
107
|
+
write_file(subdir / "b.txt", "Some more text")
|
|
108
|
+
cli("echo-wildcard")
|
|
109
|
+
captured = capfd.readouterr()
|
|
110
|
+
assert captured.out == "subdir/a.txt subdir/b.txt\n".replace("/", os.sep)
|
|
111
|
+
assert captured.err == ""
|
|
@@ -219,12 +219,43 @@ from . import in_dir, write_file
|
|
|
219
219
|
"paths": {
|
|
220
220
|
"description": "Run paths script",
|
|
221
221
|
"print-header": False,
|
|
222
|
-
"commands": [["echo",
|
|
222
|
+
"commands": [["echo", Path("a", "b")]],
|
|
223
223
|
}
|
|
224
224
|
}
|
|
225
225
|
),
|
|
226
226
|
id="list script with relative path",
|
|
227
227
|
),
|
|
228
|
+
pytest.param(
|
|
229
|
+
"""
|
|
230
|
+
[tool.ppqs.scripts]
|
|
231
|
+
paths = [
|
|
232
|
+
["echo", ["*", "b"]],
|
|
233
|
+
]
|
|
234
|
+
""",
|
|
235
|
+
pytest.raises(
|
|
236
|
+
InvalidScriptError,
|
|
237
|
+
match="may contain wildcards only in the last element",
|
|
238
|
+
),
|
|
239
|
+
id="list script with path and invalid wildcard",
|
|
240
|
+
),
|
|
241
|
+
pytest.param(
|
|
242
|
+
"""
|
|
243
|
+
[tool.ppqs.scripts]
|
|
244
|
+
paths = [
|
|
245
|
+
["echo", ["a", "*.txt"]],
|
|
246
|
+
]
|
|
247
|
+
""",
|
|
248
|
+
nullcontext(
|
|
249
|
+
{
|
|
250
|
+
"paths": {
|
|
251
|
+
"description": "Run paths script",
|
|
252
|
+
"print-header": False,
|
|
253
|
+
"commands": [["echo", Path("a", "*.txt")]],
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
),
|
|
257
|
+
id="list script with path and valid wildcard",
|
|
258
|
+
),
|
|
228
259
|
],
|
|
229
260
|
)
|
|
230
261
|
def test_parse_scripts(tmp_path, script_toml, expectation):
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|