summaryrefslogtreecommitdiffstats
path: root/rpmci/artifact.py
blob: 13841adfc22f3a0ede4239d33683471124ecdd99 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#!/usr/bin/python

# artifact.py:
# Set of RPMs built into a repository.
#
# Licensed under the new-BSD license (http://www.opensource.org/licenses/bsd-license.php)
# Copyright (C) 2010 Red Hat, Inc.
# Written by Colin Walters <walters@verbum.org>

import os
import sys
import urllib
import ConfigParser

from . import spec

FEDORA_ANONGIT_URL = 'git:git://pkgs.fedoraproject.org'

def get_default_architectures():
    # There's probably some RPM thingy to find this
    uname = os.uname()
    arch = uname[-1]
    if arch == 'x86_64':
        # On x86_64, we can build both
        return ('i686', 'x86_64')
    elif arch == 'i686':
        # 32 bit can only build itself
        return 'i686'
    raise SystemExit("Unhandled architecture %r from os.uname(), known=[x86_64, i686]" % (arch, ))

class BuildTarget(object):
    def __init__(self, module, os, architecture):
        self.module = module
        self.os = os
        self.architecture = architecture

    def __cmp__(self, other):
        i = cmp(self.module, other.module)
        if i != 0:
            return i
        i = cmp(self.os, other.os)
        if i != 0:
            return i
        i = cmp(self.architecture, other.architecture)
        if i != 0:
            return i
        return 0

class Artifact(object):
    def __init__(self, targets):
        self.targets = targets 

class ArtifactSet(object):
    def __init__(self, artifacts):
        self.artifacts = artifacts

    def get_build_targets(self):
        """Returns unordered set of build targets."""
        
        targets = set()
        for artifact in self.artifacts:
            for target in artifact.targets:
                targets.add(target)
        return targets

    @classmethod
    def from_config(cls, config):
        section = 'releases'
        artifacts_str = config.get(section, 'artifacts')
        artifact_list = map(str.strip, artifacts_str.split(' '))
        artifacts = []
        
        for artifact_name in artifact_list:
            artifact_build_targets = []

            config_name = artifact_name.replace('-', '_')

            modules = config.get(section, 'artifact_%s_modules' % (config_name, )).split(' ')
            modules = map(str.strip, modules)
            os = config.get(section, 'artifact_%s_os' % (config_name, ))
            try: 
                architectures = config.get(section, 'artifact_%s_architectures' % (config_name, )).split(' ')
            except ConfigParser.NoOptionError, e:
                architectures = get_default_architectures()
            architectures = map(str.strip, architectures)
            
            for module in modules:
                for architecture in architectures:
                    target = BuildTarget(module, os, architecture)
                    artifact_build_targets.append(target)

            artifacts.append(Artifact(artifact_build_targets))
        return cls(artifacts)

def fedora_git_url_for_build_target(config, buildtarget):
    fedora_os_master = config.get('fedora', 'master')
    base = '%s/%s.git' % (FEDORA_ANONGIT_URL, buildtarget.module)
    if buildtarget.os == fedora_os_master:
        return base
    else:
        return '%s#%s/master' % (base, buildtarget.os)

def upstream_vcs_url_for_build_target(config, buildtarget):
    fedora_url = fedora_git_url_for_build_target(config, buildtarget)
    escaped_url = urllib.quote(fedora_url, '')
    mirror_dir = config.get('VCS', 'mirror_dir')
    vcsdir = os.path.join(mirror_dir, escaped_url)
    if not os.path.isdir(vcsdir):
        raise SystemExit("Not a directory: %r" % (vcsdir, ))
    specpath = None
    for filename in os.listdir(vcsdir):
        if filename.endswith('.spec'):
            specpath = os.path.join(vcsdir, filename)
            break
    assert specpath is not None
    spec_obj = spec.Spec(specpath)
    return spec_obj.get_vcs()