depkeeper 0.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.
depkeeper/__init__.py ADDED
@@ -0,0 +1,32 @@
1
+ """
2
+ depkeeper — modern Python dependency management for requirements.txt.
3
+
4
+ depkeeper is an intelligent dependency management tool that helps developers
5
+ keep their ``requirements.txt`` files up to date, secure, and conflict-free.
6
+
7
+ Quick start
8
+ -----------
9
+ Check for available updates::
10
+
11
+ $ depkeeper check
12
+
13
+ Update packages to newer versions::
14
+
15
+ $ depkeeper update
16
+
17
+ Programmatic usage::
18
+
19
+ >>> from depkeeper.core.parser import RequirementsParser
20
+ >>> from depkeeper.core.checker import VersionChecker
21
+ >>> parser = RequirementsParser()
22
+ >>> requirements = parser.parse_file("requirements.txt")
23
+
24
+ For more information, see:
25
+ https://rahulkaushal04.github.io/depkeeper/
26
+ """
27
+
28
+ from __future__ import annotations
29
+
30
+ from depkeeper.__version__ import __version__
31
+
32
+ __all__ = ["__version__"]
depkeeper/__main__.py ADDED
@@ -0,0 +1,45 @@
1
+ """
2
+ Module entry point for depkeeper.
3
+
4
+ This file enables execution via ``python -m depkeeper`` and delegates
5
+ control to the main CLI implementation.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import sys
11
+
12
+
13
+ def main() -> int:
14
+ """Entry point for ``python -m depkeeper``.
15
+
16
+ Returns:
17
+ Exit code:
18
+ 0 Success
19
+ 1 Import or runtime error
20
+ 130 Interrupted by user
21
+ """
22
+ try:
23
+ from depkeeper.cli import main as cli_main
24
+ except ImportError as exc:
25
+ _print_startup_error(exc)
26
+ return 1
27
+
28
+ return cli_main()
29
+
30
+
31
+ def _print_startup_error(exc: ImportError) -> None:
32
+ """Print a helpful error message if the CLI cannot be imported."""
33
+ try:
34
+ from depkeeper.__version__ import __version__
35
+
36
+ sys.stderr.write(f"depkeeper version: {__version__}\n")
37
+ except Exception:
38
+ sys.stderr.write("depkeeper version: <unknown>\n")
39
+
40
+ sys.stderr.write("\n")
41
+ sys.stderr.write(f"ImportError: {exc}\n")
42
+
43
+
44
+ if __name__ == "__main__":
45
+ sys.exit(main())
@@ -0,0 +1,12 @@
1
+ """
2
+ Version information for depkeeper.
3
+
4
+ This module exposes the canonical version string for the depkeeper
5
+ package. It is intentionally isolated to avoid import cycles and to
6
+ allow tools (CLI, packaging, docs) to query the version reliably.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ #: Current depkeeper version (PEP 440 compliant).
12
+ __version__: str = "0.1.0"
depkeeper/cli.py ADDED
@@ -0,0 +1,169 @@
1
+ """
2
+ Command-line interface for depkeeper.
3
+
4
+ This module provides the main CLI entry point and handles global options,
5
+ configuration loading, and command registration.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import os
11
+ import sys
12
+ import logging
13
+ from pathlib import Path
14
+ from typing import Optional
15
+
16
+ import click
17
+
18
+ from depkeeper.config import load_config
19
+ from depkeeper.__version__ import __version__
20
+ from depkeeper.context import DepKeeperContext
21
+ from depkeeper.exceptions import ConfigError, DepKeeperError
22
+ from depkeeper.utils.logger import get_logger, setup_logging
23
+ from depkeeper.utils.console import print_error, print_warning
24
+
25
+ logger = get_logger("cli")
26
+
27
+
28
+ @click.group(context_settings={"help_option_names": ["-h", "--help"]})
29
+ @click.option(
30
+ "--config",
31
+ "-c",
32
+ type=click.Path(exists=True, dir_okay=False, path_type=Path),
33
+ help="Path to configuration file.",
34
+ envvar="DEPKEEPER_CONFIG",
35
+ )
36
+ @click.option(
37
+ "--verbose",
38
+ "-v",
39
+ count=True,
40
+ help="Increase verbosity (can be repeated: -v, -vv).",
41
+ )
42
+ @click.option(
43
+ "--color/--no-color",
44
+ default=True,
45
+ help="Enable or disable colored output.",
46
+ envvar="DEPKEEPER_COLOR",
47
+ )
48
+ @click.version_option(
49
+ version=__version__,
50
+ prog_name="depkeeper",
51
+ message="%(prog)s %(version)s",
52
+ )
53
+ @click.pass_context
54
+ def cli(
55
+ ctx: click.Context,
56
+ config: Optional[Path],
57
+ verbose: int,
58
+ color: bool,
59
+ ) -> None:
60
+ """depkeeper — modern dependency management for requirements.txt files.
61
+
62
+ \b
63
+ Available commands:
64
+ depkeeper check Check for available updates
65
+ depkeeper update Update packages to newer versions
66
+
67
+ \b
68
+ Examples:
69
+ depkeeper check
70
+ depkeeper update
71
+ depkeeper -v check
72
+
73
+ Use ``depkeeper COMMAND --help`` for command-specific options.
74
+ """
75
+ _configure_logging(verbose)
76
+
77
+ try:
78
+ loaded_config = load_config(config)
79
+ except ConfigError as exc:
80
+ print_error(str(exc))
81
+ raise SystemExit(1) from exc
82
+
83
+ depkeeper_ctx = DepKeeperContext()
84
+ depkeeper_ctx.config_path = config or (
85
+ loaded_config.source_path if loaded_config.source_path else None
86
+ )
87
+ depkeeper_ctx.color = color
88
+ depkeeper_ctx.verbose = verbose
89
+ depkeeper_ctx.config = loaded_config
90
+ ctx.obj = depkeeper_ctx
91
+
92
+ # Respect NO_COLOR for downstream libraries
93
+ if color:
94
+ os.environ.pop("NO_COLOR", None)
95
+ else:
96
+ os.environ["NO_COLOR"] = "1"
97
+
98
+ logger.debug("depkeeper v%s", __version__)
99
+ logger.debug("Config path: %s", depkeeper_ctx.config_path)
100
+ if loaded_config.source_path:
101
+ logger.debug("Loaded configuration: %s", loaded_config.to_log_dict())
102
+ logger.debug("Verbosity: %s | Color: %s", verbose, color)
103
+
104
+
105
+ def _configure_logging(verbose: int) -> None:
106
+ """Configure logging level based on verbosity flags."""
107
+ if verbose <= 0:
108
+ level = logging.WARNING
109
+ elif verbose == 1:
110
+ level = logging.INFO
111
+ else:
112
+ level = logging.DEBUG
113
+
114
+ setup_logging(level=level)
115
+ logger.debug("Logging initialized at %s level", logging.getLevelName(level))
116
+
117
+
118
+ # Register CLI subcommands
119
+ try:
120
+ from depkeeper.commands.check import check
121
+ from depkeeper.commands.update import update
122
+
123
+ cli.add_command(check)
124
+ cli.add_command(update)
125
+
126
+ except ImportError as exc:
127
+ sys.stderr.write(f"FATAL: Failed to import CLI commands: {exc}\n")
128
+ sys.exit(1)
129
+
130
+
131
+ def main() -> int:
132
+ """Main entry point for the depkeeper CLI.
133
+
134
+ Returns:
135
+ Exit code:
136
+ 0 Success
137
+ 1 Unhandled or application error
138
+ 2 Usage error (Click)
139
+ 130 Interrupted by user (Ctrl+C)
140
+ """
141
+ try:
142
+ cli(standalone_mode=False)
143
+ return 0
144
+
145
+ except click.ClickException as exc:
146
+ exc.show()
147
+ return exc.exit_code
148
+
149
+ except DepKeeperError as exc:
150
+ print_error(str(exc))
151
+ logger.debug(
152
+ "DepKeeperError details: %s",
153
+ exc.details or "<none>",
154
+ exc_info=True,
155
+ )
156
+ return 1
157
+
158
+ except KeyboardInterrupt:
159
+ print_warning("\nOperation cancelled by user")
160
+ return 130
161
+
162
+ except Exception as exc:
163
+ print_error(f"Unexpected error: {exc}")
164
+ logger.exception("Unhandled exception in CLI")
165
+ return 1
166
+
167
+
168
+ if __name__ == "__main__":
169
+ sys.exit(main())
File without changes