views.main: Add an 'Unstage' button to the 'Actions' dock widget
[git-cola.git] / setup.py
blob892abd6e85088cb3c2a3842a59769280c65d4217
1 #!/usr/bin/env python
2 import re
3 import os
4 import sys
5 import stat
6 from glob import glob
8 from distutils.core import setup
9 from distutils.command import build_scripts
10 build_scripts.first_line_re = re.compile('^should not match$')
12 from cola import version
13 from cola import utils
14 from cola import resources
15 from cola import core
17 def main():
18 # ensure readable files
19 old_mask = os.umask(0022)
20 git_version = version.git_version()
21 if sys.argv[1] in ['install', 'build']:
22 _setup_environment()
23 _check_python_version()
24 _check_git_version(git_version)
25 _check_pyqt_version()
26 _build_views() # pyuic4: .ui -> .py
27 _build_translations() # msgfmt: .po -> .qm
28 try:
29 version.write_builtin_version()
30 _run_setup(git_version)
31 finally:
32 version.delete_builtin_version()
33 # restore the old mask
34 os.umask(old_mask)
36 def _setup_environment():
37 """Adds win32/ to our path for windows only"""
38 if sys.platform != 'win32':
39 return
40 path = os.environ['PATH']
41 win32 = os.path.join(os.path.dirname(__file__), 'win32')
42 os.environ['PATH'] = win32 + os.pathsep + path
44 def _run_setup(git_version):
45 """Runs distutils.setup()"""
47 scripts = ['bin/git-cola']
49 # git-difftool first moved out of git.git's contrib area in git 1.6.3
50 if (os.environ.get('INSTALL_GIT_DIFFTOOL', '') or
51 not version.check('difftool-builtin', git_version)):
52 scripts.append('bin/difftool/git-difftool')
53 scripts.append('bin/difftool/git-difftool--helper')
55 if sys.platform == 'win32':
56 scripts.append('win32/cola')
57 scripts.append('win32/dirname')
58 scripts.append('win32/py2exe-setup.py')
59 scripts.append('win32/py2exe-setup.cmd')
61 setup(name = 'git-cola',
62 version = version.version(),
63 license = 'GPLv2',
64 author = 'David Aguilar and contributors',
65 author_email = 'davvid@gmail.com',
66 url = 'http://cola.tuxfamily.org/',
67 description = 'git-cola',
68 long_description = 'A highly caffeinated git gui',
69 scripts = scripts,
70 packages = [],
71 data_files = cola_data_files())
74 def cola_data_files():
75 return [_app_path('share/git-cola/qm', '*.qm'),
76 _app_path('share/git-cola/icons', '*.png'),
77 _app_path('share/git-cola/icons', '*.svg'),
78 _app_path('share/git-cola/styles', '*.qss'),
79 _app_path('share/git-cola/styles/images', '*.png'),
80 _app_path('share/applications', '*.desktop'),
81 _app_path('share/doc/git-cola', '*.txt'),
82 _lib_path('cola/*.py'),
83 _lib_path('cola/models/*.py'),
84 _lib_path('cola/controllers/*.py'),
85 _lib_path('cola/gui/*.py'),
86 _lib_path('cola/views/*.py'),
87 _lib_path('jsonpickle/*.py'),
88 _lib_path('simplejson/*.py')]
90 def _lib_path(entry):
91 dirname = os.path.dirname(entry)
92 app_dir = os.path.join('share/git-cola/lib', dirname)
93 return (app_dir, glob(entry))
96 def _app_path(dirname, entry):
97 return (dirname, glob(os.path.join(dirname, entry)))
100 def _check_python_version():
101 """Check the minimum Python version
103 pyver = '.'.join(map(lambda x: str(x), sys.version_info))
104 if not version.check('python', pyver):
105 print >> sys.stderr, ('Python version %s or newer required. '
106 'Found %s' % (version.get('python'), pyver))
107 sys.exit(1)
110 def _check_git_version(git_ver):
111 """Check the minimum GIT version
113 if not version.check('git', git_ver):
114 print >> sys.stderr, ('GIT version %s or newer required. '
115 'Found %s' % (version.get('git'), git_ver))
116 sys.exit(1)
118 def _check_pyqt_version():
119 """Check the minimum PyQt version
121 failed = False
122 try:
123 # We avoid utils.run_cmd() because older versions of
124 # pyuic4 were implemented as a shell script with a missing
125 # #!/bin/sh line.
126 pyqtver = _run_cmd('sh -c "pyuic4 --version"').split()[-1]
127 except IndexError:
128 pyqtver = 'nothing'
129 failed = True
130 if failed or not version.check('pyqt', pyqtver):
131 print >> sys.stderr, ('PYQT version %s or newer required. '
132 'Found %s' % (version.get('pyqt'), pyqtver))
133 sys.exit(1)
136 def _dirty(src, dst):
137 if not os.path.exists(dst):
138 return True
139 srcstat = os.stat(src)
140 dststat = os.stat(dst)
141 return srcstat[stat.ST_MTIME] > dststat[stat.ST_MTIME]
144 def _workaround_pyuic4(src, dst):
145 fh = open(src, 'r')
146 contents = core.read_nointr(fh)
147 fh.close()
148 fh = open(dst, 'w')
149 for line in contents.splitlines():
150 if 'sortingenabled' in line.lower():
151 continue
152 core.write_nointr(fh, line+os.linesep)
153 fh.close()
154 os.unlink(src)
157 def _build_views():
158 print 'running build_views'
159 views = os.path.join('cola', 'gui')
160 sources = glob('ui/*.ui')
161 for src in sources:
162 dst = os.path.join(views, os.path.basename(src)[:-3] + '.py')
163 dsttmp = dst + '.tmp'
164 if _dirty(src, dst):
165 print '\tpyuic4 -x %s -o %s' % (src, dsttmp)
166 utils.run_cmd(['pyuic4', '-x', src, '-o', dsttmp])
167 _workaround_pyuic4(dsttmp, dst)
170 def _build_translations():
171 print 'running build_translations'
172 sources = glob(resources.share('po', '*.po'))
173 sources = glob('share/git-cola/po/*.po')
174 for src in sources:
175 dst = resources.qm(os.path.basename(src)[:-3])
176 if _dirty(src, dst):
177 print '\tmsgfmt --qt %s -o %s' % (src, dst)
178 utils.run_cmd(['msgfmt', '--qt', src, '-o', dst])
180 def _run_cmd(cmd):
181 """Runs a command and returns its output."""
182 pipe = os.popen(cmd)
183 contents = core.read_nointr(pipe).strip()
184 pipe.close()
185 return contents
188 if __name__ == '__main__':
189 main()