Added utility to create todo files
authorepage <eopage@byu.net>
Fri, 30 Jan 2009 01:17:49 +0000 (01:17 +0000)
committerepage <eopage@byu.net>
Fri, 30 Jan 2009 01:17:49 +0000 (01:17 +0000)
git-svn-id: file:///svnroot/ejpi/trunk@2 df6cc7de-23d0-4ae0-bb86-c17aa67b2a9d

Makefile
support/todo.py [new file with mode: 0755]

index 209f39f..aa139ca 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -3,6 +3,7 @@ SOURCE_PATH=src
 SOURCE=$(shell find $(SOURCE_PATH) -iname *.py)
 OBJ=$(SOURCE:.py=.pyc)
 TAG_FILE=~/.ctags/$(PROJECT_NAME).tags
+TODO_FILE=./TODO
 
 DEBUGGER=winpdb
 UNIT_TEST=nosetests -w $(TEST_PATH)
@@ -12,8 +13,9 @@ LINT=pylint --rcfile=$(LINT_RC)
 COVERAGE_TEST=figleaf
 PROFILER=pyprofiler
 CTAGS=ctags-exuberant
+TODO_FINDER=support/todo.py
 
-.PHONY: all run debug test lint tags package clean
+.PHONY: all run debug test lint tags todo package clean
 
 all: test package
 
@@ -34,6 +36,8 @@ lint:
 
 tags: $(TAG_FILE) 
 
+todo: $(TODO_FILE)
+
 clean:
        rm -Rf $(OBJ)
 
@@ -41,6 +45,9 @@ $(TAG_FILE): $(SOURCE)
        mkdir -p $(dir $(TAG_FILE))
        $(CTAGS) -o $(TAG_FILE) $(SOURCE)
 
+$(TODO_FILE): $(SOURCE)
+       @- $(TODO_FINDER) $(SOURCE) > $(TODO_FILE)
+
 #Makefile Debugging
 #Target to print any variable, can be added to the dependencies of any other target
 #Userfule flags for make, -d, -p, -n
diff --git a/support/todo.py b/support/todo.py
new file mode 100755 (executable)
index 0000000..90cbd04
--- /dev/null
@@ -0,0 +1,104 @@
+#!/usr/bin/env python
+
+from __future__ import with_statement
+import itertools
+
+
+verbose = False
+
+
+def tag_parser(file, tag):
+       """
+       >>> nothing = []
+       >>> for todo in tag_parser(nothing, "@todo"):
+       ...     print todo
+       ...
+       >>> one = ["@todo Help!"]
+       >>> for todo in tag_parser(one, "@todo"):
+       ...     print todo
+       ...
+       1: @todo Help!
+       >>> mixed = ["one", "@todo two", "three"]
+       >>> for todo in tag_parser(mixed, "@todo"):
+       ...     print todo
+       ...
+       2: @todo two
+       >>> embedded = ["one @todo two", "three"]
+       >>> for todo in tag_parser(embedded, "@todo"):
+       ...     print todo
+       ...
+       1: @todo two
+       >>> continuation = ["one", "@todo two", " three"]
+       >>> for todo in tag_parser(continuation, "@todo"):
+       ...     print todo
+       ...
+       2: @todo two three
+       >>> series = ["one", "@todo two", "@todo three"]
+       >>> for todo in tag_parser(series, "@todo"):
+       ...     print todo
+       ...
+       2: @todo two
+       3: @todo three
+       """
+       currentTodo = []
+       prefix = None
+       for lineNumber, line in enumerate(file):
+               column = line.find(tag)
+               if column != -1:
+                       if currentTodo:
+                               yield "\n".join (currentTodo)
+                       prefix = line[0:column]
+                       currentTodo = ["%d: %s" % (lineNumber+1, line[column:].strip())]
+               elif prefix is not None and len(prefix)+1 < len(line) and line.startswith(prefix) and line[len(prefix)].isspace():
+                       currentTodo.append (line[len(prefix):].rstrip())
+               elif currentTodo:
+                       yield "\n".join (currentTodo)
+                       currentTodo = []
+                       prefix = None
+       if currentTodo:
+               yield "\n".join (currentTodo)
+
+
+def tag_finder(filename, tag):
+       todoList = []
+
+       with open(filename) as file:
+               body = "\n".join (tag_parser(file, tag))
+       passed = not body
+       if passed:
+               output = "No %s's for %s" % (tag, filename) if verbose else ""
+       else:
+               header = "%s's for %s:\n" % (tag, filename) if verbose else ""
+               output = header + body
+               output += "\n" if verbose else ""
+
+       return (passed, output)
+
+
+if __name__ == "__main__":
+       import sys
+       import os
+       import optparse
+
+       opar = optparse.OptionParser()
+       opar.add_option("-v", "--verbose", dest="verbose", help="Toggle verbosity", action="store_true", default=False)
+       options, args = opar.parse_args(sys.argv[1:])
+       verbose = options.verbose
+
+       bugsAsError = True
+       todosAsError = False
+
+       completeOutput = []
+       allPassed = True
+       for filename in args:
+               bugPassed, bugOutput = tag_finder(filename, "@bug")
+               todoPassed, todoOutput = tag_finder(filename, "@todo")
+               output = "\n".join ([bugOutput, todoOutput])
+               if (not bugPassed and bugsAsError) or (not todoPassed and todosAsError):
+                       allPassed = False
+               output = output.strip()
+               if output:
+                       completeOutput.append(filename+":\n"+output+"\n\n")
+       print "\n".join(completeOutput)
+       
+       sys.exit(0 if allPassed else 1);