Skip to content

Commit bafaf28

Browse files
jstvzrupeshjSFDC
authored andcommitted
fix: Pin docutils<=0.21.2 to fix rst2ansi incompatibility (SFDO-Tooling#3914)
Newer versions of `docutils` (>=0.22) are incompatible with the unmaintained `rst2ansi` library, causing a `ModuleNotFoundError` on startup when `rst2ansi` tries to import `docutils.utils.error_reporting`. Fixes SFDO-Tooling#3912 Closes SFDO-Tooling#3913 Signed-off-by: Rupesh J <rupesh.j@salesforce.com>
1 parent 14177a5 commit bafaf28

9 files changed

Lines changed: 1136 additions & 1643 deletions

File tree

.github/workflows/feature_test.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ jobs:
4040
- name: Set up uv
4141
uses: astral-sh/setup-uv@v6
4242
with:
43-
version: "0.5.0"
43+
version: "0.8.4"
4444
enable-cache: true
4545
- name: Install dependencies
4646
run: uv sync --group docs
@@ -66,7 +66,7 @@ jobs:
6666
- name: Set up uv
6767
uses: astral-sh/setup-uv@v6
6868
with:
69-
version: "0.5.0"
69+
version: "0.8.4"
7070
enable-cache: true
7171
- name: Install dependencies
7272
run: uv sync -p ${{ matrix.python-version }}
@@ -94,7 +94,7 @@ jobs:
9494
- name: Set up uv
9595
uses: astral-sh/setup-uv@v6
9696
with:
97-
version: "0.5.0"
97+
version: "0.8.4"
9898
enable-cache: true
9999
- name: Install dependencies
100100
run: uv sync --all-extras -p ${{ matrix.python-version }}
@@ -117,7 +117,7 @@ jobs:
117117
- name: Set up uv
118118
uses: astral-sh/setup-uv@v6
119119
with:
120-
version: "0.5.0"
120+
version: "0.8.4"
121121
enable-cache: true
122122
- name: Install dependencies
123123
run: uv sync -p 3.11

.github/workflows/release_test_sfdx.yml.tobeupdated

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ jobs:
4848
- name: Set up uv
4949
uses: SFDO-Tooling/setup-uv@main
5050
with:
51-
version: "0.5.0"
51+
version: "0.8.4"
5252
enable-cache: true
5353
- name: Install Python dependencies
5454
run: uv sync

.github/workflows/slow_integration_tests.yml.tobeupdated

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ jobs:
3434
- name: Set up uv
3535
uses: SFDO-Tooling/setup-uv@main
3636
with:
37-
version: "0.5.0"
37+
version: "0.8.4"
3838
enable-cache: true
3939
- name: Install dependencies
4040
run: uv sync -p 3.11

cumulusci/cli/service.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,25 @@ def list_commands(self, ctx):
8383
services = self._get_services_config(runtime)
8484
return sorted(services.keys())
8585

86+
def invoke(self, ctx):
87+
"""Override to show available services instead of 'Missing command' error"""
88+
try:
89+
return super().invoke(ctx)
90+
except click.UsageError as e:
91+
if "Missing command" in str(e):
92+
# No subcommand provided - list available services
93+
services = self.list_commands(ctx)
94+
if services:
95+
click.echo("Available services:")
96+
for service in services:
97+
click.echo(f" {service}")
98+
else:
99+
click.echo("No services available to configure.")
100+
return
101+
else:
102+
# Re-raise other usage errors
103+
raise
104+
86105
def _build_param(self, attribute: str, details: dict) -> click.Option:
87106
required = details.get("required", False)
88107
default_factory: Optional[Callable] = self._get_callable_default(
@@ -288,6 +307,7 @@ def callback(*args, **kwargs):
288307
cls=ConnectServiceCommand,
289308
name="connect",
290309
help="Connect an external service to CumulusCI",
310+
no_args_is_help=False,
291311
)
292312
def service_connect():
293313
pass

cumulusci/cli/tests/test_service.py

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -106,9 +106,10 @@ def test_service_connect__attr_with_default_value():
106106
# but input of an empty line accepts the default.
107107
assert "attr (example) [PRESET]: " in result.output
108108
service_config = runtime.keychain.get_service("test", "test-alias")
109-
with mock.patch(
110-
"cumulusci.core.config.base_config.STRICT_GETATTR", False
111-
), pytest.warns(DeprecationWarning, match="attr"):
109+
with (
110+
mock.patch("cumulusci.core.config.base_config.STRICT_GETATTR", False),
111+
pytest.warns(DeprecationWarning, match="attr"),
112+
):
112113
assert service_config.lookup("attr") == "PRESET"
113114
assert service_config.attr == "PRESET"
114115

@@ -132,9 +133,10 @@ def test_service_connect__attr_with_default_factory():
132133

133134
# The service should have the attribute value returned by the default factory.
134135
service_config = runtime.keychain.get_service("test", "test-alias")
135-
with mock.patch(
136-
"cumulusci.core.config.base_config.STRICT_GETATTR", False
137-
), pytest.warns(DeprecationWarning, match="attr"):
136+
with (
137+
mock.patch("cumulusci.core.config.base_config.STRICT_GETATTR", False),
138+
pytest.warns(DeprecationWarning, match="attr"),
139+
):
138140
assert service_config.lookup("attr") == "CALCULATED"
139141
assert service_config.attr == "CALCULATED"
140142

@@ -155,13 +157,14 @@ def test_service_connect__alias_already_exists():
155157
"test-type",
156158
"already-exists",
157159
runtime=runtime,
158-
input="new\ny\n",
160+
input="new\ny\nn\n",
159161
)
160162

161163
service_config = runtime.keychain.get_service("test-type", "already-exists")
162-
with mock.patch(
163-
"cumulusci.core.config.base_config.STRICT_GETATTR", False
164-
), pytest.warns(DeprecationWarning, match="attr"):
164+
with (
165+
mock.patch("cumulusci.core.config.base_config.STRICT_GETATTR", False),
166+
pytest.warns(DeprecationWarning, match="attr"),
167+
):
165168
assert service_config.lookup("attr") == "new"
166169
assert service_config.attr == "new"
167170

@@ -536,7 +539,7 @@ def test_service_connect__connected_app():
536539
"connect",
537540
"connected_app",
538541
"new",
539-
input="\n\nID\nSECRET\n",
542+
input="\n\nID\nSECRET\nn\n",
540543
runtime=runtime,
541544
)
542545

@@ -559,7 +562,7 @@ def test_service_connect__connected_app__with_cli_options():
559562
"new",
560563
"--login_url",
561564
"https://custom",
562-
input="\nID\nSECRET\n", # not prompted for login_url
565+
input="\nID\nSECRET\nn\n", # not prompted for login_url
563566
runtime=runtime,
564567
)
565568

cumulusci/cli/tests/utils.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,7 @@ def run_click_command(cmd, *args, **kw):
1717

1818
def run_cli_command(*args, runtime=None, input=None, **kw):
1919
"""Run a click command with arg parsing and injected CCI runtime object."""
20-
if tuple(map(int, click.__version__.split("."))) >= (8, 1, 0):
21-
runner = CliRunner()
22-
else:
23-
runner = CliRunner(mix_stderr=False)
20+
runner = CliRunner()
2421
result = runner.invoke(
2522
cli,
2623
args,

cumulusci/tests/test_integration_infrastructure.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,15 @@ def _capture_orgid_using_task():
3535

3636
class TestIntegrationInfrastructure:
3737
"Test our two plugins for doing integration testing"
38+
3839
remembered_cli_specified_org_id = None
3940

4041
@pytest.mark.vcr()
4142
def test_prepare_for__test_integration_tests(
4243
self, create_task, run_code_without_recording
4344
):
4445
"Delete a VCR Cassette to ensure next test creates it."
46+
4547
# only delete the cassette if we can replace it
4648
def delete_cassette():
4749
if first_cassette.exists():
@@ -81,7 +83,7 @@ def setup():
8183

8284
run_code_without_recording(setup)
8385

84-
def test_file_was_not_created(self, capture_orgid_using_task):
86+
def test_file_was_not_created(self):
8587
filename = (
8688
Path(__file__).parent
8789
/ "cassettes/TestIntegrationInfrastructure.test_run_code_without_recording.yaml"

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ dependencies = [
5555
"simple-salesforce==1.11.4",
5656
"snowfakery>=4.1.0",
5757
"xmltodict",
58-
"docutils==0.21.2",
58+
"docutils<=0.21.2",
5959
"python-dotenv",
6060
]
6161

0 commit comments

Comments
 (0)