diff options
Diffstat (limited to 'lorrycontroller')
-rw-r--r-- | lorrycontroller/givemejob.py | 91 |
1 files changed, 89 insertions, 2 deletions
diff --git a/lorrycontroller/givemejob.py b/lorrycontroller/givemejob.py index 721b55e..ee998ea 100644 --- a/lorrycontroller/givemejob.py +++ b/lorrycontroller/givemejob.py @@ -13,10 +13,13 @@ # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - +import json import logging +import re +import urllib.parse import bottle +import cliapp import lorrycontroller @@ -80,6 +83,90 @@ class GiveMeJob(lorrycontroller.LorryControllerRoute): return lorrycontroller.get_upstream_host(host_info) \ .get_repo_metadata(lorry_info['from_path']) + @staticmethod + def get_single_repo_metadata(lorry_info): + assert not lorry_info['from_host'] + + lorry_dict = json.loads(lorry_info['text']) + _, upstream_config = lorry_dict.popitem() + upstream_type = upstream_config['type'] + + # Get the repository URL + url = None + try: + url = upstream_config['url'].strip() + except KeyError: + if upstream_type == 'bzr': + try: + url = upstream_config['branches']['trunk'].strip() + except KeyError: + pass + + # Extract the host-name and repo path + host_name, repo_path = None, None + if url: + # Handle pseudo-URLs + if upstream_type == 'bzr': + if url.startswith('lp:'): + host_name = 'launchpad.net' + repo_path = url[3:] + elif upstream_type == 'cvs': + # :pserver:user@host:/path, user@host:/path, etc. + match = re.match(r'^(?::[^:@/]+:)?(?:[^:@/]+@)?([^:@/]+):/', + url) + if match: + host_name = match.group(1) + repo_path = url[match.end():].rstrip('/') + elif upstream_type == 'git': + # user@host:path, host:path. Path must not start with + # '//' as that indicates a real URL. + match = re.match(r'^(?:[^:@/]+@)?([^:@/]+):(?!//)', url) + if match: + host_name = match.group(1) + repo_path = url[match.end():].strip('/') + + # Default to parsing as a real URL + if not host_name: + try: + url_obj = urllib.parse.urlparse(url) + except ValueError: + pass + else: + host_name = url_obj.hostname + repo_path = url_obj.path.strip('/') + + metadata = {} + + # Determine the default branch + if upstream_type == 'bzr': + # Default in Bazaar is 'trunk' and we don't remap it + metadata['head'] = 'trunk' + elif upstream_type == 'git': + if url: + # Query the remote to find its default + try: + output = cliapp.runcmd(['git', 'ls-remote', '--symref', + '--', url, 'HEAD']) \ + .decode('utf-8', errors='replace') + match = re.match(r'^ref: refs/heads/([^\s]+)\tHEAD\n', + output) + if match: + metadata['head'] = match.group(1) + except cliapp.AppException: + pass + else: + # We currently produce 'master' for all other types + metadata['head'] = 'master' + + # Use description from .lorry file, or repository name + try: + metadata['description'] = upstream_config['description'] + except KeyError: + if repo_path: + metadata['description'] = repo_path + + return host_name, metadata + def get_repo_metadata(self, statedb, lorry_info): '''Get repository head and description.''' @@ -87,7 +174,7 @@ class GiveMeJob(lorrycontroller.LorryControllerRoute): if host_name: metadata = self.get_upstream_host_repo_metadata(lorry_info) else: - metadata = {} + host_name, metadata = self.get_single_repo_metadata(lorry_info) if host_name and 'description' in metadata: # Prepend Upstream Host name |