depkeeper 0.1.0.dev0__py3-none-any.whl → 0.1.0.dev1__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 CHANGED
@@ -1,19 +1,27 @@
1
1
  """
2
- depkeeper — Modern Python Dependency Management Tool
2
+ depkeeper — modern Python dependency management for requirements.txt.
3
3
 
4
- depkeeper is an intelligent, safety-focused dependency manager that helps
5
- developers keep their Python environments up-to-date, secure, and
6
- reproducible.
4
+ depkeeper is an intelligent dependency management tool that helps developers
5
+ keep their ``requirements.txt`` files up to date, secure, and conflict-free.
7
6
 
8
- Features include:
9
- • Smart dependency updates with semantic versioning
10
- Security vulnerability scanning (OSV / PyPA)
11
- • Lock file generation for reproducible builds
12
- • Dependency health scoring
13
- • Multi-format support (requirements.txt, pyproject.toml, Pipfile, etc.)
14
- • CI/CD integration and automation
7
+ Quick start
8
+ -----------
9
+ Check for available updates::
15
10
 
16
- For documentation, examples, and API reference:
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:
17
25
  https://docs.depkeeper.dev
18
26
  """
19
27
 
@@ -21,23 +29,4 @@ from __future__ import annotations
21
29
 
22
30
  from depkeeper.__version__ import __version__
23
31
 
24
- # ---------------------------------------------------------------------------
25
- # Package Metadata
26
- # ---------------------------------------------------------------------------
27
-
28
- __author__ = "depkeeper Contributors"
29
- __license__ = "Apache-2.0"
30
- __url__ = "https://github.com/rahulkaushal04/depkeeper"
31
- __description__ = "Modern Python dependency management for requirements.txt and beyond."
32
-
33
- # ---------------------------------------------------------------------------
34
- # Public API (Phase 1+)
35
- #
36
- # Only expose stable, documented interfaces here.
37
- # Once core API classes are implemented, they should be exported via __all__.
38
- # ---------------------------------------------------------------------------
39
-
40
- __all__ = [
41
- "__version__",
42
- # "DepKeeperClient", # Example (future)
43
- ]
32
+ __all__ = ["__version__"]
depkeeper/__main__.py CHANGED
@@ -1,14 +1,8 @@
1
1
  """
2
- Executable module for depkeeper.
2
+ Module entry point for depkeeper.
3
3
 
4
- Running:
5
- python -m depkeeper
6
-
7
- is equivalent to:
8
- depkeeper
9
-
10
- This module simply forwards execution to the CLI entrypoint defined in
11
- `depkeeper.cli`.
4
+ This file enables execution via ``python -m depkeeper`` and delegates
5
+ control to the main CLI implementation.
12
6
  """
13
7
 
14
8
  from __future__ import annotations
@@ -17,34 +11,35 @@ import sys
17
11
 
18
12
 
19
13
  def main() -> int:
20
- """
21
- Main entrypoint when executing `python -m depkeeper`.
14
+ """Entry point for ``python -m depkeeper``.
22
15
 
23
16
  Returns:
24
- Exit code returned by the CLI.
17
+ Exit code:
18
+ 0 Success
19
+ 1 Import or runtime error
20
+ 130 Interrupted by user
25
21
  """
26
22
  try:
27
- # Import lazily so dependencies are only loaded during CLI use
28
23
  from depkeeper.cli import main as cli_main
29
24
  except ImportError as exc:
30
- # CLI not implemented yet (Phase 0) or import error during development
31
- sys.stderr.write("depkeeper CLI is not available yet.")
32
- sys.stderr.write("This is expected during early development (Phase 0).")
33
- sys.stderr.write()
34
- sys.stderr.write(f"Python version : {sys.version}")
35
- try:
36
- from depkeeper.__version__ import __version__
37
-
38
- sys.stderr.write(f"depkeeper version: {__version__}")
39
- except Exception:
40
- sys.stderr.write("depkeeper version: <unknown>")
41
- sys.stderr.write()
42
- sys.stderr.write(f"ImportError: {exc}")
43
- return 0
44
-
45
- # Execute the CLI handler
25
+ _print_startup_error(exc)
26
+ return 1
27
+
46
28
  return cli_main()
47
29
 
48
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
+
49
44
  if __name__ == "__main__":
50
45
  sys.exit(main())
depkeeper/__version__.py CHANGED
@@ -1,72 +1,12 @@
1
1
  """
2
- depkeeper version information.
2
+ Version information for depkeeper.
3
3
 
4
- This module provides a single source of truth for the package version.
5
- It follows Semantic Versioning: https://semver.org/
6
-
7
- Version format:
8
- MAJOR.MINOR.PATCH[-PRERELEASE][+BUILD]
9
-
10
- Examples:
11
- 0.1.0
12
- 0.1.0.dev0
13
- 1.0.0-rc1
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.
14
7
  """
15
8
 
16
9
  from __future__ import annotations
17
10
 
18
- import re
19
-
20
- # ---------------------------------------------------------------------------
21
- # Main version (single source of truth)
22
- # ---------------------------------------------------------------------------
23
-
24
- __version__ = "0.1.0.dev0"
25
-
26
-
27
- # ---------------------------------------------------------------------------
28
- # Structured version metadata
29
- # ---------------------------------------------------------------------------
30
-
31
-
32
- def _parse_version(version: str):
33
- """
34
- Internal helper to break a semantic version into components.
35
- Avoids manual duplication and mistakes.
36
-
37
- Returns:
38
- dict: {
39
- "major": int,
40
- "minor": int,
41
- "patch": int,
42
- "prerelease": str | None,
43
- "is_dev": bool,
44
- }
45
- """
46
-
47
- pattern = r"^(\d+)\.(\d+)\.(\d+)(?:[.-]([a-zA-Z0-9]+))?$"
48
- match = re.match(pattern, version)
49
-
50
- if not match:
51
- error_message = f"Invalid version string: {version}"
52
- raise ValueError(error_message)
53
-
54
- major, minor, patch, pre = match.groups()
55
-
56
- return {
57
- "major": int(major),
58
- "minor": int(minor),
59
- "patch": int(patch),
60
- "prerelease": pre,
61
- "is_dev": pre is not None and pre.startswith("dev"),
62
- }
63
-
64
-
65
- VERSION_INFO = _parse_version(__version__)
66
-
67
-
68
- # ---------------------------------------------------------------------------
69
- # Human-readable version (for CLI)
70
- # ---------------------------------------------------------------------------
71
-
72
- VERSION_STRING = f"depkeeper {__version__}"
11
+ #: Current depkeeper version (PEP 440 compliant).
12
+ __version__: str = "0.1.0.dev1"
depkeeper/cli.py ADDED
@@ -0,0 +1,157 @@
1
+ """
2
+ Command-line interface for depkeeper.
3
+
4
+ This module defines the main Click entry point, global options, command
5
+ registration, and top-level error handling for the depkeeper CLI.
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.__version__ import __version__
19
+ from depkeeper.context import DepKeeperContext
20
+ from depkeeper.exceptions import DepKeeperError
21
+ from depkeeper.utils.console import print_error, print_warning
22
+ from depkeeper.utils.logger import get_logger, setup_logging
23
+
24
+ logger = get_logger("cli")
25
+
26
+
27
+ @click.group(context_settings={"help_option_names": ["-h", "--help"]})
28
+ @click.option(
29
+ "--config",
30
+ "-c",
31
+ type=click.Path(exists=True, dir_okay=False, path_type=Path),
32
+ help="Path to configuration file.",
33
+ envvar="DEPKEEPER_CONFIG",
34
+ )
35
+ @click.option(
36
+ "--verbose",
37
+ "-v",
38
+ count=True,
39
+ help="Increase verbosity (can be repeated: -v, -vv).",
40
+ )
41
+ @click.option(
42
+ "--color/--no-color",
43
+ default=True,
44
+ help="Enable or disable colored output.",
45
+ envvar="DEPKEEPER_COLOR",
46
+ )
47
+ @click.version_option(
48
+ version=__version__,
49
+ prog_name="depkeeper",
50
+ message="%(prog)s %(version)s",
51
+ )
52
+ @click.pass_context
53
+ def cli(
54
+ ctx: click.Context,
55
+ config: Optional[Path],
56
+ verbose: int,
57
+ color: bool,
58
+ ) -> None:
59
+ """depkeeper — modern dependency management for requirements.txt files.
60
+
61
+ \b
62
+ Available commands:
63
+ depkeeper check Check for available updates
64
+ depkeeper update Update packages to newer versions
65
+
66
+ \b
67
+ Examples:
68
+ depkeeper check
69
+ depkeeper update
70
+ depkeeper -v check
71
+
72
+ Use ``depkeeper COMMAND --help`` for command-specific options.
73
+ """
74
+ _configure_logging(verbose)
75
+
76
+ depkeeper_ctx = DepKeeperContext()
77
+ depkeeper_ctx.config_path = config
78
+ depkeeper_ctx.verbose = verbose
79
+ depkeeper_ctx.color = color
80
+ ctx.obj = depkeeper_ctx
81
+
82
+ # Respect NO_COLOR for downstream libraries
83
+ if color:
84
+ os.environ.pop("NO_COLOR", None)
85
+ else:
86
+ os.environ["NO_COLOR"] = "1"
87
+
88
+ logger.debug("depkeeper v%s", __version__)
89
+ logger.debug("Config path: %s", config)
90
+ logger.debug("Verbosity: %s | Color: %s", verbose, color)
91
+
92
+
93
+ def _configure_logging(verbose: int) -> None:
94
+ """Configure logging level based on verbosity flags."""
95
+ if verbose <= 0:
96
+ level = logging.WARNING
97
+ elif verbose == 1:
98
+ level = logging.INFO
99
+ else:
100
+ level = logging.DEBUG
101
+
102
+ setup_logging(level=level)
103
+ logger.debug("Logging initialized at %s level", logging.getLevelName(level))
104
+
105
+
106
+ # Register CLI subcommands
107
+ try:
108
+ from depkeeper.commands.check import check
109
+ from depkeeper.commands.update import update
110
+
111
+ cli.add_command(check)
112
+ cli.add_command(update)
113
+
114
+ except ImportError as exc:
115
+ sys.stderr.write(f"FATAL: Failed to import CLI commands: {exc}\n")
116
+ sys.exit(1)
117
+
118
+
119
+ def main() -> int:
120
+ """Main entry point for the depkeeper CLI.
121
+
122
+ Returns:
123
+ Exit code:
124
+ 0 Success
125
+ 1 Unhandled or application error
126
+ 2 Usage error (Click)
127
+ 130 Interrupted by user (Ctrl+C)
128
+ """
129
+ try:
130
+ cli(standalone_mode=False)
131
+ return 0
132
+
133
+ except click.ClickException as exc:
134
+ exc.show()
135
+ return exc.exit_code
136
+
137
+ except DepKeeperError as exc:
138
+ print_error(str(exc))
139
+ logger.debug(
140
+ "DepKeeperError details: %s",
141
+ exc.details or "<none>",
142
+ exc_info=True,
143
+ )
144
+ return 1
145
+
146
+ except KeyboardInterrupt:
147
+ print_warning("\nOperation cancelled by user")
148
+ return 130
149
+
150
+ except Exception as exc:
151
+ print_error(f"Unexpected error: {exc}")
152
+ logger.exception("Unhandled exception in CLI")
153
+ return 1
154
+
155
+
156
+ if __name__ == "__main__":
157
+ sys.exit(main())
depkeeper/constants.py ADDED
@@ -0,0 +1,94 @@
1
+ """
2
+ Centralized constants for depkeeper.
3
+
4
+ This module defines immutable configuration values used across depkeeper,
5
+ including network settings, file patterns, CLI directives, and logging
6
+ formats. All values are intended to be treated as read-only.
7
+ """
8
+
9
+ from typing import Final, Mapping, Sequence
10
+
11
+ # ---------------------------------------------------------------------------
12
+ # Project metadata
13
+ # ---------------------------------------------------------------------------
14
+
15
+ #: HTTP User-Agent template used for outbound requests.
16
+ USER_AGENT_TEMPLATE: Final[str] = (
17
+ "depkeeper/{version} (https://github.com/rahulkaushal04/depkeeper)"
18
+ )
19
+
20
+ # ---------------------------------------------------------------------------
21
+ # PyPI endpoints
22
+ # ---------------------------------------------------------------------------
23
+
24
+ #: Base URL for the PyPI JSON API.
25
+ PYPI_JSON_API: Final[str] = "https://pypi.org/pypi/{package}/json"
26
+
27
+ # ---------------------------------------------------------------------------
28
+ # HTTP configuration
29
+ # ---------------------------------------------------------------------------
30
+
31
+ #: Default network timeout in seconds.
32
+ DEFAULT_TIMEOUT: Final[int] = 30
33
+
34
+ #: Maximum number of retries for failed HTTP requests.
35
+ DEFAULT_MAX_RETRIES: Final[int] = 3
36
+
37
+ # ---------------------------------------------------------------------------
38
+ # Requirement file patterns and directives
39
+ # ---------------------------------------------------------------------------
40
+
41
+ #: Glob patterns used to detect supported requirement-related files.
42
+ REQUIREMENT_FILE_PATTERNS: Final[Mapping[str, Sequence[str]]] = {
43
+ "requirements": (
44
+ "requirements.txt",
45
+ "requirements-*.txt",
46
+ "requirements/*.txt",
47
+ ),
48
+ "constraints": (
49
+ "constraints.txt",
50
+ "constraints-*.txt",
51
+ ),
52
+ "backup": ("*.backup",),
53
+ }
54
+
55
+ #: Short include directive for requirement files.
56
+ INCLUDE_DIRECTIVE: Final[str] = "-r"
57
+
58
+ #: Long include directive for requirement files.
59
+ INCLUDE_DIRECTIVE_LONG: Final[str] = "--requirement"
60
+
61
+ #: Short constraint directive.
62
+ CONSTRAINT_DIRECTIVE: Final[str] = "-c"
63
+
64
+ #: Long constraint directive.
65
+ CONSTRAINT_DIRECTIVE_LONG: Final[str] = "--constraint"
66
+
67
+ #: Short editable-install directive.
68
+ EDITABLE_DIRECTIVE: Final[str] = "-e"
69
+
70
+ #: Long editable-install directive.
71
+ EDITABLE_DIRECTIVE_LONG: Final[str] = "--editable"
72
+
73
+ #: Hash-checking directive.
74
+ HASH_DIRECTIVE: Final[str] = "--hash"
75
+
76
+ # ---------------------------------------------------------------------------
77
+ # Security constraints
78
+ # ---------------------------------------------------------------------------
79
+
80
+ #: Maximum allowed file size (in bytes) when reading requirement files.
81
+ MAX_FILE_SIZE: Final[int] = 10 * 1024 * 1024 # 10 MB
82
+
83
+ # ---------------------------------------------------------------------------
84
+ # Logging configuration
85
+ # ---------------------------------------------------------------------------
86
+
87
+ #: Timestamp format for verbose logging.
88
+ LOG_DATE_FORMAT: Final[str] = "%Y-%m-%d %H:%M:%S"
89
+
90
+ #: Default log format (non-verbose).
91
+ LOG_DEFAULT_FORMAT: Final[str] = "%(levelname)s: %(message)s"
92
+
93
+ #: Verbose log format including timestamp and logger name.
94
+ LOG_VERBOSE_FORMAT: Final[str] = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
depkeeper/context.py ADDED
@@ -0,0 +1,37 @@
1
+ """
2
+ Shared context object for depkeeper CLI commands.
3
+
4
+ This module defines the global Click context used to share configuration
5
+ and runtime options across CLI subcommands.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ from pathlib import Path
11
+ from typing import Optional
12
+
13
+ import click
14
+
15
+
16
+ class DepKeeperContext:
17
+ """Global context object for depkeeper CLI commands.
18
+
19
+ An instance of this class is created once per CLI invocation and
20
+ passed to commands using Click's context mechanism.
21
+
22
+ Attributes:
23
+ config_path: Path to the depkeeper configuration file, if provided.
24
+ verbose: Verbosity level (0=WARNING, 1=INFO, 2+=DEBUG).
25
+ color: Whether colored terminal output is enabled.
26
+ """
27
+
28
+ __slots__ = ("config_path", "verbose", "color")
29
+
30
+ def __init__(self) -> None:
31
+ self.config_path: Optional[Path] = None
32
+ self.verbose: int = 0
33
+ self.color: bool = True
34
+
35
+
36
+ #: Click decorator for injecting :class:`DepKeeperContext` into commands.
37
+ pass_context = click.make_pass_decorator(DepKeeperContext, ensure=True)
@@ -0,0 +1,189 @@
1
+ """
2
+ Custom exception hierarchy for depkeeper.
3
+
4
+ This module defines structured exception types used across depkeeper.
5
+ All exceptions inherit from :class:`DepKeeperError` and support optional
6
+ structured metadata via the ``details`` attribute to improve diagnostics
7
+ and logging.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ from typing import Any, Mapping, MutableMapping, Optional
13
+
14
+
15
+ class DepKeeperError(Exception):
16
+ """Base exception for all depkeeper errors.
17
+
18
+ All depkeeper-specific exceptions should inherit from this class.
19
+ It supports structured metadata via ``details`` for richer error
20
+ reporting and debugging.
21
+
22
+ Args:
23
+ message: Human-readable error message.
24
+ details: Optional structured metadata describing the error.
25
+ """
26
+
27
+ __slots__ = ("message", "details")
28
+
29
+ def __init__(
30
+ self,
31
+ message: str,
32
+ details: Optional[Mapping[str, Any]] = None,
33
+ ) -> None:
34
+ self.message: str = message
35
+ # Internally normalize to a mutable dict
36
+ self.details: MutableMapping[str, Any] = dict(details) if details else {}
37
+ super().__init__(message)
38
+
39
+ def __str__(self) -> str:
40
+ if not self.details:
41
+ return self.message
42
+ formatted = ", ".join(f"{k}={v}" for k, v in self.details.items())
43
+ return f"{self.message} ({formatted})"
44
+
45
+ def __repr__(self) -> str:
46
+ return (
47
+ f"{self.__class__.__name__}("
48
+ f"message={self.message!r}, details={dict(self.details)!r})"
49
+ )
50
+
51
+
52
+ def _add_if(details: MutableMapping[str, Any], key: str, value: Any) -> None:
53
+ """Add a key to ``details`` only if ``value`` is not ``None``."""
54
+ if value is not None:
55
+ details[key] = value
56
+
57
+
58
+ def _truncate(text: str, max_length: int = 200) -> str:
59
+ """Truncate long text for safe logging or error reporting."""
60
+ if len(text) <= max_length:
61
+ return text
62
+ return text[:max_length] + "..."
63
+
64
+
65
+ class ParseError(DepKeeperError):
66
+ """Raised when a requirements file cannot be parsed.
67
+
68
+ Args:
69
+ message: Error description.
70
+ line_number: Line number where parsing failed.
71
+ line_content: Raw content of the problematic line.
72
+ file_path: Path to the file being parsed.
73
+ """
74
+
75
+ __slots__ = ("line_number", "line_content", "file_path")
76
+
77
+ def __init__(
78
+ self,
79
+ message: str,
80
+ *,
81
+ line_number: Optional[int] = None,
82
+ line_content: Optional[str] = None,
83
+ file_path: Optional[str] = None,
84
+ ) -> None:
85
+ details: MutableMapping[str, Any] = {}
86
+ _add_if(details, "line", line_number)
87
+ _add_if(details, "content", line_content)
88
+ _add_if(details, "file", file_path)
89
+
90
+ super().__init__(message, details)
91
+
92
+ self.line_number = line_number
93
+ self.line_content = line_content
94
+ self.file_path = file_path
95
+
96
+
97
+ class NetworkError(DepKeeperError):
98
+ """Raised when HTTP or network operations fail.
99
+
100
+ Args:
101
+ message: Error description.
102
+ url: URL being accessed.
103
+ status_code: HTTP status code, if available.
104
+ response_body: Raw response body, truncated for safety.
105
+ """
106
+
107
+ __slots__ = ("url", "status_code", "response_body")
108
+
109
+ def __init__(
110
+ self,
111
+ message: str,
112
+ *,
113
+ url: Optional[str] = None,
114
+ status_code: Optional[int] = None,
115
+ response_body: Optional[str] = None,
116
+ ) -> None:
117
+ details: MutableMapping[str, Any] = {}
118
+ _add_if(details, "url", url)
119
+ _add_if(details, "status_code", status_code)
120
+
121
+ if response_body is not None:
122
+ details["response"] = _truncate(response_body)
123
+
124
+ super().__init__(message, details)
125
+
126
+ self.url = url
127
+ self.status_code = status_code
128
+ self.response_body = response_body
129
+
130
+
131
+ class PyPIError(NetworkError):
132
+ """Raised for failures related to the PyPI API.
133
+
134
+ Args:
135
+ message: Error description.
136
+ package_name: Name of the package involved.
137
+ **kwargs: Additional arguments forwarded to ``NetworkError``.
138
+ """
139
+
140
+ __slots__ = ("package_name",)
141
+
142
+ def __init__(
143
+ self,
144
+ message: str,
145
+ *,
146
+ package_name: Optional[str] = None,
147
+ **kwargs: Any,
148
+ ) -> None:
149
+ super().__init__(message, **kwargs)
150
+
151
+ self.package_name = package_name
152
+ if package_name is not None:
153
+ self.details["package"] = package_name
154
+
155
+
156
+ class FileOperationError(DepKeeperError):
157
+ """Raised when file system operations fail.
158
+
159
+ Args:
160
+ message: Error description.
161
+ file_path: Path to the file involved.
162
+ operation: Operation being performed (read/write/delete).
163
+ original_error: Original exception that triggered this error.
164
+ """
165
+
166
+ __slots__ = ("file_path", "operation", "original_error")
167
+
168
+ def __init__(
169
+ self,
170
+ message: str,
171
+ *,
172
+ file_path: Optional[str] = None,
173
+ operation: Optional[str] = None,
174
+ original_error: Optional[Exception] = None,
175
+ ) -> None:
176
+ details: MutableMapping[str, Any] = {}
177
+ _add_if(details, "path", file_path)
178
+ _add_if(details, "operation", operation)
179
+ _add_if(
180
+ details,
181
+ "original_error",
182
+ str(original_error) if original_error else None,
183
+ )
184
+
185
+ super().__init__(message, details)
186
+
187
+ self.file_path = file_path
188
+ self.operation = operation
189
+ self.original_error = original_error
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: depkeeper
3
- Version: 0.1.0.dev0
3
+ Version: 0.1.0.dev1
4
4
  Summary: Modern Python dependency management for requirements.txt files
5
5
  Author: depkeeper Contributors
6
6
  License: Apache-2.0
@@ -25,25 +25,23 @@ Classifier: Topic :: System :: Software Distribution
25
25
  Requires-Python: >=3.8
26
26
  Description-Content-Type: text/markdown
27
27
  License-File: LICENSE
28
- Requires-Dist: click>=8.1.0
29
- Requires-Dist: packaging>=23.0
28
+ Requires-Dist: click>=8.1.8
29
+ Requires-Dist: packaging>=23.2
30
30
  Requires-Dist: httpx>=0.24.0
31
- Requires-Dist: rich>=13.0.0
32
- Requires-Dist: pydantic>=2.0.0
31
+ Requires-Dist: rich>=13.9.4
33
32
  Provides-Extra: dev
34
33
  Requires-Dist: pytest>=7.4.0; extra == "dev"
35
34
  Requires-Dist: pytest-cov>=4.1.0; extra == "dev"
36
35
  Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
37
36
  Requires-Dist: pytest-mock>=3.11.0; extra == "dev"
38
37
  Requires-Dist: pytest-httpx>=0.22.0; extra == "dev"
39
- Requires-Dist: ruff>=0.1.0; extra == "dev"
40
38
  Requires-Dist: mypy>=1.5.0; extra == "dev"
41
39
  Requires-Dist: types-setuptools; extra == "dev"
42
40
  Requires-Dist: pre-commit>=3.4.0; extra == "dev"
43
41
  Provides-Extra: docs
44
- Requires-Dist: mkdocs>=1.5.0; extra == "docs"
45
- Requires-Dist: mkdocs-material>=9.4.0; extra == "docs"
46
- Requires-Dist: mkdocstrings[python]>=0.23.0; extra == "docs"
42
+ Requires-Dist: mkdocs>=1.6.1; extra == "docs"
43
+ Requires-Dist: mkdocs-material>=9.7.1; extra == "docs"
44
+ Requires-Dist: mkdocstrings[python]>=0.26.1; extra == "docs"
47
45
  Provides-Extra: test
48
46
  Requires-Dist: pytest>=7.4.0; extra == "test"
49
47
  Requires-Dist: pytest-cov>=4.1.0; extra == "test"
@@ -167,7 +165,6 @@ This project is licensed under the **Apache-2.0 License** — see the [LICENSE](
167
165
 
168
166
  ## ❤️ Support
169
167
 
170
- - 📬 Email: [support@depkeeper.dev](mailto:support@depkeeper.dev)
171
168
  - 💬 GitHub Discussions: [https://github.com/rahulkaushal04/depkeeper/discussions](https://github.com/rahulkaushal04/depkeeper/discussions)
172
169
  - 🐞 Issues: [https://github.com/rahulkaushal04/depkeeper/issues](https://github.com/rahulkaushal04/depkeeper/issues)
173
170
 
@@ -0,0 +1,13 @@
1
+ depkeeper/__init__.py,sha256=UIoEBq1BYqo2JHMk3c0z2DZlQi__VktO9CzuRep6sQ4,784
2
+ depkeeper/__main__.py,sha256=h09RSyNLf7dD-EnkGsG516MzrxZgi0PVX_8FVgcA8fo,1034
3
+ depkeeper/__version__.py,sha256=sw3KDzEzAip0NjFJQLhvzc4DAFqJTGskHEN9B4a-4Wc,364
4
+ depkeeper/cli.py,sha256=JrUyEkXyl2O7vyxdWuolmS0-MCOxtUxYwCDfyZCNSd0,3893
5
+ depkeeper/constants.py,sha256=LjTxrGBTn1bDWAp1fvkwVNGWCkGw4Vt4Y0kUvsAcMYU,3236
6
+ depkeeper/context.py,sha256=nuXkLr7QFmRw-J5eqC4k6HZxb2GnRF8YkPtWeXFOhdE,1057
7
+ depkeeper/exceptions.py,sha256=oHNfN1rgqAS1-voEVMOoFT50amNnVFHRlUQ_a5aRhkk,5466
8
+ depkeeper-0.1.0.dev1.dist-info/LICENSE,sha256=HL8wcF7XoKpnBonRaNS5fZTZeu_u1dQyZaQ_7epQgYY,11347
9
+ depkeeper-0.1.0.dev1.dist-info/METADATA,sha256=h1taZOGMjvIylX56IGdCoOURYu7ztT8BnBZvL0xZ2Io,6142
10
+ depkeeper-0.1.0.dev1.dist-info/WHEEL,sha256=WnJ8fYhv8N4SYVK2lLYNI6N0kVATA7b0piVUNvqIIJE,91
11
+ depkeeper-0.1.0.dev1.dist-info/entry_points.txt,sha256=Uk9IOuB-ERZvqXqCPKZzi1Zl3bGu5zmgv_Yboja_9qo,49
12
+ depkeeper-0.1.0.dev1.dist-info/top_level.txt,sha256=QWTyulVejqUZRiioAiSn-vM5uqRlE3wtghBGh6VSGAE,10
13
+ depkeeper-0.1.0.dev1.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.3.2)
2
+ Generator: setuptools (75.3.3)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,9 +0,0 @@
1
- depkeeper/__init__.py,sha256=RhuvUMBLyn1V-QaN-AipFGcmHMZx-wKpeVwY49oEA28,1496
2
- depkeeper/__main__.py,sha256=WfuwNInn0cc68UEVI7MYioet-GJWSiO33OkLMdR7r2Y,1286
3
- depkeeper/__version__.py,sha256=RWbadCYYvs9zdpNLFPSOsb17-8GURNZPq1eMFPhoqi4,1825
4
- depkeeper-0.1.0.dev0.dist-info/LICENSE,sha256=HL8wcF7XoKpnBonRaNS5fZTZeu_u1dQyZaQ_7epQgYY,11347
5
- depkeeper-0.1.0.dev0.dist-info/METADATA,sha256=GEMlNgQtCOJG4pQfGIQLI0LiXifUGIzQ8cDrLlu0kZY,6284
6
- depkeeper-0.1.0.dev0.dist-info/WHEEL,sha256=iAkIy5fosb7FzIOwONchHf19Qu7_1wCWyFNR5gu9nU0,91
7
- depkeeper-0.1.0.dev0.dist-info/entry_points.txt,sha256=Uk9IOuB-ERZvqXqCPKZzi1Zl3bGu5zmgv_Yboja_9qo,49
8
- depkeeper-0.1.0.dev0.dist-info/top_level.txt,sha256=QWTyulVejqUZRiioAiSn-vM5uqRlE3wtghBGh6VSGAE,10
9
- depkeeper-0.1.0.dev0.dist-info/RECORD,,