aboutsummaryrefslogtreecommitdiff
path: root/merge-fragments.py
blob: a6c9e6b1bbfdf0a4880d5544a51e831478e00d40 (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
119
120
121
#!/usr/bin/python

from optparse import OptionParser
import json
import logging
import os
import re
import sys
import urllib2

log = logging.getLogger("jsonmerge")
log.setLevel(logging.DEBUG)
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s [%(levelname)s] %(message)s')
ch.setFormatter(formatter)
log.addHandler(ch)


def download_custom_json(url, auth=None):
    request = urllib2.Request(url)
    if auth:
        request.add_header('Authorization', auth)
    try:
        response = urllib2.urlopen(request)
    except urllib2.URLError, e:
        if hasattr(e, 'reason'):
            log.error('Failed to reach %s.' % url)
            log.error('Reason: ', e.reason)
        elif hasattr(e, 'code'):
            log.error('ci.linaro.org could not fulfill the request: %s' % \
                  url)
            log.error('Error code: ', e.code)
        sys.exit('Failed to get last successful artifact.')
    return response.read()


def substitute_template_variables(template, environ):
    """ Env variable names for substitution
        have to start with SUB_
        Template variables are marked with
        %%VARIABLE%%
        Variable names need to be uppercase
    """
    sub_expr = re.compile("%%(?P<variable>[_A-Z]+)%%")
    for var in sub_expr.finditer(template):
        var_name = var.group('variable')
        log.debug("Substituting: SUB_%s" % (var_name))
        var_value = environ.get("SUB_%s" % var_name)
        if var_value:
            template = template.replace(var.group(0), var_value)
        else:
            log.error("Variable SUB_%s is not set" % (var_name))
            sys.exit("Failed to create valid JSON")
    return template


def main():
    usage = "usage: %prog [OPTIONS]"
    parser = OptionParser(usage=usage)
    parser.add_option("-e", "--environment", dest="environ",
                  help="Environment variable for running script")
    parser.add_option("-m", "--metadata", dest="metadata",
                  help="Metadata in JSON format \
                        to be placed in the output definition")
    parser.add_option("-i", "--input", dest="input_file",
                  help="Input template JSON file")
    parser.add_option("-o", "--output", dest="output",
                  help="Output file to store JSON")
    (options, args) = parser.parse_args()

    if options.environ:
        f = open(options.environ, "r")
        for line in f.readlines():
            split_result = line.split("=", 1)
            if len(split_result) > 1:
                os.environ[split_result[0]] = split_result[1].strip()
        f.close()

    if not options.input_file:
        parser.error("Unable to construct job definition \
                      without the template")

    config_tmpl = open(options.input_file, "r")
    config = substitute_template_variables(config_tmpl.read(), os.environ)
    config_tmpl.close()
    json_config = json.loads(config)

    metadata_json = None
    if options.metadata:
        f = open(options.metadata, "r")
        metadata = f.read()
        try:
            metadata_json = json.loads(metadata)
        except:
            log.error("Unable to parse metadata file")

    metadata_url = os.environ.get("METADATA_URL", None)
    if metadata_url:
        metadata = download_custom_json(metadata_url)
        try:
            metadata_json = json.loads(metadata)
        except:
            log.error("Unable to parse metadata URL")

    if metadata_json:
        if 'metadata' in json_config['actions'][0]:
            json_config['actions'][0]['metadata'].update(metadata_json)
        else:
            json_config['actions'][0]['metadata'] = metadata_json

    if options.output:
        f = open(options.output, "w")
        f.write(json.dumps(json_config, indent=2))
        f.close()
    else:
        print json.dumps(json_config, indent=2)


if __name__ == '__main__':
    main()