Skip to content

Commit

Permalink
Merge pull request #550 from JrGoodle/git-config
Browse files Browse the repository at this point in the history
Add git config to clowder yaml
  • Loading branch information
JrGoodle committed May 30, 2020
2 parents b7f8d37 + 5668956 commit 9d1cdb4
Show file tree
Hide file tree
Showing 27 changed files with 1,006 additions and 351 deletions.
14 changes: 0 additions & 14 deletions .github/workflows/cancel.yml

This file was deleted.

56 changes: 56 additions & 0 deletions .github/workflows/ci-cats-git-config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
name: 'CI - cats git config'

on:
push:
branches:
- master
paths-ignore:
- 'docs/**'
pull_request:
branches:
- master
paths-ignore:
- 'docs/**'

defaults:
run:
shell: bash

jobs:
cats_git_config:
env:
PYTHON_VERSION: ${{ matrix.python-version }}
OS_NAME: ${{ matrix.os }}
CLOWDER_DEBUG: true
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [macos-latest, ubuntu-latest] # TODO: windows-latest
python-version: ['3.6', '3.7', '3.8']
exclude:
- os: macos-latest
python-version: '3.6'
- os: macos-latest
python-version: '3.8'
steps:
- uses: actions/checkout@v2
- name: Setup python
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Setup git config
run:
git config --global user.email "joe@polka.cat";
git config --global user.name "GitHub Actions Workflow"
- name: Install clowder requirements
run: pip3 install -r src/requirements.txt
- name: CI before script
run: script/ci_before
- name: Install clowder
run: script/update
- name: Install clowder test
run: script/test
- name: Test git config commands
run: clowder-test -c cats git-config
- name: CI after script
run: script/ci_after
8 changes: 8 additions & 0 deletions clowder_test/clowder_test/cli/cats_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,14 @@ def groups(self) -> None:

self._execute_command('./groups.sh', self.path)

@expose(
help='Run cats git config tests'
)
def git_config(self) -> None:
"""clowder cats git config tests"""

self._execute_command('./git-config.sh', self.path)

@expose(
help='Run cats help tests'
)
Expand Down
12 changes: 6 additions & 6 deletions codecov.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
codecov:
require_ci_to_pass: yes
require_ci_to_pass: no

coverage:
precision: 2
Expand All @@ -14,11 +14,11 @@ parsers:
method: no
macro: no

comment:
# layout: "reach,diff,flags,tree"
layout: "files"
behavior: default
require_changes: no
# comment:
# # layout: "reach,diff,flags,tree"
# # layout: "files"
# behavior: default
# require_changes: no

ignore:
- ".github/**/*"
Expand Down
3 changes: 1 addition & 2 deletions src/clowder/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,7 @@ def existing_clowder_repo(directory: Path) -> bool:
CLOWDER_DIR = path
CLOWDER_REPO_DIR = clowder_repo_dir
break
else:
path = path.parent
path = path.parent


# If clowder repo exists, try to set other global path variables
Expand Down
2 changes: 2 additions & 0 deletions src/clowder/cli/yaml.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import argparse

from clowder.clowder_controller import CLOWDER_CONTROLLER
from clowder.model.util import validate_project_statuses
from clowder.util.decorators import (
print_clowder_name,
print_clowder_repo_status,
Expand Down Expand Up @@ -40,6 +41,7 @@ def yaml(args) -> None:
"""Clowder yaml command private implementation"""

if args.resolved:
validate_project_statuses(CLOWDER_CONTROLLER.projects, allow_missing_repo=False)
print(yaml_string(CLOWDER_CONTROLLER.get_yaml(resolved=True)))
else:
print_clowder_yaml()
18 changes: 9 additions & 9 deletions src/clowder/clowder_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"""

from pathlib import Path
from typing import Tuple
from typing import Optional, Tuple

import clowder.util.formatting as fmt
from clowder import CLOWDER_DIR, CLOWDER_YAML
Expand Down Expand Up @@ -38,14 +38,14 @@ def __init__(self):
:raise ClowderError:
"""

self.error = None
self.error: Optional[Exception] = None

self.name = None
self.defaults = None
self.sources = ()
self.projects = ()
self.project_names = ()
self.project_choices = ()
self.name: Optional[str] = None
self.defaults: Optional[Defaults] = None
self.sources: Tuple[Source, ...] = ()
self.projects: Tuple[Project, ...] = ()
self.project_names: Tuple[str, ...] = ()
self.project_choices: Tuple[str, ...] = ()
self.project_choices_with_default = ('default',)

try:
Expand Down Expand Up @@ -113,7 +113,7 @@ def get_yaml(self, resolved: bool = False) -> dict:
"""

if resolved:
projects = [p.get_yaml(resolved=True) for p in self.projects]
projects = [p.get_yaml(resolved_sha=p.sha()) for p in self.projects]
else:
projects = [p.get_yaml() for p in self.projects]

Expand Down
2 changes: 1 addition & 1 deletion src/clowder/config/clowder_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def __init__(self, clowder_config: Optional[dict] = None,
raise ClowderError(ClowderErrorType.CONFIG_YAML_INVALID_CLOWDER_PATH,
fmt.error_no_clowder_found(self.clowder_dir))

self.name = clowder_config['name']
self.name: str = clowder_config['name']
defaults = clowder_config.get('defaults', None)
if defaults is not None:
projects = defaults.get('projects', None)
Expand Down
8 changes: 4 additions & 4 deletions src/clowder/config/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

from .clowder_config import ClowderConfig

CONFIG_VERSION = 0.1
CONFIG_VERSION = '0.1'


class Config(object):
Expand All @@ -39,9 +39,9 @@ class Config(object):
def __init__(self, current_clowder_name: Optional[str], project_options: Tuple[str, ...]):
"""Config __init__"""

self.error = None
self.current_clowder_config = None
self.clowder_configs = ()
self.error: Optional[Exception] = None
self.current_clowder_config: Optional[ClowderConfig] = None
self.clowder_configs: Tuple[ClowderConfig, ...] = ()
self._project_options = project_options

# Config file doesn't currently exist
Expand Down
2 changes: 2 additions & 0 deletions src/clowder/error.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ class ClowderErrorType(IntEnum):
PRUNE_NO_BRANCHES = 25
INVALID_GIT_PROTOCOL = 26
PARALLEL_COMMAND_UNAVAILABLE = 27
INVALID_GIT_CONFIG_VALUE = 28
INVALID_GIT_SETTINGS_INIT_PARAMETERS = 29

# Yaml errors
YAML_UNKNOWN = 41
Expand Down
70 changes: 54 additions & 16 deletions src/clowder/git/git_repo.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from pathlib import Path
from typing import Optional

from git import Repo, GitError
from git import Repo, GitCommandError, GitError
from termcolor import colored

import clowder.util.formatting as fmt
Expand All @@ -22,9 +22,6 @@
truncate_ref,
)

__REPO_DEFAULT_REF__ = 'refs/heads/master'
__REPO_DEFAULT_REMOTE__ = 'origin'


class GitRepo(object):
"""Class encapsulating base git utilities
Expand Down Expand Up @@ -187,18 +184,13 @@ def fetch(self, remote: str, ref: Optional[str] = None, depth: int = 0,

remote_output = fmt.remote_string(remote)
quiet = not self._print_output
if depth == 0:
if depth == 0 or ref is None:
self._print(f' - Fetch from {remote_output}')
message = colored(' - Failed to fetch from ', 'red')
error_message = message + remote_output
elif ref is None:
message = colored(' - Failed to fetch remote ', 'red')
error_message = message + remote_output
error_message = f'{fmt.ERROR} Failed to fetch from remote {remote_output}'
else:
ref_output = fmt.ref_string(truncate_ref(ref))
self._print(' - Fetch from ' + remote_output + ' ' + ref_output)
message = colored(' - Failed to fetch from ', 'red')
error_message = message + f'{remote_output} {ref_output}'
self._print(f' - Fetch from {remote_output} {ref_output}')
error_message = f'{fmt.ERROR} Failed to fetch from {remote_output} {ref_output}'

try:
if depth == 0:
Expand Down Expand Up @@ -279,6 +271,47 @@ def get_current_timestamp(self) -> str:
except (KeyboardInterrupt, SystemExit):
raise ClowderError(ClowderErrorType.USER_INTERRUPT, fmt.error_user_interrupt())

def git_config_unset_all_local(self, variable: str) -> None:
"""Unset all local git config values for given variable key
:param str variable: Fully qualified git config variable
:raise ClowderError:
"""

try:
self.repo.git.config('--local', '--unset-all', variable)
except GitCommandError as err:
LOG_DEBUG('Git command error', err)
if err.status != 5: # git returns error code 5 when trying to unset variable that doesn't exist
message = f'{fmt.ERROR} Failed to unset all local git config values for {variable}'
message = self._format_error_message(message)
raise ClowderError(ClowderErrorType.GIT_ERROR, message, error=err)
except GitError as err:
LOG_DEBUG('Git error', err)
message = f'{fmt.ERROR} Failed to unset all local git config values for {variable}'
message = self._format_error_message(message)
raise ClowderError(ClowderErrorType.GIT_ERROR, message, error=err)
except (KeyboardInterrupt, SystemExit):
raise ClowderError(ClowderErrorType.USER_INTERRUPT, fmt.error_user_interrupt())

def git_config_add_local(self, variable: str, value: str) -> None:
"""Add local git config value for given variable key
:param str variable: Fully qualified git config variable
:param str value: Git config value
:raise ClowderError:
"""

try:
self.repo.git.config('--local', '--add', variable, value)
except GitError as err:
LOG_DEBUG('Git error', err)
message = f'{fmt.ERROR} Failed to add local git config value {value} for variable {variable}'
message = self._format_error_message(message)
raise ClowderError(ClowderErrorType.GIT_ERROR, message, error=err)
except (KeyboardInterrupt, SystemExit):
raise ClowderError(ClowderErrorType.USER_INTERRUPT, fmt.error_user_interrupt())

def install_lfs_hooks(self) -> None:
"""Install git lfs hooks
Expand Down Expand Up @@ -501,15 +534,20 @@ def status_verbose(self) -> None:
except (KeyboardInterrupt, SystemExit):
raise ClowderError(ClowderErrorType.USER_INTERRUPT, fmt.error_user_interrupt())

def validate_repo(self) -> bool:
def validate_repo(self, allow_missing_repo: bool = True) -> bool:
"""Validate repo state
:param bool allow_missing_repo: Whether to allow validation to succeed with missing repo
:return: True, if repo not dirty or doesn't exist on disk
:rtype: bool
"""

if not existing_git_repository(self.repo_path):
return True
if allow_missing_repo:
if not existing_git_repository(self.repo_path):
return True
else:
if not existing_git_repository(self.repo_path):
return False

return not self.is_dirty()

Expand Down

0 comments on commit 9d1cdb4

Please sign in to comment.