Skip to content
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
2 changes: 1 addition & 1 deletion .github/actions/features_parse/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ outputs:
runs:
using: composite
steps:
- uses: gardenlinux/python-gardenlinux-lib/.github/actions/setup@0.9.0
- uses: gardenlinux/python-gardenlinux-lib/.github/actions/setup@0.10.0
- id: result
shell: bash
run: |
Expand Down
2 changes: 1 addition & 1 deletion .github/actions/flavors_parse/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ outputs:
runs:
using: composite
steps:
- uses: gardenlinux/python-gardenlinux-lib/.github/actions/setup@0.9.0
- uses: gardenlinux/python-gardenlinux-lib/.github/actions/setup@0.10.0
- id: matrix
shell: bash
run: |
Expand Down
2 changes: 1 addition & 1 deletion .github/actions/setup/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ description: Installs the given GardenLinux Python library
inputs:
version:
description: GardenLinux Python library version
default: "0.9.0"
default: "0.10.0"
python_version:
description: Python version to setup
default: "3.13"
Expand Down
856 changes: 419 additions & 437 deletions poetry.lock

Large diffs are not rendered by default.

14 changes: 7 additions & 7 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "gardenlinux"
version = "0.9.0"
version = "0.10.0"
description = "Contains tools to work with the features directory of gardenlinux, for example deducting dependencies from feature sets or validating cnames"
authors = ["Garden Linux Maintainers <[email protected]>"]
license = "Apache-2.0"
Expand All @@ -10,23 +10,23 @@ packages = [{include = "gardenlinux", from="src"}]
[tool.poetry.dependencies]
python = "^3.13"
apt-repo = "^0.5"
boto3 = "^1.40.10"
boto3 = "^1.40.30"
click = "^8.2.1"
cryptography = "^45.0.6"
gitpython = "^3.1.45"
jsonschema = "^4.25.0"
jsonschema = "^4.25.1"
networkx = "^3.5"
oras = "^0.2.37"
oras = "^0.2.38"
pygit2 = "^1.18.2"
pygments = "^2.19.2"
PyYAML = "^6.0.2"

[tool.poetry.group.dev.dependencies]
bandit = "^1.8.6"
black = "^25.1.0"
moto = "^5.1.10"
moto = "^5.1.12"
python-dotenv = "^1.1.1"
pytest = "^8.4.1"
pytest-cov = "^6.2.1"
pytest-cov = "^6.3.0"

[tool.poetry.group.docs.dependencies]
sphinx-rtd-theme = "^3.0.2"
Expand Down
25 changes: 9 additions & 16 deletions src/gardenlinux/flavors/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,9 @@
import os
import sys

from git import Repo
from git.exc import GitError

from .parser import Parser
from ..constants import GL_REPOSITORY_URL
from ..git import Git
from ..git import Repository


def _get_flavors_file_data(flavors_file):
Expand Down Expand Up @@ -140,21 +137,17 @@ def main():
args = parse_args()

try:
flavors_data = _get_flavors_file_data(Path(Git().root, "flavors.yaml"))
except (GitError, RuntimeError):
flavors_data = _get_flavors_file_data(Path(Repository().root, "flavors.yaml"))
except RuntimeError:
with TemporaryDirectory() as git_directory:
repo = Repo.clone_from(
GL_REPOSITORY_URL, git_directory, no_origin=True, sparse=True
repo = Repository.checkout_repo_sparse(
git_directory,
["flavors.yaml"],
repo_url=GL_REPOSITORY_URL,
commit=args.commit,
)

ref = repo.heads.main

if args.commit is not None:
ref = ref.set_commit(args.commit)

flavors_data = _get_flavors_file_data(
Path(repo.working_dir, "flavors.yaml")
)
flavors_data = _get_flavors_file_data(Path(repo.root, "flavors.yaml"))

combinations = Parser(flavors_data).filter(
include_only_patterns=args.include_only,
Expand Down
4 changes: 2 additions & 2 deletions src/gardenlinux/git/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
Git module
"""

from .git import Git
from .repository import Repository

__all__ = ["Git"]
__all__ = ["Repository"]
84 changes: 0 additions & 84 deletions src/gardenlinux/git/git.py

This file was deleted.

173 changes: 173 additions & 0 deletions src/gardenlinux/git/repository.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
# -*- coding: utf-8 -*-

from os import PathLike
from pathlib import Path
import sys

from pygit2 import init_repository, Oid
from pygit2 import Repository as _Repository

from ..constants import GL_REPOSITORY_URL
from ..logger import LoggerSetup


class Repository(_Repository):
"""
Repository operations handler based on the given Git directory.
:author: Garden Linux Maintainers
:copyright: Copyright 2024 SAP SE
:package: gardenlinux
:subpackage: git
:since: 0.10.0
:license: https://www.apache.org/licenses/LICENSE-2.0
Apache License, Version 2.0
"""

def __init__(self, git_directory=".", logger=None, **kwargs):
"""
Constructor __init__(Repository)
:param git_directory: Git directory
:param logger: Logger instance
:since: 0.10.0
"""

if logger is None or not logger.hasHandlers():
logger = LoggerSetup.get_logger("gardenlinux.git")

if not isinstance(git_directory, PathLike):
git_directory = Path(git_directory)

if not git_directory.exists():
raise RuntimeError(f"Git directory given is invalid: {git_directory}")

_Repository.__init__(self, git_directory, **kwargs)

self._git_directory = git_directory
self._logger = logger

@property
def commit_id(self):
"""
Returns the commit ID for Git `HEAD`.
:return: (str) Git commit ID
:since: 0.10.0
"""

return str(self.root_repo.head.target)

@property
def root(self):
"""
Returns the root directory of the current Git repository.
:return: (object) Git root directory
:since: 0.10.0
"""

root_dir = self.workdir

if self.is_bare:
root_dir = self.path

usual_git_dir = Path(root_dir, ".git")

# Possible submodule Git repository. Validate repository containing `.git` directory.
if self.path != str(usual_git_dir):
try:
repo = Repository(usual_git_dir, self._logger)

if self.path != repo.path:
root_dir = repo.root
except Exception as exc:
self._logger.warning(f"Failed to inspect Git directory: {exc}")

self._logger.debug(f"Git root directory: {root_dir}")
return Path(root_dir)

@property
def root_repo(self):
"""
Returns the root Git `Repository` instance.
:return: (object) Git root `Repository` instance
:since: 0.10.0
"""

repo = self

if self._git_directory != self.root:
repo = Repository(self.root, self._logger)

return repo

@staticmethod
def checkout_repo(
git_directory,
repo_url=GL_REPOSITORY_URL,
branch="main",
commit=None,
pathspecs=None,
logger=None,
**kwargs,
):
"""
Returns the root Git `Repo` instance.
:return: (object) Git `Repo` instance
:since: 0.10.0
"""

if not isinstance(git_directory, PathLike):
git_directory = Path(git_directory)

if not git_directory.is_dir() or git_directory.match("/*"):
raise RuntimeError(
"Git directory should not exist or be empty before checkout"
)

repo = init_repository(git_directory, origin_url=repo_url)
repo.remotes["origin"].fetch()

if commit is None:
refish = f"origin/{branch}"
resolved = repo.resolve_refish(refish)
commit = str(resolved[0].id)

checkout_tree_kwargs = kwargs
if pathspecs is not None:
checkout_tree_kwargs["paths"] = pathspecs

repo.checkout_tree(repo[Oid(hex=commit)], **checkout_tree_kwargs)

return Repository(git_directory, logger)

@staticmethod
def checkout_repo_sparse(
git_directory,
pathspecs=[],
repo_url=GL_REPOSITORY_URL,
branch="main",
commit=None,
logger=None,
**kwargs,
):
"""
Sparse checkout given Git repository and return the `Repository` instance.
:return: (object) Git `Repository` instance
:since: 0.10.0
"""

# @TODO: pygit2 does not support sparse checkouts. We use the `paths` parameter at the moment.
return Repository.checkout_repo(
git_directory,
repo_url=repo_url,
branch=branch,
commit=commit,
pathspecs=pathspecs,
logger=logger,
)
4 changes: 2 additions & 2 deletions tests/constants.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-

from gardenlinux.git import Git
from gardenlinux.git import Repository

TEST_DATA_DIR = "test-data"
GL_ROOT_DIR = f"{TEST_DATA_DIR}/gardenlinux"
Expand All @@ -17,6 +17,6 @@
TEST_ARCHITECTURES = ["arm64", "amd64"]
TEST_FEATURE_STRINGS_SHORT = ["gardener_prod"]
TEST_FEATURE_SET = "_slim,base,container"
TEST_COMMIT = Git(GL_ROOT_DIR).commit_id[:8]
TEST_COMMIT = Repository(GL_ROOT_DIR).commit_id[:8]
TEST_VERSION = "1000.0"
TEST_VERSION_STABLE = "1000"
Loading