From e7b75f26c301c5fba2b4fb718973bb23f206a92a Mon Sep 17 00:00:00 2001 From: David Aguilar Date: Tue, 18 Nov 2008 03:30:21 -0800 Subject: [PATCH] cola: add more documentation strings to the cola modules Signed-off-by: David Aguilar --- bin/git-cola | 1 + cola/controllers/__init__.py | 37 ++++++++--------------- cola/controllers/bookmark.py | 2 ++ cola/controllers/compare.py | 2 ++ cola/controllers/createbranch.py | 3 ++ cola/controllers/merge.py | 3 ++ cola/controllers/remote.py | 3 ++ cola/controllers/repobrowser.py | 3 ++ cola/controllers/search.py | 3 ++ cola/controllers/stash.py | 3 ++ cola/controllers/util.py | 4 +++ cola/core.py | 6 ++++ cola/git.py | 5 +++- cola/inotify.py | 5 ++++ cola/main.py | 16 ++++++++-- cola/model.py | 4 +++ cola/models.py | 3 ++ cola/observer.py | 3 +- cola/qobserver.py | 15 ++++++++++ cola/qtutils.py | 65 ++++++++++++++++++++++++---------------- cola/settings.py | 4 ++- cola/syntax.py | 6 ++++ cola/utils.py | 35 +++++++++++++++++++++- cola/version.py | 17 ++++++++--- cola/views/__init__.py | 5 ++++ cola/views/main.py | 3 ++ 26 files changed, 197 insertions(+), 59 deletions(-) diff --git a/bin/git-cola b/bin/git-cola index 295f7d5d..135f13ba 100755 --- a/bin/git-cola +++ b/bin/git-cola @@ -34,6 +34,7 @@ if sys.path[0] not in path_entries: # It is assumed that the user installed Cola using the --prefix= option prefix, bin = os.path.split(sys.path[0]) +# Scripts is win32 if bin in ('bin', 'Scripts') and prefix != sys.prefix: sys.prefix = prefix sys.exec_prefix = prefix diff --git a/cola/controllers/__init__.py b/cola/controllers/__init__.py index 7816efe8..7a4e0666 100644 --- a/cola/controllers/__init__.py +++ b/cola/controllers/__init__.py @@ -1,4 +1,6 @@ #!/usr/bin/env python +"""This module provides access to the application controllers.""" + import os import sys import time @@ -14,11 +16,15 @@ from PyQt4.QtGui import QFont from cola import utils from cola import qtutils -from cola import defaults from cola import version from cola.core import encode from cola.qobserver import QObserver +try: # linux-only + from cola import inotify +except ImportError: + pass + # controllers namespace import search from util import logger @@ -60,15 +66,11 @@ class Controller(QObserver): """ model.create( project = os.path.basename(model.git.get_work_tree()), - window_geom = utils.parse_geom(model.get_cola_config('geometry')), git_version = model.git.version(), ) self.reset_mode() - # Load window settings - settings = QtCore.QSettings('git', 'cola'); - geom = settings.value('geometry').toByteArray() - self.view.restoreState(geom) + # Parent-less log window qtutils.LOGGER = logger() @@ -80,7 +82,6 @@ class Controller(QObserver): # Binds model params to their equivalent view widget self.add_observables('commitmsg')#, 'staged', 'unstaged', - #'show_untracked') # When a model attribute changes, this runs a specific action self.add_actions(global_cola_fontdiff = self.update_diff_font) @@ -183,8 +184,6 @@ class Controller(QObserver): ) # Delegate window events here - view.moveEvent = self.move_event - view.resizeEvent = self.resize_event view.closeEvent = self.quit_app view.status_tree.mousePressEvent = self.click_tree @@ -330,7 +329,7 @@ class Controller(QObserver): ##################################################################### # event() is called in response to messages from the inotify thread def event(self, msg): - if msg.type() == defaults.INOTIFY_EVENT: + if msg.type() == inotify.INOTIFY_EVENT: self.rescan() return True else: @@ -595,10 +594,8 @@ class Controller(QObserver): def quit_app(self, *args): """Save config settings and cleanup any inotify threads.""" if self.model.remember_gui_settings(): - self.model.save_gui_settings() - settings = QtCore.QSettings('git', 'cola'); - settings.setValue('geometry', - QtCore.QVariant(self.view.saveState())); + self.model.set_window_geom(self.view.width(), self.view.height(), + self.view.x(), self.view.y()) qtutils.close_log_window() pattern = self.model.get_tmp_file_pattern() for filename in glob.glob(pattern): @@ -611,9 +608,9 @@ class Controller(QObserver): def load_commitmsg(self): file = qtutils.open_dialog(self.view, 'Load Commit Message...', - defaults.DIRECTORY) + self.model.get_directory()) if file: - defaults.DIRECTORY = os.path.dirname(file) + self.model.set_directory(os.path.dirname(file)) slushy = utils.slurp(file) if slushy: self.model.set_commitmsg(slushy) @@ -910,14 +907,6 @@ class Controller(QObserver): browser = self.model.get_history_browser() utils.fork(browser, self.model.get_currentbranch()) - def move_event(self, event): - defaults.X = event.pos().x() - defaults.Y = event.pos().y() - - def resize_event(self, event): - defaults.WIDTH = event.size().width() - defaults.HEIGHT = event.size().height() - def load_gui_settings(self): try: (w,h,x,y) = self.model.get_window_geom() diff --git a/cola/controllers/bookmark.py b/cola/controllers/bookmark.py index c6c49aa6..4ed1b08c 100644 --- a/cola/controllers/bookmark.py +++ b/cola/controllers/bookmark.py @@ -1,4 +1,6 @@ #!/usr/bin/env python +"""This controller handles the bookmarks dialog.""" + import os import sys diff --git a/cola/controllers/compare.py b/cola/controllers/compare.py index c496b7f0..74fc6eaa 100644 --- a/cola/controllers/compare.py +++ b/cola/controllers/compare.py @@ -1,3 +1,5 @@ +"""This controller handles the compare commits dialog.""" + import os from cola import utils diff --git a/cola/controllers/createbranch.py b/cola/controllers/createbranch.py index fe3ff7d0..7a9a167b 100644 --- a/cola/controllers/createbranch.py +++ b/cola/controllers/createbranch.py @@ -1,4 +1,7 @@ #!/usr/bin/env python +"""This controller handles the create branch dialog.""" + + import os from PyQt4.QtGui import QDialog diff --git a/cola/controllers/merge.py b/cola/controllers/merge.py index be00ebee..7f9656e9 100644 --- a/cola/controllers/merge.py +++ b/cola/controllers/merge.py @@ -1,4 +1,7 @@ #!/usr/bin/env python +"""This controller handles the merge dialog.""" + + from PyQt4.Qt import Qt from cola import utils diff --git a/cola/controllers/remote.py b/cola/controllers/remote.py index c46df62b..1ebd19a3 100644 --- a/cola/controllers/remote.py +++ b/cola/controllers/remote.py @@ -1,3 +1,6 @@ +"""This controller handles the remote dialog.""" + + import os from PyQt4.QtGui import QDialog diff --git a/cola/controllers/repobrowser.py b/cola/controllers/repobrowser.py index 9f828f7a..c269587c 100644 --- a/cola/controllers/repobrowser.py +++ b/cola/controllers/repobrowser.py @@ -1,4 +1,7 @@ #!/usr/bin/env python +"""This controller handles the repository file browser.""" + + import os from PyQt4.QtGui import QDialog diff --git a/cola/controllers/search.py b/cola/controllers/search.py index 8a37b131..ea82797c 100644 --- a/cola/controllers/search.py +++ b/cola/controllers/search.py @@ -1,4 +1,7 @@ #!/usr/bin/env python +"""This controller handles the search dialog.""" + + import os import re import time diff --git a/cola/controllers/stash.py b/cola/controllers/stash.py index f7e57a3d..333329a7 100644 --- a/cola/controllers/stash.py +++ b/cola/controllers/stash.py @@ -1,3 +1,6 @@ +"""This controller handles the stash dialog.""" + + import os from cola import utils diff --git a/cola/controllers/util.py b/cola/controllers/util.py index 0df36f1c..9c4bd702 100644 --- a/cola/controllers/util.py +++ b/cola/controllers/util.py @@ -1,4 +1,8 @@ #!/usr/bin/env python +"""This module provides utility controllers. +""" + + import os import time from PyQt4.QtGui import QDialog diff --git a/cola/core.py b/cola/core.py index c8c8cd2f..d8421ec9 100644 --- a/cola/core.py +++ b/cola/core.py @@ -1,3 +1,5 @@ +"""This module provides unicode encode and decode utilities. +""" # Some files are not in UTF-8; some other aren't in any codification. # Remember that GIT doesn't care about encodings (saves binary data) _encoding_tests = [ @@ -8,6 +10,8 @@ _encoding_tests = [ # <-- add encodings here ] def decode(enc): + """decode(encoded_string) returns an unencoded unicode string + """ for encoding in _encoding_tests: try: return unicode(enc.decode(encoding)) @@ -16,4 +20,6 @@ def decode(enc): raise Exception('error encoding %s' % enc) def encode(unenc): + """encode(unencoded_string) returns a string encoded in utf-8 + """ return unenc.encode('utf-8', 'replace') diff --git a/cola/git.py b/cola/git.py index 5a6bb3e6..cb39b392 100644 --- a/cola/git.py +++ b/cola/git.py @@ -25,12 +25,15 @@ class Git(object): The Git class manages communication with the Git binary """ def __init__(self): - self._git_cwd = None + """Constructs a Git command object.""" + self._git_cwd = None #: The working directory used by execute() def set_cwd(self, path): + """Sets the current directory.""" self._git_cwd = path def __getattr__(self, name): + """Handles the self.git_command(..) dispatching.""" if name[0] == '_': raise AttributeError(name) return lambda *args, **kwargs: self._call_process(name, *args, **kwargs) diff --git a/cola/inotify.py b/cola/inotify.py index 20c44826..bc0260f3 100644 --- a/cola/inotify.py +++ b/cola/inotify.py @@ -1,5 +1,10 @@ #!/usr/bin/env python # Copyright (c) 2008 David Aguilar +"""This module provides an inotify plugin for Linux and other systems +which provide the pyinotify module. + +""" + import os import time from PyQt4.QtCore import QCoreApplication diff --git a/cola/main.py b/cola/main.py index 709989f5..3516ae87 100644 --- a/cola/main.py +++ b/cola/main.py @@ -1,4 +1,7 @@ # Copyright(C) 2008, David Aguilar +"""This module provides the main() routine used by the +git-cola launcher script. +""" import optparse import sys @@ -8,6 +11,8 @@ from cola import utils from cola import version def main(): + """Parses the command-line arguments and starts git-cola. + """ parser = optparse.OptionParser(usage='%prog [options]') parser.add_option('-v', '--version', @@ -58,9 +63,12 @@ def main(): trtxt = trtxt[:-6] return trtxt + # Initialize the ap app = ColaApplication(sys.argv) - QtGui.QApplication.translate = app.translate app.setWindowIcon(QtGui.QIcon(utils.get_icon('git.png'))) + + # Handle i18n -- load translation files and install a translator + QtGui.QApplication.translate = app.translate locale = str(QtCore.QLocale().system().name()) qmfile = utils.get_qm_for_locale(locale) if os.path.exists(qmfile): @@ -94,6 +102,7 @@ def main(): print >> sys.stderr, ("warn: '%s' is not a valid style." % opts.style) + # Initialize the model/view/controller framework from cola.models import Model from cola.views import View from cola.controllers import Controller @@ -101,14 +110,17 @@ def main(): model = Model() view = View(app.activeWindow()) + # Ensure that we're working in a valid git repository. + # If not, try to find one. When found, chdir there. valid = model.use_worktree(repo) while not valid: gitdir = qtutils.opendir_dialog(view, 'Open Git Repository...', os.getcwd()) if not gitdir: sys.exit(-1) valid = model.use_worktree(gitdir) - os.chdir(model.git.get_work_tree()) + + # Show the GUI and start the event loop view.show() ctl = Controller(model, view) sys.exit(app.exec_()) diff --git a/cola/model.py b/cola/model.py index 69f76fa3..8830868e 100644 --- a/cola/model.py +++ b/cola/model.py @@ -1,5 +1,9 @@ #!/usr/bin/env python # Copyright (c) 2008 David Aguilar +"""This module provides the Model class, an observable and serializable +data model. +""" + import os import imp from cStringIO import StringIO diff --git a/cola/models.py b/cola/models.py index 951fe173..a077bd1d 100644 --- a/cola/models.py +++ b/cola/models.py @@ -1,4 +1,7 @@ # Copyright (c) 2008 David Aguilar +"""This module provides the cola model class. +""" + import os import sys import re diff --git a/cola/observer.py b/cola/observer.py index 6687166c..16f40469 100644 --- a/cola/observer.py +++ b/cola/observer.py @@ -1,6 +1,7 @@ #!/usr/bin/env python # Copyright (c) 2008 David Aguilar -from pprint import pformat +"""This module provides the Observer design pattern. +""" class Observer(object): """ diff --git a/cola/qobserver.py b/cola/qobserver.py index 1193faf7..dbacfdd8 100644 --- a/cola/qobserver.py +++ b/cola/qobserver.py @@ -1,5 +1,18 @@ #!/usr/bin/env python # Copyright (c) 2008 David Aguilar +"""This module provides the QObserver class which allows for simple +correspondancies between model parameters and Qt widgets. + +The QObserver class handles receiving notifications from +model classes and updating Qt widgets accordingly. + +Qt signals are also relayed back to the model so that changes +are always available in the model without having to worry about the +different ways to query Qt widgets. + +""" + + from PyQt4.QtCore import Qt from PyQt4.QtCore import QObject from PyQt4.QtCore import SIGNAL @@ -22,6 +35,7 @@ from PyQt4.QtCore import QVariant from cola.observer import Observer + class QObserver(Observer, QObject): def __init__(self, model, view, *args, **kwargs): @@ -301,6 +315,7 @@ class QObserver(Observer, QObject): action(*widgets) def refresh_view(self, *params): + """Sends a notification message for each known model parameter.""" if not params: params= tuple(self.__model_to_view.keys() +self.__actions.keys()) diff --git a/cola/qtutils.py b/cola/qtutils.py index d459f7e6..b033b839 100644 --- a/cola/qtutils.py +++ b/cola/qtutils.py @@ -1,4 +1,7 @@ # Copyright (c) 2008 David Aguilar +"""This module provides miscellaneous Qt utility functions. +""" + import os from PyQt4 import QtCore from PyQt4 import QtGui @@ -17,6 +20,8 @@ from cola.core import encode LOGGER = None def log(output, quiet=True, doraise=False): + """Sends messages to the log window. + """ if not LOGGER: return LOGGER.log(output) @@ -28,9 +33,11 @@ def log(output, quiet=True, doraise=False): raise_logger() def raise_logger(): + """Raises the log window.""" LOGGER.raise_() def input(msg, title=None): + """Presents the user with an input widget and returns the input.""" if title is None: title = msg parent = QtGui.qApp.activeWindow() @@ -38,15 +45,20 @@ def input(msg, title=None): return (unicode(result[0]), result[1]) def close_log_window(): + """Closes the log window.""" LOGGER.hide() LOGGER.done(0) def show_output(output, **kwargs): - if not output: return + """Sends output to the log window.""" + if not output: + return log(output, quiet=False) def toggle_log_window(): - if not LOGGER: return + """Shows/hides the log window.""" + if not LOGGER: + return if LOGGER.isVisible(): LOGGER.hide() else: @@ -54,16 +66,16 @@ def toggle_log_window(): LOGGER.raise_() def create_listwidget_item(text, filename): - icon = QIcon(filename) + """Creates a QListWidgetItem with text and the icon at filename.""" item = QListWidgetItem() - item.setIcon(icon) + item.setIcon(QIcon(filename)) item.setText(text) return item def create_treewidget_item(text, filename): - icon = QIcon(filename) + """Creates a QTreeWidgetItem with text and the icon at filename.""" item = QTreeWidgetItem() - item.setIcon(0, icon) + item.setIcon(0, QIcon(filename)) item.setText(0, text) return item @@ -116,6 +128,7 @@ def get_tree_selection(treeitem, items): return selected def get_selected_item(list_widget, items): + """Returns the selected item in a QListWidget.""" row, selected = get_selected_row(list_widget) if selected and row < len(items): return items[row] @@ -123,35 +136,33 @@ def get_selected_item(list_widget, items): return None def open_dialog(parent, title, filename=None): - qstr = QFileDialog.getOpenFileName(parent, parent.tr(title), filename) - return unicode(qstr) + """Creates an Open File dialog and returns a filename.""" + return unicode(QFileDialog.getOpenFileName(parent, parent.tr(title), + filename)) def opendir_dialog(parent, title, directory): + """Creates an Open Directory dialog and returns the file path.""" flags = QtGui.QFileDialog.ShowDirsOnly | QtGui.QFileDialog.DontResolveSymlinks - qstr = QFileDialog.getExistingDirectory(parent, parent.tr(title), - directory, - flags) - return unicode(qstr) + return unicode(QFileDialog.getExistingDirectory(parent, parent.tr(title), + directory, flags)) def save_dialog(parent, title, filename=''): + """Creates a Save File dialog and returns a filename.""" return unicode(QFileDialog.getSaveFileName(parent, parent.tr(title), filename)) def new_dir_dialog(parent, title, filename=''): + """Creates a New Directory dialog and returns the file path.""" return unicode(QFileDialog.getSaveFileName(parent, parent.tr(title), filename, os.getcwd(), parent.tr('New Directory ()'))) -def dir_dialog(parent, title, directory): - directory = QFileDialog.getExistingDirectory(parent, parent.tr(title), directory) - return unicode(directory) - def get_icon(filename): - icon = utils.get_icon(filename) - return QIcon(icon) + """Given a basename returns a QIcon from the corresponding cola icon.""" + return QIcon(utils.get_icon(filename)) def question(parent, title, message, default=True): """Launches a QMessageBox question with the provided title and message. @@ -167,10 +178,12 @@ def question(parent, title, message, default=True): return result == QMessageBox.Yes def set_clipboard(text): + """Sets the copy/paste buffer to text.""" QtGui.qApp.clipboard().setText(text, QClipboard.Clipboard) QtGui.qApp.clipboard().setText(text, QClipboard.Selection) def set_selected_item(widget, idx): + """Sets a the currently selected item to the item at index idx.""" if type(widget) is QTreeWidget: item = widget.topLevelItem(idx) if item: @@ -178,16 +191,21 @@ def set_selected_item(widget, idx): widget.setCurrentItem(item) def add_items(widget, items): - for item in items: widget.addItem(item) + """Adds items to a widget.""" + for item in items: + widget.addItem(item) def set_items(widget, items): + """Clear the existing widget contents and set the new items.""" widget.clear() add_items(widget, items) def tr(txt): + """Translate a string into a local language.""" return unicode(QtGui.qApp.translate('', txt)) def get_icon_file(filename, staged=False, untracked=False): + """Returns a file path representing a corresponding file path.""" if staged: if os.path.exists(encode(filename)): icon_file = utils.get_icon('staged.png') @@ -200,6 +218,7 @@ def get_icon_file(filename, staged=False, untracked=False): return icon_file def get_icon_for_file(filename, staged=False, untracked=False): + """Returns a QIcon for a particular file path.""" icon_file = get_icon_file(filename, staged=staged, untracked=untracked) return get_icon(icon_file) @@ -218,11 +237,6 @@ def create_treeitem(filename, staged=False, untracked=False): return create_treewidget_item(filename, icon_file) -def create_txt_item(txt): - item = QListWidgetItem() - item.setText(txt) - return item - def update_file_icons(widget, items, staged=True, untracked=False, offset=0): """Populate a QListWidget with custom icon items.""" @@ -239,5 +253,6 @@ def update_listwidget(widget, items, staged=True, add_items(widget, [ create_listitem(i, staged, untracked) for i in items ]) def set_listwidget_strings(widget, items): + """Sets a list widget to the strings passed in items.""" widget.clear() - add_items(widget, [ create_txt_item(i) for i in items ]) + add_items(widget, [ QListWidgetItem(i) for i in items ]) diff --git a/cola/settings.py b/cola/settings.py index d12090c1..82e5545c 100644 --- a/cola/settings.py +++ b/cola/settings.py @@ -1,5 +1,8 @@ #!/usr/bin/env python # Copyright (c) 2008 David Aguilar +"""This handles saving complex settings such as bookmarks, etc. +""" + HAS_SIMPLEJSON = False try: import simplejson @@ -12,7 +15,6 @@ import user from cola.model import Model class SettingsModel(Model): - def init(self): self.create( bookmarks = [] ) if not HAS_SIMPLEJSON: diff --git a/cola/syntax.py b/cola/syntax.py index 3801de4d..93af4865 100644 --- a/cola/syntax.py +++ b/cola/syntax.py @@ -1,5 +1,11 @@ #!/usr/bin/python # Copyright (c) 2008 David Aguilar +"""This module provides SyntaxHighlighter classes. +These classes are installed onto specific cola widgets and +implement the diff syntax highlighting. + +""" + import re from PyQt4.QtCore import Qt from PyQt4.QtCore import pyqtProperty diff --git a/cola/utils.py b/cola/utils.py index 5a0bdddc..c3dab35f 100644 --- a/cola/utils.py +++ b/cola/utils.py @@ -1,5 +1,7 @@ #!/usr/bin/env python # Copyright (c) 2008 David Aguilar +"""This module provides miscellaneous utility functions.""" + import os import re import sys @@ -41,6 +43,7 @@ def run_cmd(*command): return git.Git.execute(command) def get_qm_for_locale(locale): + """Returns the .qm file for a particular $LANG values.""" regex = re.compile(r'([^\.])+\..*$') match = regex.match(locale) if match: @@ -51,9 +54,11 @@ def get_qm_for_locale(locale): return os.path.join(QMDIR, basename +'.qm') def get_resource_dirs(styledir): + """Returns all directories underneath the share/cola/styles directory.""" return [ r for r in glob(styledir+ '/*') if os.path.isdir(r) ] def get_stylesheet(name): + """Returns the path to a stylesheet within the cola install tree.""" stylesheet = os.path.join(STYLEDIR, name+'.qss') if os.path.exists(stylesheet): return stylesheet @@ -61,6 +66,7 @@ def get_stylesheet(name): return None def get_htmldocs(): + """Returns the path to the cola html documentation.""" return os.path.join(DOCDIR, 'git-cola.html') def ident_file_type(filename): @@ -84,9 +90,11 @@ def get_file_icon(filename): return get_icon(icon_file) def get_icon(icon_file): + """Returns the full path to an icon file given a basename.""" return os.path.join(ICONSDIR, icon_file) def fork(*args): + """Launches a command in the background.""" args = tuple([ encode(a) for a in args ]) if os.name in ('nt', 'dos'): for path in os.environ['PATH'].split(os.pathsep): @@ -101,8 +109,9 @@ def fork(*args): argv = map(shell_quote, args) return os.system(' '.join(argv) + '&') -# c = a - b def sublist(a,b): + """Subtracts list b from list a and returns the resulting list.""" + # conceptually, c = a - b c = [] for item in a: if item not in b: @@ -111,6 +120,9 @@ def sublist(a,b): __grep_cache = {} def grep(pattern, items, squash=True): + """Greps a list for items that match a pattern and return a list of + matching items. If only one item matches, return just that item. + """ isdict = type(items) is dict if pattern in __grep_cache: regex = __grep_cache[pattern] @@ -184,17 +196,20 @@ def project_name(): return os.path.basename(defaults.DIRECTORY) def slurp(path): + """Slurps a filepath into a string.""" file = open(path) slushy = file.read() file.close() return decode(slushy) def write(path, contents): + """Writes a string to a file.""" file = open(path, 'w') file.write(encode(contents)) file.close() class DiffParser(object): + """Handles parsing diff for use by the interactive index editor.""" def __init__(self, model, filename='', cached=True, branch=None, reverse=False): @@ -231,6 +246,7 @@ class DiffParser(object): reverse=bool(branch)) def write_diff(self,filename,which,selected=False,noop=False): + """Writes a new diff corresponding to the user's selection.""" if not noop and which < len(self.diffs): diff = self.diffs[which] write(filename, self.header + '\n' + diff + '\n') @@ -239,9 +255,12 @@ class DiffParser(object): return False def get_diffs(self): + """Returns the list of diffs.""" return self.__diffs def get_diff_subset(self, diff, start, end): + """Processes the diffs and returns a selected subset from that diff. + """ adds = 0 deletes = 0 newdiff = [] @@ -299,27 +318,33 @@ class DiffParser(object): return (self.header + '\n' + '\n'.join(newdiff) + '\n') def get_spans(self): + """Returns the line spans of each hunk.""" return self.__diff_spans def get_offsets(self): + """Returns the offsets.""" return self.__diff_offsets def set_diff_to_offset(self, offset): + """Sets the diff selection to be the hunk at a particular offset.""" self.offset = offset self.diffs, self.selected = self.get_diff_for_offset(offset) def set_diffs_to_range(self, start, end): + """Sets the diff selection to be a range of hunks.""" self.start = start self.end = end self.diffs, self.selected = self.get_diffs_for_range(start,end) def get_diff_for_offset(self, offset): + """Returns the hunks for a particular offset.""" for idx, diff_offset in enumerate(self.__diff_offsets): if offset < diff_offset: return (['\n'.join(self.__diffs[idx])], [idx]) return ([],[]) def get_diffs_for_range(self, start, end): + """Returns the hunks for a selected range.""" diffs = [] indices = [] for idx, span in enumerate(self.__diff_spans): @@ -337,6 +362,8 @@ class DiffParser(object): return diffs, indices def parse_diff(self, diff): + """Parses a diff and extracts headers, offsets, hunks, etc. + """ total_offset = 0 self.__idx = -1 self.__headers = [] @@ -371,6 +398,8 @@ class DiffParser(object): def process_diff_selection(self, selected, offset, selection, apply_to_worktree=False): + """Processes a diff selection and applies changes to the work tree + or index.""" if selection: start = self.fwd_diff.index(selection) end = start + len(selection) @@ -408,16 +437,20 @@ def strip_prefix(prefix, string): return string[len(prefix):] def sanitize_input(input): + """Removes shell metacharacters from a string.""" for c in """ \t!@#$%^&*()\\;,<>"'[]{}~|""": input = input.replace(c, '_') return input def is_linux(): + """Is this a linux machine?""" return platform.system() == 'Linux' def is_debian(): + """Is it debian?""" return os.path.exists('/usr/bin/apt-get') def is_broken(): + """Is it windows or mac? (e.g. is running git-mergetool non-trivial?)""" return (platform.system() == 'Windows' or 'Macintosh' in platform.platform()) diff --git a/cola/version.py b/cola/version.py index 5eee9cf8..8c580eab 100644 --- a/cola/version.py +++ b/cola/version.py @@ -1,4 +1,8 @@ # Copyright (c) 2008 David Aguilar +"""This module inspects the cola repository and calculates +cola version numbers. +""" + import re import os import sys @@ -11,6 +15,7 @@ class VersionUnavailable(ColaException): pass def git_describe_version(): + """Inspect the cola git repository and return the current version.""" path = sys.path[0] try: v = git.Git.execute(['git', 'describe', '--tags', '--abbrev=4']) @@ -27,6 +32,7 @@ def git_describe_version(): return re.sub('-', '.', utils.strip_prefix('v', v)) def builtin_version(): + """Return the builtin version or calculate it as needed.""" try: import builtin_version as bv except ImportError: @@ -35,9 +41,11 @@ def builtin_version(): return bv.version def _builtin_version_file(ext = 'py'): + """Returns the path to cola/builtin_version.py.""" return os.path.join(sys.path[0], 'cola', 'builtin_version.%s' % ext) def write_builtin_version(): + """Writes cola/builtin_version.py.""" try: v = git_describe_version() except VersionUnavailable: @@ -47,12 +55,14 @@ def write_builtin_version(): 'version = %r\n' % v) def delete_builtin_version(): + """Deletes cola/builtin_version.py.""" for ext in ['py', 'pyc', 'pyo']: fn = _builtin_version_file(ext) if os.path.exists(fn): os.remove(fn) def get_version(): + """Returns the builtin version or calculates the current version.""" for v in [builtin_version, git_describe_version]: try: return v() @@ -62,7 +72,6 @@ def get_version(): version = get_version() -# minimum version requirements -git_min_ver = '1.5.2' -python_min_ver = '2.4' -pyqt_min_ver = '4.3' +git_min_ver = '1.5.2' #: minimum git version +python_min_ver = '2.4' #: minimum python version +pyqt_min_ver = '4.3' #: minimum PyQt version diff --git a/cola/views/__init__.py b/cola/views/__init__.py index fea09cff..cf350c43 100644 --- a/cola/views/__init__.py +++ b/cola/views/__init__.py @@ -1,3 +1,8 @@ +"""This module creates simple wrapper classes around the auto-generated +.ui classes. +""" + + import sys import time diff --git a/cola/views/main.py b/cola/views/main.py index 983baffc..3dd63bf8 100644 --- a/cola/views/main.py +++ b/cola/views/main.py @@ -1,3 +1,6 @@ +"""This view provides the main git-cola user interface. +""" + from PyQt4.QtCore import Qt from PyQt4.QtCore import SIGNAL from PyQt4.QtGui import QMainWindow -- 2.11.4.GIT