multiCMD 1.57__tar.gz → 1.58__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.
- {multicmd-1.57 → multicmd-1.58}/PKG-INFO +11 -2
- {multicmd-1.57 → multicmd-1.58}/README.md +10 -1
- {multicmd-1.57 → multicmd-1.58}/multiCMD.egg-info/PKG-INFO +11 -2
- {multicmd-1.57 → multicmd-1.58}/multiCMD.egg-info/SOURCES.txt +2 -0
- {multicmd-1.57 → multicmd-1.58}/multiCMD.egg-info/entry_points.txt +0 -1
- {multicmd-1.57 → multicmd-1.58}/multiCMD.py +1 -1
- multicmd-1.58/scripts/multiCMD +6 -0
- {multicmd-1.57 → multicmd-1.58}/setup.py +3 -1
- multicmd-1.58/tests/test_packaging.py +26 -0
- {multicmd-1.57 → multicmd-1.58}/LICENSE +0 -0
- {multicmd-1.57 → multicmd-1.58}/multiCMD.egg-info/dependency_links.txt +0 -0
- {multicmd-1.57 → multicmd-1.58}/multiCMD.egg-info/top_level.txt +0 -0
- {multicmd-1.57 → multicmd-1.58}/setup.cfg +0 -0
- {multicmd-1.57 → multicmd-1.58}/tests/test_api.py +0 -0
- {multicmd-1.57 → multicmd-1.58}/tests/test_async_executor.py +0 -0
- {multicmd-1.57 → multicmd-1.58}/tests/test_cli.py +0 -0
- {multicmd-1.57 → multicmd-1.58}/tests/test_cli_input.py +0 -0
- {multicmd-1.57 → multicmd-1.58}/tests/test_cli_summary.py +0 -0
- {multicmd-1.57 → multicmd-1.58}/tests/test_display.py +0 -0
- {multicmd-1.57 → multicmd-1.58}/tests/test_env.py +0 -0
- {multicmd-1.57 → multicmd-1.58}/tests/test_expand_ranges.py +0 -0
- {multicmd-1.57 → multicmd-1.58}/tests/test_helpers.py +0 -0
- {multicmd-1.57 → multicmd-1.58}/tests/test_interrupts.py +0 -0
- {multicmd-1.57 → multicmd-1.58}/tests/test_parsing.py +0 -0
- {multicmd-1.57 → multicmd-1.58}/tests/test_ping.py +0 -0
- {multicmd-1.57 → multicmd-1.58}/tests/test_pool.py +0 -0
- {multicmd-1.57 → multicmd-1.58}/tests/test_process_groups.py +0 -0
- {multicmd-1.57 → multicmd-1.58}/tests/test_pty.py +0 -0
- {multicmd-1.57 → multicmd-1.58}/tests/test_reader.py +0 -0
- {multicmd-1.57 → multicmd-1.58}/tests/test_regressions.py +0 -0
- {multicmd-1.57 → multicmd-1.58}/tests/test_run_command.py +0 -0
- {multicmd-1.57 → multicmd-1.58}/tests/test_run_commands.py +0 -0
- {multicmd-1.57 → multicmd-1.58}/tests/test_sudo.py +0 -0
- {multicmd-1.57 → multicmd-1.58}/tests/test_supervision.py +0 -0
- {multicmd-1.57 → multicmd-1.58}/tests/test_task.py +0 -0
- {multicmd-1.57 → multicmd-1.58}/tests/test_windows.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: multiCMD
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.58
|
|
4
4
|
Summary: Run commands simultaneously
|
|
5
5
|
Home-page: https://github.com/yufei-pan/multiCMD
|
|
6
6
|
Author: Yufei Pan
|
|
@@ -56,7 +56,7 @@ It works both as a command-line tool and as an importable wrapper around
|
|
|
56
56
|
pip install multiCMD
|
|
57
57
|
```
|
|
58
58
|
|
|
59
|
-
This installs the module and three equivalent
|
|
59
|
+
This installs the module and three equivalent commands:
|
|
60
60
|
|
|
61
61
|
```bash
|
|
62
62
|
mcmd
|
|
@@ -491,6 +491,15 @@ pytest -m "not slow" # skip intentional sleep-heavy cases
|
|
|
491
491
|
|
|
492
492
|
`test_expand_ranges_perf.py` is a manual performance microbenchmark and is not collected by pytest.
|
|
493
493
|
|
|
494
|
+
## Upgrading to 1.58 from 1.57
|
|
495
|
+
|
|
496
|
+
- The `multiCMD` command is now a script file, not an entry point, so `entry_points.txt` no longer has two names that differ only in case. All three commands still work the same way, except in the venv case below. From 1.58 on, stock pip 9 on EL7 and EL8 upgrades and uninstalls multiCMD without `configparser.DuplicateOptionError`.
|
|
497
|
+
- With pip 9, the pip of EL7 and EL8 (`pip3 --version`), upgrading from 1.57 or earlier and `pip3 uninstall multiCMD` of those releases stop with `configparser.DuplicateOptionError: ... option 'multicmd' in section 'console_scripts' already exists`, and nothing changes: the installed release keeps working. Run `pip3 install -U pip` once, then upgrade or uninstall.
|
|
498
|
+
- With `--user` the same happens, except that `pip3 install --user -U multiCMD` with no version does not stop: it installs the new release, which works, and leaves the old release's metadata behind. `pip3 list` then shows the old release after `pip3 uninstall multiCMD`, and the next uninstall stops with that error. To avoid this, run `pip3 install --user -U pip` once first. If it has already happened, run that, run `pip3 uninstall multiCMD` until it says multiCMD is not installed, and install again. From 1.58 on the same upgrade leaves the metadata too, but with no error: `pip3 uninstall multiCMD` takes one run per release left.
|
|
499
|
+
- Without `--user`, with multiCMD 1.57 or earlier installed, `pip3 install -U hpcp`, `statblk` or `statbtrfs` stops the same way once a newer multiCMD is out, because pip 9 upgrades dependencies too. `pip3 install -U --no-deps hpcp` gets past it.
|
|
500
|
+
- With pip 10 or later, in a venv whose path has a space or is too long for the kernel's `#!` line, the `multiCMD` spelling does not start (the error varies: "bad interpreter", `import: command not found`), because pip gives a script file a plain `#!` line: use `multicmd`. With pip 9 no spelling starts in such a venv, as in 1.57. uv and system or `--user` installs are not affected.
|
|
501
|
+
- An embedded copy made by the generator now falls back from any failure to import the installed multiCMD, not only the three errors it named.
|
|
502
|
+
|
|
494
503
|
## Upgrading to 1.57 from 1.56
|
|
495
504
|
|
|
496
505
|
- Faster command starts on Python 3.6 - 3.10: the wrapper that puts a command in its own process group
|
|
@@ -30,7 +30,7 @@ It works both as a command-line tool and as an importable wrapper around
|
|
|
30
30
|
pip install multiCMD
|
|
31
31
|
```
|
|
32
32
|
|
|
33
|
-
This installs the module and three equivalent
|
|
33
|
+
This installs the module and three equivalent commands:
|
|
34
34
|
|
|
35
35
|
```bash
|
|
36
36
|
mcmd
|
|
@@ -465,6 +465,15 @@ pytest -m "not slow" # skip intentional sleep-heavy cases
|
|
|
465
465
|
|
|
466
466
|
`test_expand_ranges_perf.py` is a manual performance microbenchmark and is not collected by pytest.
|
|
467
467
|
|
|
468
|
+
## Upgrading to 1.58 from 1.57
|
|
469
|
+
|
|
470
|
+
- The `multiCMD` command is now a script file, not an entry point, so `entry_points.txt` no longer has two names that differ only in case. All three commands still work the same way, except in the venv case below. From 1.58 on, stock pip 9 on EL7 and EL8 upgrades and uninstalls multiCMD without `configparser.DuplicateOptionError`.
|
|
471
|
+
- With pip 9, the pip of EL7 and EL8 (`pip3 --version`), upgrading from 1.57 or earlier and `pip3 uninstall multiCMD` of those releases stop with `configparser.DuplicateOptionError: ... option 'multicmd' in section 'console_scripts' already exists`, and nothing changes: the installed release keeps working. Run `pip3 install -U pip` once, then upgrade or uninstall.
|
|
472
|
+
- With `--user` the same happens, except that `pip3 install --user -U multiCMD` with no version does not stop: it installs the new release, which works, and leaves the old release's metadata behind. `pip3 list` then shows the old release after `pip3 uninstall multiCMD`, and the next uninstall stops with that error. To avoid this, run `pip3 install --user -U pip` once first. If it has already happened, run that, run `pip3 uninstall multiCMD` until it says multiCMD is not installed, and install again. From 1.58 on the same upgrade leaves the metadata too, but with no error: `pip3 uninstall multiCMD` takes one run per release left.
|
|
473
|
+
- Without `--user`, with multiCMD 1.57 or earlier installed, `pip3 install -U hpcp`, `statblk` or `statbtrfs` stops the same way once a newer multiCMD is out, because pip 9 upgrades dependencies too. `pip3 install -U --no-deps hpcp` gets past it.
|
|
474
|
+
- With pip 10 or later, in a venv whose path has a space or is too long for the kernel's `#!` line, the `multiCMD` spelling does not start (the error varies: "bad interpreter", `import: command not found`), because pip gives a script file a plain `#!` line: use `multicmd`. With pip 9 no spelling starts in such a venv, as in 1.57. uv and system or `--user` installs are not affected.
|
|
475
|
+
- An embedded copy made by the generator now falls back from any failure to import the installed multiCMD, not only the three errors it named.
|
|
476
|
+
|
|
468
477
|
## Upgrading to 1.57 from 1.56
|
|
469
478
|
|
|
470
479
|
- Faster command starts on Python 3.6 - 3.10: the wrapper that puts a command in its own process group
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: multiCMD
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.58
|
|
4
4
|
Summary: Run commands simultaneously
|
|
5
5
|
Home-page: https://github.com/yufei-pan/multiCMD
|
|
6
6
|
Author: Yufei Pan
|
|
@@ -56,7 +56,7 @@ It works both as a command-line tool and as an importable wrapper around
|
|
|
56
56
|
pip install multiCMD
|
|
57
57
|
```
|
|
58
58
|
|
|
59
|
-
This installs the module and three equivalent
|
|
59
|
+
This installs the module and three equivalent commands:
|
|
60
60
|
|
|
61
61
|
```bash
|
|
62
62
|
mcmd
|
|
@@ -491,6 +491,15 @@ pytest -m "not slow" # skip intentional sleep-heavy cases
|
|
|
491
491
|
|
|
492
492
|
`test_expand_ranges_perf.py` is a manual performance microbenchmark and is not collected by pytest.
|
|
493
493
|
|
|
494
|
+
## Upgrading to 1.58 from 1.57
|
|
495
|
+
|
|
496
|
+
- The `multiCMD` command is now a script file, not an entry point, so `entry_points.txt` no longer has two names that differ only in case. All three commands still work the same way, except in the venv case below. From 1.58 on, stock pip 9 on EL7 and EL8 upgrades and uninstalls multiCMD without `configparser.DuplicateOptionError`.
|
|
497
|
+
- With pip 9, the pip of EL7 and EL8 (`pip3 --version`), upgrading from 1.57 or earlier and `pip3 uninstall multiCMD` of those releases stop with `configparser.DuplicateOptionError: ... option 'multicmd' in section 'console_scripts' already exists`, and nothing changes: the installed release keeps working. Run `pip3 install -U pip` once, then upgrade or uninstall.
|
|
498
|
+
- With `--user` the same happens, except that `pip3 install --user -U multiCMD` with no version does not stop: it installs the new release, which works, and leaves the old release's metadata behind. `pip3 list` then shows the old release after `pip3 uninstall multiCMD`, and the next uninstall stops with that error. To avoid this, run `pip3 install --user -U pip` once first. If it has already happened, run that, run `pip3 uninstall multiCMD` until it says multiCMD is not installed, and install again. From 1.58 on the same upgrade leaves the metadata too, but with no error: `pip3 uninstall multiCMD` takes one run per release left.
|
|
499
|
+
- Without `--user`, with multiCMD 1.57 or earlier installed, `pip3 install -U hpcp`, `statblk` or `statbtrfs` stops the same way once a newer multiCMD is out, because pip 9 upgrades dependencies too. `pip3 install -U --no-deps hpcp` gets past it.
|
|
500
|
+
- With pip 10 or later, in a venv whose path has a space or is too long for the kernel's `#!` line, the `multiCMD` spelling does not start (the error varies: "bad interpreter", `import: command not found`), because pip gives a script file a plain `#!` line: use `multicmd`. With pip 9 no spelling starts in such a venv, as in 1.57. uv and system or `--user` installs are not affected.
|
|
501
|
+
- An embedded copy made by the generator now falls back from any failure to import the installed multiCMD, not only the three errors it named.
|
|
502
|
+
|
|
494
503
|
## Upgrading to 1.57 from 1.56
|
|
495
504
|
|
|
496
505
|
- Faster command starts on Python 3.6 - 3.10: the wrapper that puts a command in its own process group
|
|
@@ -7,6 +7,7 @@ multiCMD.egg-info/SOURCES.txt
|
|
|
7
7
|
multiCMD.egg-info/dependency_links.txt
|
|
8
8
|
multiCMD.egg-info/entry_points.txt
|
|
9
9
|
multiCMD.egg-info/top_level.txt
|
|
10
|
+
scripts/multiCMD
|
|
10
11
|
tests/test_api.py
|
|
11
12
|
tests/test_async_executor.py
|
|
12
13
|
tests/test_cli.py
|
|
@@ -17,6 +18,7 @@ tests/test_env.py
|
|
|
17
18
|
tests/test_expand_ranges.py
|
|
18
19
|
tests/test_helpers.py
|
|
19
20
|
tests/test_interrupts.py
|
|
21
|
+
tests/test_packaging.py
|
|
20
22
|
tests/test_parsing.py
|
|
21
23
|
tests/test_ping.py
|
|
22
24
|
tests/test_pool.py
|
|
@@ -27,7 +27,7 @@ import traceback
|
|
|
27
27
|
from pprint import pformat
|
|
28
28
|
|
|
29
29
|
#%% global vars
|
|
30
|
-
version = '1.
|
|
30
|
+
version = '1.58'
|
|
31
31
|
__version__ = version
|
|
32
32
|
COMMIT_DATE = '2026-11-06'
|
|
33
33
|
# fire-and-forget threads (run_commands with wait_for_return=False) that join_threads() waits on. multiCMD takes no
|
|
@@ -11,10 +11,12 @@ setup(
|
|
|
11
11
|
author_email='pan@zopyr.us',
|
|
12
12
|
url='https://github.com/yufei-pan/multiCMD',
|
|
13
13
|
py_modules=['multiCMD'],
|
|
14
|
+
# The mixed-case command is a script file and not an entry point: pip 9 (stock on EL7 and EL8) reads entry_points.txt with a
|
|
15
|
+
# parser that folds case, so two commands that differ only in case make it fail to upgrade or uninstall the package.
|
|
16
|
+
scripts=['scripts/multiCMD'],
|
|
14
17
|
entry_points={
|
|
15
18
|
'console_scripts': [
|
|
16
19
|
'mcmd=multiCMD:main',
|
|
17
|
-
'multiCMD=multiCMD:main',
|
|
18
20
|
'multicmd=multiCMD:main',
|
|
19
21
|
],
|
|
20
22
|
},
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"""The packaging: the commands setup.py installs."""
|
|
2
|
+
import os
|
|
3
|
+
import subprocess
|
|
4
|
+
import sys
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
import pytest
|
|
8
|
+
|
|
9
|
+
PACKAGE_ROOT = Path(__file__).resolve().parents[1]
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def test_no_two_commands_differ_only_in_case(tmp_path):
|
|
13
|
+
pytest.importorskip("setuptools", reason="needs setuptools to run setup.py")
|
|
14
|
+
# pip 9 (stock on EL7 and EL8) reads entry_points.txt with a parser that folds case, so two commands that differ only
|
|
15
|
+
# in case make it fail to upgrade or uninstall the package. The mixed-case command is a script file (scripts=) instead.
|
|
16
|
+
result = subprocess.run([sys.executable, "setup.py", "-q", "egg_info", "--egg-base", str(tmp_path)],
|
|
17
|
+
cwd=str(PACKAGE_ROOT), env=dict(os.environ, PYTHONDONTWRITEBYTECODE="1"), stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
|
18
|
+
universal_newlines=True, timeout=120)
|
|
19
|
+
assert result.returncode == 0, result.stderr
|
|
20
|
+
egg_info = tmp_path / "multiCMD.egg-info"
|
|
21
|
+
entry_points = (egg_info / "entry_points.txt").read_text(encoding="utf-8")
|
|
22
|
+
names = [line.split("=")[0].strip() for line in entry_points.splitlines() if "=" in line]
|
|
23
|
+
assert sorted(names) == ["mcmd", "multicmd"]
|
|
24
|
+
# the mixed-case command ships in the sdist as a script, so the three spellings stay three commands
|
|
25
|
+
assert "scripts/multiCMD" in (egg_info / "SOURCES.txt").read_text(encoding="utf-8").splitlines()
|
|
26
|
+
assert (PACKAGE_ROOT / "scripts" / "multiCMD").read_text(encoding="utf-8").startswith("#!")
|
|
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
|