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.
Files changed (47) hide show
  1. gitwebhooks/__init__.py +18 -0
  2. gitwebhooks/__main__.py +10 -0
  3. gitwebhooks/auth/__init__.py +20 -0
  4. gitwebhooks/auth/custom.py +40 -0
  5. gitwebhooks/auth/factory.py +73 -0
  6. gitwebhooks/auth/gitee.py +86 -0
  7. gitwebhooks/auth/github.py +52 -0
  8. gitwebhooks/auth/gitlab.py +29 -0
  9. gitwebhooks/auth/verifier.py +34 -0
  10. gitwebhooks/cli/__init__.py +107 -0
  11. gitwebhooks/cli/config.py +216 -0
  12. gitwebhooks/cli/init_wizard.py +701 -0
  13. gitwebhooks/cli/prompts.py +275 -0
  14. gitwebhooks/cli/service.py +374 -0
  15. gitwebhooks/config/__init__.py +17 -0
  16. gitwebhooks/config/loader.py +170 -0
  17. gitwebhooks/config/models.py +145 -0
  18. gitwebhooks/config/registry.py +104 -0
  19. gitwebhooks/config/server.py +85 -0
  20. gitwebhooks/handlers/__init__.py +22 -0
  21. gitwebhooks/handlers/base.py +107 -0
  22. gitwebhooks/handlers/custom.py +73 -0
  23. gitwebhooks/handlers/factory.py +83 -0
  24. gitwebhooks/handlers/gitee.py +113 -0
  25. gitwebhooks/handlers/github.py +43 -0
  26. gitwebhooks/handlers/gitlab.py +43 -0
  27. gitwebhooks/handlers/request.py +248 -0
  28. gitwebhooks/logging/__init__.py +10 -0
  29. gitwebhooks/logging/setup.py +57 -0
  30. gitwebhooks/main/__init__.py +117 -0
  31. gitwebhooks/main/__main__.py +12 -0
  32. gitwebhooks/models/__init__.py +14 -0
  33. gitwebhooks/models/provider.py +22 -0
  34. gitwebhooks/models/request.py +61 -0
  35. gitwebhooks/models/result.py +40 -0
  36. gitwebhooks/server.py +128 -0
  37. gitwebhooks/utils/__init__.py +14 -0
  38. gitwebhooks/utils/constants.py +55 -0
  39. gitwebhooks/utils/exceptions.py +34 -0
  40. gitwebhooks/utils/executor.py +34 -0
  41. gitwebhooks/utils/systemd.py +274 -0
  42. gitwebhooks-2.1.0.dist-info/METADATA +494 -0
  43. gitwebhooks-2.1.0.dist-info/RECORD +47 -0
  44. gitwebhooks-2.1.0.dist-info/WHEEL +5 -0
  45. gitwebhooks-2.1.0.dist-info/entry_points.txt +2 -0
  46. gitwebhooks-2.1.0.dist-info/licenses/LICENSE +21 -0
  47. 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'