diff options
-rw-r--r-- | README | 8 | ||||
-rwxr-xr-x | morphlib/app.py | 36 | ||||
-rw-r--r-- | morphlib/util.py | 45 | ||||
-rwxr-xr-x | tests/trove-prefix.script | 99 |
4 files changed, 178 insertions, 10 deletions
@@ -40,11 +40,11 @@ something like this: cachedir = /home/username/baserock/cache log = /home/username/baserock/morph.log log-max = 200M - git-base-url = git://gitorious.org/baserock-morphs - bundle-server = http://roadtrain.codethink.co.uk/bundles + trove-host = git.baserock.org + bundle-server = http://git.baserock.org/bundles -All of the above settings apart from `log` are the defaults, so may be -omitted. +All of the above settings apart from `log` and `bundle-server` are the +defaults, so may be omitted. Morphology file syntax diff --git a/morphlib/app.py b/morphlib/app.py index 508e0975..d5af6ccc 100755 --- a/morphlib/app.py +++ b/morphlib/app.py @@ -18,6 +18,7 @@ import cliapp import collections import logging import os +import sys import time import warnings @@ -25,13 +26,9 @@ import morphlib defaults = { + 'trove-host': 'git.baserock.org', + 'trove-prefix': [ ], 'repo-alias': [ - ('upstream=' - 'git://git.baserock.org/delta/#' - 'ssh://gitano@git.baserock.org/delta/'), - ('baserock=' - 'git://git.baserock.org/baserock/#' - 'ssh://gitano@git.baserock.org/baserock/'), ('freedesktop=' 'git://anongit.freedesktop.org/#' 'ssh://git.freedesktop.org/'), @@ -59,6 +56,22 @@ class Morph(cliapp.Application): 'show what is happening in much detail') self.settings.boolean(['quiet', 'q'], 'show no output unless there is an error') + self.settings.string(['trove-host'], + 'hostname of Trove instance', + metavar='HOST', + default=defaults['trove-host']) + self.settings.string_list(['trove-prefix'], + 'define URL prefix aliases stored ' + 'directly on the Trove host. Uses ' + 'the form ' + 'alias=pathprefix#pullmethod#pushmethod ' + 'for example, foocorp=fooprojects#git#ssh ' + 'will be expanded into a repo-alias of ' + 'foocorp=git://trove-host/fooprojects/%s#...' + ' with the push side set to the ssh url to ' + 'the trove.',\ + metavar='ALIAS=PREFIX#PULL#PUSH', + default=defaults['trove-prefix']) self.settings.string_list(['repo-alias'], 'define URL prefix aliases to allow ' 'repository addresses to be shortened; ' @@ -151,6 +164,17 @@ class Morph(cliapp.Application): metavar='PREFIX', default=defaults['build-ref-prefix']) + def process_args(self, args): + # Combine the aliases into repo-alias before passing on to normal + # command processing. This means everything from here on down can + # treat settings['repo-alias'] as the sole source of prefixes for git + # URL expansion. + self.settings['repo-alias'] = morphlib.util.combine_aliases(self) + if 'MORPH_DUMP_PROCESSED_CONFIG' in os.environ: + self.settings.dump_config(sys.stdout) + sys.exit(0) + cliapp.Application.process_args(self, args) + def setup_plugin_manager(self): cliapp.Application.setup_plugin_manager(self) diff --git a/morphlib/util.py b/morphlib/util.py index d1c60c36..ce9d0dc9 100644 --- a/morphlib/util.py +++ b/morphlib/util.py @@ -13,6 +13,8 @@ # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +import re + import morphlib '''Utility functions for morph.''' @@ -97,6 +99,49 @@ def new_artifact_caches(settings): # pragma: no cover rac = None return lac, rac +def combine_aliases(app): # pragma: no cover + '''Create a full repo-alias set from the app's settings.''' + trove_host = app.settings['trove-host'] + trove_prefixes = app.settings['trove-prefix'] + repo_aliases = app.settings['repo-alias'] + repo_pat = r'^(?P<prefix>[a-z0-9]+)=(?P<pull>[^#]+)#(?P<push>[^#]+)$' + trove_pat = (r'^(?P<prefix>[a-z0-9]+)=(?P<path>[^#]+)#' + '(?P<pull>[^#]+)#(?P<push>[^#]+)$') + alias_map = {} + def _expand(protocol, path): + if protocol == "git": + return "git://%s/%s/%%s" % (trove_host, path) + elif protocol == "ssh": + return "ssh://git@%s/%s/%%s" % (trove_host, path) + else: + raise cliapp.AppException( + 'Unknown protocol in trove_prefix: %s' % protocol) + + if trove_host: + alias_map['baserock'] = "baserock=%s#%s" % ( + _expand('git', 'baserock'), + _expand('ssh', 'baserock')) + alias_map['upstream'] = "upstream=%s#%s" % ( + _expand('git', 'delta'), + _expand('ssh', 'delta')) + for trove_prefix in trove_prefixes: + m = re.match(trove_pat, trove_prefix) + if m: + alias_map[m.group('prefix')] = "%s=%s#%s" % ( + m.group('prefix'), + _expand(m.group('pull'), m.group('path')), + _expand(m.group('push'), m.group('path'))) + elif '=' not in trove_prefix: + alias_map[trove_prefix] = "%s=%s#%s" % ( + trove_prefix, + _expand('ssh', trove_prefix), + _expand('ssh', trove_prefix)) + for repo_alias in repo_aliases: + m = re.match(repo_pat, repo_alias) + if m: + alias_map[m.group('prefix')] = repo_alias + + return alias_map.values() def new_repo_caches(app): # pragma: no cover '''Create new objects for local, remote git repository caches.''' diff --git a/tests/trove-prefix.script b/tests/trove-prefix.script new file mode 100755 index 00000000..612311f3 --- /dev/null +++ b/tests/trove-prefix.script @@ -0,0 +1,99 @@ +#!/bin/sh +# +# Verify that trove-prefix (and by corollary trove-host) work properly. +# +# Copyright (C) 2012 Codethink Limited +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +set -eu + +RAWDUMP="$DATADIR/raw-configdump" +PROCESSEDDUMP="$DATADIR/processed-configdump" + +# Step 1, gather all the raw and processed repo-alias entries + +"$SRCDIR/scripts/test-morph" \ + --trove-host="TROVEHOST" \ + --trove-prefix="fudge" \ + --trove-prefix="github" \ + --dump-config > "$RAWDUMP" +env MORPH_DUMP_PROCESSED_CONFIG=1 "$SRCDIR/scripts/test-morph" \ + --trove-host="TROVEHOST" \ + --trove-prefix="fudge" \ + --trove-prefix="github" \ + > "$PROCESSEDDUMP" + +RAW_ALIAS=$(grep repo-alias "$RAWDUMP" | cut -d\ -f3-) +PROCESSED_ALIAS=$(grep repo-alias "$PROCESSEDDUMP" | cut -d\ -f3-) + +find_alias () { + ALIASES="$1" + WHICH="$2" + for alias in $ALIASES; do + alias=$(echo $alias | sed -e's/,$//') + prefix=$(echo $alias | cut -d= -f1) + if test "x$WHICH" = "x$prefix"; then + echo $alias + exit 0 + fi + done +} + +# Step 2, all raw aliases should be in processed aliases unchanged. As part of +# this, we're also validating that the 'github' prefix we pass in does not +# affect the alias output since it is overridden by repo-alias. + +for raw_alias in $RAW_ALIAS; do + raw_alias=$(echo $raw_alias | sed -e's/,$//') + raw_prefix=$(echo $raw_alias | cut -d= -f1) + processed_alias=$(find_alias "$PROCESSED_ALIAS" "$raw_prefix") + if test "x$raw_alias" != "x$processed_alias"; then + echo >&2 "Raw $raw_alias not in processed aliases" + fi +done + +# Step 3, all aliases in the processed aliases which do not come from the raw +# aliases should contain the trove host. + +for processed_alias in $PROCESSED_ALIAS; do + processed_alias=$(echo $processed_alias | sed -e's/,$//') + processed_prefix=$(echo $processed_alias | cut -d= -f1) + raw_alias=$(find_alias "$RAW_ALIAS" "$processed_prefix") + if test "x$raw_alias" = "x"; then + grep_out=$(echo "$processed_alias" | grep TROVEHOST) + if test "x$grep_out" = "x"; then + echo >&2 "Processed $processed_alias does not mention TROVEHOST" + fi + fi +done + +# Step 4, validate that the processed aliases do contain a baserock and an +# upstream alias since those are implicit in morph's behaviour. + +for prefix in baserock upstream; do + processed_alias=$(find_alias "$PROCESSED_ALIAS" "$prefix") + if test "x$processed_alias" = "x"; then + echo >&2 "Processed aliases lack $prefix prefix" + fi +done + +# Step 5, validate that the fudge prefix has been correctly expanded as though +# it were fudge=fudge#ssh#ssh + +fudge_alias=$(find_alias "$PROCESSED_ALIAS" "fudge") +desired_fudge="fudge=ssh://git@TROVEHOST/fudge/%s#ssh://git@TROVEHOST/fudge/%s" +if test "x$fudge_alias" != "x$desired_fudge"; then + echo >&2 "Fudge alias was '$fudge_alias' where we wanted '$desired_fudge'" +fi |