refactor: eliminate `cola.prefs` package
[git-cola.git] / bin / git-cola
blobaadf8ca077284d73aaaa187cbc805920dc605d65
1 #!/usr/bin/env python
2 # -*- python-mode -*-
3 """git-cola: The highly caffeinated Git GUI
4 """
6 __copyright__ = """
7 Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013
8 David Aguilar <davvid@gmail.com> and contributors
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License version 2 as
12 published by the Free Software Foundation.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 """
21 import os
22 import sys
23 import subprocess
24 from argparse import ArgumentParser
25 from os.path import abspath
26 from os.path import dirname
27 from os.path import realpath
30 def setup_environment():
31 """Provides access to the cola modules"""
32 # Try to detect where it is run from and set prefix and the search path.
33 # It is assumed that the user installed Cola using the --prefix= option
34 prefix = dirname(dirname(realpath(abspath(__file__))))
36 # Look for modules in the source or install trees
37 cola_mod = os.path.join(prefix, 'cola', '__init__.py')
38 if os.path.exists(cola_mod):
39 # Source tree
40 sys.path.insert(1, prefix)
41 else:
42 # Install tree
43 install_lib = os.path.join(prefix, 'share', 'git-cola', 'lib')
44 sys.path.insert(1, install_lib)
45 setup_environment()
47 from cola import core
48 from cola.app import add_common_arguments
49 from cola.app import application_init
50 from cola.app import application_start
53 def main():
54 # we're using argparse with subparser, but argparse
55 # does not allow us to assign a default subparser
56 # when none has been specified. We fake it by injecting
57 # 'cola' into the command-line so that parse_args()
58 # routes them to the 'cola' parser by default.
59 if (len(sys.argv) < 2 or
60 sys.argv[1].startswith('-') and
61 sys.argv[1] not in ('-h', '--help')):
62 sys.argv.insert(1, 'cola')
63 args = parse_args()
64 return args.func(args)
67 def parse_args():
68 parser = ArgumentParser()
69 cmds = parser.add_subparsers(title='valid commands')
71 add_cola_command(cmds)
72 add_archive_command(cmds)
73 add_branch_command(cmds)
74 add_browse_command(cmds)
75 add_config_command(cmds)
76 add_dag_command(cmds)
77 add_diff_command(cmds)
78 add_fetch_command(cmds)
79 add_grep_command(cmds)
80 add_merge_command(cmds)
81 add_pull_command(cmds)
82 add_push_command(cmds)
83 add_rebase_command(cmds)
84 add_remote_command(cmds)
85 add_search_command(cmds)
86 add_stash_command(cmds)
87 add_tag_command(cmds)
88 add_version_command(cmds)
90 return parser.parse_args()
93 def add_command(parent, name, description, func):
94 parser = parent.add_parser(name, help=description)
95 parser.set_defaults(func=func)
96 add_common_arguments(parser)
97 return parser
100 def add_cola_command(cmds):
101 add_command(cmds, 'cola', 'start git-cola', cola)
104 def add_archive_command(parent):
105 parser = add_command(parent, 'archive', 'save an archive', archive)
106 parser.add_argument('ref', metavar='<ref>', nargs='?', default=None,
107 help='SHA-1 to archive')
110 def add_branch_command(cmds):
111 add_command(cmds, 'branch', 'create a branch', branch)
114 def add_browse_command(cmds):
115 add_command(cmds, 'browse', 'browse repository', browse)
116 add_command(cmds, 'classic', 'browse repository', browse)
119 def add_config_command(cmds):
120 add_command(cmds, 'config', 'edit configuration', config)
123 def add_dag_command(cmds):
124 parser = add_command(cmds, 'dag', 'start git-dag', dag)
125 parser.add_argument('-c', '--count', metavar='<count>',
126 type=int, default=1000,
127 help='number of commits to display')
128 parser.add_argument('args', nargs='*', metavar='<args>',
129 help='git log arguments')
131 def add_diff_command(cmds):
132 parser = add_command(cmds, 'diff', 'view diffs', diff)
133 parser.add_argument('args', nargs='*', metavar='<args>',
134 help='git diff arguments')
137 def add_fetch_command(cmds):
138 add_command(cmds, 'fetch', 'fetch remotes', fetch)
141 def add_grep_command(cmds):
142 parser = add_command(cmds, 'grep', 'grep source', grep)
143 parser.add_argument('args', nargs='*', metavar='<args>',
144 help='git grep arguments')
146 def add_merge_command(cmds):
147 add_command(cmds, 'merge', 'merge branches', merge)
150 def add_pull_command(cmds):
151 parser = add_command(cmds, 'pull', 'pull remote branches', pull)
152 parser.add_argument('--rebase', default=False, action='store_true',
153 help='rebase local branch when pulling')
156 def add_push_command(cmds):
157 add_command(cmds, 'push', 'push remote branches', push)
160 def add_rebase_command(cmds):
161 parser = add_command(cmds, 'rebase', 'interactive rebase', rebase)
162 parser.add_argument('branch', metavar='<branch>',
163 help='New upstream branch')
166 def add_remote_command(cmds):
167 add_command(cmds, 'remote', 'edit remotes', remote)
170 def add_search_command(cmds):
171 add_command(cmds, 'search', 'search commits', search)
174 def add_stash_command(cmds):
175 add_command(cmds, 'stash', 'stash and unstash changes', stash)
178 def add_tag_command(cmds):
179 parser = add_command(cmds, 'tag', 'create tags', tag)
180 parser.add_argument('name', metavar='<name>', nargs='?', default=None,
181 help='tag name')
182 parser.add_argument('ref', metavar='<ref>', nargs='?', default=None,
183 help='SHA-1 to tag')
184 parser.add_argument('-s', '--sign', default=False, action='store_true',
185 help='annotated and GPG-signed tag')
187 def add_version_command(cmds):
188 add_command(cmds, 'version', 'print the git-cola version', print_version)
190 # entry points
192 def cola(args):
193 context = application_init(args)
194 from cola.main.view import MainView
195 view = MainView(context.model)
196 return application_start(context, view)
199 def archive(args):
200 context = application_init(args, update=True)
201 if args.ref is None:
202 args.ref = context.model.currentbranch
204 from cola.widgets.archive import GitArchiveDialog
205 view = GitArchiveDialog(args.ref)
206 return application_start(context, view)
209 def branch(args):
210 context = application_init(args, update=True)
211 from cola.widgets.createbranch import create_new_branch
212 view = create_new_branch()
213 return application_start(context, view)
216 def browse(args):
217 context = application_init(args)
218 from cola.classic import cola_classic
219 view = cola_classic(update=False)
220 return application_start(context, view)
223 def config(args):
224 context = application_init(args)
225 from cola.widgets.prefs import preferences
226 view = preferences()
227 return application_start(context, view)
230 def dag(args):
231 context = application_init(args)
232 from cola.widgets.dag import git_dag
233 view = git_dag(context.model, args=args)
234 return application_start(context, view)
237 def diff(args):
238 context = application_init(args)
239 from cola.difftool import diff_expression
240 expr = subprocess.list2cmdline(map(core.decode, args.args))
241 view = diff_expression(None, expr, create_widget=True)
242 return application_start(context, view)
245 def fetch(args):
246 # TODO: the calls to update_status() can be done asynchronously
247 # by hooking into the message_updated notification.
248 context = application_init(args)
249 from cola.widgets import remote
250 context.model.update_status()
251 view = remote.fetch()
252 return application_start(context, view)
255 def grep(args):
256 context = application_init(args)
257 from cola.widgets import grep
258 text = subprocess.list2cmdline(map(core.decode, args.args))
259 view = grep.run_grep(text=text, parent=None)
260 return application_start(context, view)
263 def merge(args):
264 context = application_init(args, update=True)
265 from cola.merge import view
266 view = view.MergeView(context.model, parent=None)
267 return application_start(context, view)
270 def print_version(args):
271 from cola import version
272 version.print_version()
273 return 0
276 def pull(args):
277 context = application_init(args, update=True)
278 from cola.widgets import remote
279 view = remote.pull()
280 if args.rebase:
281 view.set_rebase(True)
282 return application_start(context, view)
285 def push(args):
286 context = application_init(args, update=True)
287 from cola.widgets import remote
288 view = remote.push()
289 return application_start(context, view)
292 def rebase(args):
293 from cola import cmds
294 status, out, err = cmds.do(cmds.Rebase, args.branch)
295 if out:
296 core.stdout(out)
297 if err:
298 core.stderr(err)
299 return status
302 def remote(args):
303 context = application_init(args)
304 from cola.widgets import editremotes
305 view = editremotes.edit()
306 return application_start(context, view)
309 def search(args):
310 context = application_init(args)
311 from cola.widgets.search import search as searchwidget
312 view = searchwidget()
313 return application_start(context, view)
316 def stash(args):
317 context = application_init(args)
318 from cola.stash import stash as stashwidget
319 view = stashwidget()
320 return application_start(context, view)
323 def tag(args):
324 context = application_init(args)
325 from cola.widgets.createtag import create_tag
326 view = create_tag(name=args.name, ref=args.ref, sign=args.sign)
327 return application_start(context, view)
330 if __name__ == '__main__':
331 sys.exit(main())