Skip to content

Commit 0b669b0

Browse files
committed
install pycharm debugger for cicd
1 parent a79b5cc commit 0b669b0

File tree

11 files changed

+177
-14
lines changed

11 files changed

+177
-14
lines changed

.github/workflows/pyright.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ jobs:
4848
run: |
4949
pip list
5050
pip install -r ckan/requirements.txt -r ckan/dev-requirements.txt ckan/.
51+
pip install -e".[pycharm2025]"
5152
pip install -e".[test]"
5253
5354
- name: Install node deps

.github/workflows/pytest.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ jobs:
5151
# Install any extra requirements your extension has here (dev requirements, other extensions etc)
5252
run: |
5353
apt install git
54+
pip install -e ".[pycharm2025]"
5455
pip install -e ".[test]"
5556
# .[test] will install base dependencies as well as the test optional group
5657

@@ -66,7 +67,7 @@ jobs:
6667
- name: ${{ matrix.experimental && '**Fail_Ignored** ' || '' }} Run tests
6768
continue-on-error: ${{ matrix.experimental }}
6869
run: |
69-
pytest --ckan-ini=test.ini --cov=ckanext.selfinfo ckanext/selfinfo --cov-branch --cov-report=xml --junit-xml=./results/junit_results.xml -o junit_family=legacy
70+
pytest --ckan-ini=test.ini --cov=ckanext.pycharm_debugger ckanext/pycharm_debugger --cov-branch --cov-report=xml --junit-xml=./results/junit_results.xml -o junit_family=legacy
7071
7172
- name: Generate Test results artifacts
7273
continue-on-error: ${{ matrix.experimental }}

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,10 @@ htmlcov/
3737
.cache
3838
nosetests.xml
3939
coverage.xml
40+
results/
4041

4142
# Sphinx documentation
4243
docs/_build/
4344

4445
# mkdocs
45-
site/
46+
site/

ckanext/__init__.py

Whitespace-only changes.

ckanext/pycharm_debugger/config_declaration.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
version: 1
22
groups:
3-
- annotation: selfinfo configuration
3+
- annotation: pycharm debugger configuration
44
options:
55
- key: debug.remote.egg_dir
66
type: str

ckanext/pycharm_debugger/plugin.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ def update_config(self, config: CKANConfig):
2424
# If we have an egg directory, add the egg to the system path
2525
# If not set, user is expected to have made pycharm egg findable
2626
if egg_dir and egg_file:
27+
log.info("Initiating supplied egg path: %s file: %s", egg_dir, egg_file)
2728
sys.path.append(os.path.join(egg_dir, egg_file))
2829

2930
debug = asbool(config.get('debug.remote', 'False'))
@@ -42,9 +43,12 @@ def update_config(self, config: CKANConfig):
4243
stdoutToServer=stdout,
4344
stderrToServer=stderr,
4445
suspend=suspend)
45-
except NameError or ImportError:
46-
log.warning("debug.enabled set to True, but pydevd_pycharm is missing.")
47-
except SystemExit or ConnectionRefusedError:
46+
except (SystemExit, ConnectionRefusedError):
4847
log.warning("Failed to connect to debug server; is it started?")
48+
49+
except (Exception):
50+
# Catch all other exceptions
51+
log.warning("debug.enabled set to True, but pydevd_pycharm is missing.")
52+
4953
else:
5054
log.info("PyCharm Debugger not enabled")

ckanext/pycharm_debugger/test/__init__.py

Whitespace-only changes.
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
import sys
2+
import types
3+
import logging
4+
from unittest import mock
5+
6+
from ckanext.pycharm_debugger.plugin import PycharmDebugger
7+
8+
9+
def test_update_config_debug_enabled_import_failure(monkeypatch, caplog):
10+
caplog.set_level(logging.INFO)
11+
12+
config = {
13+
'debug.remote': 'True',
14+
'debug.remote.host.ip': '127.0.0.1',
15+
'debug.remote.host.port': '1234',
16+
'debug.remote.stdout_to_server': 'True',
17+
'debug.remote.stderr_to_server': 'True',
18+
'debug.remote.suspend': 'False',
19+
}
20+
21+
sys_path_original = list(sys.path)
22+
monkeypatch.setattr(sys, 'path', list(sys_path_original))
23+
24+
# Mock pydevd_pycharm to simulate import failure
25+
mock_pydevd = types.SimpleNamespace(settrace=mock.Mock(side_effect=ConnectionRefusedError("Connection refused")))
26+
monkeypatch.setitem(sys.modules, 'pydevd_pycharm', mock_pydevd)
27+
28+
plugin = PycharmDebugger()
29+
plugin.update_config(config)
30+
31+
assert "pydevd_pycharm is missing" in caplog.text or \
32+
"Failed to connect to debug server" in caplog.text
33+
34+
sys.path = sys_path_original
35+
36+
37+
def test_update_config_debug_enabled_mimic_missing(monkeypatch, caplog):
38+
caplog.set_level(logging.INFO)
39+
40+
config = {
41+
'debug.remote': 'True',
42+
'debug.remote.egg_dir': '/dummy/dir',
43+
'debug.remote.egg_file': 'dummy.egg',
44+
'debug.remote.host.ip': '127.0.0.1',
45+
'debug.remote.host.port': '1234',
46+
'debug.remote.stdout_to_server': 'True',
47+
'debug.remote.stderr_to_server': 'True',
48+
'debug.remote.suspend': 'True',
49+
}
50+
51+
sys_path_original = list(sys.path)
52+
monkeypatch.setattr(sys, 'path', list(sys_path_original))
53+
54+
monkeypatch.delitem(sys.modules, 'pydevd_pycharm', raising=False)
55+
56+
plugin = PycharmDebugger()
57+
plugin.update_config(config)
58+
59+
assert "pydevd_pycharm is missing" in caplog.text or \
60+
"Failed to connect to debug server" in caplog.text
61+
62+
sys.path = sys_path_original
63+
64+
65+
def test_update_config_see_manual_egg_injected_into_sys(monkeypatch, caplog):
66+
caplog.set_level(logging.INFO)
67+
68+
config = {
69+
'debug.remote': 'False',
70+
'debug.remote.egg_dir': '/dummy/dir',
71+
'debug.remote.egg_file': 'dummy.egg',
72+
'debug.remote.host.ip': '127.0.0.1',
73+
'debug.remote.host.port': '1234',
74+
'debug.remote.stdout_to_server': 'True',
75+
'debug.remote.stderr_to_server': 'True',
76+
'debug.remote.suspend': 'True',
77+
}
78+
79+
sys_path_original = list(sys.path)
80+
monkeypatch.setattr(sys, 'path', list(sys_path_original))
81+
82+
plugin = PycharmDebugger()
83+
plugin.update_config(config)
84+
85+
assert "Initiating supplied egg path: /dummy/dir file: dummy.egg" in caplog.text
86+
assert '/dummy/dir/dummy.egg' in sys.path
87+
88+
sys.path = sys_path_original
89+
90+
91+
def test_update_config_debug_disabled(monkeypatch, caplog):
92+
caplog.set_level(logging.INFO)
93+
94+
config = {
95+
'debug.remote': 'False',
96+
}
97+
98+
sys_path_original = list(sys.path)
99+
monkeypatch.setattr(sys, 'path', list(sys_path_original))
100+
101+
plugin = PycharmDebugger()
102+
plugin.update_config(config)
103+
104+
assert "PyCharm Debugger not enabled" in caplog.text
105+
106+
sys.path = sys_path_original
107+
108+
109+
def test_update_config_debug_import_failure(monkeypatch, caplog):
110+
caplog.set_level(logging.INFO)
111+
112+
config = {
113+
'debug.remote': 'True',
114+
}
115+
116+
sys_path_original = list(sys.path)
117+
monkeypatch.setattr(sys, 'path', list(sys_path_original))
118+
119+
# Mock pydevd_pycharm to raise ImportError when accessed
120+
monkeypatch.setattr('builtins.__import__', mock.Mock(side_effect=ImportError("pydevd_pycharm not found")))
121+
122+
plugin = PycharmDebugger()
123+
plugin.update_config(config)
124+
125+
assert "debug.enabled set to True, but pydevd_pycharm is missing." in caplog.text
126+
127+
sys.path = sys_path_original
128+
129+
130+
def test_update_config_debug_enabled_nameerror_or_importerror(monkeypatch, caplog):
131+
caplog.set_level(logging.WARNING)
132+
133+
config = {
134+
'debug.remote': 'True',
135+
'debug.remote.host.ip': '127.0.0.1',
136+
'debug.remote.host.port': '1234',
137+
'debug.remote.stdout_to_server': 'True',
138+
'debug.remote.stderr_to_server': 'True',
139+
'debug.remote.suspend': 'True',
140+
}
141+
142+
sys_path_original = list(sys.path)
143+
monkeypatch.setattr(sys, 'path', list(sys_path_original))
144+
145+
# Simulate ImportError by removing the module from sys.modules
146+
monkeypatch.delitem(sys.modules, 'pydevd_pycharm', raising=False)
147+
148+
# Mock pydevd_pycharm to raise ImportError when accessed
149+
monkeypatch.setattr('builtins.__import__', mock.Mock(side_effect=ConnectionRefusedError("Can't Connect")))
150+
151+
plugin = PycharmDebugger()
152+
plugin.update_config(config)
153+
154+
assert "Failed to connect to debug server; is it started?" in caplog.text
155+
156+
sys.path = sys_path_original

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ build-backend = "setuptools.build_meta"
88
name = "ckanext-pycharm_debugger"
99
version = "0.0.1"
1010
requires-python = ">=3.8"
11-
description = "Web based Sys Admin server statistics"
11+
description = "CKAN extension to enable PyCharm remote debugging"
1212
classifiers = ["Development Status :: 4 - Beta",
1313
"License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)",
1414
"Programming Language :: Python :: 3.7",
@@ -19,7 +19,7 @@ classifiers = ["Development Status :: 4 - Beta",
1919
"Programming Language :: Python :: 3.12",
2020
]
2121
keywords = [
22-
"CKAN",
22+
"CKAN", "PyCharm", "remote debugging", "debugger", "extension", "plugin",
2323
]
2424
dependencies = [
2525
"ckan",
@@ -144,4 +144,4 @@ reportIncompleteStub = true
144144
reportUnsupportedDunderAll = true
145145
reportUnusedCoroutine = true
146146
reportUnnecessaryTypeIgnoreComment = true
147-
reportMatchNotExhaustive = true
147+
reportMatchNotExhaustive = true

0 commit comments

Comments
 (0)