Better error reason "Not source code"
[zeroinstall/solver.git] / setup.py
blob81d4162b31a0d206bf869bc2fce07c5fdb33d7c9
1 from distutils.core import setup
2 from distutils.util import convert_path
3 from distutils.core import Command
4 from distutils.command.build_py import build_py
5 from distutils.command.install import install
6 from distutils.command.install_lib import install_lib
7 from distutils.command.install_data import install_data
8 import os, subprocess, sys
9 import glob
10 import zeroinstall
12 class adjust_scripts_for_home(Command):
13 """setup.py install --home puts libraries in ~/lib/python, but Python doesn't look there.
14 If we're installing with --home, modify the scripts to add this to sys.path.
15 Don't do this otherwise; the system copy mustn't conflict with the copy in $HOME.
16 """
17 description = "(used internally when using --home)"
19 user_options = [
20 ('scripts-dir=', 'd', "directory to install scripts to"),
21 ('lib-dir=', 'd', "directory libraries install to"),
24 def initialize_options (self):
25 self.scripts_dir = None
26 self.lib_dir = None
28 def finalize_options (self):
29 self.set_undefined_options('install',
30 ('install_scripts', 'scripts_dir'),
31 ('install_lib', 'lib_dir'),
34 def run(self):
35 for script in self.distribution.scripts:
36 outfile = os.path.join(self.scripts_dir, os.path.basename(script))
38 stream = open(outfile)
39 code = stream.read()
40 stream.close()
42 code = code.replace('## PATH ##', '''
43 import os, sys
44 sys.path.insert(0, %s)''' % repr(self.lib_dir))
45 stream = open(outfile, 'w')
46 stream.write(code)
47 stream.close()
49 class build_with_data(build_py):
50 """Python < 2.4 doesn't support package_data_files, so add it manually."""
51 package_data_files = [
52 "zeroinstall/0launch-gui/README",
53 "zeroinstall/0launch-gui/0launch-gui",
54 "zeroinstall/0launch-gui/zero-install.ui",
55 "zeroinstall/gtkui/desktop.ui",
56 "zeroinstall/gtkui/cache.ui",
57 "zeroinstall/injector/EquifaxSecureCA.crt",
58 "zeroinstall/zerostore/_unlzma",
60 def run(self):
61 # Copy .py files and build, as usual
62 build_py.run(self)
63 # Copy data files
64 for data_file in self.package_data_files:
65 outfile = os.path.join(self.build_lib, data_file)
66 self.copy_file(data_file, outfile, preserve_mode=0)
67 executable = (os.stat(data_file).st_mode & 0111) != 0
68 if executable:
69 os.chmod(outfile, os.stat(outfile).st_mode | 0111)
71 class install_lib_exec(install_lib):
72 def run(self):
73 install_lib.run(self) # super.run()
74 if os.name != 'posix': return
76 launch = os.path.join(self.install_dir, 'zeroinstall/0launch-gui/0launch-gui')
77 os.chmod(launch, os.stat(launch).st_mode | 0111)
79 class install_data_locale(install_data):
80 def run(self):
81 self.data_files.extend(self._compile_po_files())
82 install_data.run(self) # super.run()
84 def _compile_po_files(self):
85 i18nfiles = []
86 mo_pattern = "share/locale/*/LC_MESSAGES/zero-install.mo"
87 mo_files = glob.glob(mo_pattern)
88 if not mo_files:
89 print "No translations (Git checkout?)... trying to build them..."
90 subprocess.check_call(["make", "translations"])
91 mo_files = glob.glob(mo_pattern)
92 assert mo_files
93 for mo in mo_files:
94 dest = os.path.dirname(mo)
95 i18nfiles.append((dest, [mo]))
96 return i18nfiles
98 # distutils doesn't seem to have any support for adding configuration files.
99 # Unfortunately, the freedesktop.org menu spec strangely defines part of the
100 # menu definitions as configuration.
101 class my_install(install):
102 def finalize_options(self):
103 install.finalize_options(self) # super.finalize_options()
104 if self.home:
105 self.__config_dir = os.path.join(self.home, '.config')
106 elif self.prefix == '/usr':
107 self.__config_dir = os.path.join(self.root or '/', 'etc/xdg')
108 else:
109 self.__config_dir = os.path.join(self.root or '/', self.prefix[1:], 'etc/xdg')
111 def run(self):
112 install.run(self) # super.run()
113 menus_dir = os.path.join(self.__config_dir, 'menus/applications-merged')
114 self.mkpath(menus_dir)
115 menu = convert_path('share/applications/zeroinstall.menu')
116 self.copy_file(menu, menus_dir)
118 if self.home:
119 self.run_command('adjust_scripts_for_home')
121 setup(name="zeroinstall-injector",
122 version=zeroinstall.version,
123 description="The Zero Install Injector (0launch)",
124 author="Thomas Leonard",
125 author_email="zero-install-devel@lists.sourceforge.net",
126 url="http://0install.net",
127 scripts=['0launch', '0alias', '0store', '0store-secure-add', '0desktop', '0install'],
128 data_files = [('man/man1', ['0launch.1', '0alias.1', '0store-secure-add.1', '0store.1', '0desktop.1', '0install.1']),
129 ('share/applications', ['share/applications/zeroinstall-add.desktop', 'share/applications/zeroinstall-manage.desktop']),
130 ('share/desktop-directories', ['share/desktop-directories/zeroinstall.directory']),
131 ('share/icons/hicolor/24x24/apps', ['share/icons/24x24/zeroinstall.png']),
132 ('share/icons/hicolor/48x48/apps', ['share/icons/48x48/zeroinstall.png']),
133 ('share/icons/hicolor/128x128/apps', ['share/icons/128x128/zeroinstall.png']),
134 ('share/icons/hicolor/scalable/apps', ['share/icons/scalable/zeroinstall.svg'])],
135 license='LGPL',
136 cmdclass={
137 'build_py': build_with_data,
138 'install_lib': install_lib_exec,
139 'install_data': install_data_locale,
140 'adjust_scripts_for_home': adjust_scripts_for_home,
141 'install': my_install,
143 long_description="""\
144 A running process is created by combining many different libraries (and other
145 components). In the Zero Install world, we have all versions of each library
146 available at all times. The problem then is how to choose which versions to
147 use.
149 The injector solves this problem by selecting components to meet a program's
150 requirements, according to a policy you give it. The injector finds out which
151 versions are available, and downloads and runs the ones you choose.""",
152 packages=["zeroinstall", "zeroinstall.support", "zeroinstall.zerostore", "zeroinstall.injector", "zeroinstall.0launch-gui", "zeroinstall.gtkui", "zeroinstall.cmd"])