[WIP] base contentproviders commit

Very much a WIP, but some thougts on how we can support more
than just git.
pull/242/head
yuvipanda 2018-02-12 14:18:35 -08:00 zatwierdzone przez Tim Head
rodzic 1990c0644f
commit 18f11b8c1f
4 zmienionych plików z 92 dodań i 0 usunięć

Wyświetl plik

@ -0,0 +1,26 @@
"""
Base classes for repo2docker ContentProviders
ContentProviders accept a `spec` of various kinds, and
provide the contents from the spec to a given output directory.
"""
class ContentProviderException(Exception):
"""Exception raised when a ContentProvider can not provide content
"""
pass
class ContentProvider:
kind = ""
def provide(self, spec, output_dir, yield_output=False):
"""Provide the contents of given spec to output_dir
This is a generator, and so should be yielded from or iterated over.
Arguments:
spec -- Dict / String specification understood by this ContentProvider
output_dir {string} -- Path to output directory (must already exist)
yield_output {bool} -- If True, return output line by line. If not, output just goes to stdout.
"""
raise NotImplementedError()

Wyświetl plik

@ -0,0 +1,28 @@
import subprocess
from .base import ContentProvider, ContentProviderException
from ..utils import execute_cmd
class GitContentProvider(ContentProvider):
"""Provides contents of a git repository (optionally at a given ref)
"""
kind = "git"
def provide(self, spec, output_dir, yield_output=False):
url = spec['url']
ref = spec.get('ref', None)
try:
for line in execute_cmd(['git', 'clone', url, output_dir],
capture=yield_output):
yield line
except subprocess.CalledProcessError as e:
raise ContentProviderException("Failed to clone repository!") from e
if ref:
try:
for line in execute_cmd(['git', 'reset', '--hard', ref],
cwd=output_dir,
capture=yield_output):
yield line
except subprocess.CalledProcessError:
raise ContentProviderException("Failed to checkout ref {}!".format(ref)) from e

Wyświetl plik

@ -0,0 +1,38 @@
from contextlib import contextmanager
import shutil
import os
import subprocess
from tempfile import TemporaryDirectory
from repo2docker.contentproviders.git import GitContentProvider
@contextmanager
def git_repo():
"""
Makes a dummy git repo in which user can perform git operations
Should be used as a contextmanager, it will delete directory when done
"""
with TemporaryDirectory() as gitdir:
subprocess.check_call(['git', 'init'], cwd=gitdir)
yield gitdir
def test_clone():
"""Test simple git clone to a target dir
"""
with git_repo() as upstream:
with open(os.path.join(upstream, 'test'), 'w') as f:
f.write("Hello")
subprocess.check_call(['git', 'add', 'test'], cwd=upstream)
subprocess.check_call(['git', 'commit', '-m', 'Test commit'], cwd=upstream)
with TemporaryDirectory() as clone_dir:
spec = {
'url': upstream
}
for _ in GitContentProvider().provide(spec, clone_dir, False):
pass
assert os.path.exists(os.path.join(clone_dir, 'test'))