-
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
19 changed files
with
414 additions
and
30 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
# Command Line Interface | ||
|
||
It's recommend to use [pipx] to install the CLI, but | ||
you can also install it with [pip]: | ||
|
||
```shell | ||
pipx install hatch-pip-compile | ||
``` | ||
|
||
::: mkdocs-click | ||
:module: hatch_pip_compile.cli | ||
:command: cli | ||
:prog_name: hatch-pip-compile | ||
:style: table | ||
:list_subcommands: True | ||
|
||
## How it works | ||
|
||
The `hatch-pip-compile` CLI is a wrapper around `hatch` that simply | ||
sets the `PIP_COMPILE_UPGRADE` / `PIP_COMPILE_UPGRADE_PACKAGE` environment | ||
variables before running a `hatch` command in a given environment. | ||
|
||
These environment variables are used by the `hatch-pip-compile` plugin | ||
to run the `pip-compile` command with the `--upgrade` / `--upgrade-package` | ||
flags. | ||
|
||
## Examples | ||
|
||
### Upgrade the `default` environment | ||
|
||
The below command will upgrade all packages in the `default` environment. | ||
|
||
```shell | ||
hatch-pip-compile --upgrade | ||
``` | ||
|
||
### Upgrade a non-default environment | ||
|
||
The below command will upgrade all packages in the `docs` environment. | ||
|
||
```shell | ||
hatch-pip-compile docs --upgrade | ||
``` | ||
|
||
### Upgrade a specific package | ||
|
||
The below command will upgrade the `requests` package in the `default` | ||
environment. | ||
|
||
```shell | ||
hatch-pip-compile --upgrade-package requests | ||
``` | ||
|
||
### Upgrade all `pip-compile` environments | ||
|
||
The below command will upgrade all packages in all `pip-compile` environments. | ||
|
||
```shell | ||
hatch-pip-compile --upgrade --all | ||
``` | ||
|
||
[pipx]: https://github.com/pypa/pipx | ||
[pip]: https://pip.pypa.io/en/stable/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
""" | ||
hatch_pip_compile module hook | ||
""" | ||
|
||
from hatch_pip_compile.cli import cli | ||
|
||
if __name__ == "__main__": | ||
cli() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,192 @@ | ||
""" | ||
hatch-pip-compile CLI | ||
""" | ||
|
||
from __future__ import annotations | ||
|
||
import dataclasses | ||
import json | ||
import os | ||
import subprocess | ||
from typing import Any, Self, Sequence | ||
|
||
import click | ||
import rich.traceback | ||
|
||
|
||
@dataclasses.dataclass | ||
class _HatchCommandRunner: | ||
""" | ||
Hatch Command Runner | ||
""" | ||
|
||
environments: Sequence[str] = dataclasses.field(default_factory=list) | ||
upgrade: bool = False | ||
upgrade_all: bool = False | ||
upgrade_packages: Sequence[str] = dataclasses.field(default_factory=list) | ||
|
||
former_env_vars: dict[str, Any] = dataclasses.field(init=False, default_factory=dict) | ||
console: rich.console.Console = dataclasses.field(init=False) | ||
supported_environments: set[str] = dataclasses.field(init=False) | ||
|
||
def __post_init__(self): | ||
""" | ||
Initialize the internal state | ||
""" | ||
self.console = rich.console.Console() | ||
rich.traceback.install(show_locals=True, console=self.console) | ||
self.supported_environments = self._get_supported_environments() | ||
if all( | ||
[not self.environments, "default" in self.supported_environments, not self.upgrade_all] | ||
): | ||
self.environments = ["default"] | ||
elif not self.environments and not self.upgrade_all: | ||
msg = "Either `--all` or an environment name must be specified" | ||
raise click.BadParameter(msg) | ||
elif self.upgrade_all: | ||
self.environments = list(self.supported_environments) | ||
elif isinstance(self.environments, str): | ||
self.environments = [self.environments] | ||
unsupported_environments = set(self.environments).difference(self.supported_environments) | ||
if unsupported_environments: | ||
msg = ( | ||
f"The following environments are not supported or unknown: " | ||
f"{', '.join(unsupported_environments)}. " | ||
f"Supported environments are: {', '.join(sorted(self.supported_environments))}" | ||
) | ||
raise click.BadParameter(msg) | ||
|
||
def __enter__(self) -> Self: | ||
""" | ||
Set the environment variables | ||
""" | ||
env_vars = {"__PIP_COMPILE_FORCE__": "1"} | ||
if self.upgrade: | ||
env_vars["PIP_COMPILE_UPGRADE"] = "1" | ||
self.console.print( | ||
"[bold green]hatch-pip-compile[/bold green]: Upgrading all dependencies" | ||
) | ||
elif self.upgrade_packages: | ||
env_vars["PIP_COMPILE_UPGRADE_PACKAGES"] = ",".join(self.upgrade_packages) | ||
message = ( | ||
"[bold green]hatch-pip-compile[/bold green]: " | ||
f"Upgrading packages: {', '.join(self.upgrade_packages)}" | ||
) | ||
self.console.print(message) | ||
self.former_env_vars = { | ||
key: os.environ.get(key) for key in env_vars.keys() if os.environ.get(key) is not None | ||
} | ||
os.environ.update(env_vars) | ||
return self | ||
|
||
def __exit__(self, *args, **kwargs): | ||
""" | ||
Restore the environment variables | ||
""" | ||
os.environ.update(self.former_env_vars) | ||
|
||
def hatch_cli(self): | ||
""" | ||
Run the `hatch` CLI | ||
""" | ||
self.console.print( | ||
"[bold green]hatch-pip-compile[/bold green]: Targeting environments: " | ||
f"{', '.join(sorted(self.environments))}" | ||
) | ||
for environment in sorted(self.environments): | ||
environment_command = [ | ||
"hatch", | ||
"env", | ||
"run", | ||
"--env", | ||
environment, | ||
"--", | ||
"python", | ||
"--version", | ||
] | ||
self.console.print( | ||
f"[bold green]hatch-pip-compile[/bold green]: Running " | ||
f"`[bold blue]{' '.join(environment_command)}`[/bold blue]" | ||
) | ||
result = subprocess.run( | ||
args=environment_command, | ||
capture_output=True, | ||
check=False, | ||
) | ||
if result.returncode != 0: | ||
self.console.print( | ||
"[bold yellow]hatch command[/bold yellow]: " | ||
f"[bold blue]`{' '.join(environment_command)}`[/bold blue]" | ||
) | ||
self.console.print(result.stdout.decode("utf-8")) | ||
self.console.print( | ||
"[bold red]hatch-pip-compile[/bold red]: Error running hatch command" | ||
) | ||
raise click.exceptions.Exit(1) | ||
|
||
@classmethod | ||
def _get_supported_environments(cls) -> set[str]: | ||
""" | ||
Get the names of the environments from `hatch env show --json` | ||
Returns | ||
------- | ||
List[str] | ||
The name of the environments | ||
""" | ||
result = subprocess.run( | ||
args=["hatch", "env", "show", "--json"], | ||
capture_output=True, | ||
check=True, | ||
) | ||
environment_dict: dict[str, Any] = json.loads(result.stdout) | ||
return { | ||
key for key, value in environment_dict.items() if value.get("type") == "pip-compile" | ||
} | ||
|
||
|
||
@click.command("hatch-pip-compile") | ||
@click.argument("environment", default=None, type=click.STRING, required=False, nargs=-1) | ||
@click.option( | ||
"-U", | ||
"--upgrade/--no-upgrade", | ||
is_flag=True, | ||
default=False, | ||
help="Try to upgrade all dependencies to their latest versions", | ||
) | ||
@click.option( | ||
"-P", | ||
"--upgrade-package", | ||
"upgrade_packages", | ||
nargs=1, | ||
multiple=True, | ||
help="Specify a particular package to upgrade; may be used more than once", | ||
) | ||
@click.option( | ||
"--all", | ||
"upgrade_all", | ||
is_flag=True, | ||
default=False, | ||
help="Upgrade all environments", | ||
) | ||
def cli( | ||
environment: Sequence[str], | ||
upgrade: bool, | ||
upgrade_packages: Sequence[str], | ||
upgrade_all: bool, | ||
): | ||
""" | ||
Upgrade your `hatch-pip-compile` managed dependencies | ||
from the command line. | ||
""" | ||
with _HatchCommandRunner( | ||
environments=environment, | ||
upgrade=upgrade, | ||
upgrade_packages=upgrade_packages, | ||
upgrade_all=upgrade_all, | ||
) as hatch_runner: | ||
hatch_runner.hatch_cli() | ||
|
||
|
||
if __name__ == "__main__": | ||
cli() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.