Skip to content

Commit f4f909a

Browse files
committed
feat(cli): update to 2.5
Starting with 2.5, the Pact Standalone repo contains a number of Rust-based CLIs to replace the (now legacy) Ruby CLIs. Signed-off-by: JP-Ellis <[email protected]>
1 parent 8009ddb commit f4f909a

File tree

6 files changed

+69
-18
lines changed

6 files changed

+69
-18
lines changed

pact-python-cli/CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
All notable changes to this project will be documented in this file.
44

5-
Note that this _only_ includes changes to the Python re-packaging of the Pact CLI. For changes to the Pact CLI itself, see the [Pact CLI changelog](https://github.com/pact-foundation/pact-ruby-standalone/blob/master/CHANGELOG.md).
5+
Note that this _only_ includes changes to the Python re-packaging of the Pact CLI. For changes to the Pact CLI itself, see the [Pact CLI changelog](https://github.com/pact-foundation/pact-standalone/blob/master/CHANGELOG.md).
66

77
<!-- markdownlint-disable no-duplicate-heading -->
88
<!-- markdownlint-disable emph-style -->

pact-python-cli/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@
9090

9191
---
9292

93-
This sub-package is part of the [Pact Python](https://github.com/pact-foundation/pact-python) project and exists solely to distribute the [Pact CLI](https://github.com/pact-foundation/pact-ruby-standalone) as a Python package. If you are looking for the main Pact Python library for contract testing, please see the [root package](https://github.com/pact-foundation/pact-python#pact-python).
93+
This sub-package is part of the [Pact Python](https://github.com/pact-foundation/pact-python) project and exists solely to distribute the [Pact CLI](https://github.com/pact-foundation/pact-standalone) as a Python package. If you are looking for the main Pact Python library for contract testing, please see the [root package](https://github.com/pact-foundation/pact-python#pact-python).
9494

9595
It is used by version 2 of Pact Python, and can be used to install the Pact CLI in Python environments.
9696

@@ -108,7 +108,7 @@ pip install pact-python-cli
108108

109109
Contributions to this package are generally not required as it contains minimal Python functionality and generally only requires updating the version number. This is done by pushing a tag of the form `pact-python-cli/<version>` which will automatically trigger a release build in the CI pipeline.
110110

111-
To contribute to the Pact CLI itself, please refer to the [Pact Ruby Standalone repository](https://github.com/pact-foundation/pact-ruby-standalone).
111+
To contribute to the Pact CLI itself, please refer to the [Pact Ruby Standalone repository](https://github.com/pact-foundation/pact-standalone).
112112

113113
For contributing to Pact Python, see the [main contributing guide](https://github.com/pact-foundation/pact-python/blob/main/CONTRIBUTING.md).
114114

pact-python-cli/cliff.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ header = """
99
1010
All notable changes to this project will be documented in this file.
1111
12-
Note that this _only_ includes changes to the Python re-packaging of the Pact CLI. For changes to the Pact CLI itself, see the [Pact CLI changelog](https://github.com/pact-foundation/pact-ruby-standalone/blob/master/CHANGELOG.md).
12+
Note that this _only_ includes changes to the Python re-packaging of the Pact CLI. For changes to the Pact CLI itself, see the [Pact CLI changelog](https://github.com/pact-foundation/pact-standalone/blob/master/CHANGELOG.md).
1313
1414
<!-- markdownlint-disable no-duplicate-heading -->
1515
<!-- markdownlint-disable emph-style -->

pact-python-cli/pyproject.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,10 @@ requires-python = ">=3.10"
4545
pact-mock-service = "pact_cli:_exec"
4646
pact-plugin-cli = "pact_cli:_exec"
4747
pact-provider-verifier = "pact_cli:_exec"
48+
pact-stub-server = "pact_cli:_exec"
4849
pact-stub-service = "pact_cli:_exec"
50+
pact_mock_server_cli = "pact_cli:_exec"
51+
pact_verifier_cli = "pact_cli:_exec"
4952
pactflow = "pact_cli:_exec"
5053

5154
[dependency-groups]

pact-python-cli/src/pact_cli/__init__.py

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,16 @@
4343
)
4444

4545
if TYPE_CHECKING:
46-
from collections.abc import Mapping
46+
from collections.abc import Container, Mapping
4747

4848
_USE_SYSTEM_BINS = os.getenv("PACT_USE_SYSTEM_BINS", "").upper() in ("TRUE", "YES")
4949
_BIN_DIR = Path(__file__).parent.resolve() / "bin"
50+
_LEGACY_BINS: Container[str] = frozenset((
51+
"pact-message",
52+
"pact-mock-service",
53+
"pact-provider-verifier",
54+
"pact-stub-service",
55+
))
5056

5157

5258
def _telemetry_env() -> Mapping[str, str]:
@@ -91,15 +97,26 @@ def _exec() -> None:
9197
"pact-broker",
9298
"pact-message",
9399
"pact-mock-service",
94-
"pact-provider-verifier",
95100
"pact-plugin-cli",
96-
"pact-publish",
101+
"pact-provider-verifier",
102+
"pact-stub-server",
97103
"pact-stub-service",
104+
"pact_mock_server_cli",
105+
"pact_verifier_cli",
98106
"pactflow",
99107
):
100108
print("Unknown command:", command, file=sys.stderr) # noqa: T201
101109
sys.exit(1)
102110

111+
if command in _LEGACY_BINS:
112+
warnings.warn(
113+
f"The '{command}' executable is deprecated and will be removed in "
114+
"a future release. Please migrate to the new Pact CLI tools. "
115+
"See: <https://github.com/pact-foundation/pact-standalone>",
116+
DeprecationWarning,
117+
stacklevel=2,
118+
)
119+
103120
if not _USE_SYSTEM_BINS:
104121
executable = _find_executable(command)
105122
else:
@@ -173,6 +190,9 @@ def _find_executable(executable: str) -> str | None:
173190
BROKER_CLIENT_PATH = _find_executable("pact-broker")
174191
"""
175192
Path to the Pact Broker executable
193+
194+
This value is identical to `BROKER_PATH` and is provided for backward
195+
compatibility.
176196
"""
177197
MESSAGE_PATH = _find_executable("pact-message")
178198
"""
@@ -190,10 +210,25 @@ def _find_executable(executable: str) -> str | None:
190210
"""
191211
Path to the Pact Provider Verifier executable
192212
"""
213+
STUB_SERVER_PATH = _find_executable("pact-stub-server")
214+
"""
215+
Path to the Pact Stub Server executable
216+
"""
193217
STUB_SERVICE_PATH = _find_executable("pact-stub-service")
194218
"""
195219
Path to the Pact Stub Service executable
196220
"""
221+
MOCK_SERVER_PATH = _find_executable("pact_mock_server_cli")
222+
"""
223+
Path to the Pact Mock Server CLI executable
224+
"""
225+
VERIFIER_CLI_PATH = _find_executable("pact_verifier_cli")
226+
"""
227+
Path to the Pact Verifier CLI executable
228+
229+
This is distinct to the `VERIFIER_PATH` which points to the older Ruby-based
230+
CLI.
231+
"""
197232
PACTFLOW_PATH = _find_executable("pactflow")
198233
"""
199234
Path to the PactFlow CLI executable

pact-python-cli/tests/test_init.py

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -56,17 +56,22 @@ def assert_in_sys_path(p: str | Path) -> None:
5656
@pytest.mark.parametrize(
5757
("constant", "expected"),
5858
[
59-
pytest.param("PACT_PATH", "pact", id="pact"),
60-
pytest.param("BROKER_PATH", "pact-broker", id="pact-broker"),
6159
pytest.param("BROKER_CLIENT_PATH", "pact-broker", id="pact-broker"),
60+
pytest.param("BROKER_PATH", "pact-broker", id="pact-broker"),
6261
pytest.param("MESSAGE_PATH", "pact-message", id="pactmessage"),
63-
pytest.param("MOCK_SERVICE_PATH", "pact-mock-service", id="pact-message"),
62+
pytest.param(
63+
"MOCK_SERVER_PATH", "pact_mock_server_cli", id="pact_mock_server_cli"
64+
),
65+
pytest.param("MOCK_SERVICE_PATH", "pact-mock-service", id="pact-mock-service"),
66+
pytest.param("PACTFLOW_PATH", "pactflow", id="pactflow"),
67+
pytest.param("PACT_PATH", "pact", id="pact"),
6468
pytest.param("PLUGIN_CLI_PATH", "pact-plugin-cli", id="pact-plugin-cli"),
69+
pytest.param("STUB_SERVER_PATH", "pact-stub-server", id="pact-stub-server"),
70+
pytest.param("STUB_SERVICE_PATH", "pact-stub-service", id="pact-stub-service"),
71+
pytest.param("VERIFIER_CLI_PATH", "pact_verifier_cli", id="pact_verifier_cli"),
6572
pytest.param(
6673
"VERIFIER_PATH", "pact-provider-verifier", id="pact-provider-verifier"
6774
),
68-
pytest.param("STUB_SERVICE_PATH", "pact-stub-service", id="pact-stub-service"),
69-
pytest.param("PACTFLOW_PATH", "pactflow", id="pactflow"),
7075
],
7176
)
7277
def test_constants_are_valid_executable_paths(constant: str, expected: str) -> None:
@@ -86,7 +91,10 @@ def test_constants_are_valid_executable_paths(constant: str, expected: str) -> N
8691
pytest.param("pact-message", id="pact-message"),
8792
pytest.param("pact-plugin-cli", id="pact-plugin-cli"),
8893
pytest.param("pact-provider-verifier", id="pact-provider-verifier"),
94+
pytest.param("pact-stub-server", id="pact-stub-server"),
8995
pytest.param("pact-stub-service", id="pact-stub-service"),
96+
pytest.param("pact_mock_server_cli", id="pact_mock_server_cli"),
97+
pytest.param("pact_verifier_cli", id="pact_verifier_cli"),
9098
pytest.param("pactflow", id="pactflow"),
9199
],
92100
)
@@ -154,7 +162,10 @@ def test_cli_exec_wrapper_for_mock_service() -> None:
154162
pytest.param("pact-mock-service", id="pact-mock-service"),
155163
pytest.param("pact-plugin-cli", id="pact-plugin-cli"),
156164
pytest.param("pact-provider-verifier", id="pact-provider-verifier"),
165+
pytest.param("pact-stub-server", id="pact-stub-server"),
157166
pytest.param("pact-stub-service", id="pact-stub-service"),
167+
pytest.param("pact_mock_server_cli", id="pact_mock_server_cli"),
168+
pytest.param("pact_verifier_cli", id="pact_verifier_cli"),
158169
pytest.param("pactflow", id="pactflow"),
159170
],
160171
)
@@ -167,21 +178,23 @@ def test_exec_directly(executable: str) -> None:
167178

168179
with (
169180
patch.object(sys, "argv", new=[executable, "--help"]),
170-
patch("os.execv") as mock_execv,
181+
patch("os.execve") as mock_execve,
171182
):
172183
pact_cli._exec() # noqa: SLF001
173-
mock_execv.assert_called_once()
174-
cmd, args = mock_execv.call_args[0]
184+
mock_execve.assert_called_once()
185+
cmd, args, env = mock_execve.call_args[0]
175186
assert (os.sep + executable) in cmd
176187
assert args == [cmd, "--help"]
188+
assert env
177189

178190
patch.object(sys, "argv", new=[executable])
179191
with (
180192
patch.object(sys, "argv", new=[executable]),
181-
patch("os.execv") as mock_execv,
193+
patch("os.execve") as mock_execve,
182194
):
183195
pact_cli._exec() # noqa: SLF001
184-
mock_execv.assert_called_once()
185-
cmd, args = mock_execv.call_args[0]
196+
mock_execve.assert_called_once()
197+
cmd, args, env = mock_execve.call_args[0]
186198
assert (os.sep + executable) in cmd
187199
assert args == [cmd]
200+
assert env

0 commit comments

Comments
 (0)