Permalink
Browse files

Add caching to archive command

  • Loading branch information...
1 parent 1179835 commit c1030d0982e3ff07e50abc0375ea20b47ccd8dc2 @mwilliamson committed Dec 20, 2012
Showing with 56 additions and 19 deletions.
  1. +6 −0 blah/caching.py
  2. +15 −3 blah/fetcher.py
  3. +7 −8 blah/git.py
  4. +1 −1 blah/util.py
  5. +24 −7 tests/fetcher_tests.py
  6. +3 −0 tests/test_repos.py
View
@@ -0,0 +1,6 @@
+import os
+
+
+def cache_root():
+ xdg_cache_home = os.environ.get("XDG_CACHE_HOME", os.path.expanduser("~/.cache"))
+ return os.environ.get("BLAH_CACHE_DIR", os.path.join(xdg_cache_home, "blah"))
View
@@ -1,13 +1,25 @@
import os
import shutil
+import hashlib
import blah.systems
import blah.uri_parser
import blah.errors
+import blah.caching
-def archive(uri_str, local_path, use_cache=True):
- vcs = _fetch(uri_str, local_path)
- shutil.rmtree(os.path.join(local_path, vcs.directory_name))
+def archive(uri_str, local_path):
+ uri_hash = _sha1(uri_str)
+ cache_dir = os.path.join(blah.caching.cache_root(), "archive", uri_hash)
+ if not os.path.exists(os.path.dirname(cache_dir)):
+ os.makedirs(os.path.dirname(cache_dir))
+ if not os.path.exists(cache_dir):
+ vcs = _fetch(uri_str, cache_dir)
+ shutil.rmtree(os.path.join(cache_dir, vcs.directory_name))
+
+ shutil.copytree(cache_dir, local_path)
+
+def _sha1(value):
+ return hashlib.sha1(value).hexdigest()
# Define fetch as distinct from _fetch to stop return value leaking
def fetch(*args, **kwargs):
View
@@ -2,9 +2,8 @@
import os.path
import hashlib
-from xdg.BaseDirectory import save_cache_path
-
from blah.util import run
+import blah.caching
class Git(object):
@@ -35,16 +34,16 @@ def local_repo(self, working_directory):
return GitRepository(working_directory)
def _update_cache(self, repository_uri):
- cache_dir = os.environ.get("BLAH_CACHE_DIR", save_cache_path("blah"))
+ cache_root = blah.caching.cache_root()
repo_hash = hashlib.sha1(repository_uri).hexdigest()
- cache_repo = os.path.join(cache_dir, repo_hash)
+ cache_dir = os.path.join(cache_root, repo_hash)
- if os.path.exists(cache_repo):
- _git(["fetch"], cwd=cache_repo)
+ if os.path.exists(cache_dir):
+ _git(["fetch"], cwd=cache_dir)
else:
- _git(["clone", repository_uri, cache_repo])
+ _git(["clone", repository_uri, cache_dir])
- return cache_repo
+ return cache_dir
class GitRepository(object):
type = Git.name
View
@@ -28,7 +28,7 @@ def run(command, cwd=None, allow_error=False):
error = subprocess.CalledProcessError(return_code, command)
error.output = output
error.stderr_output = stderr_output
- raise error
+ raise RuntimeError("error: " + stderr_output)
return result
class ExecutionResult(object):
View
@@ -10,7 +10,7 @@
from blah.errors import BlahUserError
from blah.systems import all_systems
-from test_repos import temporary_hg_repo, temporary_git_repo, add_commit_to_repo
+from test_repos import temporary_hg_repo, temporary_git_repo, add_commit_to_repo, tag_git_repo
import test_repos
def vcs_agnostic_test(func=None, params=(), **kwargs):
@@ -128,12 +128,13 @@ def can_clone_repository_to_specific_commit_using_hash_before_commit_name(vcs, t
@vcs_agnostic_test
def can_fetch_repo_without_vcs_files(vcs, temp_dir):
- target = os.path.join(temp_dir, "clone")
- with vcs.temporary_repo() as repo:
- original_uri = "{0}+file://{1}".format(vcs.name, repo.working_directory)
- archive(original_uri, target)
- assert_equal("Run it.", read_file(os.path.join(target, "README")))
- assert_false(os.path.exists(os.path.join(target, vcs.directory_name)))
+ with temporary_xdg_cache_dir():
+ target = os.path.join(temp_dir, "clone")
+ with vcs.temporary_repo() as repo:
+ original_uri = "{0}+file://{1}".format(vcs.name, repo.working_directory)
+ archive(original_uri, target)
+ assert_equal("Run it.", read_file(os.path.join(target, "README")))
+ assert_false(os.path.exists(os.path.join(target, vcs.directory_name)))
@istest
def origin_is_prefixed_to_git_commit_if_necessary():
@@ -161,6 +162,22 @@ def can_use_cache_when_cloning_git_repository():
assert_equal("Run it.", read_file(os.path.join(target, "README")))
@istest
+def remote_connection_is_not_required_when_archiving_cached_tagged_commit():
+ with temporary_xdg_cache_dir():
+ with temporary_git_repo() as git_repo:
+ original_uri = "git+file://" + git_repo.working_directory
+ tag_git_repo(git_repo, "0.1")
+ add_commit_to_repo(git_repo)
+ with temporary_directory() as directory:
+ target = os.path.join(directory, "clone")
+ archive(original_uri + "#0.1", target)
+
+ with temporary_directory() as directory:
+ target = os.path.join(directory, "clone")
+ archive(original_uri + "#0.1", target)
+ assert_equal("Run it.", read_file(os.path.join(target, "README")))
+
+@istest
def error_is_raised_if_target_is_file():
with temporary_directory() as directory:
target = os.path.join(directory, "clone")
View
@@ -51,6 +51,9 @@ def add_commit_to_repo(repo):
execute(repo, ["add", "README"])
execute(repo, ["commit", "-mUpdating README"])
+def tag_git_repo(repo, tag_name):
+ execute(repo, ["tag", tag_name])
+
_dev_null = open('/dev/null', 'w')
def execute(repo, command):

0 comments on commit c1030d0

Please sign in to comment.