Skip to content

feat: [CG-10557] Codegen update command #353

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Feb 11, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions docs/cli/update.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
---
title: "Update Command"
sidebarTitle: "update"
icon: "sync"
iconType: "solid"
---

The `update` command is designed to help you manage the version of Codegen installed on your system. Whether you want to update to the latest version or switch to a specific version, this command offers a streamlined way to do so. Additionally, you can list all supported versions available on PyPI.

```bash
codegen update [OPTIONS]
```

## Usage

```bash
codegen update [OPTIONS]
```

## Options

- `--list, -l`: List all supported versions of Codegen.
When used, the command fetches the available releases from PyPI, filters them to display a range of versions (typically including the current version and a few preceding minor versions), and highlights the current version in the output.

- `--version, -v`: Update to a specific version of Codegen (e.g., `2.1.0`).
This option enables you to target a particular version rather than updating to the latest available release.

## Examples

Update Codegen to the latest version:
```bash
codegen update
```

List all supported versions of Codegen:
```bash
codegen update --list
```

Update Codegen to a specific version:
```bash
codegen update --version 2.1.0
```

## Execution Flow

When you run the `update` command, the following steps occur:

1. **Retrieve Current Version:**
The command retrieves the current version of Codegen by accessing package metadata.

2. **Option Handling:**
- **Listing Versions:**
If you use the `--list` flag, the command fetches all available releases from PyPI, filters them based on a defined range (typically covering future versions and a couple of previous minor versions), and prints the list with the current version highlighted.

- **Specific Version Update:**
If the `--version` option is provided, the command installs the specified version by invoking `pip install` with the exact version (e.g., `pip install codegen==2.1.0`).

- **Default Update:**
If no options are provided, the command updates Codegen to the latest version using `pip install --upgrade`.

3. **Error Handling:**
The command checks for mutually exclusive options. If both `--list` and `--version` are specified simultaneously, an error is raised.

<Note>
Ensure you use either `--list` or `--version` when running the update command, not both.
</Note>
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ dependencies = [
"tomlkit>=0.13.2",
"python-semantic-release",
"uvicorn[standard]>=0.30.0",
"packaging>=24.2",
"langchain[openai]",
"langchain_core",
"langchain_openai",
Expand Down
2 changes: 2 additions & 0 deletions src/codegen/cli/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from codegen.cli.commands.run.main import run_command
from codegen.cli.commands.run_on_pr.main import run_on_pr_command
from codegen.cli.commands.style_debug.main import style_debug_command
from codegen.cli.commands.update.main import update_command

click.rich_click.USE_RICH_MARKUP = True
install(show_locals=True)
Expand All @@ -40,6 +41,7 @@ def main():
main.add_command(run_on_pr_command)
main.add_command(notebook_command)
main.add_command(reset_command)
main.add_command(update_command)
main.add_command(config_command)


Expand Down
67 changes: 67 additions & 0 deletions src/codegen/cli/commands/update/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import subprocess
import sys
from importlib.metadata import distribution

import requests
import rich
import rich_click as click
from packaging.version import Version

import codegen


def fetch_pypi_releases(package: str) -> list[str]:
response = requests.get(f"https://pypi.org/pypi/{package}/json")
response.raise_for_status()
return response.json()["releases"].keys()


def filter_versions(versions: list[Version], current_version: Version, num_prev_minor_version: int = 1) -> list[Version]:
descending_minor_versions = [v_tuple for v_tuple in sorted(set(v.release[:2] for v in versions), reverse=True) if v_tuple < current_version.release[:2]]
try:
compare_tuple = descending_minor_versions[:num_prev_minor_version][-1] + (0,)
except IndexError:
compare_tuple = (current_version.major, current_version.minor, 0)

return [v for v in versions if (v.major, v.minor, v.micro) >= compare_tuple] # v.release will only show major,minor if micro doesn't exist.


def install_package(package: str, *args: str) -> None:
subprocess.check_call([sys.executable, "-m", "pip", "install", package, *args])


@click.command(name="update")
@click.option(
"--list",
"-l",
"list_",
is_flag=True,
help="List all supported versions of the codegen",
)
@click.option("--version", "-v", type=str, help="Update to a specific version of the codegen")
def update_command(list_: bool = False, version: str | None = None):
"""Update Codegen to the latest or specified version

--list: List all supported versions of the codegen
--version: Update to a specific version of the codegen
"""
if list_ and version:
msg = "Cannot specify both --list and --version"
raise click.ClickException(msg)

package_info = distribution(codegen.__package__)
current_version = Version(package_info.version)

if list_:
releases = fetch_pypi_releases(package_info.name)
filtered_releases = filter_versions([Version(r) for r in releases], current_version, num_prev_minor_version=2)
for release in filtered_releases:
if release.release == current_version.release:
rich.print(f"[bold]{release}[/bold] (current)")
else:
rich.print(release)
elif version:
install_package(f"{package_info.name}=={version}")
else:
# Update to latest version
install_package(package_info.name, "--upgrade")
Loading