gitwebhooks 2.2.0__py3-none-any.whl → 2.3.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 CHANGED
@@ -3,7 +3,7 @@
3
3
  Automated deployment server supporting GitHub, Gitee, GitLab, and custom webhooks.
4
4
  """
5
5
 
6
- __version__ = '2.2.0'
6
+ __version__ = '2.3.0'
7
7
 
8
8
  # Export main classes for convenient import paths
9
9
  from .server import WebhookServer
@@ -5,6 +5,8 @@ Provides subcommand registration and implementation for gitwebhooks-cli.
5
5
 
6
6
  from gitwebhooks.cli.service import cmd_install, cmd_uninstall
7
7
  from gitwebhooks.cli.config import cmd_init, cmd_view
8
+ from gitwebhooks.cli.help import cmd_help
9
+ from gitwebhooks.cli.serve import cmd_serve
8
10
 
9
11
 
10
12
  def register_subparsers(subparsers):
@@ -16,15 +18,101 @@ def register_subparsers(subparsers):
16
18
  Returns:
17
19
  None
18
20
  """
19
- # Register service subcommand
20
- register_service_subparser(subparsers)
21
+ # Register help subcommand
22
+ register_help_subparser(subparsers)
23
+
24
+ # Register serve subcommand
25
+ register_serve_subparser(subparsers)
21
26
 
22
27
  # Register config subcommand
23
28
  register_config_subparser(subparsers)
24
29
 
30
+ # Register service subcommand (deprecated, for backward compatibility)
31
+ register_service_subparser(subparsers)
32
+
33
+
34
+ def register_serve_subparser(subparsers):
35
+ """Register serve subcommand and its actions
36
+
37
+ Args:
38
+ subparsers: argparse subparsers object
39
+
40
+ Returns:
41
+ None
42
+ """
43
+ serve_parser = subparsers.add_parser(
44
+ 'serve',
45
+ add_help=False,
46
+ help='Start webhook server or manage systemd service'
47
+ )
48
+ serve_parser.add_argument(
49
+ '-c', '--config',
50
+ dest='config',
51
+ help='Path to configuration file (default: auto-discover)'
52
+ )
53
+ serve_subparsers = serve_parser.add_subparsers(dest='serve_action')
54
+
55
+ # install action
56
+ install_parser = serve_subparsers.add_parser('install', add_help=False)
57
+ install_parser.add_argument(
58
+ '--force',
59
+ action='store_true',
60
+ help='Force overwrite existing service'
61
+ )
62
+ install_parser.add_argument(
63
+ '--verbose',
64
+ action='count',
65
+ default=0,
66
+ help='Increase verbosity'
67
+ )
68
+ install_parser.add_argument(
69
+ '--dry-run',
70
+ action='store_true',
71
+ help='Preview mode without making changes'
72
+ )
73
+ install_parser.add_argument(
74
+ '--config-level',
75
+ choices=['user', 'local', 'system'],
76
+ help='Configuration file level (user/local/system)'
77
+ )
78
+ install_parser.set_defaults(func=cmd_serve)
79
+
80
+ # uninstall action
81
+ uninstall_parser = serve_subparsers.add_parser('uninstall', add_help=False)
82
+ uninstall_parser.add_argument(
83
+ '--purge',
84
+ action='store_true',
85
+ help='Also remove configuration file'
86
+ )
87
+ uninstall_parser.set_defaults(func=cmd_serve)
88
+
89
+ # Set default function for serve (when no action specified)
90
+ serve_parser.set_defaults(func=cmd_serve)
91
+
92
+
93
+ def register_help_subparser(subparsers):
94
+ """Register help subcommand
95
+
96
+ Args:
97
+ subparsers: argparse subparsers object
98
+
99
+ Returns:
100
+ None
101
+ """
102
+ help_parser = subparsers.add_parser(
103
+ 'help',
104
+ add_help=False
105
+ )
106
+ help_parser.add_argument(
107
+ 'topic',
108
+ nargs='?',
109
+ help='Subcommand to show help for (serve, config)'
110
+ )
111
+ help_parser.set_defaults(func=cmd_help)
112
+
25
113
 
26
114
  def register_service_subparser(subparsers):
27
- """Register service subcommand and its actions
115
+ """Register service subcommand and its actions (deprecated)
28
116
 
29
117
  Args:
30
118
  subparsers: argparse subparsers object
@@ -34,12 +122,13 @@ def register_service_subparser(subparsers):
34
122
  """
35
123
  service_parser = subparsers.add_parser(
36
124
  'service',
37
- help='Manage systemd service installation'
125
+ add_help=False,
126
+ help='Manage systemd service installation (deprecated, use "serve" instead)'
38
127
  )
39
128
  service_subparsers = service_parser.add_subparsers(dest='service_action')
40
129
 
41
130
  # install action
42
- install_parser = service_subparsers.add_parser('install')
131
+ install_parser = service_subparsers.add_parser('install', add_help=False)
43
132
  install_parser.add_argument(
44
133
  '--force',
45
134
  action='store_true',
@@ -56,10 +145,15 @@ def register_service_subparser(subparsers):
56
145
  action='store_true',
57
146
  help='Preview service file without installing'
58
147
  )
148
+ install_parser.add_argument(
149
+ '--config-level',
150
+ choices=['user', 'local', 'system'],
151
+ help='Configuration file level (user/local/system). If not specified, will be prompted.'
152
+ )
59
153
  install_parser.set_defaults(func=cmd_install)
60
154
 
61
155
  # uninstall action
62
- uninstall_parser = service_subparsers.add_parser('uninstall')
156
+ uninstall_parser = service_subparsers.add_parser('uninstall', add_help=False)
63
157
  uninstall_parser.add_argument(
64
158
  '--purge',
65
159
  action='store_true',
@@ -79,6 +173,7 @@ def register_config_subparser(subparsers):
79
173
  """
80
174
  config_parser = subparsers.add_parser(
81
175
  'config',
176
+ add_help=False,
82
177
  help='Manage gitwebhooks configuration'
83
178
  )
84
179
  config_subparsers = config_parser.add_subparsers(dest='config_action')
@@ -86,6 +181,7 @@ def register_config_subparser(subparsers):
86
181
  # init action
87
182
  init_parser = config_subparsers.add_parser(
88
183
  'init',
184
+ add_help=False,
89
185
  help='Initialize configuration file using interactive wizard'
90
186
  )
91
187
  init_parser.add_argument(
@@ -97,7 +193,7 @@ def register_config_subparser(subparsers):
97
193
  init_parser.set_defaults(func=cmd_init)
98
194
 
99
195
  # view action
100
- view_parser = config_subparsers.add_parser('view')
196
+ view_parser = config_subparsers.add_parser('view', add_help=False)
101
197
  view_parser.add_argument(
102
198
  '-c',
103
199
  '--config',
@@ -0,0 +1,155 @@
1
+ """Help command module
2
+
3
+ Provides help information display functionality for gitwebhooks-cli.
4
+ """
5
+
6
+ import argparse
7
+ import sys
8
+
9
+
10
+ def cmd_help(args: argparse.Namespace) -> int:
11
+ """Handle help subcommand.
12
+
13
+ Displays main help or subcommand-specific help depending on the topic.
14
+
15
+ Args:
16
+ args: Parsed command-line arguments
17
+ - topic: Optional subcommand name to show help for
18
+
19
+ Returns:
20
+ Exit code (0 = success)
21
+
22
+ Examples:
23
+ >>> args = argparse.Namespace(topic=None)
24
+ >>> cmd_help(args) # doctest: +SKIP
25
+ 0
26
+ >>> args = argparse.Namespace(topic='serve')
27
+ >>> cmd_help(args) # doctest: +SKIP
28
+ 0
29
+ """
30
+ # Import here to avoid circular dependency
31
+ from gitwebhooks.main import get_parser
32
+
33
+ parser = get_parser()
34
+
35
+ if hasattr(args, 'topic') and args.topic:
36
+ # Show subcommand help
37
+ show_subcommand_help(parser, args.topic)
38
+ else:
39
+ # Show main help
40
+ show_main_help(parser)
41
+
42
+ return 0
43
+
44
+
45
+ def show_main_help(parser: argparse.ArgumentParser) -> None:
46
+ """Display main help information.
47
+
48
+ Args:
49
+ parser: The main argument parser
50
+
51
+ Returns:
52
+ None
53
+ """
54
+ # Custom help output
55
+ help_text = """Git Webhooks Server - Automated deployment webhook handler
56
+
57
+ Usage:
58
+ gitwebhooks-cli [-v] [-c CONFIG] <command> [<args>]
59
+
60
+ Commands:
61
+ serve Start webhook server or manage systemd service
62
+ config Manage configuration file
63
+ help Show help information
64
+
65
+ Options:
66
+ -v, --version Show version information
67
+ -c, --config Path to configuration file (default: auto-discover)
68
+
69
+ Examples:
70
+ gitwebhooks-cli serve # Start server
71
+ gitwebhooks-cli serve install # Install systemd service
72
+ gitwebhooks-cli config init # Initialize configuration
73
+ gitwebhooks-cli help serve # Show serve command help
74
+
75
+ For more information on a specific command:
76
+ gitwebhooks-cli help <command>
77
+ """
78
+ print(help_text)
79
+
80
+
81
+ def show_subcommand_help(parser: argparse.ArgumentParser, topic: str) -> None:
82
+ """Display help for a specific subcommand.
83
+
84
+ Args:
85
+ parser: The main argument parser
86
+ topic: Subcommand name
87
+
88
+ Returns:
89
+ None
90
+ """
91
+ # Map topic to help text
92
+ help_texts = {
93
+ 'serve': """Command: serve
94
+ Start webhook server or manage systemd service
95
+
96
+ Usage:
97
+ gitwebhooks-cli serve [-c CONFIG]
98
+ gitwebhooks-cli serve install [--force] [--dry-run] [--verbose]
99
+ gitwebhooks-cli serve uninstall [--purge]
100
+
101
+ Subcommands:
102
+ (none) Start the webhook server
103
+ install Install systemd service
104
+ uninstall Uninstall systemd service
105
+
106
+ Options:
107
+ -c, --config Path to configuration file
108
+
109
+ Install options:
110
+ --force Force overwrite existing service
111
+ --dry-run Preview mode, don't make changes
112
+ --verbose Increase verbosity
113
+
114
+ Uninstall options:
115
+ --purge Also remove configuration file
116
+
117
+ Examples:
118
+ gitwebhooks-cli serve # Start server
119
+ gitwebhooks-cli serve -c /etc/webhooks.ini # Start with custom config
120
+ gitwebhooks-cli serve install # Install service
121
+ gitwebhooks-cli serve install --force # Force overwrite
122
+ gitwebhooks-cli serve uninstall # Uninstall service
123
+ """,
124
+ 'config': """Command: config
125
+ Manage configuration file
126
+
127
+ Usage:
128
+ gitwebhooks-cli config init [level]
129
+ gitwebhooks-cli config view [-c CONFIG]
130
+
131
+ Subcommands:
132
+ init Initialize configuration file
133
+ view View configuration file
134
+
135
+ Init arguments:
136
+ level Configuration level (system, local, user)
137
+
138
+ View options:
139
+ -c, --config Path to configuration file
140
+
141
+ Examples:
142
+ gitwebhooks-cli config init # Interactive init
143
+ gitwebhooks-cli config init user # User-level config
144
+ gitwebhooks-cli config init system # System-level config (requires sudo)
145
+ gitwebhooks-cli config view # View current config
146
+ """,
147
+ }
148
+
149
+ if topic in help_texts:
150
+ print(help_texts[topic])
151
+ else:
152
+ print(f"Error: Unknown command '{topic}'", file=sys.stderr)
153
+ print("Available commands: serve, config", file=sys.stderr)
154
+ print()
155
+ print("Use 'gitwebhooks-cli help' to see main help", file=sys.stderr)
@@ -4,7 +4,9 @@ Provides functions for interactive user input and validation.
4
4
  """
5
5
 
6
6
  import sys
7
- from typing import Any, Callable, Optional, Dict, List
7
+ from typing import Any, Callable, Optional, Dict, List, Tuple
8
+
9
+ from gitwebhooks.utils.constants import ConfigLevel
8
10
 
9
11
 
10
12
  # Question template for configuration initialization
@@ -273,3 +275,48 @@ def validate_text(value: str) -> str:
273
275
  if not value:
274
276
  raise ValueError('Input cannot be empty')
275
277
  return value
278
+
279
+
280
+ def ask_config_level() -> ConfigLevel:
281
+ """Ask user to select configuration file level
282
+
283
+ Displays an interactive menu for selecting configuration file level
284
+ with descriptions of each option.
285
+
286
+ Returns:
287
+ Selected ConfigLevel enum value
288
+
289
+ Raises:
290
+ KeyboardInterrupt: If user confirms exit on Ctrl+C
291
+ """
292
+ print('Select configuration file level for the service:')
293
+ print(' 1. User level (~/.gitwebhooks.ini) - Single user, highest priority')
294
+ print(' 2. Local level (/usr/local/etc/gitwebhooks.ini) - Local system, medium priority')
295
+ print(' 3. System level (/etc/gitwebhooks.ini) - Global system, lowest priority')
296
+ print()
297
+
298
+ choice_map = {
299
+ '1': ConfigLevel.USER,
300
+ '2': ConfigLevel.LOCAL,
301
+ '3': ConfigLevel.SYSTEM,
302
+ }
303
+
304
+ while True:
305
+ try:
306
+ response = input('Enter choice [1-3] (default: 1): ').strip()
307
+
308
+ # Use default if empty input
309
+ if not response:
310
+ return ConfigLevel.USER
311
+
312
+ # Validate and map response
313
+ if response in choice_map:
314
+ return choice_map[response]
315
+
316
+ # Invalid input
317
+ print('Invalid choice. Please enter a number between 1 and 3.')
318
+
319
+ except KeyboardInterrupt:
320
+ if ask_yes_no('Confirm exit? (y/N) ', default=False):
321
+ print('\nService installation cancelled')
322
+ sys.exit(0)
@@ -0,0 +1,151 @@
1
+ """Serve command module
2
+
3
+ Provides server startup and systemd service management functionality.
4
+ """
5
+
6
+ import argparse
7
+ import sys
8
+ from pathlib import Path
9
+ from typing import Optional
10
+
11
+ from gitwebhooks.server import WebhookServer
12
+ from gitwebhooks.utils.exceptions import ConfigurationError
13
+ from gitwebhooks.utils.constants import CONFIG_SEARCH_PATHS
14
+
15
+ # Import service management functions
16
+ from gitwebhooks.cli.service import (
17
+ cmd_install as service_cmd_install,
18
+ cmd_uninstall as service_cmd_uninstall,
19
+ install_service,
20
+ uninstall_service,
21
+ )
22
+
23
+ # Import version display
24
+ from gitwebhooks import __version__
25
+
26
+
27
+ def cmd_serve(args: argparse.Namespace) -> int:
28
+ """Handle serve subcommand.
29
+
30
+ This function dispatches to the appropriate serve action:
31
+ - No action: Start the webhook server
32
+ - install: Install systemd service
33
+ - uninstall: Uninstall systemd service
34
+
35
+ Args:
36
+ args: Parsed command-line arguments
37
+ - serve_action: The serve sub-action (install, uninstall, or None)
38
+ - config: Configuration file path (from global -c argument)
39
+ - force: Force overwrite existing service (install action)
40
+ - dry_run: Preview mode (install action)
41
+ - verbose: Verbosity level (install action)
42
+ - purge: Also remove config file (uninstall action)
43
+
44
+ Returns:
45
+ Exit code (0 = success, 1 = error)
46
+ """
47
+ # Get serve_action from args
48
+ serve_action = getattr(args, 'serve_action', None)
49
+
50
+ if serve_action == 'install':
51
+ # Delegate to service install command
52
+ return service_cmd_install(args)
53
+ elif serve_action == 'uninstall':
54
+ # Delegate to service uninstall command
55
+ return service_cmd_uninstall(args)
56
+ else:
57
+ # Start server
58
+ return start_server(args)
59
+
60
+
61
+ def start_server(args: argparse.Namespace) -> int:
62
+ """Start the webhook server.
63
+
64
+ Args:
65
+ args: Parsed command-line arguments
66
+ - config: Configuration file path (from global -c argument)
67
+
68
+ Returns:
69
+ Exit code (0 = success, 1 = error)
70
+ """
71
+ # Get config path from args
72
+ config_file = getattr(args, 'config', None)
73
+
74
+ # Print version
75
+ print(f'gitwebhooks-cli {__version__}')
76
+
77
+ # Auto-discover config file if not specified
78
+ if config_file is None:
79
+ config_file = find_config_file()
80
+ if config_file is None:
81
+ # No config found - format error with all search paths
82
+ searched_paths = [Path(p).expanduser().resolve() for p in CONFIG_SEARCH_PATHS]
83
+ error_msg = format_config_error(searched_paths)
84
+ print(error_msg, file=sys.stderr)
85
+ return 1
86
+
87
+ # Expand user path
88
+ config_path = Path(config_file).expanduser()
89
+
90
+ # Check configuration file exists
91
+ if not config_path.exists():
92
+ print(f'Error: Configuration file not found: {config_path}', file=sys.stderr)
93
+ return 1
94
+
95
+ # Print configuration file being used
96
+ print(f'Using configuration file: {config_path}')
97
+ print('Starting server...')
98
+
99
+ # Create and run server
100
+ try:
101
+ server = WebhookServer(config_path=str(config_path))
102
+ server.run()
103
+ return 0
104
+ except ConfigurationError as e:
105
+ print(f'Configuration error: {e}', file=sys.stderr)
106
+ return 1
107
+ except KeyboardInterrupt:
108
+ print('\nServer stopped by user')
109
+ return 0
110
+ except Exception as e:
111
+ print(f'Error: {e}', file=sys.stderr)
112
+ return 1
113
+
114
+
115
+ def find_config_file() -> Optional[str]:
116
+ """Find configuration file by priority order.
117
+
118
+ Searches for configuration files in the following order:
119
+ 1. User level: ~/.gitwebhooks.ini
120
+ 2. Local level: /usr/local/etc/gitwebhooks.ini
121
+ 3. System level: /etc/gitwebhooks.ini
122
+
123
+ Returns:
124
+ Path string of the first existing configuration file, or None if not found.
125
+ """
126
+ for config_path in CONFIG_SEARCH_PATHS:
127
+ expanded_path = Path(config_path).expanduser().resolve()
128
+ if expanded_path.exists():
129
+ return str(expanded_path)
130
+ return None
131
+
132
+
133
+ def format_config_error(searched_paths: list) -> str:
134
+ """Format user-friendly error message for missing configuration file.
135
+
136
+ Args:
137
+ searched_paths: List of paths that were searched.
138
+
139
+ Returns:
140
+ Formatted error message string.
141
+ """
142
+ lines = [
143
+ 'Error: Configuration file not found.',
144
+ 'Searched paths:'
145
+ ]
146
+ for i, path in enumerate(searched_paths, 1):
147
+ lines.append(f' {i}. {path}')
148
+ lines.append('')
149
+ lines.append('You can create a configuration file using:')
150
+ lines.append(' gitwebhooks-cli config init')
151
+ return '\n'.join(lines)
@@ -7,6 +7,7 @@ import argparse
7
7
  import subprocess
8
8
  import sys
9
9
  from pathlib import Path
10
+ from typing import Optional
10
11
 
11
12
  from gitwebhooks.utils.systemd import (
12
13
  check_systemd,
@@ -16,7 +17,8 @@ from gitwebhooks.utils.systemd import (
16
17
  detect_installation_type,
17
18
  InstallationType,
18
19
  )
19
- from gitwebhooks.cli.prompts import ask_yes_no
20
+ from gitwebhooks.utils.constants import ConfigLevel
21
+ from gitwebhooks.cli.prompts import ask_yes_no, ask_config_level
20
22
 
21
23
 
22
24
  # Error codes
@@ -26,21 +28,39 @@ E_EXISTS = 1
26
28
 
27
29
 
28
30
  def cmd_install(args: argparse.Namespace) -> int:
29
- """Install systemd service
31
+ """Install systemd service (deprecated, use 'serve install' instead)
30
32
 
31
33
  Args:
32
34
  args: Parsed command-line arguments
33
35
  - force: Force overwrite existing service
34
36
  - verbose: Verbosity level (0=normal, 1=verbose, 2=extra verbose)
35
37
  - dry_run: Preview mode without actual installation
38
+ - config: Path to configuration file (from global -c argument)
39
+ - config_level: Config level from --config-level argument
36
40
 
37
41
  Returns:
38
42
  Exit code (0 = success, 1 = error)
39
43
  """
44
+ # Show deprecation warning
45
+ print('Warning: "service install" is deprecated. Use "serve install" instead.', file=sys.stderr)
46
+ print()
40
47
  # Get verbose and dry_run from args
41
48
  verbose = getattr(args, 'verbose', 0)
42
49
  dry_run = getattr(args, 'dry_run', False)
43
50
 
51
+ # Get config path from global -c argument (backward compatibility)
52
+ config_path = getattr(args, 'config', None)
53
+ config_level = getattr(args, 'config_level', None)
54
+
55
+ # Check for conflicting options
56
+ if config_path and config_level:
57
+ print('Error: Conflicting options: --config-level and -c cannot be used together.', file=sys.stderr)
58
+ print()
59
+ print('Please use either:', file=sys.stderr)
60
+ print(' - gitwebhooks-cli service install --config-level <level>', file=sys.stderr)
61
+ print(' - gitwebhooks-cli service install -c <config-file>', file=sys.stderr)
62
+ return 1
63
+
44
64
  # For dry-run mode, skip root check
45
65
  if not dry_run:
46
66
  # Check root permission
@@ -76,16 +96,30 @@ def cmd_install(args: argparse.Namespace) -> int:
76
96
  print()
77
97
 
78
98
  # Perform installation
79
- return install_service(force=args.force, verbose=verbose, dry_run=dry_run)
99
+ return install_service(
100
+ force=args.force,
101
+ verbose=verbose,
102
+ dry_run=dry_run,
103
+ config_level_override=config_level,
104
+ config_path_override=config_path
105
+ )
80
106
 
81
107
 
82
- def install_service(force: bool = False, verbose: int = 0, dry_run: bool = False) -> int:
108
+ def install_service(
109
+ force: bool = False,
110
+ verbose: int = 0,
111
+ dry_run: bool = False,
112
+ config_level_override: Optional[str] = None,
113
+ config_path_override: Optional[str] = None
114
+ ) -> int:
83
115
  """Execute service installation logic
84
116
 
85
117
  Args:
86
118
  force: Force overwrite existing service
87
119
  verbose: Verbosity level (0=normal, 1=verbose, 2=extra verbose)
88
120
  dry_run: Preview mode without actual installation
121
+ config_level_override: Config level from command line argument (user/local/system)
122
+ config_path_override: Config path from -c argument (for backward compatibility)
89
123
 
90
124
  Returns:
91
125
  Exit code (0 = success, 1 = error)
@@ -124,13 +158,43 @@ def install_service(force: bool = False, verbose: int = 0, dry_run: bool = False
124
158
  print('Consider using pipx or venv for better isolation.', file=sys.stderr)
125
159
  print()
126
160
 
161
+ # Determine configuration level and path
162
+ config_level: ConfigLevel
163
+ config_path: str
164
+
165
+ if config_path_override:
166
+ # Backward compatibility: -c parameter takes precedence
167
+ config_path = config_path_override
168
+ # Map path to config level for display purposes
169
+ expanded_path = Path(config_path).expanduser()
170
+ if str(expanded_path) == str(Path('~/.gitwebhooks.ini').expanduser()):
171
+ config_level = ConfigLevel.USER
172
+ elif str(expanded_path) == '/usr/local/etc/gitwebhooks.ini':
173
+ config_level = ConfigLevel.LOCAL
174
+ elif str(expanded_path) == '/etc/gitwebhooks.ini':
175
+ config_level = ConfigLevel.SYSTEM
176
+ else:
177
+ # Custom path, default to USER for display
178
+ config_level = ConfigLevel.USER
179
+ elif config_level_override:
180
+ # Command-line --config-level parameter
181
+ try:
182
+ config_level = ConfigLevel.from_string(config_level_override)
183
+ except ValueError as e:
184
+ print(f'Error: {e}', file=sys.stderr)
185
+ return 1
186
+ config_path = str(config_level.get_config_path())
187
+ else:
188
+ # Interactive selection
189
+ config_level = ask_config_level()
190
+ config_path = str(config_level.get_config_path())
191
+
127
192
  # Get paths
128
193
  service_path = get_service_path()
129
- config_path = '~/.gitwebhook.ini'
130
194
 
131
195
  # Generate service file based on installation type
132
196
  # For pipx: use cli_path directly
133
- # For others: use python -m gitwebhooks.cli
197
+ # For others: use python -m gitwebhooks.main
134
198
  use_python_module = env.type != InstallationType.PIPX
135
199
 
136
200
  service_content = generate_service_file(
@@ -147,6 +211,9 @@ def install_service(force: bool = False, verbose: int = 0, dry_run: bool = False
147
211
  print(service_content)
148
212
  print('---')
149
213
  print()
214
+ if config_level_override or not config_path_override:
215
+ print(f'Configuration level: {config_level.value}')
216
+ print(f'Configuration path: {config_path}')
150
217
  print(f'Service file would be written to: {service_path}')
151
218
  print('Dry-run complete: No changes made.')
152
219
  return 0
@@ -174,6 +241,10 @@ def install_service(force: bool = False, verbose: int = 0, dry_run: bool = False
174
241
  print(f'Warning: systemctl daemon-reload failed: {e}', file=sys.stderr)
175
242
  # Continue anyway
176
243
 
244
+ # Display configuration file information
245
+ print()
246
+ print(f'Using configuration file: {config_path}')
247
+
177
248
  # Enable and start service
178
249
  return enable_and_start_service()
179
250
 
@@ -240,7 +311,7 @@ def enable_and_start_service() -> int:
240
311
 
241
312
 
242
313
  def cmd_uninstall(args: argparse.Namespace) -> int:
243
- """Uninstall systemd service
314
+ """Uninstall systemd service (deprecated, use 'serve uninstall' instead)
244
315
 
245
316
  Args:
246
317
  args: Parsed command-line arguments
@@ -249,6 +320,9 @@ def cmd_uninstall(args: argparse.Namespace) -> int:
249
320
  Returns:
250
321
  Exit code (0 = success, 1 = error)
251
322
  """
323
+ # Show deprecation warning
324
+ print('Warning: "service uninstall" is deprecated. Use "serve uninstall" instead.', file=sys.stderr)
325
+ print()
252
326
  # Check root permission
253
327
  if not check_root_permission():
254
328
  print('Error: This operation requires root privileges', file=sys.stderr)
@@ -19,6 +19,57 @@ try:
19
19
  except ImportError:
20
20
  HAS_SUBCOMMANDS = False
21
21
 
22
+ # Global parser reference for help command
23
+ _parser = None
24
+
25
+
26
+ def get_parser() -> argparse.ArgumentParser:
27
+ """Get the main argument parser instance.
28
+
29
+ Returns:
30
+ The main ArgumentParser instance
31
+
32
+ Examples:
33
+ >>> parser = get_parser()
34
+ >>> isinstance(parser, argparse.ArgumentParser)
35
+ True
36
+ """
37
+ global _parser
38
+ if _parser is None:
39
+ _parser = create_parser()
40
+ return _parser
41
+
42
+
43
+ def create_parser() -> argparse.ArgumentParser:
44
+ """Create and configure the main argument parser.
45
+
46
+ Returns:
47
+ Configured ArgumentParser instance
48
+
49
+ Examples:
50
+ >>> parser = create_parser()
51
+ >>> isinstance(parser, argparse.ArgumentParser)
52
+ True
53
+ """
54
+ # Create main argument parser (help disabled)
55
+ parser = argparse.ArgumentParser(
56
+ prog='gitwebhooks-cli',
57
+ description='Git Webhooks Server - Automated deployment webhook handler',
58
+ add_help=False
59
+ )
60
+ parser.add_argument(
61
+ '-c', '--config',
62
+ default=None,
63
+ help='Path to INI configuration file (default: auto-discover)'
64
+ )
65
+
66
+ # Add subcommands if available
67
+ if HAS_SUBCOMMANDS:
68
+ subparsers = parser.add_subparsers(dest='command', help='Subcommands')
69
+ register_subparsers(subparsers)
70
+
71
+ return parser
72
+
22
73
 
23
74
  def find_config_file() -> Optional[str]:
24
75
  """Find configuration file by priority order.
@@ -83,10 +134,11 @@ def main(argv: List[str] = None) -> int:
83
134
  SystemExit: Exit on error
84
135
 
85
136
  Command Line Arguments:
86
- -h, --help Show help message and exit
87
- -c, --config Specify configuration file path (optional)
88
- service Service management subcommands
89
- config Configuration management subcommands
137
+ -v, --version Show version information and exit
138
+ -c, --config Specify configuration file path (optional)
139
+ serve Start webhook server or manage systemd service
140
+ config Configuration management subcommands
141
+ help Show help information
90
142
 
91
143
  Config Discovery:
92
144
  When -c is not specified, searches in order:
@@ -95,38 +147,58 @@ def main(argv: List[str] = None) -> int:
95
147
  3. /etc/gitwebhooks.ini (system level)
96
148
 
97
149
  Examples:
98
- python3 -m gitwebhooks.main
99
- python3 -m gitwebhooks.main -c /path/to/config.ini
100
- gitwebhooks-cli --config /etc/webhooks.ini
101
- gitwebhooks-cli service install
150
+ python3 -m gitwebhooks.main -v
151
+ python3 -m gitwebhooks.main serve
152
+ python3 -m gitwebhooks.main serve -c /path/to/config.ini
153
+ gitwebhooks-cli serve install
102
154
  gitwebhooks-cli config init
155
+ gitwebhooks-cli help
103
156
  """
104
157
  if argv is None:
105
158
  argv = sys.argv[1:]
106
159
 
107
- # Create main argument parser
108
- parser = argparse.ArgumentParser(
109
- prog='gitwebhooks-cli',
110
- description='Git Webhooks Server - Automated deployment webhook handler',
111
- add_help=True
112
- )
113
- parser.add_argument(
114
- '-c', '--config',
115
- default=None,
116
- help='Path to INI configuration file (default: auto-discover)'
117
- )
160
+ # Pre-check for -v/--version parameters (takes priority over everything)
161
+ if '-v' in argv or '--version' in argv:
162
+ from gitwebhooks.main.version import print_version
163
+ print_version()
164
+ return 0
118
165
 
119
- # Add subcommands if available
120
- if HAS_SUBCOMMANDS:
121
- subparsers = parser.add_subparsers(dest='command', help='Subcommands')
122
- register_subparsers(subparsers)
166
+ # Check for -h/--help parameters and show error
167
+ if '-h' in argv or '--help' in argv:
168
+ print('Error: -h/--help parameters are not supported.', file=sys.stderr)
169
+ print('Use \'gitwebhooks-cli help\' or \'gitwebhooks-cli help <subcommand>\' instead.', file=sys.stderr)
170
+ return 1
171
+
172
+ # Create parser and parse arguments
173
+ parser = create_parser()
174
+
175
+ # Check if user provided a command (first argument without leading dash)
176
+ command = None
177
+ for i, arg in enumerate(argv):
178
+ if not arg.startswith('-'):
179
+ command = arg
180
+ break
123
181
 
124
- # Parse arguments
125
- args = parser.parse_args(argv)
182
+ # Try to parse arguments
183
+ try:
184
+ args = parser.parse_args(argv)
185
+ except SystemExit as e:
186
+ # argparse will call sys.exit on error, catch it to provide better error
187
+ if e.code != 0:
188
+ # Parsing failed, check if it's an unknown command
189
+ if command and command not in ['serve', 'config', 'help', 'service']:
190
+ print(f"Error: Unknown command '{command}'", file=sys.stderr)
191
+ print("Available commands: serve, config, help", file=sys.stderr)
192
+ print()
193
+ print("Use 'gitwebhooks-cli help' to see usage information", file=sys.stderr)
194
+ return 1
195
+ raise
126
196
 
127
- # If no subcommand, run server (backward compatible behavior)
128
- if not hasattr(args, 'func'):
129
- return run_server(args.config)
197
+ # If no subcommand specified, show help (new default behavior)
198
+ if not hasattr(args, 'func') or args.func is None:
199
+ from gitwebhooks.cli.help import show_main_help
200
+ show_main_help(parser)
201
+ return 0
130
202
 
131
203
  # Execute subcommand
132
204
  return args.func(args)
@@ -0,0 +1,24 @@
1
+ """Version display module
2
+
3
+ Provides version information display functionality for gitwebhooks-cli.
4
+ """
5
+
6
+ import sys
7
+
8
+
9
+ def print_version() -> None:
10
+ """Print version information and exit.
11
+
12
+ Displays version in the format: gitwebhooks-cli x.x.x
13
+
14
+ Returns:
15
+ None
16
+
17
+ Examples:
18
+ >>> print_version() # doctest: +SKIP
19
+ gitwebhooks-cli 2.2.0
20
+ """
21
+ # Import __version__ from package
22
+ from gitwebhooks import __version__
23
+
24
+ print(f'gitwebhooks-cli {__version__}')
@@ -6,9 +6,11 @@ Defines core data types and enumerations.
6
6
  from .provider import Provider
7
7
  from .request import WebhookRequest
8
8
  from .result import SignatureVerificationResult
9
+ from .config import ServiceInstallContext
9
10
 
10
11
  __all__ = [
11
12
  'Provider',
12
13
  'WebhookRequest',
13
14
  'SignatureVerificationResult',
15
+ 'ServiceInstallContext',
14
16
  ]
@@ -0,0 +1,74 @@
1
+ """Configuration-related data models
2
+
3
+ Provides data classes for configuration and service installation contexts.
4
+ """
5
+
6
+ from dataclasses import dataclass
7
+ from pathlib import Path
8
+ from typing import Optional
9
+
10
+ from gitwebhooks.utils.constants import ConfigLevel
11
+ from gitwebhooks.utils.systemd import InstallationType
12
+
13
+
14
+ @dataclass
15
+ class ServiceInstallContext:
16
+ """Service installation context
17
+
18
+ Contains all information needed for service installation,
19
+ including configuration level, paths, and installation type.
20
+
21
+ Attributes:
22
+ config_level: Configuration file level (user/local/system)
23
+ config_path: Full path to configuration file
24
+ install_type: Installation type (pipx/venv/virtualenv/system)
25
+ use_python_module: Whether to use 'python -m' format
26
+ cli_path: Path to gitwebhooks-cli executable
27
+ python_path: Python interpreter path (required when use_python_module=True)
28
+ """
29
+
30
+ config_level: ConfigLevel
31
+ config_path: Path
32
+ install_type: InstallationType
33
+ use_python_module: bool
34
+ cli_path: str
35
+ python_path: Optional[str] = None
36
+
37
+ def __post_init__(self):
38
+ """Validate the service installation context
39
+
40
+ Raises:
41
+ ValueError: If validation fails
42
+ """
43
+ # Ensure config_path is a Path object
44
+ if isinstance(self.config_path, str):
45
+ self.config_path = Path(self.config_path)
46
+
47
+ # Validate use_python_module requires python_path
48
+ if self.use_python_module and not self.python_path:
49
+ raise ValueError(
50
+ "python_path is required when use_python_module is True"
51
+ )
52
+
53
+ # Validate config_path is not empty
54
+ if not self.config_path or str(self.config_path) == '.':
55
+ raise ValueError("config_path cannot be empty")
56
+
57
+ def get_exec_start_command(self) -> str:
58
+ """Generate the ExecStart command for systemd service file
59
+
60
+ Returns:
61
+ Complete ExecStart command string
62
+ """
63
+ if self.use_python_module and self.python_path:
64
+ return f"{self.python_path} -m gitwebhooks.main -c {self.config_path}"
65
+ else:
66
+ return f"{self.cli_path} -c {self.config_path}"
67
+
68
+ def get_config_path_str(self) -> str:
69
+ """Get configuration file path as string
70
+
71
+ Returns:
72
+ Configuration file path as string
73
+ """
74
+ return str(self.config_path)
@@ -3,6 +3,9 @@
3
3
  Defines all constants used in the project.
4
4
  """
5
5
 
6
+ from enum import Enum
7
+ from pathlib import Path
8
+
6
9
  # HTTP Status Codes
7
10
  HTTP_OK = 200
8
11
  HTTP_BAD_REQUEST = 400
@@ -53,3 +56,49 @@ SENSITIVE_KEYWORDS = {"secret", "password", "token", "key", "passphrase"}
53
56
  # ANSI color codes for sensitive field highlighting
54
57
  COLOR_SENSITIVE = "\033[33m" # Yellow
55
58
  COLOR_RESET = "\033[0m"
59
+
60
+
61
+ class ConfigLevel(Enum):
62
+ """Configuration file level for service installation
63
+
64
+ Represents the three configuration file levels supported by gitwebhooks,
65
+ ordered by priority (highest to lowest).
66
+ """
67
+
68
+ USER = "user" # ~/.gitwebhooks.ini (highest priority)
69
+ LOCAL = "local" # /usr/local/etc/gitwebhooks.ini
70
+ SYSTEM = "system" # /etc/gitwebhooks.ini (lowest priority)
71
+
72
+ def get_config_path(self) -> Path:
73
+ """Get the configuration file path for this level
74
+
75
+ Returns:
76
+ Path object pointing to the configuration file
77
+ """
78
+ paths = {
79
+ ConfigLevel.USER: Path(CONFIG_PATH_USER).expanduser(),
80
+ ConfigLevel.LOCAL: Path(CONFIG_PATH_LOCAL),
81
+ ConfigLevel.SYSTEM: Path(CONFIG_PATH_SYSTEM),
82
+ }
83
+ return paths[self]
84
+
85
+ @classmethod
86
+ def from_string(cls, value: str) -> 'ConfigLevel':
87
+ """Create ConfigLevel from string value
88
+
89
+ Args:
90
+ value: String value ('user', 'local', or 'system')
91
+
92
+ Returns:
93
+ ConfigLevel enum value
94
+
95
+ Raises:
96
+ ValueError: If value is not a valid config level
97
+ """
98
+ try:
99
+ return cls(value.lower())
100
+ except ValueError:
101
+ valid_values = ', '.join([e.value for e in cls])
102
+ raise ValueError(
103
+ f"Invalid config level '{value}'. Valid values are: {valid_values}"
104
+ )
@@ -223,15 +223,15 @@ def generate_service_file(
223
223
  cli_path: Path to gitwebhooks-cli executable
224
224
  config_path: Path to configuration file
225
225
  python_path: Python interpreter path (if using python -m mode)
226
- use_python_module: If True, use 'python -m gitwebhooks.cli' format
226
+ use_python_module: If True, use 'python -m gitwebhooks.main' format
227
227
 
228
228
  Returns:
229
229
  Service file content as string
230
230
  """
231
231
  if use_python_module and python_path:
232
- exec_start = f"{python_path} -m gitwebhooks.cli -c {config_path}"
232
+ exec_start = f"{python_path} -m gitwebhooks.main serve -c {config_path}"
233
233
  else:
234
- exec_start = f"{cli_path} -c {config_path}"
234
+ exec_start = f"{cli_path} serve -c {config_path}"
235
235
 
236
236
  return SERVICE_TEMPLATE.format(
237
237
  exec_start=exec_start
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gitwebhooks
3
- Version: 2.2.0
3
+ Version: 2.3.0
4
4
  Summary: A lightweight Git webhook server for automated deployment supporting GitHub, Gitee, GitLab, and custom webhooks
5
5
  Author-email: Troy Tse <troy@holyhi.net>
6
6
  Maintainer-email: Troy Tse <troy@holyhi.net>
@@ -169,28 +169,40 @@ This will create a configuration file with secure permissions (0600).
169
169
  The service installation command automatically detects your installation type (pipx, venv, or system) and generates the appropriate service file.
170
170
 
171
171
  ```bash
172
- # Install and start as a systemd service
173
- sudo gitwebhooks-cli service install
172
+ # Install and start as a systemd service (interactive config level selection)
173
+ sudo gitwebhooks-cli serve install
174
+
175
+ # Install with specific config level (skip interactive selection)
176
+ sudo gitwebhooks-cli serve install --config-level user # User level (~/.gitwebhooks.ini)
177
+ sudo gitwebhooks-cli serve install --config-level local # Local level (/usr/local/etc/gitwebhooks.ini)
178
+ sudo gitwebhooks-cli serve install --config-level system # System level (/etc/gitwebhooks.ini)
179
+
180
+ # Use custom config file (backward compatibility)
181
+ sudo gitwebhooks-cli serve install -c /path/to/config.ini
174
182
 
175
183
  # Preview service file without installing (dry-run mode)
176
- sudo gitwebhooks-cli service install --dry-run
184
+ sudo gitwebhooks-cli serve install --dry-run
185
+ sudo gitwebhooks-cli serve install --config-level local --dry-run # Preview specific level
177
186
 
178
187
  # Install with verbose output
179
- sudo gitwebhooks-cli service install --verbose
180
- sudo gitwebhooks-cli service install -v # Basic verbosity
181
- sudo gitwebhooks-cli service install -vv # Extra verbosity
188
+ sudo gitwebhooks-cli serve install --verbose
182
189
 
183
190
  # Force overwrite existing service
184
- sudo gitwebhooks-cli service install --force
191
+ sudo gitwebhooks-cli serve install --force
185
192
 
186
193
  # Uninstall the service
187
- sudo gitwebhooks-cli service uninstall
194
+ sudo gitwebhooks-cli serve uninstall
188
195
  ```
189
196
 
197
+ **Configuration levels**:
198
+ - **user**: `~/.gitwebhooks.ini` - Single user configuration, highest priority
199
+ - **local**: `/usr/local/etc/gitwebhooks.ini` - Local system configuration, medium priority
200
+ - **system**: `/etc/gitwebhooks.ini` - Global system configuration, lowest priority
201
+
190
202
  **Service file auto-detection**:
191
203
  - **pipx installation**: Uses `gitwebhooks-cli` command directly
192
- - **venv/virtualenv**: Uses `python -m gitwebhooks.cli` with environment's Python
193
- - **System pip**: Uses system Python with `python -m gitwebhooks.cli`
204
+ - **venv/virtualenv**: Uses `python -m gitwebhooks.main` with environment's Python
205
+ - **System pip**: Uses system Python with `python -m gitwebhooks.main`
194
206
  - **conda**: Not supported - installation will be refused with clear error message
195
207
 
196
208
  ### Manual Installation
@@ -208,7 +220,14 @@ sudo ln "$(pwd)/gitwebhooks-cli" /usr/local/bin/gitwebhooks-cli
208
220
  ### Verify Installation
209
221
 
210
222
  ```bash
211
- gitwebhooks-cli --help
223
+ # Show version
224
+ gitwebhooks-cli -v
225
+
226
+ # Show help
227
+ gitwebhooks-cli help
228
+
229
+ # View configuration
230
+ gitwebhooks-cli config view
212
231
  ```
213
232
 
214
233
  ## Migrating from System pip Installation
@@ -1,4 +1,4 @@
1
- gitwebhooks/__init__.py,sha256=KUi3jpqSom1NA9r8du8t2kG1mZ0NN8Jtdbl9wlxr5bg,422
1
+ gitwebhooks/__init__.py,sha256=mwkwwmLU4XQc5li5wJQkU4XRdOwlNvqcgi3dmdWwxuo,422
2
2
  gitwebhooks/__main__.py,sha256=DW1lmngPDSFHJKSyaG2Dd5k3UguGSuYPUM2xKR8DhTo,189
3
3
  gitwebhooks/server.py,sha256=keQcfOysoitx7cINcTkaDvhe6nScIFL2K8dCCViFF-o,3986
4
4
  gitwebhooks/auth/__init__.py,sha256=Hu88BS6aOickrWBBWM2ppTzy2xOJfWODYkp752bPTPM,532
@@ -8,11 +8,13 @@ gitwebhooks/auth/gitee.py,sha256=8o_tKugZrW2or-uoRzjCo3h-WRlm3zbYmkTNbf5zL6s,324
8
8
  gitwebhooks/auth/github.py,sha256=sY3xPwfYvD3tID5b26qHhTI1E9EW2VNHaFEygmsZYCg,1619
9
9
  gitwebhooks/auth/gitlab.py,sha256=Aoz77VbYRASxNXqOAnK5__9hkGgaf9kLMoCgOnvFMNE,862
10
10
  gitwebhooks/auth/verifier.py,sha256=onIvbmFVWpk7vkdEiyF48S4KrtbP48NH3FLz0fE24XE,971
11
- gitwebhooks/cli/__init__.py,sha256=o81CV1rggR_YqSW80JP_CSKMGBQkQYJqDjsiUtvvW-I,2891
11
+ gitwebhooks/cli/__init__.py,sha256=A8GyUtejo5qtzD9K_0mvuWGcs1WWYmeSQrJwoLz4b70,5657
12
12
  gitwebhooks/cli/config.py,sha256=rVq7qh2KB9Z4Up2bc9zWDvGpf28iALdnu1pGIJ0p6-8,6373
13
+ gitwebhooks/cli/help.py,sha256=zjWrpKfs4GdvoxR9awy4Hc-pc6Lgyb-RFMV-bO1_TG8,4284
13
14
  gitwebhooks/cli/init_wizard.py,sha256=7nJHFrXsqC5FS79CE3xyftP9_KW9Q5FO2Duuj8nuO4M,23926
14
- gitwebhooks/cli/prompts.py,sha256=slbAcjEUY83lanuXbfyt7BP4m1ZrgQEcgkjI96hsw60,7167
15
- gitwebhooks/cli/service.py,sha256=6w8jlOOkHAURWKTbqPqW83lC8qbgDuxM_0W0IXhLo24,11001
15
+ gitwebhooks/cli/prompts.py,sha256=8XDUyplQqvcqDEARI3XI5qGh5PpJLYwHGCNuqERn4UI,8655
16
+ gitwebhooks/cli/serve.py,sha256=MP58IuuZpva0soMR34zxv-856XsMBkHJnF-VLETSK6w,4665
17
+ gitwebhooks/cli/service.py,sha256=cpMOTwjU58Nurjo5zBpsMJTNLo7GHixHe4CSPpmifdc,14175
16
18
  gitwebhooks/config/__init__.py,sha256=CnU2ybNi8Yf5YqGWe7uls98ditREEuxuj5mW0t1ti0s,413
17
19
  gitwebhooks/config/loader.py,sha256=fbuIPeDFx5f6-HjPuo35U5CMYxeH1ZWPD18vZJRpSiE,5774
18
20
  gitwebhooks/config/models.py,sha256=oZ0ISLxh0zq5U7fqpAk2as7qHsOcbwj257BZEaK1zO8,4758
@@ -28,20 +30,22 @@ gitwebhooks/handlers/gitlab.py,sha256=UkK3R_KSKSt0s7XAtH1_G_uid85tqiL12qND8_Pnos
28
30
  gitwebhooks/handlers/request.py,sha256=GsKH-R7L7j7h9GKEAse-O4tnmXeQMkbsT8WK_J8ACl8,9184
29
31
  gitwebhooks/logging/__init__.py,sha256=CmL5WD2RgZ76uhrxzwnIfOEd_HgTZMTtTjjqYSY06GA,146
30
32
  gitwebhooks/logging/setup.py,sha256=scu4nfEJTLR6QpmO4exXbKaMcTU11qHR2Jv8fEpEMD8,2095
31
- gitwebhooks/main/__init__.py,sha256=kg7QtoWHljnEkysei5XoIwXMjveNHf_bdPwfei5Vypw,5559
33
+ gitwebhooks/main/__init__.py,sha256=WV4io9b8qJ4_v6GExq_w-fF0v0eoEeL8fCpdT-aYAgk,7920
32
34
  gitwebhooks/main/__main__.py,sha256=qE-72BSpj15NeV6-oWpMXR3ARmATeSGUO8VUB98sxF8,223
33
- gitwebhooks/models/__init__.py,sha256=DmZBPoNeh7eB9Ntr6d4T9QY6-LckvrHNGg8FVcpuvP0,273
35
+ gitwebhooks/main/version.py,sha256=u0iDPU2FE132Bq2s-fManXjDcoBxJ0jnRP77flN5Mug,497
36
+ gitwebhooks/models/__init__.py,sha256=3uS3rYD5EG2F8Vc-pJ02ufmMreL6sIcJ_fTjRh7V398,344
37
+ gitwebhooks/models/config.py,sha256=7T8vE-eNMRcd4dNPDwNNmB0NkTlh_Rk00XcgMIAy7bo,2419
34
38
  gitwebhooks/models/provider.py,sha256=lmjJvGjklD1VTKB6UF9V-gZCPwXhiip8DR8qXs_A-F8,451
35
39
  gitwebhooks/models/request.py,sha256=UkdTiBpX4-XipeOnhE0SvAaR53bFFh8EKftSVFjNBLM,1838
36
40
  gitwebhooks/models/result.py,sha256=0M3fjeUH3CM4Mjpc9e4ZxBdfPO9xlODRRdlshVomQYQ,1020
37
41
  gitwebhooks/utils/__init__.py,sha256=qZcrINToHF8qAtIIDAjOlzfKcohCVyYe2ZaKYsWbOxY,219
38
- gitwebhooks/utils/constants.py,sha256=V_SFYrHpkX-fKSfVwx8fXwBjZe2f4EjoVz925RZryrs,1729
42
+ gitwebhooks/utils/constants.py,sha256=PGmwV9lkH8VP8XblEopdm2lr71ZaNISXzuWcU0KfcAU,3220
39
43
  gitwebhooks/utils/exceptions.py,sha256=Mfz-FOCiHZiYmpSQDw36S9HarLE2wPLfFbkeHfWJnkk,627
40
44
  gitwebhooks/utils/executor.py,sha256=-zQUV5t-eq0JF6T4EvsUlvg4lnBtahRGrV8N3iVgx_c,923
41
- gitwebhooks/utils/systemd.py,sha256=00k55_vcstkTmJi99RrSfx-RIuI1dwTlggCPRPfbhNU,7901
42
- gitwebhooks-2.2.0.dist-info/licenses/LICENSE,sha256=NV5F0xpN-DVJuhc0qzOsXtLjf3l8X18zehW_7F4qI50,1083
43
- gitwebhooks-2.2.0.dist-info/METADATA,sha256=gPht52jk7aXxx3AhQEZCHNpij_IrFY97UUYHEIvOyLM,14346
44
- gitwebhooks-2.2.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
45
- gitwebhooks-2.2.0.dist-info/entry_points.txt,sha256=kcbGwiZPNGnfEYlsrOaNQinGC1rTkiaDOF2NJ6S_5MU,58
46
- gitwebhooks-2.2.0.dist-info/top_level.txt,sha256=9a6CxnHxBD53HL38GUeZETIvnUhUKcgDRIGJkCqwc3o,12
47
- gitwebhooks-2.2.0.dist-info/RECORD,,
45
+ gitwebhooks/utils/systemd.py,sha256=1g2-oByu-XTgZZI_FzsyLl7A1b-NKcwWqtzapvoVGUs,7915
46
+ gitwebhooks-2.3.0.dist-info/licenses/LICENSE,sha256=NV5F0xpN-DVJuhc0qzOsXtLjf3l8X18zehW_7F4qI50,1083
47
+ gitwebhooks-2.3.0.dist-info/METADATA,sha256=v521rAHS_nift5U89wwgElSumqjxcjAHnMV50_N6E58,15188
48
+ gitwebhooks-2.3.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
49
+ gitwebhooks-2.3.0.dist-info/entry_points.txt,sha256=kcbGwiZPNGnfEYlsrOaNQinGC1rTkiaDOF2NJ6S_5MU,58
50
+ gitwebhooks-2.3.0.dist-info/top_level.txt,sha256=9a6CxnHxBD53HL38GUeZETIvnUhUKcgDRIGJkCqwc3o,12
51
+ gitwebhooks-2.3.0.dist-info/RECORD,,