kopia lustrzana https://github.com/jupyterhub/repo2docker
[WIP] base contentproviders commit
Very much a WIP, but some thougts on how we can support more than just git.pull/242/head
rodzic
1990c0644f
commit
18f11b8c1f
|
@ -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()
|
||||
|
|
@ -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
|
|
@ -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'))
|
Ładowanie…
Reference in New Issue