Skip to content

Commit

Permalink
Merge pull request #383 from JrGoodle/refactor
Browse files Browse the repository at this point in the history
Fix error handling
  • Loading branch information
JrGoodle committed Nov 12, 2017
2 parents 71ddfc2 + 1ae2345 commit fa87103
Show file tree
Hide file tree
Showing 45 changed files with 365 additions and 271 deletions.
2 changes: 2 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ matrix:
env: TARGET="parallel" PYVERSION="python3"
- os: linux
env: TARGET="swift" PYVERSION="python3"
- os: linux
env: TARGET="write" PYVERSION="python3"

before_install: script/bootstrap "$PYVERSION"

Expand Down
8 changes: 3 additions & 5 deletions clowder/clowder/cli/link_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,11 @@

from cement.ext.ext_argparse import ArgparseController, expose

from clowder.clowder_repo import (
CLOWDER_REPO,
print_clowder_repo_status
)
from clowder.clowder_repo import print_clowder_repo_status
from clowder.util.decorators import clowder_required
from clowder.util.clowder_utils import (
get_saved_version_names,
link_clowder_yaml,
options_help_message
)

Expand Down Expand Up @@ -51,4 +49,4 @@ def _link(self):
version = None
else:
version = self.app.pargs.version[0]
CLOWDER_REPO.link(version)
link_clowder_yaml(version)
12 changes: 4 additions & 8 deletions clowder/clowder/cli/repo_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,7 @@ def clean(self):

@clowder_required
@print_clowder_repo_status
@staticmethod
def _clean():
def _clean(self):
"""Clowder repo clean command private implementation"""

CLOWDER_REPO.clean()
Expand Down Expand Up @@ -163,8 +162,7 @@ def pull(self):
@network_connection_required
@clowder_required
@print_clowder_repo_status_fetch
@staticmethod
def _pull():
def _pull(self):
"""Clowder repo pull command private implementation"""

CLOWDER_REPO.pull()
Expand Down Expand Up @@ -192,8 +190,7 @@ def push(self):
@network_connection_required
@clowder_required
@print_clowder_repo_status_fetch
@staticmethod
def _push():
def _push(self):
"""Clowder repo push command private implementation"""

CLOWDER_REPO.push()
Expand Down Expand Up @@ -250,8 +247,7 @@ def status(self):

@clowder_required
@print_clowder_repo_status
@staticmethod
def _status():
def _status(self):
"""Clowder repo status command private implementation"""

CLOWDER_REPO.git_status()
33 changes: 27 additions & 6 deletions clowder/clowder/clowder_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@

from __future__ import print_function

import sys

import colorama
from cement.core.exc import FrameworkError, CaughtSignal
from cement.core.foundation import CementApp

import clowder.cli as cmd
Expand All @@ -23,6 +22,7 @@ class Meta:
"""Clowder command CLI Meta configuration"""

label = 'clowder'
exit_on_close = True
extensions = ['argcomplete']
base_controller = 'base'
handlers = [
Expand Down Expand Up @@ -62,10 +62,31 @@ def main():
with ClowderApp() as app:
try:
app.run()
except ClowderExit:
sys.tracebacklimit = 0
raise
print()
except CaughtSignal as err:
# determine what the signal is, and do something with it?
from signal import SIGINT, SIGABRT

if err.signum == SIGINT:
# do something... maybe change the exit code?
app.exit_code = 110
elif err.signum == SIGABRT:
# do something else...
app.exit_code = 111
except FrameworkError as err:
# do something when a framework error happens
app.args.print_help()

# and maybe set the exit code to something unique as well
app.exit_code = 300
except ClowderExit as err:
app.exit_code = err.code
finally:
# Maybe we want to see a full-stack trace for the above
# exceptions, but only if --debug was passed?
print()
if app.debug:
import traceback
traceback.print_exc()


if __name__ == '__main__':
Expand Down
36 changes: 4 additions & 32 deletions clowder/clowder/clowder_repo.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,10 @@
format_project_string,
print_validation
)
from clowder.util.clowder_utils import link_clowder_yaml
from clowder.util.connectivity import is_offline
from clowder.util.execute import execute_command
from clowder.util.file_system import (
force_symlink,
remove_directory
)
from clowder.util.file_system import remove_directory
from clowder.yaml.validating import validate_yaml


Expand All @@ -55,7 +53,7 @@ def __init__(self):
# Create clowder.yaml symlink if .clowder dir and yaml file exist
clowder_symlink = os.path.join(ROOT_DIR, 'clowder.yaml')
if os.path.isdir(self.clowder_path) and not os.path.islink(clowder_symlink):
self.link()
link_clowder_yaml()

self.error = None
if os.path.islink(clowder_symlink):
Expand Down Expand Up @@ -131,7 +129,7 @@ def init(self, url, branch):
atexit.register(self.init_exit_handler)

self.repo.create_clowder_repo(url, branch)
self.link()
link_clowder_yaml()

def init_exit_handler(self):
"""Exit handler for deleting files if init fails
Expand All @@ -154,32 +152,6 @@ def is_dirty(self):

return self.repo.is_dirty()

@staticmethod
def link(version=None):
"""Create symlink pointing to clowder.yaml file
.. py:function:: link(version=None)
:param Optional[str] version: Version name of clowder.yaml to link
:raise ClowderExit:
"""

if version is None:
yaml_file = os.path.join(ROOT_DIR, '.clowder', 'clowder.yaml')
path_output = fmt.get_path('.clowder/clowder.yaml')
else:
relative_path = os.path.join('.clowder', 'versions', version, 'clowder.yaml')
path_output = fmt.get_path(relative_path)
yaml_file = os.path.join(ROOT_DIR, relative_path)

if not os.path.isfile(yaml_file):
print('\n' + path_output + " doesn't seem to exist\n")
raise ClowderExit(1)

yaml_symlink = os.path.join(ROOT_DIR, 'clowder.yaml')
print(' - Symlink ' + path_output)
force_symlink(yaml_file, yaml_symlink)

def print_status(self, fetch=False):
"""Print clowder repo status
Expand Down
2 changes: 1 addition & 1 deletion clowder/clowder/git/project_repo.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ def herd_branch(self, url, branch, **kwargs):
self._herd_branch_existing_local(branch, depth=depth, rebase=rebase, fork_remote=fork_remote)
return

self.fetch(self.remote, depth=depth, ref=branch_ref)
self.fetch(self.remote, depth=depth, ref=branch_ref, allow_failure=True)
if self.existing_remote_branch(branch, self.remote):
self._herd(self.remote, branch_ref, depth=depth, fetch=False, rebase=rebase)
return
Expand Down
9 changes: 6 additions & 3 deletions clowder/clowder/git/repo.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,19 +176,21 @@ def existing_local_branch(self, branch):
def fetch(self, remote, **kwargs):
"""Fetch from a specific remote ref
.. py:function:: fetch(remote, ref=None, depth=0, remove_dir=False)
.. py:function:: fetch(remote, ref=None, depth=0, remove_dir=False, allow_failure=False)
:param str remote: Remote name
Keyword Args:
ref (str): Ref to fetch
depth (int): Git clone depth. 0 indicates full clone, otherwise must be a positive integer
remove_dir (bool): Whether to remove the directory if commands fail
allow_failure (bool): Whether to allow failure
"""

ref = kwargs.get('ref', None)
depth = kwargs.get('depth', 0)
remove_dir = kwargs.get('remove_dir', False)
allow_failure = kwargs.get('allow_failure', False)

remote_output = fmt.remote_string(remote)
if depth == 0:
Expand All @@ -212,8 +214,9 @@ def fetch(self, remote, **kwargs):
except ClowderError:
if remove_dir:
remove_directory(self.repo_path)
self._print(error)
self._exit(error)
if not allow_failure:
self._print(error)
self._exit(error)

def get_current_timestamp(self):
"""Get current timestamp of HEAD commit
Expand Down
11 changes: 10 additions & 1 deletion clowder/clowder/git/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

from termcolor import colored

from clowder.error. clowder_error import ClowderError


def existing_git_repository(path):
"""Check if a git repository exists
Expand Down Expand Up @@ -112,11 +114,18 @@ def git_url(protocol, url, name):
:param str protocol: Git protocol ('ssh' or 'https')
:param str url: Repo url
:param str name: Repo name
:return: Full git repo url for specified protocol
:rtype: str
:raise ClowderError:
"""

if protocol == 'ssh':
return 'git@' + url + ':' + name + ".git"
return 'https://' + url + '/' + name + ".git"

if protocol == 'https':
return 'https://' + url + '/' + name + ".git"

raise ClowderError


def ref_type(ref):
Expand Down
14 changes: 11 additions & 3 deletions clowder/clowder/model/fork.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,20 @@ class Fork(object):
:ivar str remote_name: Git remote name
"""

def __init__(self, fork, path, source):
def __init__(self, fork, path, source, protocol):
"""Project __init__
:param dict fork: Parsed YAML python object for fork
:param str path: Fork relative path
:param Source source: Source instance
:param str protocol: Git protocol ('ssh' or 'https')
"""

self.path = path
self.name = fork['name']
self.remote_name = fork['remote']
self._source = source
self._protocol = protocol

def full_path(self):
"""Return full path to project
Expand Down Expand Up @@ -76,6 +78,12 @@ def status(self):
return project_output + ' ' + current_ref_output

def url(self, protocol):
"""Return project url"""
"""Return project url
return git_url(protocol, self._source.url, self.name)
:param str protocol: Git protocol ('ssh' or 'https')
"""

if protocol:
return git_url(protocol, self._source.url, self.name)

return git_url(self._protocol, self._source.url, self.name)
14 changes: 7 additions & 7 deletions clowder/clowder/model/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ def __init__(self, project, group, defaults, sources):
self.remote = project.get('remote', group.get('remote', defaults.remote))
self.depth = project.get('depth', group.get('depth', defaults.depth))
self.recursive = project.get('recursive', group.get('recursive', defaults.recursive))
self._protocol = defaults.protocol
self._timestamp_author = project.get('timestamp_author',
group.get('timestamp_author', defaults.timestamp_author))
self._print_output = True

self.source = None
source_name = project.get('source', group.get('source', defaults.source))
Expand All @@ -88,12 +92,7 @@ def __init__(self, project, group, defaults, sources):
fork = project['fork']
if fork['remote'] == self.remote:
raise ClowderYAMLError(fmt.remote_name_error(fork['name'], self.name, self.remote))
self.fork = Fork(fork, self.path, self.source)

self._protocol = defaults.protocol
self._timestamp_author = project.get('timestamp_author',
group.get('timestamp_author', defaults.timestamp_author))
self._print_output = True
self.fork = Fork(fork, self.path, self.source, self._protocol)

@project_repo_exists
def branch(self, local=False, remote=False):
Expand Down Expand Up @@ -450,7 +449,7 @@ def sync(self, rebase=False, parallel=False):
self._print_output = not parallel

repo = self._repo(self.full_path(), self.remote, self.ref, self.recursive, parallel=parallel)
self._run_herd_command('herd', repo, self._url(), rebase=rebase)
self._run_herd_command('herd', repo, self._protocol, rebase=rebase)
self._print(self.fork.status())
repo.sync(self.fork.remote_name, rebase=rebase)

Expand Down Expand Up @@ -549,4 +548,5 @@ def _url(self, protocol=None):

if protocol:
return git_url(protocol, self.source.url, self.name)

return git_url(self._protocol, self.source.url, self.name)
25 changes: 25 additions & 0 deletions clowder/clowder/util/clowder_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import clowder.util.formatting as fmt
from clowder import ROOT_DIR
from clowder.error.clowder_exit import ClowderExit
from clowder.util.file_system import force_symlink


def existing_branch_groups(groups, branch, is_remote):
Expand Down Expand Up @@ -96,6 +97,30 @@ def get_saved_version_names():
return [v for v in os.listdir(versions_dir) if not v.startswith('.') if v.lower() != 'default']


def link_clowder_yaml(version=None):
"""Create symlink pointing to clowder.yaml file
:param Optional[str] version: Version name of clowder.yaml to link
:raise ClowderExit:
"""

if version is None:
yaml_file = os.path.join(ROOT_DIR, '.clowder', 'clowder.yaml')
path_output = fmt.get_path('.clowder/clowder.yaml')
else:
relative_path = os.path.join('.clowder', 'versions', version, 'clowder.yaml')
path_output = fmt.get_path(relative_path)
yaml_file = os.path.join(ROOT_DIR, relative_path)

if not os.path.isfile(yaml_file):
print('\n' + path_output + " doesn't seem to exist\n")
raise ClowderExit(1)

yaml_symlink = os.path.join(ROOT_DIR, 'clowder.yaml')
print(' - Symlink ' + path_output)
force_symlink(yaml_file, yaml_symlink)


def options_help_message(options, message):
"""Help message for groups option
Expand Down

0 comments on commit fa87103

Please sign in to comment.