Added some code comments and optimizations
M .ditz/issue-3455abd67e78f997c74d72aff184585b74083415.yaml +6 -0
@@ 20,4 20,10 @@ log_events:
   - Sean Russell <ser@ser1.net>
   - assigned to release 2010.2 from unassigned
   - ""
+- - 2010-01-28 02:31:29.798370 Z
+  - Sean Russell <ser@ser1.net>
+  - commented
+  - |-
+    Right now, ditz-trac syncs by ID, but when that fails (the ticket was created on Trac, for instance)
+    it attempts to match by title.  Also, the title isn't something that ditz-trac syncs.
 trac_id: 3

          
A => .ditz/issue-346223318c35bdac90b33437bc0d266e05475d9f.yaml +19 -0
@@ 0,0 1,19 @@ 
+--- !ditz.rubyforge.org,2008-03-06/issue 
+title: Filter out empty comments when updating Trac
+desc: It's just noise.
+type: :bugfix
+component: ditz to trac
+release: 
+reporter: Sean Russell <ser@ser1.net>
+status: :unstarted
+disposition: 
+creation_time: 2010-01-28 03:18:45.215182 Z
+references: []
+
+id: 346223318c35bdac90b33437bc0d266e05475d9f
+log_events: 
+- - 2010-01-28 03:18:45.854285 Z
+  - Sean Russell <ser@ser1.net>
+  - created
+  - ""
+trac_id: 

          
A => .ditz/issue-8a82d727a91a667548b847a1e22d2ceb42f3709d.yaml +23 -0
@@ 0,0 1,23 @@ 
+--- !ditz.rubyforge.org,2008-03-06/issue 
+title: Find a way to stop circular syncs
+desc: "We can't control the time stamp or author in the change log in Trac.  Therefore,\n\
+  when we update tickets from issues, the next time we update, we'll get the ticket\n\
+  change logs back as new changes to add to the issues.  This is Very Bad\xE2\x84\xA2, although\n\
+  at least there's only one loop, because when we add the dupe changes back to the\n\
+  issues, they get the same time stamp as the Trac changes."
+type: :bugfix
+component: ditz-trac
+release: "2010.1"
+reporter: Sean Russell <ser@ser1.net>
+status: :unstarted
+disposition: 
+creation_time: 2010-01-28 03:21:04.750402 Z
+references: []
+
+id: 8a82d727a91a667548b847a1e22d2ceb42f3709d
+log_events: 
+- - 2010-01-28 03:21:05.958296 Z
+  - Sean Russell <ser@ser1.net>
+  - created
+  - ""
+trac_id: 

          
M .ditz/issue-9618638bbe9059ffa431f5edc8d7b9c9a938dbab.yaml +6 -2
@@ 5,8 5,8 @@ type: :feature
 component: trac to ditz
 release: 
 reporter: Sean Russell <ser@ser1.net>
-status: :unstarted
-disposition: 
+status: :closed
+disposition: :wontfix
 creation_time: 2010-01-27 13:24:08.081006 Z
 references: []
 

          
@@ 16,4 16,8 @@ log_events:
   - Sean Russell <ser@ser1.net>
   - created
   - ""
+- - 2010-01-28 02:37:56.430334 Z
+  - Sean Russell <ser@ser1.net>
+  - closed with disposition wontfix
+  - No need for this.
 trac_id: 7

          
A => .ditz/issue-9bfea1cdc188c9047e6d0b0b95eb931133997bd1.yaml +21 -0
@@ 0,0 1,21 @@ 
+--- !ditz.rubyforge.org,2008-03-06/issue 
+title: More error checking in the code.
+desc: |-
+  There are a lot of assumptions that things just work, and there's little
+  graceful failing in the code.
+type: :bugfix
+component: ditz-trac
+release: 
+reporter: Sean Russell <ser@ser1.net>
+status: :unstarted
+disposition: 
+creation_time: 2010-01-28 02:26:09.882404 Z
+references: []
+
+id: 9bfea1cdc188c9047e6d0b0b95eb931133997bd1
+log_events: 
+- - 2010-01-28 02:26:23.862289 Z
+  - Sean Russell <ser@ser1.net>
+  - created
+  - What's a creator comment for?
+trac_id: 8

          
M trac-sync.rb +28 -12
@@ 137,9 137,9 @@ EOS
 
     # Syncs ditz issues -> Trac
     def create_tickets( issues, trac )
+      rv = {}
       maybe_create_milestones( trac )
       maybe_create_components( trac )
-      new_tickets = []
       issues.each do |t,i| # t will always be nil
         tid = trac.tickets.create( i.title, i.desc, { 
             "created_at" => i.creation_time,

          
@@ 150,10 150,10 @@ EOS
             "status"     => DSTATUS_TSTATUS[ i.status ] || "",
             "resolution" => DISPO_RES[ i.disposition ] || ""
           } )
-        new_tickets << trac.tickets.get( tid )
         i.trac_id = tid
+        rv[i] = trac.tickets.get(tid)
       end
-      new_tickets
+      rv
     end
     
     # Creates Trac components for all of the ditz components that are missing

          
@@ 192,7 192,9 @@ EOS
 
 
     # Syncs Trac tickets -> issues
+    # tickets: [tickets,nil] -- only the tickets
     def create_issues( tickets )
+      rv = {} # will contain {ticket=>new_issue}
       tickets.each do |t,i|   # i will always be nil
         # trac4r doesn't yet support resolution
         resolution = t.status == "closed" ? :fixed : nil

          
@@ 218,8 220,10 @@ EOS
 
           @project.add_issue( issue )
           puts "Created issue #{issue.id[0,4]}: #{issue.title}"
+          rv[t] = issue
         end
       end
+      rv
     end
 
 

          
@@ 397,18 401,30 @@ EOS
       # already been updated, and we're re-pairing too much.  The create methods
       # could just pair in the method and return the pairs
 
-      # Existing ticket/issue matches
+      # Existing [ticket,issue] matches
       pairs = util.pair(tickets)
 
-      # Create and update any missing issues
-      util.create_issues( pairs.find_all {|m| m[1] == nil} )
-      pairs = util.pair(tickets)  # re-match the pairs
-      util.update_issues( pairs.find_all {|m| m[0] != nil && m[1] != nil}, trac )
+      # Create and update any missing issues.  new_pairs is {ticket=>new_issue} hash
+      issues_only = pairs.find_all {|m| m[1] == nil}
+      new_issues = util.create_issues( issues_only )
+      issues_only.each { |m| m[1] = new_issues[m[0]] }
+
+      # Create and update any missing tickets. new_tickets is {issue=>new_ticket} hash
+      tickets_only = pairs.find_all {|m| m[0] == nil}
+      new_tickets = util.create_tickets( tickets_only, trac )
+      tickets_only.each { |m| m[0] = new_tickets[m[1]] }
 
-      # Create and update any missing tickets
-      new_tickets = util.create_tickets( pairs.find_all {|m| m[0] == nil}, trac )
-      pairs = util.pair( tickets + new_tickets )
-      util.update_tickets( pairs.find_all {|m| m[0] != nil && m[1] != nil}, trac )
+      # Now, update the issues and tickets with any changes that have occurred since
+      # the last change on the partner. We don't need to update objects which caused a
+      # new partner to be created... so if a ticket created a new issue, don't update
+      # the ticket.
+      #
+      # Don't update issues that just created a new ticket
+      issues_to_update = pairs.reject {|t,i| !new_tickets[i].nil? }
+      util.update_issues( issues_to_update, trac )
+      # Don't update tickets that just created a new issue
+      tickets_to_update = pairs.reject {|t,i| !new_issues[t].nil? }
+      util.update_tickets( tickets_to_update, trac )
     end
   end
 end