Skip to content
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

add API to check whether it's a GTO repo #187

Merged
merged 2 commits into from
Jun 29, 2022
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
12 changes: 10 additions & 2 deletions gto/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from git import Repo

from gto.constants import NAME, STAGE, VERSION
from gto.exceptions import WrongArgs
from gto.exceptions import NoRepo, WrongArgs
from gto.ext import EnrichmentInfo
from gto.index import (
EnrichmentManager,
Expand All @@ -19,7 +19,15 @@
from gto.tag import parse_name_reference


def get_index(repo: Union[str, Repo], file=False):
def _is_gto_repo(repo: Union[str, Repo]):
"""Check if repo is a gto repo"""
try:
return GitRegistry.from_repo(repo).is_gto_repo()
except NoRepo:
return False


def _get_index(repo: Union[str, Repo], file=False):
"""Get index state"""
if file:
return FileIndexManager.from_path(
Expand Down
4 changes: 3 additions & 1 deletion gto/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -782,7 +782,9 @@ def print_index(repo: str = option_repo):
Examples:
$ gto print-index
"""
index = gto.api.get_index(repo).artifact_centric_representation()
index = gto.api._get_index( # pylint: disable=protected-access
repo
).artifact_centric_representation()
format_echo(index, "json")


Expand Down
9 changes: 9 additions & 0 deletions gto/config.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# pylint: disable=no-self-use, no-self-argument, inconsistent-return-statements, invalid-name, import-outside-toplevel
import pathlib
import re
from pathlib import Path
from typing import Any, Dict, List, Optional
Expand Down Expand Up @@ -86,6 +87,10 @@ def stages_are_valid(cls, v):
assert_name_is_valid(name)
return v

def check_index_exist(self, repo: str):
index = pathlib.Path(repo) / pathlib.Path(self.INDEX)
return index.exists() and index.is_file()


def _set_location_init_source(init_source: InitSettingsSource):
def inner(settings: "RegistryConfig"):
Expand Down Expand Up @@ -134,6 +139,10 @@ def customise_sources(
file_secret_settings,
)

def config_file_exists(self):
config = pathlib.Path(self.CONFIG_FILE_NAME)
return config.exists() and config.is_file()


def read_registry_config(config_file_name):
try:
Expand Down
9 changes: 9 additions & 0 deletions gto/registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,15 @@ def from_repo(cls, repo=Union[str, Repo], config: RegistryConfig = None):
enrichment_manager=EnrichmentManager(repo=repo, config=config),
)

def is_gto_repo(self):
if self.config.config_file_exists():
return True
if self.config.check_index_exist(self.repo.working_dir):
return True
if self.get_state() != BaseRegistryState():
return True
return False

def get_state(
self,
all_branches=False,
Expand Down
43 changes: 33 additions & 10 deletions tests/test_api.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# pylint: disable=unused-variable, protected-access
"""TODO: add more tests for API"""
import os
from contextlib import contextmanager
Expand All @@ -13,32 +14,32 @@


def test_empty_index(empty_git_repo: Tuple[git.Repo, Callable]):
repo, write_file = empty_git_repo # pylint: disable=unused-variable
index = gto.api.get_index(repo.working_dir)
repo, write_file = empty_git_repo
index = gto.api._get_index(repo.working_dir)
assert len(index.artifact_centric_representation()) == 0


def test_empty_state(empty_git_repo: Tuple[git.Repo, Callable]):
repo, write_file = empty_git_repo # pylint: disable=unused-variable
state = gto.api._get_state(repo.working_dir) # pylint: disable=protected-access
repo, write_file = empty_git_repo
state = gto.api._get_state(repo.working_dir)
assert len(state.artifacts) == 0


def test_api_info_commands_empty_repo(empty_git_repo: Tuple[git.Repo, Callable]):
repo, write_file = empty_git_repo # pylint: disable=unused-variable
repo, write_file = empty_git_repo
gto.api.show(repo.working_dir)
gto.api.history(repo.working_dir)


def test_add_remove(empty_git_repo: Tuple[git.Repo, Callable]):
repo, write_file = empty_git_repo # pylint: disable=unused-variable
repo, write_file = empty_git_repo
name, type, path, must_exist = "new-artifact", "new-type", "new/path", False
gto.api.annotate(
repo.working_dir, name, type=type, path=path, must_exist=must_exist
)
with pytest.raises(PathIsUsed):
gto.api.annotate(repo.working_dir, "other-name", path=path)
index = gto.api.get_index(repo.working_dir).get_index()
index = gto.api._get_index(repo.working_dir).get_index()
assert name in index
_check_obj(
index.state[name],
Expand All @@ -52,14 +53,14 @@ def test_add_remove(empty_git_repo: Tuple[git.Repo, Callable]):
[],
)
gto.api.remove(repo.working_dir, name)
index = gto.api.get_index(repo.working_dir).get_index()
index = gto.api._get_index(repo.working_dir).get_index()
assert name not in index


@pytest.fixture
def repo_with_artifact(init_showcase_semver):
repo: git.Repo
repo, write_file = init_showcase_semver # pylint: disable=unused-variable
repo, write_file = init_showcase_semver
name, type, path, must_exist = "new-artifact", "new-type", "new/path", False
gto.api.annotate(
repo.working_dir, name, type=type, path=path, must_exist=must_exist
Expand Down Expand Up @@ -168,7 +169,7 @@ def environ(**overrides):


def test_check_ref(repo_with_artifact: Tuple[git.Repo, Callable]):
repo, name = repo_with_artifact # pylint: disable=unused-variable
repo, name = repo_with_artifact

NAME = "model"
VERSION = "v1.2.3"
Expand Down Expand Up @@ -200,3 +201,25 @@ def test_check_ref(repo_with_artifact: Tuple[git.Repo, Callable]):
},
skip_keys={"commit_hexsha", "created_at", "message"},
)


def test_is_not_gto_repo(empty_git_repo):
repo, _ = empty_git_repo
assert not gto.api._is_gto_repo(repo.working_dir)


def test_is_gto_repo_because_of_config(init_showcase_semver):
repo, _ = init_showcase_semver
assert gto.api._is_gto_repo(repo.working_dir)


def test_is_gto_repo_because_of_registered_artifact(repo_with_commit):
repo, _ = repo_with_commit
gto.api.register(repo, "model", "HEAD", "v1.0.0")
assert gto.api._is_gto_repo(repo)


def test_is_gto_repo_because_of_artifacts_yaml(empty_git_repo):
repo, write_file = empty_git_repo
write_file("artifacts.yaml", "{}")
assert gto.api._is_gto_repo(repo)
6 changes: 4 additions & 2 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from typer.main import get_command_from_info
from typer.testing import CliRunner

from gto.api import get_index
from gto.api import _get_index
from gto.cli import app

from .utils import _check_obj
Expand Down Expand Up @@ -181,7 +181,9 @@ def test_annotate(empty_git_repo: Tuple[git.Repo, Callable]):
],
"",
)
artifact = get_index(repo.working_dir, file=True).get_index().state[name]
artifact = (
_get_index(repo.working_dir, file=True).get_index().state[name]
) # pylint: disable=protected-access
_check_obj(
artifact,
dict(
Expand Down