diff options
author | Richard Maw <richard.maw@codethink.co.uk> | 2012-11-12 17:28:57 +0000 |
---|---|---|
committer | Richard Maw <richard.maw@codethink.co.uk> | 2012-11-12 17:28:57 +0000 |
commit | 2ac6f661130322e63b8d2737145ea11d445aaa79 (patch) | |
tree | dd30179d22c09cc73898d7db6218e0d620d74ac8 /morphlib | |
parent | 19b16a2cc6d67871d0a4298354eb446ada136a8e (diff) | |
parent | a5b913a83db94380fc91d15571f55cbf7b5c741b (diff) | |
download | morph-2ac6f661130322e63b8d2737145ea11d445aaa79.tar.gz |
Merge branch 'samthursfield/build-without-push' of git://git.baserock.org/baserock/morph
Diffstat (limited to 'morphlib')
-rwxr-xr-x | morphlib/app.py | 4 | ||||
-rw-r--r-- | morphlib/buildcommand.py | 1 | ||||
-rw-r--r-- | morphlib/cachedrepo.py | 7 | ||||
-rw-r--r-- | morphlib/cachedrepo_tests.py | 6 | ||||
-rw-r--r-- | morphlib/git.py | 7 | ||||
-rw-r--r-- | morphlib/localrepocache.py | 10 | ||||
-rw-r--r-- | morphlib/localrepocache_tests.py | 5 | ||||
-rw-r--r-- | morphlib/plugins/branch_and_merge_plugin.py | 43 |
8 files changed, 66 insertions, 17 deletions
diff --git a/morphlib/app.py b/morphlib/app.py index 8769b41c..0a11c716 100755 --- a/morphlib/app.py +++ b/morphlib/app.py @@ -139,6 +139,10 @@ class Morph(cliapp.Application): 'build chunks with prefix PREFIX', metavar='PREFIX', default=defaults['prefix'], group=group_build) + self.settings.boolean(['push-build-branches'], + 'always push temporary build branches to the ' + 'remote repository', + group=group_build) self.settings.boolean(['staging-chroot'], 'build things in an isolated chroot ' '(default: true)', diff --git a/morphlib/buildcommand.py b/morphlib/buildcommand.py index aa6c7d0e..95f3812e 100644 --- a/morphlib/buildcommand.py +++ b/morphlib/buildcommand.py @@ -38,6 +38,7 @@ class BuildCommand(object): self.ckc = self.new_cache_key_computer(self.build_env) self.lac, self.rac = self.new_artifact_caches() self.lrc, self.rrc = self.new_repo_caches() + self.supports_local_build = True def build(self, args): '''Build triplets specified on command line.''' diff --git a/morphlib/cachedrepo.py b/morphlib/cachedrepo.py index c40cb657..0b5ce60f 100644 --- a/morphlib/cachedrepo.py +++ b/morphlib/cachedrepo.py @@ -102,6 +102,7 @@ class CachedRepo(object): self.original_name = original_name self.url = url self.path = path + self.is_mirror = not url.startswith('file://') def resolve_ref(self, ref): '''Attempts to resolve a ref into its SHA1 and tree SHA1. @@ -223,6 +224,9 @@ class CachedRepo(object): ''' + if not self.is_mirror: + return + try: self._update() except cliapp.AppException, e: @@ -260,7 +264,8 @@ class CachedRepo(object): def _copy_repository(self, source_dir, target_dir): # pragma: no cover try: - morphlib.git.copy_repository(self._runcmd, source_dir, target_dir) + morphlib.git.copy_repository( + self._runcmd, source_dir, target_dir, self.is_mirror) except cliapp.AppException: raise CopyError(self, target_dir) diff --git a/morphlib/cachedrepo_tests.py b/morphlib/cachedrepo_tests.py index 0ca0882f..81673880 100644 --- a/morphlib/cachedrepo_tests.py +++ b/morphlib/cachedrepo_tests.py @@ -246,6 +246,12 @@ class CachedRepoTests(unittest.TestCase): self.repo._update = self.update_with_failure self.assertRaises(cachedrepo.UpdateError, self.repo.update) + def test_no_update_if_local(self): + self.repo = cachedrepo.CachedRepo( + object(), 'local:repo', 'file:///local/repo/', '/local/repo/') + self.repo._update = self.update_with_failure + self.repo.update() + def test_clone_checkout(self): self.repo.clone_checkout('master', '/.DOES_NOT_EXIST') self.assertEqual(self.clone_target, '/.DOES_NOT_EXIST') diff --git a/morphlib/git.py b/morphlib/git.py index 973e4af7..7985b815 100644 --- a/morphlib/git.py +++ b/morphlib/git.py @@ -175,13 +175,18 @@ def set_remote(runcmd, gitdir, name, url): return runcmd(['git', 'remote', 'set-url', name, url], cwd=gitdir) -def copy_repository(runcmd, repo, destdir): +def copy_repository(runcmd, repo, destdir, is_mirror=True): '''Copies a cached repository into a directory using cp. This also fixes up the repository afterwards, so that it can contain code etc. It does not leave any given branch ready for use. ''' + if is_mirror == False: + runcmd(['cp', '-a', os.path.join(repo, '.git'), + os.path.join(destdir, '.git')]) + return + runcmd(['cp', '-a', repo, os.path.join(destdir, '.git')]) # core.bare should be false so that git believes work trees are possible runcmd(['git', 'config', 'core.bare', 'false'], cwd=destdir) diff --git a/morphlib/localrepocache.py b/morphlib/localrepocache.py index ae5fa655..465e9f03 100644 --- a/morphlib/localrepocache.py +++ b/morphlib/localrepocache.py @@ -193,9 +193,13 @@ class LocalRepoCache(object): return quote_url(url) def _cache_name(self, url): - basename = self._escape(url) - path = os.path.join(self._cachedir, basename) - return path + scheme, netloc, path, query, fragment = urlparse.urlsplit(url) + if scheme == 'file': + return path + else: + basename = self._escape(url) + path = os.path.join(self._cachedir, basename) + return path def has_repo(self, reponame): '''Have we already got a cache of a given repo?''' diff --git a/morphlib/localrepocache_tests.py b/morphlib/localrepocache_tests.py index 26a92616..6c5410ce 100644 --- a/morphlib/localrepocache_tests.py +++ b/morphlib/localrepocache_tests.py @@ -163,3 +163,8 @@ class LocalRepoCacheTests(unittest.TestCase): def test_noremote_error_message_contains_repo_name(self): e = morphlib.localrepocache.NoRemote(self.repourl, []) self.assertTrue(self.repourl in str(e)) + + def test_avoids_caching_local_repo(self): + self.lrc.cache_repo('file:///local/repo') + cached = self.lrc.get_repo('file:///local/repo') + assert cached.path == '/local/repo' diff --git a/morphlib/plugins/branch_and_merge_plugin.py b/morphlib/plugins/branch_and_merge_plugin.py index 21a5970c..efaa8dfe 100644 --- a/morphlib/plugins/branch_and_merge_plugin.py +++ b/morphlib/plugins/branch_and_merge_plugin.py @@ -1126,6 +1126,11 @@ class BranchAndMergePlugin(cliapp.Plugin): # Generate a UUID for the build. build_uuid = uuid.uuid4().hex + build_command = morphlib.buildcommand.BuildCommand(self.app) + build_command = self.app.hookmgr.call('new-build-command', + build_command) + push = self.app.settings['push-build-branches'] + self.app.status(msg='Starting build %(uuid)s', uuid=build_uuid) self.app.status(msg='Collecting morphologies involved in ' @@ -1143,26 +1148,34 @@ class BranchAndMergePlugin(cliapp.Plugin): # Create the build refs for all these repositories and commit # all uncommitted changes to them, updating all references # to system branch refs to point to the build refs instead. - self.update_build_refs(build_repos, branch, build_uuid) + self.update_build_refs(build_repos, branch, build_uuid, push) - # Push the temporary build refs. - self.push_build_refs(build_repos) + if push: + self.push_build_refs(build_repos) + build_branch_root = branch_root + else: + dirname = build_repos[branch_root]['dirname'] + build_branch_root = urlparse.urljoin('file://', dirname) # Run the build. - build_command = morphlib.buildcommand.BuildCommand(self.app) - build_command = self.app.hookmgr.call('new-build-command', - build_command) - build_command.build([branch_root, + build_command.build([build_branch_root, build_repos[branch_root]['build-ref'], system_name]) - # Delete the temporary refs on the server. - self.delete_remote_build_refs(build_repos) + if push: + self.delete_remote_build_refs(build_repos) self.app.status(msg='Finished build %(uuid)s', uuid=build_uuid) def get_system_build_repos(self, system_branch, branch_dir, branch_root, system_name): + '''Map upstream repository URLs to their checkouts in the system branch + + Also provides the list of morphologies stored in each repository, + grouped by kind. + + ''' + build_repos = {} def prepare_repo_info(repo, dirname): @@ -1205,7 +1218,7 @@ class BranchAndMergePlugin(cliapp.Plugin): return build_repos - def inject_build_refs(self, morphology, build_repos): + def inject_build_refs(self, morphology, build_repos, will_push): # Starting from a system or stratum morphology, update all ref # pointers of strata or chunks involved in a system build (represented # by build_repos) to point to temporary build refs of the repos @@ -1215,6 +1228,9 @@ class BranchAndMergePlugin(cliapp.Plugin): info['morph'] in build_repos[info['repo']]['strata'] or info['morph'] in build_repos[info['repo']]['chunks']): info['ref'] = build_repos[info['repo']]['build-ref'] + if not will_push: + dirname = build_repos[info['repo']]['dirname'] + info['repo'] = urlparse.urljoin('file://', dirname) if morphology['kind'] == 'system': for info in morphology['strata']: inject_build_ref(info) @@ -1230,7 +1246,10 @@ class BranchAndMergePlugin(cliapp.Plugin): branch_uuid, repo_uuid) info['build-ref'] = build_ref - def update_build_refs(self, build_repos, system_branch, build_uuid): + def update_build_refs(self, build_repos, system_branch, build_uuid, + will_push): + '''Update build branches for each repository with any local changes ''' + # Define the committer. committer_name = 'Morph (on behalf of %s)' % \ (morphlib.git.get_user_name(self.app.runcmd)) @@ -1282,7 +1301,7 @@ class BranchAndMergePlugin(cliapp.Plugin): for filename in filenames: # Inject temporary refs in the right places in each morphology. morphology = self.load_morphology(repo_dir, filename) - self.inject_build_refs(morphology, build_repos) + self.inject_build_refs(morphology, build_repos, will_push) handle, tmpfile = tempfile.mkstemp(suffix='.morph') self.save_morphology(repo_dir, tmpfile, morphology) |