Skip to content

Commit

Permalink
Add github cloning utility
Browse files Browse the repository at this point in the history
  • Loading branch information
JakobGM committed Feb 27, 2018
1 parent e64ec12 commit 696745f
Show file tree
Hide file tree
Showing 4 changed files with 143 additions and 1 deletion.
3 changes: 3 additions & 0 deletions astrality/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,6 @@ class NonExistentEnabledModule(AstralityConfigurationError):

class MisconfiguredConfigurationFile(AstralityConfigurationError):
pass

class GithubModuleError(AstralityConfigurationError):
pass
41 changes: 41 additions & 0 deletions astrality/github.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import os
from pathlib import Path
from typing import Union

from astrality.exceptions import GithubModuleError
from astrality.utils import run_shell

def clone_repo(
user: str,
repository: str,
modules_directory: Path,
timeout: Union[int, float] = 50,
) -> Path:

github_user_directory = modules_directory / user
github_user_directory.mkdir(parents=True, exist_ok=True)
repository_directory = github_user_directory / repository
github_url = f'https://github.com/{user}/{repository}.git {repository_directory}'

# Fail on git credential prompt: https://serverfault.com/a/665959
result = run_shell(
command='GIT_TERMINAL_PROMPT=0 git clone ' + github_url,
timeout=timeout,
fallback=False,
working_directory=github_user_directory,
allow_error_codes=True,
)

if not repository_directory.is_dir() or result is False:
try:
github_user_directory.rmdir()
except OSError:
pass

raise GithubModuleError(
f'Could not clone repository "{user}/{repository}.\n'
f'Return value from cloning operation: "{result}".'
)

return repository_directory

97 changes: 97 additions & 0 deletions astrality/tests/config/test_github.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
"""Test module for enabled modules sourced from Github."""
from pathlib import Path

import pytest

from astrality.exceptions import GithubModuleError
from astrality.github import clone_repo


def test_clone_github_repo(tmpdir):
modules_directory = Path(tmpdir.mkdir('modules'))
repo_dir = clone_repo(
user='jakobgm',
repository='color-schemes.astrality',
modules_directory=modules_directory,
)
assert repo_dir.is_dir()

module_config = repo_dir / 'config.yml'
assert module_config.is_file()

assert repo_dir.name == 'color-schemes.astrality'
assert repo_dir.parent.name == 'jakobgm'


def test_cloning_non_existent_github_repository(tmpdir):
modules_directory = Path(tmpdir.mkdir('modules'))

with pytest.raises(GithubModuleError):
clone_repo(
user='jakobgm',
repository='i-will-never-create-this-repository',
modules_directory=modules_directory,
)

github_user_directory = modules_directory / 'jakobgm'
assert not github_user_directory.is_dir()

repository_directory = github_user_directory / 'i-will-never-create-this-repository'
assert not repository_directory.is_dir()


def test_cloning_two_repositories(tmpdir):
modules_directory = Path(tmpdir.mkdir('modules'))
repo_dir = clone_repo(
user='jakobgm',
repository='color-schemes.astrality',
modules_directory=modules_directory,
)
repo_dir = clone_repo(
user='jakobgm',
repository='solar-desktop.astrality',
modules_directory=modules_directory,
)

github_user_directory = modules_directory / 'jakobgm'
assert len(tuple(github_user_directory.iterdir())) == 2


def test_cloning_one_existent_and_one_non_existent_repo(tmpdir):
modules_directory = Path(tmpdir.mkdir('modules'))
repo_dir = clone_repo(
user='jakobgm',
repository='color-schemes.astrality',
modules_directory=modules_directory,
)

with pytest.raises(GithubModuleError):
repo_dir = clone_repo(
user='jakobgm',
repository='i-will-never-create-this-repository',
modules_directory=modules_directory,
)

github_user_directory = modules_directory / 'jakobgm'
assert len(tuple(github_user_directory.iterdir())) == 1


def test_cloning_the_same_repo_twice(tmpdir):
modules_directory = Path(tmpdir.mkdir('modules'))
repo_dir = clone_repo(
user='jakobgm',
repository='color-schemes.astrality',
modules_directory=modules_directory,
)

config_file = modules_directory / 'jakobgm' / 'color-schemes.astrality' / 'config.yml'
config_file.write_text('user edited')

repo_dir = clone_repo(
user='jakobgm',
repository='color-schemes.astrality',
modules_directory=modules_directory,
)

with open(config_file) as file:
assert file.read() == 'user edited'
3 changes: 2 additions & 1 deletion astrality/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ def run_shell(
timeout: Union[int, float] = 2,
fallback: Any = '',
working_directory: Path = Path.home(),
allow_error_codes: bool = False,
) -> str:
"""
Return the standard output of a shell command.
Expand Down Expand Up @@ -40,7 +41,7 @@ def run_shell(
for error_line in process.stderr:
logger.error(str(error_line))

if process.returncode != 0:
if process.returncode != 0 and not allow_error_codes:
logger.error(
f'Command "{command}" exited with non-zero return code: ' +
str(process.returncode)
Expand Down

0 comments on commit 696745f

Please sign in to comment.