cleepcli 1.45.0__tar.gz → 1.45.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.
- {cleepcli-1.45.0/cleepcli.egg-info → cleepcli-1.45.1}/PKG-INFO +2 -2
- {cleepcli-1.45.0 → cleepcli-1.45.1}/README.md +1 -1
- {cleepcli-1.45.0 → cleepcli-1.45.1}/cleepcli/console.py +45 -8
- {cleepcli-1.45.0 → cleepcli-1.45.1}/cleepcli/test.py +9 -52
- {cleepcli-1.45.0 → cleepcli-1.45.1}/cleepcli/version.py +1 -1
- {cleepcli-1.45.0 → cleepcli-1.45.1/cleepcli.egg-info}/PKG-INFO +2 -2
- {cleepcli-1.45.0 → cleepcli-1.45.1}/LICENSE +0 -0
- {cleepcli-1.45.0 → cleepcli-1.45.1}/MANIFEST.in +0 -0
- {cleepcli-1.45.0 → cleepcli-1.45.1}/bin/ccli +0 -0
- {cleepcli-1.45.0 → cleepcli-1.45.1}/bin/cleep-cli +0 -0
- {cleepcli-1.45.0 → cleepcli-1.45.1}/cleepcli/__init__.py +0 -0
- {cleepcli-1.45.0 → cleepcli-1.45.1}/cleepcli/check.py +0 -0
- {cleepcli-1.45.0 → cleepcli-1.45.1}/cleepcli/ci.py +0 -0
- {cleepcli-1.45.0 → cleepcli-1.45.1}/cleepcli/cleepapi.py +0 -0
- {cleepcli-1.45.0 → cleepcli-1.45.1}/cleepcli/config.py +0 -0
- {cleepcli-1.45.0 → cleepcli-1.45.1}/cleepcli/docs.py +0 -0
- {cleepcli-1.45.0 → cleepcli-1.45.1}/cleepcli/file.py +0 -0
- {cleepcli-1.45.0 → cleepcli-1.45.1}/cleepcli/git.py +0 -0
- {cleepcli-1.45.0 → cleepcli-1.45.1}/cleepcli/module.py +0 -0
- {cleepcli-1.45.0 → cleepcli-1.45.1}/cleepcli/package.py +0 -0
- {cleepcli-1.45.0 → cleepcli-1.45.1}/cleepcli/tools.py +0 -0
- {cleepcli-1.45.0 → cleepcli-1.45.1}/cleepcli/watch.py +0 -0
- {cleepcli-1.45.0 → cleepcli-1.45.1}/cleepcli.egg-info/SOURCES.txt +0 -0
- {cleepcli-1.45.0 → cleepcli-1.45.1}/cleepcli.egg-info/dependency_links.txt +0 -0
- {cleepcli-1.45.0 → cleepcli-1.45.1}/cleepcli.egg-info/requires.txt +0 -0
- {cleepcli-1.45.0 → cleepcli-1.45.1}/cleepcli.egg-info/top_level.txt +0 -0
- {cleepcli-1.45.0 → cleepcli-1.45.1}/pyproject.toml +0 -0
- {cleepcli-1.45.0 → cleepcli-1.45.1}/requirements.txt +0 -0
- {cleepcli-1.45.0 → cleepcli-1.45.1}/setup.cfg +0 -0
- {cleepcli-1.45.0 → cleepcli-1.45.1}/setup.py +0 -0
- {cleepcli-1.45.0 → cleepcli-1.45.1}/tests/test_check.py +0 -0
- {cleepcli-1.45.0 → cleepcli-1.45.1}/tests/test_config.py +0 -0
- {cleepcli-1.45.0 → cleepcli-1.45.1}/tests/test_console.py +0 -0
- {cleepcli-1.45.0 → cleepcli-1.45.1}/tests/test_coverage.py +0 -0
- {cleepcli-1.45.0 → cleepcli-1.45.1}/tests/test_docs_breaking.py +0 -0
- {cleepcli-1.45.0 → cleepcli-1.45.1}/tests/test_module_scaffold.py +0 -0
- {cleepcli-1.45.0 → cleepcli-1.45.1}/tests/test_watch.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cleepcli
|
|
3
|
-
Version: 1.45.
|
|
3
|
+
Version: 1.45.1
|
|
4
4
|
Summary: Cleep-cli helps developers to build great Cleep applications from command line.
|
|
5
5
|
Home-page: https://github.com/CleepDevice/cleep-cli
|
|
6
6
|
Author: Tanguy Bonneau
|
|
@@ -142,7 +142,7 @@ The [watchdog](https://pypi.org/project/watchdog/) python library is used to det
|
|
|
142
142
|
|
|
143
143
|
## CI (GitHub Actions)
|
|
144
144
|
|
|
145
|
-
A tag `vX.Y.Z` (or a manual **workflow_dispatch**) builds a **py3** wheel + sdist on `ubuntu-latest` (Python 3.
|
|
145
|
+
A tag `vX.Y.Z` (or a manual **workflow_dispatch**) builds a **py3** wheel + sdist on `ubuntu-latest` (Python 3.12) via `python -m build` and uploads them to PyPI.
|
|
146
146
|
|
|
147
147
|
GitHub **environment** `actions` (Settings → Environments), secret:
|
|
148
148
|
|
|
@@ -106,7 +106,7 @@ The [watchdog](https://pypi.org/project/watchdog/) python library is used to det
|
|
|
106
106
|
|
|
107
107
|
## CI (GitHub Actions)
|
|
108
108
|
|
|
109
|
-
A tag `vX.Y.Z` (or a manual **workflow_dispatch**) builds a **py3** wheel + sdist on `ubuntu-latest` (Python 3.
|
|
109
|
+
A tag `vX.Y.Z` (or a manual **workflow_dispatch**) builds a **py3** wheel + sdist on `ubuntu-latest` (Python 3.12) via `python -m build` and uploads them to PyPI.
|
|
110
110
|
|
|
111
111
|
GitHub **environment** `actions` (Settings → Environments), secret:
|
|
112
112
|
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import sys
|
|
5
5
|
import subprocess
|
|
6
6
|
import time
|
|
7
|
+
import atexit
|
|
7
8
|
from threading import Timer, Thread
|
|
8
9
|
try: # pragma: no cover
|
|
9
10
|
from Queue import Queue, Empty
|
|
@@ -58,12 +59,40 @@ class EndlessConsole(Thread):
|
|
|
58
59
|
self.__stderr_queue = Queue()
|
|
59
60
|
self.__stdout_thread = None
|
|
60
61
|
self.__stderr_thread = None
|
|
62
|
+
self.__proc = None
|
|
63
|
+
self.__pid = None
|
|
64
|
+
# Child runs in its own session (setsid). Reap it if the CLI exits via
|
|
65
|
+
# Ctrl-C before kill() — otherwise coverage/pytest can orphan and OOM a Pi.
|
|
66
|
+
atexit.register(self.__reap_child)
|
|
61
67
|
|
|
62
68
|
def __del__(self):
|
|
63
69
|
"""
|
|
64
70
|
Destructor
|
|
65
71
|
"""
|
|
66
72
|
self.__stop()
|
|
73
|
+
self.__reap_child()
|
|
74
|
+
|
|
75
|
+
def __reap_child(self):
|
|
76
|
+
"""Kill leftover process group if the subprocess is still running."""
|
|
77
|
+
pid = self.__pid
|
|
78
|
+
proc = self.__proc
|
|
79
|
+
if not pid or pid == 1:
|
|
80
|
+
return
|
|
81
|
+
try:
|
|
82
|
+
if proc is not None and proc.poll() is None:
|
|
83
|
+
self.logger.debug('Reaping leftover process group pid=%s', pid)
|
|
84
|
+
if ON_POSIX:
|
|
85
|
+
os.killpg(os.getpgid(pid), signal.SIGKILL)
|
|
86
|
+
else: # pragma: no cover
|
|
87
|
+
proc.kill()
|
|
88
|
+
self.killed = True
|
|
89
|
+
except Exception: # pragma: no cover
|
|
90
|
+
pass
|
|
91
|
+
finally:
|
|
92
|
+
try:
|
|
93
|
+
atexit.unregister(self.__reap_child)
|
|
94
|
+
except Exception: # pragma: no cover
|
|
95
|
+
pass
|
|
67
96
|
|
|
68
97
|
def __enqueue_output(self, output, queue):
|
|
69
98
|
for line in iter(output.readline, b''):
|
|
@@ -103,6 +132,7 @@ class EndlessConsole(Thread):
|
|
|
103
132
|
self.logger.debug('Process killed manually')
|
|
104
133
|
self.killed = True
|
|
105
134
|
self.__stop()
|
|
135
|
+
self.__reap_child()
|
|
106
136
|
|
|
107
137
|
def __send_stds(self):
|
|
108
138
|
"""
|
|
@@ -156,7 +186,9 @@ class EndlessConsole(Thread):
|
|
|
156
186
|
close_fds=True,
|
|
157
187
|
preexec_fn=os.setsid
|
|
158
188
|
)
|
|
159
|
-
|
|
189
|
+
self.__proc = proc
|
|
190
|
+
self.__pid = proc.pid
|
|
191
|
+
pid = self.__pid
|
|
160
192
|
self.logger.trace('PID=%d' % pid)
|
|
161
193
|
|
|
162
194
|
if self.callback:
|
|
@@ -214,14 +246,19 @@ class EndlessConsole(Thread):
|
|
|
214
246
|
except Exception: # pragma: no cover
|
|
215
247
|
pass
|
|
216
248
|
|
|
217
|
-
#
|
|
218
|
-
if
|
|
249
|
+
# Always reap the process group if still alive. The child is started in its
|
|
250
|
+
# own session (setsid): if the CLI exits on Ctrl-C without kill(), pytest/
|
|
251
|
+
# coverage would otherwise keep running and can OOM a Raspberry Pi.
|
|
252
|
+
if pid != 1:
|
|
219
253
|
try:
|
|
220
|
-
if
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
254
|
+
if proc.poll() is None:
|
|
255
|
+
self.logger.debug('Terminating leftover process group pid=%s', pid)
|
|
256
|
+
if ON_POSIX:
|
|
257
|
+
os.killpg(os.getpgid(pid), signal.SIGKILL)
|
|
258
|
+
else: # pragma: no cover
|
|
259
|
+
proc.kill()
|
|
260
|
+
self.killed = True
|
|
261
|
+
except Exception: # pragma: no cover
|
|
225
262
|
pass
|
|
226
263
|
|
|
227
264
|
# process is over
|
|
@@ -379,56 +379,6 @@ PYTHONPATH=. python3 -m pytest tests -k "%s"
|
|
|
379
379
|
"""
|
|
380
380
|
return config.REPO_DIR
|
|
381
381
|
|
|
382
|
-
def __list_core_files(self, core_path, pattern=None):
|
|
383
|
-
"""
|
|
384
|
-
Return all python files on core with their associated tests
|
|
385
|
-
|
|
386
|
-
Args:
|
|
387
|
-
core_path (string): core path
|
|
388
|
-
pattern (str): custom pattern to filter files to process
|
|
389
|
-
|
|
390
|
-
Returns:
|
|
391
|
-
dict: list of files with test file path::
|
|
392
|
-
|
|
393
|
-
{
|
|
394
|
-
python file (string): test file (string)
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
"""
|
|
398
|
-
files = []
|
|
399
|
-
tests_path = self.__get_core_tests_path()
|
|
400
|
-
|
|
401
|
-
self.logger.info('Searching core files...')
|
|
402
|
-
for root, _, filenames in os.walk(core_path):
|
|
403
|
-
for filename in filenames:
|
|
404
|
-
# build paths
|
|
405
|
-
filepath = os.path.join(root, filename)
|
|
406
|
-
core_relative_path = root.replace('%s' % core_path, '')
|
|
407
|
-
core_relative_path = core_relative_path[1:] if core_relative_path.startswith('/') else core_relative_path
|
|
408
|
-
test_filepath = os.path.join(tests_path, core_relative_path, 'test_%s' % filename)
|
|
409
|
-
|
|
410
|
-
# drop useless files
|
|
411
|
-
if not filename.endswith('.py'):
|
|
412
|
-
self.logger.debug(' Drop file "%s": not python file', filepath)
|
|
413
|
-
continue
|
|
414
|
-
if filename.startswith('__init__'):
|
|
415
|
-
self.logger.debug(' Drop file "%s": python init file', filepath)
|
|
416
|
-
continue
|
|
417
|
-
if filename.startswith('test_'):
|
|
418
|
-
self.logger.debug(' Drop file "%s": test file', filepath)
|
|
419
|
-
continue
|
|
420
|
-
if root.endswith('libs/tests'):
|
|
421
|
-
self.logger.debug(' Drop file "%s": test lib', filepath)
|
|
422
|
-
continue
|
|
423
|
-
if pattern and not re.search(pattern, test_filepath) and not re.search(pattern, filepath):
|
|
424
|
-
self.logger.debug(' Drop file "%s": does not match pattern %s', filepath, pattern)
|
|
425
|
-
continue
|
|
426
|
-
|
|
427
|
-
self.logger.debug(' Found "%s" [%s]' % (filepath, test_filepath))
|
|
428
|
-
files.append((filepath, test_filepath))
|
|
429
|
-
|
|
430
|
-
return files
|
|
431
|
-
|
|
432
382
|
def core_tests(self, display_coverage=False, display_test_output=False, xml=False, quiet=True, pattern=None):
|
|
433
383
|
"""
|
|
434
384
|
Execute core unit tests and display process output on stdout
|
|
@@ -469,8 +419,15 @@ PYTHONPATH=. coverage run --omit="*/lib/python*/*","*/tests/*","*test_*.py" --so
|
|
|
469
419
|
c = EndlessConsole(cmd, console_callback, self.__console_end_callback)
|
|
470
420
|
c.start()
|
|
471
421
|
|
|
472
|
-
|
|
473
|
-
|
|
422
|
+
try:
|
|
423
|
+
while self.__endless_command_running:
|
|
424
|
+
time.sleep(0.25)
|
|
425
|
+
except KeyboardInterrupt:
|
|
426
|
+
self.logger.warning('Interrupted — stopping tests...')
|
|
427
|
+
c.kill()
|
|
428
|
+
while self.__endless_command_running:
|
|
429
|
+
time.sleep(0.1)
|
|
430
|
+
raise
|
|
474
431
|
|
|
475
432
|
success = self.__endless_command_return_code == 0
|
|
476
433
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cleepcli
|
|
3
|
-
Version: 1.45.
|
|
3
|
+
Version: 1.45.1
|
|
4
4
|
Summary: Cleep-cli helps developers to build great Cleep applications from command line.
|
|
5
5
|
Home-page: https://github.com/CleepDevice/cleep-cli
|
|
6
6
|
Author: Tanguy Bonneau
|
|
@@ -142,7 +142,7 @@ The [watchdog](https://pypi.org/project/watchdog/) python library is used to det
|
|
|
142
142
|
|
|
143
143
|
## CI (GitHub Actions)
|
|
144
144
|
|
|
145
|
-
A tag `vX.Y.Z` (or a manual **workflow_dispatch**) builds a **py3** wheel + sdist on `ubuntu-latest` (Python 3.
|
|
145
|
+
A tag `vX.Y.Z` (or a manual **workflow_dispatch**) builds a **py3** wheel + sdist on `ubuntu-latest` (Python 3.12) via `python -m build` and uploads them to PyPI.
|
|
146
146
|
|
|
147
147
|
GitHub **environment** `actions` (Settings → Environments), secret:
|
|
148
148
|
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|