~dhananjaysathe/nuvola-player/TelepathyExt

« back to all changes in this revision

Viewing changes to wafextras.py

  • Committer: Jiří Janoušek
  • Date: 2012-07-14 21:23:34 UTC
  • Revision ID: janousek.jiri@gmail.com-20120714212334-4oow3eufqbw0rdme
Build script refactoring with a breakage.

 * More `./waf configure` options, type `./waf --help`
   or `./waf features` for details.
 * All fetures are enabled by default, some of them can
   be disabled if it is not possible to satisfy all
   dependencies. See INSTALL.
 * Removed README.Ubuntu and README.Fedora.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/python2
 
2
# encoding: utf-8
 
3
# License: GNU GPL 3
 
4
# Copyright 2011, 2012 Jiří Janoušek <janousek.jiri@gmail.com>
 
5
 
 
6
# Extra functions for wscript file
 
7
 
 
8
import os
 
9
from waflib.Configure import conf
 
10
from waflib.Errors import ConfigurationError 
 
11
 
 
12
class Flags(object):
 
13
        """Class that manage extra configure flags."""
 
14
        def __init__(self):
 
15
                self.flags = []
 
16
                self.flags_with_requires = []
 
17
                self.deps = {}
 
18
        
 
19
        def _requires_string(self, requires):
 
20
                result = []
 
21
                for key, value in requires.iteritems():
 
22
                        result.append(self._dep_key(key, value))
 
23
                        result.append(", ")
 
24
                result = result[:-1]
 
25
                if len(result) >= 3:
 
26
                        result[-2] = " and "
 
27
                return "".join(result)
 
28
        
 
29
        def add(self, id, name, default, requires=None, vala_def=None):
 
30
                """Adds a new flag."""
 
31
                flag = (id, name, default, requires, vala_def)
 
32
                self.flags.append(flag)
 
33
                if requires:
 
34
                        self.flags_with_requires.append(flag)
 
35
                        self._add_dep(flag)
 
36
        
 
37
        def _dep_key(self, name, version):
 
38
                if version:
 
39
                        return "%s >= %s" % (name, version)
 
40
                else:
 
41
                        return name
 
42
        
 
43
        def _add_dep(self, flag):
 
44
                id, name, default, requires, vala_def = flag
 
45
                for key, value in requires.iteritems():
 
46
                        key = self._dep_key(key, value)
 
47
                        try:
 
48
                                self.deps[key].append(flag)
 
49
                        except KeyError, e:
 
50
                                self.deps[key] = [flag]
 
51
        
 
52
        def add_options(self, ctx):
 
53
                """Adds flags to the options context."""
 
54
                for id, name, default, requires, vala_def in self.flags:
 
55
                        if default:
 
56
                                help_true = "Build with %s (default)." % name
 
57
                                help_false = "Build without %s." % name
 
58
                        else:
 
59
                                help_true = "Build with %s." % name
 
60
                                help_false = "Build without %s (default)." % name
 
61
                        if requires:
 
62
                                        help_true += " Requires %s." % self._requires_string(requires)
 
63
                        ctx.add_option("--" + id.replace("_", "-"), action='store_true', dest=id, help=help_true, default=default)
 
64
                        ctx.add_option("--no-" + id.replace("_", "-"), action='store_false', dest=id, help=help_false)
 
65
        
 
66
        def store_result(self, ctx):
 
67
                """Stores status of a feature to ctx.env.feature_<id> and appends Vala definitions"""
 
68
                for id, name, default, requires, vala_def in self.flags:
 
69
                        if getattr(ctx.options, id):
 
70
                                if vala_def is True:
 
71
                                        ctx.vala_def(id.upper())
 
72
                                elif vala_def:
 
73
                                        ctx.vala_def(vala_def)
 
74
                                ctx.env["feature_" + id] = True
 
75
                        else:
 
76
                                ctx.env["feature_" + id] = False
 
77
        
 
78
        def print_restrictive(self, ctx, message):
 
79
                """Prints message and list of flags with non-empty 'requires' field"""
 
80
                if self.flags_with_requires:
 
81
                        print "\n", message
 
82
                for id, name, default, requires, vala_def in self.flags_with_requires:
 
83
                        if getattr(ctx.options, id):
 
84
                                print " * Feature %s requires %s.\n   You can disable it by a flag --no-%s." % (name, self._requires_string(requires), id.replace("_", "-"))
 
85
        
 
86
        def get_feature_for_dep(self, ctx, dep_name, dep_version=None):
 
87
                """Returns information about features that require particular dependency."""
 
88
                flags = self.deps.get(self._dep_key(dep_name, dep_version), None)
 
89
                if(flags):
 
90
                        for id, name, default, requires, vala_def in flags:
 
91
                                if getattr(ctx.options, id):
 
92
                                        yield "Feature %s requires %s.\n   You can disable it by a flag --no-%s." % (name, self._requires_string(requires), id.replace("_", "-"))
 
93
        
 
94
        def print_info(self):
 
95
                """Prints features and their flags"""
 
96
                print "Use `./waf configure --feature` to turn the feature on."
 
97
                print "Use `./waf configure --no-feature` to turn the feature off."
 
98
                print
 
99
                print "Available features: \n"
 
100
                for id, name, default, requires, vala_def in self.flags:
 
101
                        if default:
 
102
                                help_true = "Build with %s (default)." % name
 
103
                                help_false = "Build without %s." % name
 
104
                        else:
 
105
                                help_true = "Build with %s." % name
 
106
                                help_false = "Build without %s (default)." % name
 
107
                        if requires:
 
108
                                        help_true += " Requires %s." % self._requires_string(requires)
 
109
                        print "--" + id.replace("_", "-")
 
110
                        print "\t" + help_true
 
111
                        print "--no-" + id.replace("_", "-")
 
112
                        print "\t" + help_false
 
113
        
 
114
        def print_summary(self, ctx):
 
115
                """Prints status of features"""
 
116
                print
 
117
                print "Features: \n"
 
118
                for id, name, default, requires, vala_def in self.flags:
 
119
                        if getattr(ctx.options, id):
 
120
                                ctx.msg(name, "ON", "GREEN")
 
121
                        else:
 
122
                                ctx.msg(name, "OFF", "RED")
 
123
 
 
124
flags = Flags()
 
125
 
 
126
@conf
 
127
def vala_def(ctx, vala_definition):
 
128
        """Appends a Vala definition"""
 
129
        if not hasattr(ctx.env, "VALA_DEFINES"):
 
130
                ctx.env.VALA_DEFINES = []
 
131
        if isinstance(vala_def, tuple) or isinstance(vala_def, list):
 
132
                for d in vala_definition:
 
133
                        ctx.env.VALA_DEFINES.append(d)
 
134
        else:
 
135
                ctx.env.VALA_DEFINES.append(vala_definition)
 
136
 
 
137
@conf
 
138
def check_dep(ctx, pkg, uselib, version, mandatory=True, store=None, vala_def=None, define=None):
 
139
        """Wrapper for ctx.check_cfg that stores errors instead of termination of the script."""
 
140
        result = True
 
141
        try:
 
142
                ctx.check_cfg(package=pkg, uselib_store=uselib, atleast_version=version, mandatory=True, args = '--cflags --libs')
 
143
                if vala_def:
 
144
                        ctx.vala_def(vala_def)
 
145
                if define:
 
146
                        for key, value in define.iteritems():
 
147
                                ctx.define(key, value)
 
148
        except ConfigurationError, e:
 
149
                if mandatory:
 
150
                        fail = "Unable to satisfy dependency %s >= %s" % (pkg, version)
 
151
                        ctx.append_error(fail)
 
152
                        for fail in flags.get_feature_for_dep(ctx, pkg, version):
 
153
                                ctx.append_error(fail)
 
154
                result = False
 
155
        if store is not None:
 
156
                ctx.env[store] = result
 
157
        return result
 
158
 
 
159
@conf
 
160
def check_prog(ctx, name, mandatory=True):
 
161
        """Wrapper for ctx.find_program that stores errors instead of termination of the script."""
 
162
        try:
 
163
                ctx.find_program(name, mandatory=True)
 
164
                return True
 
165
        except ConfigurationError:
 
166
                if mandatory:
 
167
                        ctx.append_error("Unable to find program '%s'" % name)
 
168
                        for fail in flags.get_feature_for_dep(ctx, name):
 
169
                                ctx.append_error(fail)
 
170
                return False
 
171
 
 
172
@conf
 
173
def append_error(ctx, fail):
 
174
        """Appends error message"""
 
175
        try:
 
176
                ctx.conf_errors.append(fail)
 
177
        except AttributeError:
 
178
                ctx.conf_errors = [fail]
 
179
 
 
180
@conf
 
181
def check_status(ctx,):
 
182
        """Checks status of configuration. Lists errors and terminates script if there are any errors."""
 
183
        try:
 
184
                errors = ctx.conf_errors
 
185
        except AttributeError, e:
 
186
                errors = None
 
187
        if errors:
 
188
                ctx.msg("Configuration status", "FAIL", "RED")
 
189
                print
 
190
                for error in errors:
 
191
                        print " *", error
 
192
                print
 
193
                ctx.fatal("Configuration failed. Please read file INSTALL for details about dependencies.")
 
194
        else:
 
195
                ctx.msg("Configuration status", "OK", "GREEN")
 
196
 
 
197
 
 
198
 
 
199
 
 
200
def parse_version(version):
 
201
        """Parses version string and returns SERIES, MAJOR, MINOR, BUGFIX, SUFFIX, DEV_STAGE"""
 
202
        import re
 
203
        m = re.match("^(\d+)\.(\d+)(?:\.(\d+))?(?:\~(unstable|beta\d+))?$", version)
 
204
        if not m:
 
205
                raise ValueError("VERSION '%s' doesn't match regular expression" % version)
 
206
        parts = m.groups()
 
207
        if "alpha" in version or "unstable" in version:
 
208
                dev_stage = "unstable"
 
209
        elif "beta" in version:
 
210
                dev_stage = "beta"
 
211
        else:
 
212
                dev_stage = "stable"
 
213
        return (parts[0] + "." + parts[1], int(parts[0] or 0), int(parts[1] or 0),
 
214
                        int(parts[2] or 0), parts[3] or "", dev_stage)
 
215
 
 
216
def get_revision():
 
217
        """Looks for Bazaar revision information, returns REVISION, REVISION_ID"""
 
218
        REVISION = ""
 
219
        REVISION_ID = ""
 
220
        try:
 
221
                try:
 
222
                        num, id = open(".bzr/branch/last-revision").read().split(" ")
 
223
                        REVISION = str(int(num))
 
224
                        REVISION_ID = str(id).strip()
 
225
                        ctx.msg("Revision from .bzr", REVISION, "GREEN")
 
226
                except Exception, e:
 
227
                        num, id = open("revision_info").read().split(" ")
 
228
                        REVISION = str(int(num))
 
229
                        REVISION_ID = str(id).strip()
 
230
                        ctx.msg("Revision from revision_info", REVISION, "GREEN")
 
231
        except Exception, e:
 
232
                for item in os.listdir(os.path.abspath("..")):
 
233
                        if not item.endswith(".dsc"):
 
234
                                        continue
 
235
                        for part in item.split("~"):
 
236
                                        if not part.startswith("bzr"):
 
237
                                                        continue
 
238
                                        REVISION = part[3:]
 
239
                                        ctx.msg("Revision from deb build", REVISION, "GREEN")
 
240
                                        break
 
241
                        break
 
242
        
 
243
        return REVISION, REVISION_ID