~dobey/ubuntuone-client/py-only

« back to all changes in this revision

Viewing changes to setup.py

  • Committer: Rodney Dawes
  • Date: 2013-06-07 15:22:31 UTC
  • Revision ID: rodney.dawes@canonical.com-20130607152231-7b3wd88vfk3lcbp0
Convert build system from autotools to DistUtilsExtra

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/python
 
2
#
 
3
# Copyright 2013 Canonical Ltd.
 
4
#
 
5
# This program is free software: you can redistribute it and/or modify it
 
6
# under the terms of the GNU General Public License version 3, as published
 
7
# by the Free Software Foundation.
 
8
#
 
9
# This program is distributed in the hope that it will be useful, but
 
10
# WITHOUT ANY WARRANTY; without even the implied warranties of
 
11
# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
 
12
# PURPOSE.  See the GNU General Public License for more details.
 
13
#
 
14
# You should have received a copy of the GNU General Public License along
 
15
# with this program.  If not, see <http://www.gnu.org/licenses/>.
 
16
#
 
17
# In addition, as a special exception, the copyright holders give
 
18
# permission to link the code of portions of this program with the
 
19
# OpenSSL library under certain conditions as described in each
 
20
# individual source file, and distribute linked combinations
 
21
# including the two.
 
22
# You must obey the GNU General Public License in all respects
 
23
# for all of the code used other than OpenSSL.  If you modify
 
24
# file(s) with this exception, you may extend this exception to your
 
25
# version of the file(s), but you are not obligated to do so.  If you
 
26
# do not wish to do so, delete this exception statement from your
 
27
# version.  If you delete this exception statement from all source
 
28
# files in the program, then also delete it here.
 
29
"""Setup.py: build, distribute, clean."""
 
30
 
 
31
import os
 
32
import sys
 
33
 
 
34
try:
 
35
    import DistUtilsExtra.auto
 
36
    from DistUtilsExtra.command import build_extra, build_i18n
 
37
except ImportError:
 
38
    print >> sys.stderr, 'To build this program you need '\
 
39
                         'https://launchpad.net/python-distutils-extra'
 
40
    sys.exit(1)
 
41
assert DistUtilsExtra.auto.__version__ >= '2.18', \
 
42
    'needs DistUtilsExtra.auto >= 2.18'
 
43
 
 
44
try:
 
45
    from setuptools import find_packages
 
46
except ImportError:
 
47
    from distutils.core import find_packages
 
48
 
 
49
 
 
50
PROJECT_NAME = 'ubuntuone-client'
 
51
VERSION = '13.05'
 
52
 
 
53
POT_FILE = 'po/%s.pot' % PROJECT_NAME
 
54
SERVICE_FILES = ['data/com.ubuntuone.Credentials.service',
 
55
                 'data/com.ubuntuone.SyncDaemon.service']
 
56
CONFIG_FILES = ['data/logging.conf']
 
57
CLIENTDEFS = 'ubuntuone/clientdefs.py'
 
58
 
 
59
BUILD_FILES = [CLIENTDEFS] + CONFIG_FILES
 
60
CLEANFILES = [POT_FILE, 'MANIFEST'] + BUILD_FILES + SERVICE_FILES
 
61
 
 
62
if int(VERSION.split('.')[1]) % 2 != 0:
 
63
    LOG_LEVEL = 'DEBUG'
 
64
    LOG_FILE_SIZE = '10485760'
 
65
else:
 
66
    LOG_LEVEL = 'INFO'
 
67
    LOG_FILE_SIZE = '1048576'
 
68
 
 
69
 
 
70
def replace_variables(files_to_replace, prefix=None, *args, **kwargs):
 
71
    """Replace the @VERSION@ in the constants file with the actual version."""
 
72
    for fname in files_to_replace:
 
73
        with open(fname + '.in') as in_file:
 
74
            content = in_file.read()
 
75
            with open(fname, 'w') as out_file:
 
76
                content = content.replace('@VERSION@', VERSION)
 
77
                content = content.replace('@PROJECT_NAME@', PROJECT_NAME)
 
78
                content = content.replace('@GETTEXT_PACKAGE@', PROJECT_NAME)
 
79
                content = content.replace('@LOG_LEVEL@', LOG_LEVEL)
 
80
                content = content.replace('@LOG_FILE_SIZE@', LOG_FILE_SIZE)
 
81
                if prefix is not None:
 
82
                    content = content.replace(
 
83
                        '@localedir@', os.path.join(prefix,
 
84
                                                    'share', 'locale'))
 
85
                    content = content.replace(
 
86
                        '@libexecdir@', os.path.join(prefix,
 
87
                                                     'lib', PROJECT_NAME))
 
88
                out_file.write(content)
 
89
 
 
90
 
 
91
class Install(DistUtilsExtra.auto.install_auto):
 
92
    """Class to install proper files."""
 
93
 
 
94
    def run(self):
 
95
        """Do the install.
 
96
 
 
97
        Read from *.service.in and generate .service files by replacing
 
98
        @prefix@ by self.prefix.
 
99
 
 
100
        """
 
101
        # Get just the prefix value, without the root
 
102
        prefix = self.install_data.replace(
 
103
            self.root if self.root is not None else '', '')
 
104
        replace_variables(SERVICE_FILES, prefix)
 
105
        DistUtilsExtra.auto.install_auto.run(self)
 
106
        # Replace the CLIENTDEFS paths here, so that we can do it directly in
 
107
        # the installed copy, rather than the lcoal copy. This allows us to
 
108
        # have a semi-generated version for use in tests, and a full version
 
109
        # for use in installed systems.
 
110
        with open(CLIENTDEFS) as in_file:
 
111
            content = in_file.read()
 
112
            with open(os.path.join(self.install_purelib,
 
113
                                   PROJECT_NAME,
 
114
                                   CLIENTDEFS), 'w') as out_file:
 
115
                content = content.replace(
 
116
                    '@localedir@', os.path.join(prefix, 'share', 'locale'))
 
117
                content = content.replace(
 
118
                    '@libexecdir@', os.path.join(prefix, 'lib', PROJECT_NAME))
 
119
                out_file.write(content)
 
120
 
 
121
 
 
122
class Build(build_extra.build_extra):
 
123
    """Build PyQt (.ui) files and resources."""
 
124
 
 
125
    description = "build PyQt GUIs (.ui) and resources (.qrc)"
 
126
 
 
127
    def run(self):
 
128
        """Execute the command."""
 
129
        replace_variables(BUILD_FILES)
 
130
        build_extra.build_extra.run(self)
 
131
 
 
132
 
 
133
class Clean(DistUtilsExtra.auto.clean_build_tree):
 
134
    """Class to clean up after the build."""
 
135
 
 
136
    def run(self):
 
137
        """Clean up the built files."""
 
138
        for built_file in CLEANFILES:
 
139
            if os.path.exists(built_file):
 
140
                os.unlink(built_file)
 
141
 
 
142
        DistUtilsExtra.auto.clean_build_tree.run(self)
 
143
 
 
144
 
 
145
class BuildLocale(build_i18n.build_i18n):
 
146
    """Workaround a bug in DistUtilsExtra."""
 
147
 
 
148
    def run(self):
 
149
        """Magic."""
 
150
        build_i18n.build_i18n.run(self)
 
151
        i = 0
 
152
        for df in self.distribution.data_files:
 
153
            if df[0].startswith('etc/xdg/'):
 
154
                new_df = (df[0].replace('etc/xdg/', '/etc/xdg/'), df[1])
 
155
                self.distribution.data_files[i] = new_df
 
156
            i += 1
 
157
 
 
158
 
 
159
def set_py2exe_paths():
 
160
    """Set the path so that py2exe finds the required modules."""
 
161
    # Pylint does not understand same spaced imports
 
162
    # pylint: disable=F0401
 
163
    import win32com
 
164
    # pylint: enable=F0401
 
165
    try:
 
166
        # pylint: disable=F0401
 
167
        import py2exe.mf as modulefinder
 
168
        # pylint: enable=F0401
 
169
    except ImportError:
 
170
        import modulefinder
 
171
 
 
172
    # py2exe 0.6.4 introduced a replacement modulefinder.
 
173
    # This means we have to add package paths there,
 
174
    # not to the built-in one.  If this new modulefinder gets
 
175
    # integrated into Python, then we might be able to revert
 
176
    # this some day. If this doesn't work, try import modulefinder
 
177
    for package_path in win32com.__path__[1:]:
 
178
        modulefinder.AddPackagePath("win32com", package_path)
 
179
    for extra_mod in ["win32com.server", "win32com.client"]:
 
180
        __import__(extra_mod)
 
181
        module = sys.modules[extra_mod]
 
182
        for module_path in module.__path__[1:]:
 
183
            modulefinder.AddPackagePath(extra_mod, module_path)
 
184
 
 
185
 
 
186
# pylint: disable=C0103
 
187
 
 
188
cmdclass = {
 
189
    'install': Install,
 
190
    'build': Build,
 
191
    'clean': Clean,
 
192
    'build_i18n': BuildLocale,
 
193
}
 
194
 
 
195
bin_scripts = [
 
196
    'bin/u1sdtool',
 
197
    'bin/ubuntuone-launch',
 
198
]
 
199
 
 
200
libexec_scripts = [
 
201
    'bin/ubuntuone-login',
 
202
    'bin/ubuntuone-proxy-tunnel',
 
203
    'bin/ubuntuone-syncdaemon',
 
204
]
 
205
 
 
206
data_files = []
 
207
scripts = []
 
208
 
 
209
if sys.platform == 'win32':
 
210
    set_py2exe_paths()
 
211
    extra = {
 
212
        'options': {
 
213
            'py2exe': {
 
214
                'bundle_files': 1,
 
215
                'skip_archive': 0,
 
216
                'optimize': 1,
 
217
                'dll_excludes': ["mswsock.dll", "powrprof.dll"],
 
218
            },
 
219
        },
 
220
        # add the console script so that py2exe compiles it
 
221
        'console': bin_scripts + libexec_scripts,
 
222
        'zipfile': None,
 
223
    }
 
224
else:
 
225
    data_files.extend([
 
226
        ('lib/%s' % PROJECT_NAME, libexec_scripts),
 
227
        ('share/dbus-1/services', SERVICE_FILES),
 
228
        ('/etc/xdg/ubuntuone', CONFIG_FILES + ['data/syncdaemon.conf']),
 
229
        ('/etc/apport/crashdb.conf.d', ['data/ubuntuone-client-crashdb.conf']),
 
230
        ('share/apport/package-hooks', ['data/source_ubuntuone-client.py']),
 
231
        ('share/man1', ['docs/man/u1sdtool.1']),
 
232
    ])
 
233
    scripts.extend(bin_scripts)
 
234
    extra = {}
 
235
 
 
236
DistUtilsExtra.auto.setup(
 
237
    name=PROJECT_NAME,
 
238
    version=VERSION,
 
239
    license='GPL v3',
 
240
    author='Ubuntu One Developers',
 
241
    author_email='ubuntuone-users@lists.launchpad.net',
 
242
    description='Ubuntu One file synchronization client',
 
243
    url='https://launchpad.net/%s' % PROJECT_NAME,
 
244
    extra_path=PROJECT_NAME,
 
245
    scripts=scripts,
 
246
    data_files=data_files,
 
247
    packages=find_packages(),
 
248
    cmdclass=cmdclass,
 
249
    **extra)