Skip to content

Commit

Permalink
Merge pull request #461 from JrGoodle/alias
Browse files Browse the repository at this point in the history
Add optional alias to projects
  • Loading branch information
JrGoodle committed May 6, 2020
2 parents 85a46de + bdefc58 commit 0cccbb4
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 20 deletions.
7 changes: 4 additions & 3 deletions src/clowder/error/clowder_yaml_error.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,18 @@ def __str__(self):
@unique
class ClowderYAMLYErrorType(IntEnum):
UNKNOWN = 99
REMOTE_NAME = 101
DUPLICATE_REMOTE_NAME = 101
MISSING_ENTRY = 102
UNKNOWN_ENTRY = 103
MISSING_YAML = 104
EMPTY_YAML = 106
OPEN_FILE = 107
INVALID_PROTOCOL = 108
INVALID_REF = 109
DEPTH = 111
TYPE = 112
INVALID_DEPTH = 111
WRONG_TYPE = 112
MISSING_REPO = 113
SOURCE_NOT_FOUND = 114
GROUPS_CONTAINS_ALL = 115
DUPLICATE_PATH = 116
DUPLICATE_ALIAS = 117
2 changes: 0 additions & 2 deletions src/clowder/model/fork.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@

from termcolor import colored

import clowder.util.formatting as fmt
from clowder import ROOT_DIR
from clowder.error.clowder_yaml_error import ClowderYAMLError, ClowderYAMLYErrorType
from clowder.git.project_repo import ProjectRepo
from clowder.git.util import (
existing_git_repository,
Expand Down
31 changes: 26 additions & 5 deletions src/clowder/model/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
from clowder import ROOT_DIR
from clowder.error.clowder_error import ClowderError
from clowder.error.clowder_exit import ClowderExit
from clowder.error.clowder_yaml_error import ClowderYAMLError, ClowderYAMLYErrorType
from clowder.git.project_repo import ProjectRepo
from clowder.git.project_repo_recursive import ProjectRepoRecursive
from clowder.git.util import (
Expand Down Expand Up @@ -48,6 +47,7 @@ class Project(object):
"""clowder.yaml Project model class
:ivar str name: Project name
:ivar Optional[str] alias: Alias for project
:ivar str path: Project relative path
:ivar List[str] groups: Groups project belongs to
:ivar str ref: Default git ref
Expand All @@ -69,7 +69,7 @@ def __init__(self, project: dict, defaults: Defaults, sources: List[Source]):

self.name = project['name']
self.path = project['path']

self.alias = project.get('alias', None)
self.ref = project.get('ref', defaults.ref)
self.remote = project.get('remote', defaults.remote)
self.depth = project.get('depth', defaults.depth)
Expand All @@ -83,6 +83,9 @@ def __init__(self, project: dict, defaults: Defaults, sources: List[Source]):
groups += custom_groups
if 'notdefault' in groups:
groups.remove('all')
if self.alias:
groups.append(self.alias)
groups.remove(self.name)
self.groups = list(set(groups))

self.source = None
Expand Down Expand Up @@ -249,6 +252,9 @@ def get_yaml(self, resolved: bool = False) -> dict:
'remote': self.remote,
'source': self.source.name}

if self.alias:
project['alias'] = self.alias

if self.fork:
fork_yaml = self.fork.get_yaml()
project['fork'] = fork_yaml
Expand Down Expand Up @@ -295,7 +301,7 @@ def herd(self, branch: Optional[str] = None, tag: Optional[str] = None, depth: O
self._print(self.fork.status())
repo.configure_remotes(self.remote, self._url(), self.fork.remote, self.fork.url())

self._print(fmt.fork_string(self.name))
self._print(fmt.fork_string(self.output_name()))
kwargs['depth'] = 0 # TODO: Can this be removed?
getattr(repo, command)(self._url(), *args, **kwargs)

Expand All @@ -320,6 +326,18 @@ def is_valid(self) -> bool:

return ProjectRepo(self.full_path(), self.remote, self.ref).validate_repo()

def output_name(self) -> str:
"""Name to use for output
:return: Alias if set, otherwise project name
:rtype: str
"""

if self.alias:
return self.alias

return self.name

def print_existence_message(self) -> None:
"""Print existence validation message for project"""

Expand Down Expand Up @@ -377,7 +395,7 @@ def reset(self, timestamp: Optional[str] = None, parallel: bool = False) -> None
self._print(self.fork.status())
repo.configure_remotes(self.remote, self._url(), self.fork.remote, self.fork.url())

self._print(fmt.fork_string(self.name))
self._print(fmt.fork_string(self.output_name()))
if timestamp:
repo.reset_timestamp(timestamp, self._timestamp_author, self.ref)
return
Expand All @@ -404,6 +422,9 @@ def run(self, commands: List[str], ignore_errors: bool, parallel: bool = False)
'PROJECT_REMOTE': self.remote,
'PROJECT_REF': self.ref}

if self.alias:
forall_env['PROJECT_ALIAS'] = self.alias

if self.fork:
forall_env['FORK_REMOTE'] = self.fork.remote

Expand Down Expand Up @@ -432,7 +453,7 @@ def status(self, padding: Optional[int] = None) -> str:
"""

if not existing_git_repository(self.full_path()):
return colored(self.name, 'green')
return colored(self.output_name(), 'green')

repo = ProjectRepo(self.full_path(), self.remote, self.ref)
project_output = repo.format_project_string(self.path)
Expand Down
2 changes: 1 addition & 1 deletion src/clowder/util/decorators.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
"""clowder.yaml validation
"""Decorators
.. codeauthor:: Joe Decapo <joe@polka.cat>
Expand Down
12 changes: 12 additions & 0 deletions src/clowder/util/formatting.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,18 @@ def depth_error(depth: int, yml: str) -> str:
return output_1 + output_2


def duplicate_project_name_alias_error(name: str, yml: str) -> str:
"""Return formatted error string for duplicate project name/alias
:param str name: Duplicate project alias/name
:param str yml: Path to yaml file
:return: Formatted duplicate remote fork name error
:rtype: str
"""

return yaml_path(yml) + colored(' - Error: Multiple projects with name/alias ', 'red') + colored(name, attrs=['bold'])


def duplicate_project_path_error(path: str, yml: str) -> str:
"""Return formatted error string for duplicate project path
Expand Down
31 changes: 22 additions & 9 deletions src/clowder/util/validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def validate_type(value: Any, name: str, classinfo: type, type_name: str, yaml_f
"""

if not isinstance(value, classinfo):
raise ClowderYAMLError(fmt.type_error(name, yaml_file, type_name), ClowderYAMLYErrorType.TYPE)
raise ClowderYAMLError(fmt.type_error(name, yaml_file, type_name), ClowderYAMLYErrorType.WRONG_TYPE)


def validate_yaml_contents(yaml: dict, yaml_file: str) -> None:
Expand All @@ -61,7 +61,9 @@ def validate_yaml_contents(yaml: dict, yaml_file: str) -> None:
projects_with_forks = []
for p in yaml['projects']:
project = {'name': p['name'],
'path': p['path'] if 'path' in p else p['name']}
'path': p.get('path', p['name'])}
if 'alias' in p:
project['alias'] = p['alias']
if 'remote' in p:
project['remote'] = p['remote']
if 'source' in p:
Expand Down Expand Up @@ -90,18 +92,18 @@ def validate_yaml_contents(yaml: dict, yaml_file: str) -> None:
if 'remote' in project and 'remote' in fork:
if project['remote'] == fork['remote']:
message = fmt.remote_name_error(fork['name'], project['name'], project['remote'], yaml_file)
raise ClowderYAMLError(message, ClowderYAMLYErrorType.REMOTE_NAME)
raise ClowderYAMLError(message, ClowderYAMLYErrorType.DUPLICATE_REMOTE_NAME)
elif 'remote' in project:
if project['remote'] == default_remote:
message = fmt.remote_name_error(fork['name'], project['name'], default_remote, yaml_file)
raise ClowderYAMLError(message, ClowderYAMLYErrorType.REMOTE_NAME)
raise ClowderYAMLError(message, ClowderYAMLYErrorType.DUPLICATE_REMOTE_NAME)
elif 'remote' in fork:
if fork['remote'] == default_remote:
message = fmt.remote_name_error(fork['name'], project['name'], default_remote, yaml_file)
raise ClowderYAMLError(message, ClowderYAMLYErrorType.REMOTE_NAME)
raise ClowderYAMLError(message, ClowderYAMLYErrorType.DUPLICATE_REMOTE_NAME)
else:
message = fmt.remote_name_error(fork['name'], project['name'], default_remote, yaml_file)
raise ClowderYAMLError(message, ClowderYAMLYErrorType.REMOTE_NAME)
raise ClowderYAMLError(message, ClowderYAMLYErrorType.DUPLICATE_REMOTE_NAME)

# Validate projects don't share share directories
paths = [p['path'] for p in projects]
Expand All @@ -110,7 +112,18 @@ def validate_yaml_contents(yaml: dict, yaml_file: str) -> None:
message = fmt.duplicate_project_path_error(duplicate, yaml_file)
raise ClowderYAMLError(message, ClowderYAMLYErrorType.DUPLICATE_PATH)

# TODO: Validate projects have unique name/alias
# Validate projects have unique name/alias
# names = [p['alias'] if 'alias' in p else p['name'] for p in projects]
names = []
for project in projects:
if 'alias' in project:
names.append(project['alias'])
else:
names.append(project['name'])
duplicate = _check_for_duplicates(names)
if duplicate is not None:
message = fmt.duplicate_project_name_alias_error(duplicate, yaml_file)
raise ClowderYAMLError(message, ClowderYAMLYErrorType.DUPLICATE_ALIAS)


def validate_yaml_defaults(defaults: dict, yaml_file: str) -> None:
Expand Down Expand Up @@ -172,7 +185,7 @@ def validate_yaml_projects(projects: dict, yaml_file: str) -> None:
_validate_required_string(project, 'project', 'name', yaml_file)
_validate_required_string(project, 'project', 'path', yaml_file)

args = ['remote', 'source', 'timestamp_author']
args = ['alias', 'remote', 'source', 'timestamp_author']
for arg in args:
_validate_optional_string(project, arg, yaml_file)

Expand Down Expand Up @@ -481,4 +494,4 @@ def _validate_type_depth(value: int, yaml_file: str) -> None:
"""

if not isinstance(value, int) or int(value) < 0:
raise ClowderYAMLError(fmt.depth_error(value, yaml_file), ClowderYAMLYErrorType.DEPTH)
raise ClowderYAMLError(fmt.depth_error(value, yaml_file), ClowderYAMLYErrorType.INVALID_DEPTH)
2 changes: 2 additions & 0 deletions test/scripts/cats/yaml_validation.sh
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ test_invalid_yaml() {
_test_invalid_yaml 'ls -d test-arg-type-timestamp*' '112'
_test_invalid_yaml 'ls -d test-source-not-found*' '114'
_test_invalid_yaml 'ls -d test-duplicate-project-directories*' '116'
_test_invalid_yaml 'ls -d test-duplicate-alias*' '117'
_test_invalid_yaml 'ls -d test-duplicate-name*' '117'

$COMMAND repo checkout master || exit 1
pushd .clowder || exit 1
Expand Down

0 comments on commit 0cccbb4

Please sign in to comment.