gitwebhooks 2.1.0__py3-none-any.whl
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.
- gitwebhooks/__init__.py +18 -0
- gitwebhooks/__main__.py +10 -0
- gitwebhooks/auth/__init__.py +20 -0
- gitwebhooks/auth/custom.py +40 -0
- gitwebhooks/auth/factory.py +73 -0
- gitwebhooks/auth/gitee.py +86 -0
- gitwebhooks/auth/github.py +52 -0
- gitwebhooks/auth/gitlab.py +29 -0
- gitwebhooks/auth/verifier.py +34 -0
- gitwebhooks/cli/__init__.py +107 -0
- gitwebhooks/cli/config.py +216 -0
- gitwebhooks/cli/init_wizard.py +701 -0
- gitwebhooks/cli/prompts.py +275 -0
- gitwebhooks/cli/service.py +374 -0
- gitwebhooks/config/__init__.py +17 -0
- gitwebhooks/config/loader.py +170 -0
- gitwebhooks/config/models.py +145 -0
- gitwebhooks/config/registry.py +104 -0
- gitwebhooks/config/server.py +85 -0
- gitwebhooks/handlers/__init__.py +22 -0
- gitwebhooks/handlers/base.py +107 -0
- gitwebhooks/handlers/custom.py +73 -0
- gitwebhooks/handlers/factory.py +83 -0
- gitwebhooks/handlers/gitee.py +113 -0
- gitwebhooks/handlers/github.py +43 -0
- gitwebhooks/handlers/gitlab.py +43 -0
- gitwebhooks/handlers/request.py +248 -0
- gitwebhooks/logging/__init__.py +10 -0
- gitwebhooks/logging/setup.py +57 -0
- gitwebhooks/main/__init__.py +117 -0
- gitwebhooks/main/__main__.py +12 -0
- gitwebhooks/models/__init__.py +14 -0
- gitwebhooks/models/provider.py +22 -0
- gitwebhooks/models/request.py +61 -0
- gitwebhooks/models/result.py +40 -0
- gitwebhooks/server.py +128 -0
- gitwebhooks/utils/__init__.py +14 -0
- gitwebhooks/utils/constants.py +55 -0
- gitwebhooks/utils/exceptions.py +34 -0
- gitwebhooks/utils/executor.py +34 -0
- gitwebhooks/utils/systemd.py +274 -0
- gitwebhooks-2.1.0.dist-info/METADATA +494 -0
- gitwebhooks-2.1.0.dist-info/RECORD +47 -0
- gitwebhooks-2.1.0.dist-info/WHEEL +5 -0
- gitwebhooks-2.1.0.dist-info/entry_points.txt +2 -0
- gitwebhooks-2.1.0.dist-info/licenses/LICENSE +21 -0
- gitwebhooks-2.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
"""systemd service utilities
|
|
2
|
+
|
|
3
|
+
Provides functions for generating and managing systemd service files.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import os
|
|
7
|
+
import shutil
|
|
8
|
+
import subprocess
|
|
9
|
+
import sys
|
|
10
|
+
from dataclasses import dataclass
|
|
11
|
+
from enum import Enum
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
from typing import Optional, List
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class InstallationType(Enum):
|
|
17
|
+
"""Installation type enumeration
|
|
18
|
+
|
|
19
|
+
Represents the method used to install git-webhooks-server.
|
|
20
|
+
"""
|
|
21
|
+
PIPX = "pipx" # Installed via pipx (recommended)
|
|
22
|
+
VENV = "venv" # Python standard library venv
|
|
23
|
+
VIRTUALENV = "virtualenv" # Third-party virtualenv tool
|
|
24
|
+
SYSTEM_PIP = "system" # System pip installation (not recommended)
|
|
25
|
+
CONDA = "conda" # Conda environment (not supported)
|
|
26
|
+
UNKNOWN = "unknown" # Unable to detect
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@dataclass
|
|
30
|
+
class InstallationEnvironment:
|
|
31
|
+
"""Installation environment detection result
|
|
32
|
+
|
|
33
|
+
Contains information about the current installation environment,
|
|
34
|
+
including type, paths, and support status.
|
|
35
|
+
"""
|
|
36
|
+
type: InstallationType
|
|
37
|
+
python_path: str
|
|
38
|
+
cli_path: str
|
|
39
|
+
venv_root: Optional[str] = None
|
|
40
|
+
detection_methods: List[str] = None
|
|
41
|
+
is_supported: bool = True
|
|
42
|
+
error_message: Optional[str] = None
|
|
43
|
+
|
|
44
|
+
def __post_init__(self):
|
|
45
|
+
if self.detection_methods is None:
|
|
46
|
+
self.detection_methods = []
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
# Service file template
|
|
50
|
+
SERVICE_TEMPLATE = """[Unit]
|
|
51
|
+
Description=Git Webhooks Server
|
|
52
|
+
Documentation=https://github.com/troytse/git-webhooks-server
|
|
53
|
+
After=network-online.target
|
|
54
|
+
Wants=network-online.target
|
|
55
|
+
|
|
56
|
+
[Service]
|
|
57
|
+
Type=simple
|
|
58
|
+
ExecStart={exec_start}
|
|
59
|
+
Restart=on-failure
|
|
60
|
+
RestartSec=1min
|
|
61
|
+
StandardOutput=journal
|
|
62
|
+
StandardError=journal
|
|
63
|
+
|
|
64
|
+
# Security settings
|
|
65
|
+
NoNewPrivileges=true
|
|
66
|
+
PrivateTmp=true
|
|
67
|
+
|
|
68
|
+
[Install]
|
|
69
|
+
WantedBy=multi-user.target
|
|
70
|
+
"""
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def detect_python_interpreter() -> str:
|
|
74
|
+
"""Detect the current Python interpreter path
|
|
75
|
+
|
|
76
|
+
Uses a three-tier fallback strategy:
|
|
77
|
+
1. sys.executable (most reliable, includes venv path automatically)
|
|
78
|
+
2. shutil.which('python3') or shutil.which('python')
|
|
79
|
+
3. Hardcoded '/usr/bin/python3' (last resort)
|
|
80
|
+
|
|
81
|
+
Returns:
|
|
82
|
+
Absolute path to the Python interpreter
|
|
83
|
+
"""
|
|
84
|
+
# Priority 1: Use sys.executable (most reliable)
|
|
85
|
+
if sys.executable:
|
|
86
|
+
return sys.executable
|
|
87
|
+
|
|
88
|
+
# Priority 2: Use which to find python
|
|
89
|
+
python_path = shutil.which('python3') or shutil.which('python')
|
|
90
|
+
if python_path:
|
|
91
|
+
return python_path
|
|
92
|
+
|
|
93
|
+
# Priority 3: Hardcoded fallback
|
|
94
|
+
return '/usr/bin/python3'
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def detect_installation_type(cli_path: Optional[str] = None) -> InstallationEnvironment:
|
|
98
|
+
"""Detect the current installation environment type
|
|
99
|
+
|
|
100
|
+
Detection priority order:
|
|
101
|
+
1. CONDA - Check CONDA_PREFIX environment variable (must reject)
|
|
102
|
+
2. PIPX - Check if ~/.local/pipx/venvs/gitwebhooks-server exists
|
|
103
|
+
3. VENV - Check sys.base_prefix != sys.prefix and pyvenv.cfg exists
|
|
104
|
+
4. VIRTUALENV - Check sys.real_prefix attribute
|
|
105
|
+
5. SYSTEM_PIP - Default fallback
|
|
106
|
+
|
|
107
|
+
Args:
|
|
108
|
+
cli_path: Optional path to gitwebhooks-cli (auto-detected if not provided)
|
|
109
|
+
|
|
110
|
+
Returns:
|
|
111
|
+
InstallationEnvironment instance with detected type and paths
|
|
112
|
+
"""
|
|
113
|
+
detection_methods = []
|
|
114
|
+
|
|
115
|
+
# Auto-detect CLI path if not provided
|
|
116
|
+
if cli_path is None:
|
|
117
|
+
try:
|
|
118
|
+
result = subprocess.run(
|
|
119
|
+
['which', 'gitwebhooks-cli'],
|
|
120
|
+
capture_output=True,
|
|
121
|
+
text=True,
|
|
122
|
+
timeout=5
|
|
123
|
+
)
|
|
124
|
+
if result.returncode == 0:
|
|
125
|
+
cli_path = result.stdout.strip()
|
|
126
|
+
detection_methods.append('which gitwebhooks-cli')
|
|
127
|
+
except (subprocess.TimeoutExpired, FileNotFoundError):
|
|
128
|
+
cli_path = '/usr/local/bin/gitwebhooks-cli'
|
|
129
|
+
|
|
130
|
+
# Check conda (highest priority - must reject)
|
|
131
|
+
if os.getenv('CONDA_PREFIX'):
|
|
132
|
+
detection_methods.append('CONDA_PREFIX env var')
|
|
133
|
+
return InstallationEnvironment(
|
|
134
|
+
type=InstallationType.CONDA,
|
|
135
|
+
python_path=sys.executable,
|
|
136
|
+
cli_path=cli_path,
|
|
137
|
+
detection_methods=detection_methods,
|
|
138
|
+
is_supported=False,
|
|
139
|
+
error_message=(
|
|
140
|
+
"conda environments are not supported. "
|
|
141
|
+
"Please use pipx or venv for installation."
|
|
142
|
+
)
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
# Check pipx
|
|
146
|
+
pipx_venv = Path.home() / '.local' / 'pipx' / 'venvs' / 'gitwebhooks-server'
|
|
147
|
+
if pipx_venv.exists():
|
|
148
|
+
detection_methods.append('pipx venv directory')
|
|
149
|
+
return InstallationEnvironment(
|
|
150
|
+
type=InstallationType.PIPX,
|
|
151
|
+
python_path=sys.executable,
|
|
152
|
+
cli_path=cli_path,
|
|
153
|
+
detection_methods=detection_methods,
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
# Check venv / virtualenv
|
|
157
|
+
in_venv = (
|
|
158
|
+
hasattr(sys, 'real_prefix') or
|
|
159
|
+
(hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix)
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
if in_venv:
|
|
163
|
+
if hasattr(sys, 'real_prefix'):
|
|
164
|
+
detection_methods.append('sys.real_prefix (virtualenv)')
|
|
165
|
+
venv_type = InstallationType.VIRTUALENV
|
|
166
|
+
else:
|
|
167
|
+
detection_methods.append('sys.base_prefix != sys.prefix (venv)')
|
|
168
|
+
venv_type = InstallationType.VENV
|
|
169
|
+
|
|
170
|
+
return InstallationEnvironment(
|
|
171
|
+
type=venv_type,
|
|
172
|
+
python_path=sys.executable,
|
|
173
|
+
cli_path=cli_path,
|
|
174
|
+
venv_root=sys.prefix,
|
|
175
|
+
detection_methods=detection_methods,
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
# Default: system pip installation
|
|
179
|
+
detection_methods.append('default (system pip)')
|
|
180
|
+
return InstallationEnvironment(
|
|
181
|
+
type=InstallationType.SYSTEM_PIP,
|
|
182
|
+
python_path=detect_python_interpreter(),
|
|
183
|
+
cli_path=cli_path,
|
|
184
|
+
detection_methods=detection_methods,
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
def check_systemd() -> bool:
|
|
189
|
+
"""Check if systemctl is available
|
|
190
|
+
|
|
191
|
+
Returns:
|
|
192
|
+
True if systemctl command exists, False otherwise
|
|
193
|
+
"""
|
|
194
|
+
try:
|
|
195
|
+
result = subprocess.run(
|
|
196
|
+
['which', 'systemctl'],
|
|
197
|
+
capture_output=True,
|
|
198
|
+
timeout=5
|
|
199
|
+
)
|
|
200
|
+
return result.returncode == 0
|
|
201
|
+
except (subprocess.TimeoutExpired, FileNotFoundError):
|
|
202
|
+
return False
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
def check_root_permission() -> bool:
|
|
206
|
+
"""Check if running with root privileges
|
|
207
|
+
|
|
208
|
+
Returns:
|
|
209
|
+
True if running as root, False otherwise
|
|
210
|
+
"""
|
|
211
|
+
return os.geteuid() == 0
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
def generate_service_file(
|
|
215
|
+
cli_path: str,
|
|
216
|
+
config_path: str,
|
|
217
|
+
python_path: Optional[str] = None,
|
|
218
|
+
use_python_module: bool = False
|
|
219
|
+
) -> str:
|
|
220
|
+
"""Generate systemd service file content
|
|
221
|
+
|
|
222
|
+
Args:
|
|
223
|
+
cli_path: Path to gitwebhooks-cli executable
|
|
224
|
+
config_path: Path to configuration file
|
|
225
|
+
python_path: Python interpreter path (if using python -m mode)
|
|
226
|
+
use_python_module: If True, use 'python -m gitwebhooks.cli' format
|
|
227
|
+
|
|
228
|
+
Returns:
|
|
229
|
+
Service file content as string
|
|
230
|
+
"""
|
|
231
|
+
if use_python_module and python_path:
|
|
232
|
+
exec_start = f"{python_path} -m gitwebhooks.cli -c {config_path}"
|
|
233
|
+
else:
|
|
234
|
+
exec_start = f"{cli_path} -c {config_path}"
|
|
235
|
+
|
|
236
|
+
return SERVICE_TEMPLATE.format(
|
|
237
|
+
exec_start=exec_start
|
|
238
|
+
)
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
def get_service_path() -> Path:
|
|
242
|
+
"""Get the standard systemd service file path
|
|
243
|
+
|
|
244
|
+
Returns:
|
|
245
|
+
Path to service file location
|
|
246
|
+
"""
|
|
247
|
+
return Path('/etc/systemd/system/git-webhooks-server.service')
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
def get_cli_path() -> str:
|
|
251
|
+
"""Get the absolute path to gitwebhooks-cli
|
|
252
|
+
|
|
253
|
+
Returns:
|
|
254
|
+
Absolute path to gitwebhooks-cli executable
|
|
255
|
+
|
|
256
|
+
Note:
|
|
257
|
+
This assumes the CLI is installed in /usr/local/bin
|
|
258
|
+
or available in the system PATH.
|
|
259
|
+
"""
|
|
260
|
+
# Try to find gitwebhooks-cli in PATH
|
|
261
|
+
try:
|
|
262
|
+
result = subprocess.run(
|
|
263
|
+
['which', 'gitwebhooks-cli'],
|
|
264
|
+
capture_output=True,
|
|
265
|
+
text=True,
|
|
266
|
+
timeout=5
|
|
267
|
+
)
|
|
268
|
+
if result.returncode == 0:
|
|
269
|
+
return result.stdout.strip()
|
|
270
|
+
except (subprocess.TimeoutExpired, FileNotFoundError):
|
|
271
|
+
pass
|
|
272
|
+
|
|
273
|
+
# Fallback to standard location
|
|
274
|
+
return '/usr/local/bin/gitwebhooks-cli'
|