Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
2 changes: 1 addition & 1 deletion .gitlab-ci.yml.example
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ workflow:
.nso-version-matrix:
parallel:
matrix:
- NSO_VERSION: ["6.5.7", "6.6.3"]
- NSO_VERSION: ["6.6.3", "6.7.3"]

.skip-on-release-updates:
rules:
Expand Down
58 changes: 40 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,6 @@ pythonic declarations.
```
[dependency-groups]
dev = [
"ncs_py3",
"pkg_mgmt",
"ruff>=0.14.13",
"pyang>=2.7.1",
Expand Down Expand Up @@ -246,38 +245,61 @@ pythonic declarations.

```
[dependency-groups]
pyndev-nso = [
"pyndev-nso-6.6.3" = [
"arista-dcs-cli-5.30==5.30.7+nso6.6.3",
]
```

The pyndev-nso dependency group is a special placeholder for pyndev NSO
packages that are external to the current workspace. This separate group is
needed for the pyndev specific synchronization process and this array is
manually populated.
The `pyndev-nso-${NSO_VERSION}` dependency group is a special placeholder for
pyndev NSO packages that are external to the current workspace. This
separate group is needed for the pyndev specific synchronization process and
this array is manually populated.

The pyndev-nso dependency group name is version specific to support multiple
NSO versions in single `uv.lock` file. When more than one version of NSO is
declared there must exist a uv "conflicts" configuration to keep only a
single group installed in the local environment at time.

pyproject.toml

```
[dependency-groups]
"pyndev-nso-6.6.3" = [
"arista-dcs-cli-5.30==5.30.7+nso6.6.3",
]
"pyndev-nso-6.7.3" = [
"arista-dcs-cli-5.30==5.30.7+nso6.7.3",
]

[tool.uv]
conflicts = [
[
{ group = "pyndev-nso-6.6.3" },
{ group = "pyndev-nso-6.7.3" },
],
]
```

- NSO_VERSION

pyndev supports managing multiple NSO versions in python through the use of
PEP 440 "local version identifiers". During build all NSO packages are
appended with the version that was used for the package build. Internally
this is all driven by the top level `.env` variable `NSO_VERSION`. If your
repository only supports one version of NSO this identifier can be ignored
and left off of dependency version matching. If you are concurrently
repository only supports one version of NSO this package identifier can be
ignored and left off of dependency version matching. If you are concurrently
developing towards multiple NSO releases the full identifier should be
specified in the version.
specified in the package version.

> As previously mentioned, the pkg\_mgmt tooling does some special handling
> for the NSO project. One of the tricks that impacts the top level
> pyproject.toml is that during a `just sync` the `NSO_VERSION` variable is
> read and any NSO versions are updated to be synchronized with the declared
> project version. Eg. the arista NED above has a local version tag specific
> to set NSO version and a sync function will update that package version
> automatically to ensure consistency.
> The `NSO_VERSION` variable is referenced in all docker commands to select
> a tag for the build and prod versions of the Cisco official containers.
> Additionally, the `just sync` is pinned to interact with dependency-group
> of the form `pyndev-nso-${NSO_VERSION}` so both of these configuration
> items are required.

> Anytime the NSO_VERSION is updated locally the project needs to be
> re-initialized with a `just init` and a `just sync` to setup to the proper
> context.
> re-initialized with a `just init` and a `just sync` to install to the
> proper context.

This feature can be utilized in CI platforms with tools such as Github's
strategy matrix and Gitlabs parallel matrix. This skeleton has a
Expand Down
2 changes: 1 addition & 1 deletion justfile
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ sync quiet='':
fi
just sync-pkg
uv sync --reinstall {{ if quiet != '' { '--quiet' } else { '' } }}
uv sync --group pyndev-nso {{ if quiet != '' { '--quiet' } else { '' } }}
uv sync --group "pyndev-nso-${NSO_VERSION}" {{ if quiet != '' { '--quiet' } else { '' } }}

# Build local packages, default is '--all-packages', optionally specify one or more package names to build serially
build *args:
Expand Down
2 changes: 1 addition & 1 deletion pkg_mgmt/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "pkg_mgmt"
version = "0.3.0"
version = "0.4.0"
description = "pyndev package management helpers"
authors = [
{ name = "Bill Stephens", email = "bill@es.net" }
Expand Down
3 changes: 0 additions & 3 deletions pkg_mgmt/src/pkg_mgmt/sync_pkg.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,16 @@
from functools import partial
from pathlib import Path

from .toml import sync_pyproject
from .utils import sync_managed_files


def process_package(pkg: Path, nso_version: str) -> None:
"""Sync individual package managed files"""
sync_pyproject(nso_version, pkg.name)
sync_managed_files(pkg.name)


def main() -> None:
nso_version = os.getenv("NSO_VERSION", "0.0.0")
sync_pyproject(nso_version)
packages = Path("packages")
if packages.is_dir():
with ProcessPoolExecutor() as executor:
Expand Down
31 changes: 12 additions & 19 deletions pkg_mgmt/src/pkg_mgmt/toml.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,23 +173,6 @@ def update_nso_version(nso_version: str, deps: list[str]) -> None:
deps[i] = re.sub(r"\+nso[^.]+\.[^.]+(\.[^.]+)?", f"+nso{nso_version}", dep)


def sync_pyproject(nso_version: str, pkg_name: str | None = None) -> None:
"""Synchronize pyproject.toml with .env state"""
config = load_pyproject(pkg_name)

if "build-system" in config and "requires" in config["build-system"]:
update_nso_version(nso_version, config["build-system"]["requires"])

if "project" in config and "dependencies" in config["project"]:
update_nso_version(nso_version, config["project"]["dependencies"])

if "dependency-groups" in config:
for group_deps in config["dependency-groups"].values():
update_nso_version(nso_version, group_deps)

write_pyproject(config, pkg_name)


def update_pyproject(pkg_name: str, version: str) -> None:
"""Update pyndev pyproject.toml with pkg_name"""
config = load_pyproject()
Expand Down Expand Up @@ -249,7 +232,12 @@ def get_nso_dependencies() -> str:
"""Pull out project NSO package dependencies"""
config = load_pyproject()
deps = [dep.split("==")[0] for dep in config.get("project", {}).get("dependencies", [])]
pyndev_nso = [dep.split("==")[0] for dep in config.get("dependency-groups", {}).get("pyndev-nso", [])]
pyndev_nso = [
dep.split("==")[0]
for group, deps in config.get("dependency-groups", {}).items()
Comment thread
slinkish marked this conversation as resolved.
Outdated
if "pyndev-nso" in group
for dep in deps
]

return deps + pyndev_nso

Expand All @@ -265,7 +253,12 @@ def get_pkg_version(pkg_name: str) -> str:
def get_pkg_dependencies(pkg_name: str) -> str:
Comment thread
slinkish marked this conversation as resolved.
Outdated
"""Pull out package project.dependencies"""
config = load_pyproject(pkg_name)
pyndev_nso = [dep.split("==")[0] for dep in config.get("dependency-groups", {}).get("pyndev-nso", [])]
pyndev_nso = [
dep.split("==")[0]
for group, deps in config.get("dependency-groups", {}).items()
Comment thread
slinkish marked this conversation as resolved.
Outdated
if "pyndev-nso" in group
for dep in deps
]
nso_deps = get_nso_dependencies()

return [dep for dep in pyndev_nso if dep in nso_deps]
Expand Down
8 changes: 6 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "pyndev"
dynamic = ["version"]
version = "0.4.0"
description = "Python wrapped NSO development environment"
readme = "README.md"
authors = [
Expand All @@ -18,7 +18,11 @@ dev = [
"mdformat>=1.0.0",
"mdformat-gfm>=1.0.0",
]
pyndev-nso = [
"pyndev-nso-6.6.3" = [
]

[tool.uv]
conflicts = [
]

[[tool.uv.index]]
Expand Down