GitHub Sale: sign up for any paid plan this week and pay nothing until January 1, 2009!  [ hide ]

public
Fork of jwiegley/git-issues
Description: A distributed issue tracking system based on Git repositories, written in Python
Homepage: http://www.newartisans.com/software.html
Clone URL: git://github.com/ktf/git-issues.git
Initial comment support.
ktf (author)
Sun Jun 22 09:39:45 -0700 2008
commit  a71d32caa518dbd16d851f702b2ad84274415a71
tree    3dd9b65c62f25d52cc7081318a55dc5f62408531
parent  1efa9acd0099ce387aedff3a1be8dcdfac9150e6
...
85
86
87
 
88
89
90
...
92
93
94
 
95
96
97
...
103
104
105
106
 
107
108
109
...
314
315
316
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
317
318
319
...
322
323
324
325
 
326
327
328
...
644
645
646
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
647
648
649
...
741
742
743
 
 
 
 
744
 
745
746
747
...
763
764
765
766
 
767
768
769
...
954
955
956
 
 
957
958
959
...
965
966
967
968
 
969
970
971
...
973
974
975
 
 
976
977
978
...
998
999
1000
1001
 
1002
1003
1004
...
1021
1022
1023
1024
 
 
1025
1026
1027
...
1073
1074
1075
 
 
 
 
 
 
 
 
1076
1077
1078
...
85
86
87
88
89
90
91
...
93
94
95
96
97
98
99
...
105
106
107
 
108
109
110
111
...
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
...
345
346
347
 
348
349
350
351
...
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
...
783
784
785
786
787
788
789
790
791
792
793
794
...
810
811
812
 
813
814
815
816
...
1001
1002
1003
1004
1005
1006
1007
1008
...
1014
1015
1016
 
1017
1018
1019
1020
...
1022
1023
1024
1025
1026
1027
1028
1029
...
1049
1050
1051
 
1052
1053
1054
1055
...
1072
1073
1074
 
1075
1076
1077
1078
1079
...
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
0
@@ -85,6 +85,7 @@ class Person:
0
 
0
 class Comment:
0
     def __init__(self, issue, author, comment):
0
+ self.name = None
0
         self.issue = issue
0
         self.author = author
0
         self.comment = comment
0
@@ -92,6 +93,7 @@ class Comment:
0
         self.modified = None
0
         self.self_dirty = True
0
         self.attachments = [] # records filename and blob
0
+ self.issue.comments[self.get_name()] = self # register into issue
0
 
0
     def mark_dirty(self):
0
         self.modified = datetime.now()
0
@@ -103,7 +105,7 @@ class Comment:
0
         del odict['self_dirty'] # remove self dirty flag
0
         return odict
0
 
0
- def __setstate__(self,dict):
0
+ def __setstate__(self, dict):
0
         self.__dict__.update(dict) # update attributes
0
         self.self_dirty = False
0
 
0
@@ -314,6 +316,27 @@ class IssueSet:
0
         self.shelf[self.comment_path(comment)] = comment
0
         self.mark_dirty(self_dirty = False)
0
 
0
+ def get_comment(self, idx_or_partial_hash):
0
+ comment = None
0
+ try:
0
+ idx = int(idx_or_partial_hash) - 1
0
+ comment = self.shelf[self.shelf.keys()[idx]]
0
+ except:
0
+ clean = lambda x: x.split('comment')[0].replace('/', '')
0
+ matching = [(clean(key), key) for key in self.shelf.iterkeys()
0
+ if clean(key).startswith(idx_or_partial_hash) and not "issue.xml" in clean(key)]
0
+ if len(matching) == 0:
0
+ pass
0
+ elif len(matching) == 1:
0
+ comment = self.shelf[matching[0][1]]
0
+ else:
0
+ print ("Ambiguous hash matches:\n" +
0
+ '\t\n'.join(a[0] for a in matching))
0
+ if not comment:
0
+ raise Exception("There is no issue matching the identifier '%s'.\n" %
0
+ idx_or_partial_hash)
0
+ return comment
0
+
0
     def __getitem__(self, idx_or_partial_hash):
0
         issue = None
0
         try:
0
@@ -322,7 +345,7 @@ class IssueSet:
0
         except:
0
             clean = lambda x: x.replace('issue.xml', '').replace('/','')
0
             matching = [(clean(key), key) for key in self.shelf.iterkeys()
0
- if clean(key).startswith(idx_or_partial_hash)]
0
+ if clean(key).startswith(idx_or_partial_hash) and not "comment" in clean(key)]
0
             if len(matching) == 0:
0
                 pass
0
             elif len(matching) == 1:
0
@@ -644,6 +667,25 @@ class XmlIssueBuilder:
0
 
0
     build = classmethod(build)
0
 
0
+class XmlCommentBuilder:
0
+ def build(cls, comment, node, doc):
0
+ commentNode = doc.createElement("comment")
0
+
0
+ created = doc.createElement("created")
0
+ XmlBuilder.build(comment.created, created, doc)
0
+ commentNode.appendChild(created)
0
+
0
+ author = doc.createElement("author")
0
+ XmlBuilder.build(comment.author, author, doc)
0
+ commentNode.appendChild(author)
0
+
0
+ commentText = doc.createElement("comment")
0
+ XmlBuilder.build(comment.comment, commentText, doc)
0
+ commentNode.appendChild(commentText)
0
+ node.appendChild(commentNode)
0
+
0
+ build = classmethod(build)
0
+
0
 #class XmlIssueChangesBuilder:
0
 # def build(cls, data, node, doc):
0
 # changes = doc.createElement("changes")
0
@@ -741,7 +783,12 @@ class XmlBuilder:
0
             assert not doc
0
             doc = xml.dom.minidom.Document()
0
             XmlIssueSetBuilder.build(data, doc, doc)
0
+ elif isinstance(data, Comment):
0
+ assert not doc
0
+ doc = xml.dom.minidom.Document()
0
+ XmlCommentBuilder.build(data, doc, doc)
0
         else:
0
+ print "Unknown type %s" % data
0
             assert False
0
 
0
         return doc
0
@@ -763,7 +810,7 @@ class GitComment(Comment):
0
     def get_name(self):
0
         if not self.name:
0
             hash_func = self.issue.issueSet.shelf.hash_blob
0
- name = hash_blob(str(self.created)
0
+ name = hash_func(str(self.created)
0
                              + str(self.author)
0
                              + self.comment)
0
             self.name = name
0
@@ -954,6 +1001,8 @@ if __name__ == '__main__':
0
         filteredStati = options.filterStatus.split(":")
0
         
0
         for item in issueSet.shelf.iteritems():
0
+ if "comment" in item[0]:
0
+ continue
0
             issue = item[1].get_data()
0
             if issue.status in filteredStati:
0
                 continue
0
@@ -965,7 +1014,7 @@ if __name__ == '__main__':
0
             index += 1
0
 
0
         print
0
-
0
+
0
 ######################################################################
0
 
0
     elif command == "show" or command == "dump":
0
@@ -973,6 +1022,8 @@ if __name__ == '__main__':
0
             print "Shows needs an index or Id."
0
 
0
         issue = issueSet[args[0]]
0
+ comments = "\n".join(["Comment (%s): %s" % (comment[0:7], comment[0:7])
0
+ for comment in issue.comments])
0
         if command == "show":
0
             sys.stdout.write("""
0
           Title: %s
0
@@ -998,7 +1049,7 @@ if __name__ == '__main__':
0
 
0
         Created: %s
0
        Modified: %s
0
-
0
+ %s
0
     """ % (issue.title,
0
            format_long_text(issue.summary),
0
 
0
@@ -1021,7 +1072,8 @@ if __name__ == '__main__':
0
            issue.tags or "",
0
 
0
            issue.created,
0
- issue.modified))
0
+ issue.modified,
0
+ comments))
0
         else:
0
             write_object(issue)
0
 
0
@@ -1073,6 +1125,14 @@ if __name__ == '__main__':
0
             
0
             if options.printNewBugs:
0
                 print "%s: %s (%s)" % (issue.status, issue.title, issue.name[0:7])
0
+ elif command == "comment":
0
+ if len(args) == 0:
0
+ print "Usage: %s comment <issue-id> <comment-title>" % sys.argv[0]
0
+ sys.exit(1)
0
+ issue = issueSet[args[0]]
0
+ comment = issueSet.new_comment(issue, args[1])
0
+ if options.printNewBugs:
0
+ print "### Comment(%s): %s" % (comment.name[0:7], comment.comment)
0
 
0
 ######################################################################
0
     else:

Comments

    No one has commented yet.