public
Rubygem
Description: Git based distributed ticketing system, including a command line client and web viewer
Clone URL: git://github.com/schacon/ticgit.git
commit a long time coming - added comments, tags - moved notes into 
another dir
schacon (author)
Fri Mar 21 14:08:57 -0700 2008
commit  a92f983a0c26348f00282482c605d33788072903
tree    4b05df2292e2afca75e8f4f248ba531c0510d9e8
parent  9ac66fb282a891e9f3299eaaf2338002e4121499
...
7
8
9
 
10
11
12
...
7
8
9
10
11
12
13
0
@@ -7,6 +7,7 @@ $:.unshift(File.dirname(__FILE__)) unless
0
 require 'git'
0
 require 'ticgit/base'
0
 require 'ticgit/ticket'
0
+require 'ticgit/comment'
0
 
0
 require 'ticgit/cli'
0
 
...
5
6
7
8
 
 
 
9
10
11
12
13
14
15
 
 
 
16
17
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
19
20
21
22
 
 
 
 
23
24
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
26
27
28
 
 
 
 
29
 
30
 
31
32
33
34
35
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
37
38
39
40
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
42
 
 
 
 
 
 
43
44
45
...
57
58
59
60
 
61
62
63
...
99
100
101
102
103
104
105
106
 
 
 
 
 
 
 
107
 
 
108
109
110
111
112
...
5
6
7
 
8
9
10
11
12
13
14
15
 
 
16
17
18
19
 
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
 
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
 
66
67
68
69
70
71
72
73
74
75
76
77
 
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
 
128
129
130
131
132
133
134
135
136
...
148
149
150
 
151
152
153
154
...
190
191
192
 
 
 
 
 
193
194
195
196
197
198
199
200
201
202
203
 
204
205
206
0
@@ -5,41 +5,132 @@ module TicGit
0
   class Base
0
 
0
     attr_reader :git, :logger
0
- attr_reader :tickets, :tic_working, :tic_index
0
+ attr_reader :tic_working, :tic_index
0
+ attr_reader :tickets, :last_tickets, :current_ticket # saved in state
0
+ attr_reader :state
0
     
0
     def initialize(git_dir, opts = {})
0
       @git = Git.open(git_dir)
0
       @logger = opts[:logger] || Logger.new(STDOUT)
0
       
0
- @tic_working = opts[:working_directory] || File.expand_path('~/.ticgit/working')
0
- @tic_index = opts[:index_file] || File.expand_path('~/.ticgit/index')
0
+ @tic_dir = opts[:tic_dir] || '~/.ticgit'
0
+ @tic_working = opts[:working_directory] || File.expand_path(File.join(@tic_dir, 'working'))
0
+ @tic_index = opts[:index_file] || File.expand_path(File.join(@tic_dir, 'index'))
0
       
0
- load_ticgits
0
+ @state = File.expand_path(File.join(@tic_dir, 'state'))
0
+
0
+ if File.exists?(@state)
0
+ load_state
0
+ else
0
+ reset_ticgit
0
+ end
0
+ end
0
+
0
+ def save_state
0
+ # marshal dump the internals
0
+ File.open(@state, 'w') { |f| Marshal.dump([@tickets, @last_tickets, @current_ticket], f) }
0
+ end
0
+
0
+ def load_state
0
+ # read in the internals
0
+ if(File.exists?(@state))
0
+ @tickets, @last_tickets, @current_ticket = File.open(@state) { |f| Marshal.load(f) }
0
+ end
0
     end
0
     
0
     # returns new Ticket
0
     def ticket_new(title, options = {})
0
- TicGit::Ticket.create(self, title, options)
0
+ t = TicGit::Ticket.create(self, title, options)
0
+ @current_ticket = t.ticket_name
0
+ reset_ticgit
0
+ TicGit::Ticket.open(self, t.ticket_name, @tickets[t.ticket_name])
0
     end
0
 
0
+ def reset_ticgit
0
+ load_tickets
0
+ save_state
0
+ end
0
+
0
+ # returns new Ticket
0
+ def ticket_comment(comment, ticket_id = nil)
0
+ if t = ticket_revparse(ticket_id)
0
+ ticket = TicGit::Ticket.open(self, t, @tickets[t])
0
+ ticket.add_comment(comment)
0
+ reset_ticgit
0
+ end
0
+ end
0
+
0
     # returns array of Tickets
0
     def ticket_list(options = {})
0
       ts = []
0
- @tickets.each do |name, t|
0
+ @last_tickets = []
0
+
0
+ tix = @tickets.to_a.sort
0
+ tix.each do |name, t|
0
         ts << TicGit::Ticket.open(self, name, t)
0
+ @last_tickets << name
0
       end
0
+ save_state
0
       ts
0
     end
0
     
0
     # returns single Ticket
0
- def ticket_show(ticket_id)
0
+ def ticket_show(ticket_id = nil)
0
+ # ticket_id can be index of last_tickets, partial sha or nil => last ticket
0
+ if t = ticket_revparse(ticket_id)
0
+ return TicGit::Ticket.open(self, t, @tickets[t])
0
+ end
0
+ end
0
+
0
+ def ticket_revparse(ticket_id)
0
+ if ticket_id
0
+ if t = @last_tickets[ticket_id.to_i - 1]
0
+ return t
0
+ else
0
+ # !! TODO: check for (partial) sha in @tickets
0
+ end
0
+ elsif(@current_ticket)
0
+ return @current_ticket
0
+ end
0
     end
0
     
0
     # returns array of Tickets
0
     def ticket_find(search_array)
0
     end
0
+
0
+ def ticket_tag(tag, ticket_id = nil, options = {})
0
+ if t = ticket_revparse(ticket_id)
0
+ ticket = TicGit::Ticket.open(self, t, @tickets[t])
0
+ if options[:remove]
0
+ ticket.remove_tag(tag)
0
+ else
0
+ ticket.add_tag(tag)
0
+ end
0
+ reset_ticgit
0
+ end
0
+ end
0
+
0
+ def ticket_change(new_state, ticket_id = nil)
0
+ if t = ticket_revparse(ticket_id)
0
+ ticket = TicGit::Ticket.open(self, t, @tickets[t])
0
+ in_branch do
0
+ file1 = ticket.path
0
+ file2 = File.join(new_state, ticket.ticket_name)
0
+ if file1 != file2
0
+ git.lib.mv(file1, file2)
0
+ git.commit('changed the state of ' + ticket.ticket_name + ' to ' + new_state)
0
+ reset_ticgit
0
+ end
0
+ end
0
+ end
0
+ end
0
     
0
- def ticket_change(ticket_id, new_state = 'open')
0
+ def ticket_checkout(ticket_id)
0
+ if t = ticket_revparse(ticket_id)
0
+ ticket = TicGit::Ticket.open(self, t, @tickets[t])
0
+ @current_ticket = ticket.ticket_name
0
+ save_state
0
+ end
0
     end
0
 
0
     
0
@@ -57,7 +148,7 @@ module TicGit
0
       ['open', 'resolved', 'invalid', 'hold']
0
     end
0
         
0
- def load_ticgits
0
+ def load_tickets
0
       @tickets = {}
0
 
0
       bs = git.lib.branches_all.map { |b| b[0] }
0
@@ -99,14 +190,17 @@ module TicGit
0
       end
0
       
0
       old_current = git.lib.branch_current
0
- git.lib.change_head_branch('ticgit')
0
- git.with_index(@tic_index) do
0
- git.with_working(@tic_working) do |wd|
0
- git.lib.checkout('ticgit') if needs_checkout
0
- yield wd
0
+ begin
0
+ git.lib.change_head_branch('ticgit')
0
+ git.with_index(@tic_index) do
0
+ git.with_working(@tic_working) do |wd|
0
+ git.lib.checkout('ticgit') if needs_checkout
0
+ yield wd
0
+ end
0
         end
0
+ ensure
0
+ git.lib.change_head_branch(old_current)
0
       end
0
- git.lib.change_head_branch(old_current)
0
     end
0
           
0
     def new_file(name, contents)
...
6
7
8
9
 
10
11
12
...
20
21
22
23
 
24
25
26
...
28
29
30
31
32
 
 
33
34
 
35
36
 
 
 
 
 
 
37
38
39
40
41
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
43
44
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
46
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47
48
49
 
 
50
51
52
53
54
55
56
57
...
61
62
63
64
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
65
66
67
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
69
70
 
71
72
73
74
75
76
 
 
 
 
 
 
 
 
 
 
 
 
 
77
78
79
...
6
7
8
 
9
10
11
12
...
20
21
22
 
23
24
25
26
...
28
29
30
 
 
31
32
33
 
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
 
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
 
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
 
214
215
216
...
220
221
222
 
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
0
@@ -6,7 +6,7 @@ require 'optparse'
0
 module TicGit
0
   class CLI
0
     # The array of (unparsed) command-line options
0
- attr_reader :action, :options, :args
0
+ attr_reader :action, :options, :args, :tic
0
 
0
     def self.execute
0
       parse(ARGV).execute!
0
@@ -20,7 +20,7 @@ module TicGit
0
 
0
     def initialize(args)
0
       @args = args.dup
0
- @tic = TicGit.open('.')
0
+ @tic = TicGit.open('.', :keep_state => true)
0
       $stdout.sync = true # so that Net::SSH prompts show up
0
     end
0
     
0
@@ -28,30 +28,189 @@ module TicGit
0
       case action
0
       when 'list':
0
         handle_ticket_list
0
- when 'find'
0
- puts 'find'
0
+ when 'state'
0
+ handle_ticket_state
0
       when 'show'
0
- puts 'show'
0
+ handle_ticket_show
0
       when 'new'
0
         handle_ticket_new
0
+ when 'checkout', 'co'
0
+ handle_ticket_checkout
0
+ when 'comment'
0
+ handle_ticket_comment
0
+ when 'tag'
0
+ handle_ticket_tag
0
       else
0
         puts 'not a command'
0
       end
0
     end
0
     
0
+
0
+
0
+ def parse_ticket_tag
0
+ @options = {}
0
+ OptionParser.new do |opts|
0
+ opts.banner = "Usage: ti tag [tic_id] [options] [tag_name] "
0
+ opts.on("-d", "Remove this tag from the ticket") do |v|
0
+ @options[:remove] = v
0
+ end
0
+ end.parse!
0
+ end
0
+
0
+ def handle_ticket_tag
0
+ parse_ticket_tag
0
+
0
+ if options[:remove]
0
+ puts 'remove'
0
+ end
0
+
0
+ tid = nil
0
+ if ARGV.size > 2
0
+ tid = ARGV[1].chomp
0
+ tic.ticket_tag(ARGV[2].chomp, tid, options)
0
+ elsif ARGV.size > 1
0
+ tic.ticket_tag(ARGV[1], nil, options)
0
+ else
0
+ puts 'You need to at least specify one tag to add'
0
+ end
0
+ end
0
+
0
+ def parse_ticket_comment
0
+ @options = {}
0
+ OptionParser.new do |opts|
0
+ opts.banner = "Usage: ti comment [tic_id] [options]"
0
+ opts.on("-m MESSAGE", "--message MESSAGE", "Message you would like to add as a comment") do |v|
0
+ @options[:message] = v
0
+ end
0
+ end.parse!
0
+ end
0
+
0
+ def handle_ticket_comment
0
+ parse_ticket_comment
0
+
0
+ tid = nil
0
+ tid = ARGV[1].chomp if ARGV[1]
0
+
0
+ if(m = options[:message])
0
+ tic.ticket_comment(m, tid)
0
+ else
0
+ if message = get_editor_message
0
+ tic.ticket_comment(message.join(''), tid)
0
+ end
0
+ end
0
+ end
0
+
0
+
0
+ def handle_ticket_checkout
0
+ tid = ARGV[1].chomp
0
+ tic.ticket_checkout(tid)
0
+ end
0
+
0
+ def handle_ticket_state
0
+ if ARGV.size > 2
0
+ tid = ARGV[1].chomp
0
+ new_state = ARGV[2].chomp
0
+ if valid_state(new_state)
0
+ tic.ticket_change(new_state, tid)
0
+ else
0
+ puts 'Invalid State - please choose from : ' + tic.tic_states.join(", ")
0
+ end
0
+ elsif ARGV.size > 1
0
+ # new state
0
+ new_state = ARGV[1].chomp
0
+ if valid_state(new_state)
0
+ tic.ticket_change(new_state)
0
+ else
0
+ puts 'Invalid State - please choose from : ' + tic.tic_states.join(", ")
0
+ end
0
+ else
0
+ puts 'You need to at least specify a new state for the current ticket'
0
+ end
0
+ end
0
+
0
+ def valid_state(state)
0
+ tic.tic_states.include?(state)
0
+ end
0
+
0
+ ## LIST TICKETS ##
0
+
0
     def handle_ticket_list
0
       counter = 0
0
- @tic.ticket_list.each do |t|
0
+
0
+
0
+ puts [' ', just('#', 4, 'r'),
0
+ just('TicId', 6),
0
+ just('Title', 25),
0
+ just('State', 5),
0
+ just('Date', 5),
0
+ just('Assgn', 8),
0
+ just('Tags', 20) ].join(" ")
0
+
0
+ a = []
0
+ 80.times { a << '-'}
0
+ puts a.join('')
0
+
0
+ tic.ticket_list.each do |t|
0
         counter += 1
0
- puts [counter, t.ticket_id[0,6], "\t", t.ticket_name].join(" ")
0
+ tic.current_ticket == t.ticket_name ? add = '*' : add = ' '
0
+ puts [add, just(counter, 4, 'r'),
0
+ t.ticket_id[0,6],
0
+ just(t.title, 25),
0
+ just(t.state, 5),
0
+ t.opened.strftime("%m/%d"),
0
+ just(t.assigned_name, 8),
0
+ just(t.tags.join(','), 20) ].join(" ")
0
+ end
0
+ end
0
+
0
+ ## SHOW TICKETS ##
0
+
0
+ def handle_ticket_show
0
+ if t = @tic.ticket_show(ARGV[1])
0
+ ticket_show(t)
0
+ end
0
+ end
0
+
0
+ def ticket_show(t)
0
+ days_ago = ((Time.now - t.opened) / (60 * 60 * 24)).round.to_s
0
+ puts
0
+ puts just('Title', 10) + ': ' + t.title
0
+ puts just('TicId', 10) + ': ' + t.ticket_id
0
+ puts
0
+ puts just('Assigned', 10) + ': ' + t.assigned.to_s
0
+ puts just('Opened', 10) + ': ' + t.opened.to_s + ' (' + days_ago + ' days)'
0
+ puts just('State', 10) + ': ' + t.state.upcase
0
+ if !t.tags.empty?
0
+ puts just('Tags', 10) + ': ' + t.tags.join(', ')
0
+ end
0
+ puts
0
+ if !t.comments.empty?
0
+ puts 'Comments (' + t.comments.size.to_s + '):'
0
+ t.comments.reverse.each do |c|
0
+ puts ' * Added ' + c.added.strftime("%m/%d %H:%M") + ' by ' + c.user
0
+
0
+ wrapped = c.comment.split("\n").collect do |line|
0
+ line.length > 80 ? line.gsub(/(.{1,80})(\s+|$)/, "\\1\n").strip : line
0
+ end * "\n"
0
+
0
+ wrapped = wrapped.split("\n").map { |line| "\t" + line }
0
+ if wrapped.size > 6
0
+ puts wrapped[0, 6].join("\n")
0
+ puts "\t** more... **"
0
+ else
0
+ puts wrapped.join("\n")
0
+ end
0
+ puts
0
+ end
0
       end
0
     end
0
     
0
+ ## NEW TICKETS ##
0
+
0
     def parse_ticket_new
0
       @options = {}
0
       OptionParser.new do |opts|
0
         opts.banner = "Usage: ti new [options]"
0
-
0
         opts.on("-t TITLE", "--title TITLE", "Title to use for the name of the new ticket") do |v|
0
           @options[:title] = v
0
         end
0
@@ -61,18 +220,74 @@ module TicGit
0
     def handle_ticket_new
0
       parse_ticket_new
0
       if(t = options[:title])
0
- puts @tic.ticket_new(t, options)
0
+ ticket_show(@tic.ticket_new(t, options))
0
+ else
0
+ # interactive
0
+ message_file = Tempfile.new('ticgit_message').path
0
+ File.open(message_file, 'w') do |f|
0
+ f.puts "\n# ---"
0
+ f.puts "tags:"
0
+ f.puts "# first line will be the title of the tic, the rest will be the first comment"
0
+ f.puts "# if you would like to add initial tags, put them on the 'tags:' line, comma delim"
0
+ end
0
+ if message = get_editor_message(message_file)
0
+ title = message.shift
0
+ if title && title.chomp.length > 0
0
+ title = title.chomp
0
+ if message.last[0, 5] == 'tags:'
0
+ tags = message.pop
0
+ tags = tags.gsub('tags:', '')
0
+ tags = tags.split(',').map { |t| t.strip }
0
+ end
0
+ if message.size > 0
0
+ comment = message.join("\n")
0
+ end
0
+ ticket_show(@tic.ticket_new(title, :comment => comment, :tags => tags))
0
+ else
0
+ puts "You need to at least enter a title"
0
+ end
0
+ else
0
+ puts "It seems you wrote nothing"
0
+ end
0
       end
0
     end
0
     
0
+ def get_editor_message(message_file = nil)
0
+ message_file = Tempfile.new('ticgit_message').path if !message_file
0
+
0
+ editor = ENV["EDITOR"] || 'vim'
0
+ system("#{editor} #{message_file}");
0
+ message = File.readlines(message_file)
0
+ message = message.select { |line| line[0, 1] != '#' } # removing comments
0
+ if message.empty?
0
+ return false
0
+ else
0
+ return message
0
+ end
0
+ end
0
+
0
     def parse_options! #:nodoc:
0
       if args.empty?
0
         warn "Please specify at least one action to execute."
0
+ puts " list state show new checkout comment tag "
0
         exit
0
       end
0
 
0
       @action = args.first
0
     end
0
     
0
+
0
+ def just(value, size, side = 'l')
0
+ value = value.to_s
0
+ if value.size > size
0
+ value = value[0, size]
0
+ end
0
+ if side == 'r'
0
+ return value.rjust(size)
0
+ else
0
+ return value.ljust(size)
0
+ end
0
+ end
0
+
0
   end
0
 end
0
\ No newline at end of file
...
1
2
3
4
 
5
6
 
 
7
8
 
 
 
 
9
 
 
 
 
 
10
11
12
13
 
14
15
16
17
18
19
20
 
21
 
 
 
 
 
 
 
 
 
 
22
23
24
25
26
 
 
 
 
 
 
 
 
 
 
27
28
29
30
31
32
33
34
35
 
 
 
 
 
 
 
36
37
38
39
40
41
42
43
44
45
46
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47
48
 
49
50
51
52
53
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
56
 
57
58
59
...
1
2
3
 
4
5
 
6
7
8
 
9
10
11
12
13
14
15
16
17
18
19
20
21
 
22
23
24
25
26
27
28
 
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
 
59
 
60
61
62
63
64
65
66
67
68
69
70
71
72
73
 
 
 
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
 
176
177
178
179
0
@@ -1,59 +1,179 @@
0
 module TicGit
0
   class Ticket
0
   
0
- attr_reader :base
0
+ attr_reader :base, :opts
0
     attr_accessor :ticket_id, :ticket_name
0
- attr_accessor :title, :milestone, :assigned, :comments, :tags, :attachments
0
+ attr_accessor :title, :state, :milestone, :assigned, :opened
0
+ attr_accessor :comments, :tags, :attachments # arrays
0
     
0
- def initialize(base)
0
+ def initialize(base, options = {})
0
+ options[:user_name] ||= base.git.config('user.name')
0
+ options[:user_email] ||= base.git.config('user.email')
0
+
0
       @base = base
0
+ @opts = options || {}
0
+
0
+ @comments = []
0
+ @tags = []
0
+ @attachments = []
0
     end
0
   
0
     def self.create(base, title, options = {})
0
- t = Ticket.new(base)
0
+ t = Ticket.new(base, options)
0
       t.title = title
0
       t.ticket_name = self.create_ticket_name(title)
0
       t.save_new
0
       t
0
     end
0
     
0
- def self.open(base, ticket_name, ticket_hash)
0
+ def self.open(base, ticket_name, ticket_hash, options = {})
0
       tid = nil
0
+
0
+ t = Ticket.new(base, options)
0
+ t.ticket_name = ticket_name
0
+
0
+ title, date = self.parse_ticket_name(ticket_name)
0
+
0
+ t.title = title
0
+ t.opened = date
0
+ t.state = ticket_hash['state']
0
+
0
       ticket_hash['files'].each do |fname, value|
0
         if fname == 'TICKET_ID'
0
           tid = value
0
         else
0
           # matching
0
+ data = fname.split('_')
0
+ if data[0] == 'ASSIGNED'
0
+ t.assigned = data[1]
0
+ end
0
+ if data[0] == 'COMMENT'
0
+ t.comments << TicGit::Comment.new(base, fname, value)
0
+ end
0
+ if data[0] == 'TAG'
0
+ t.tags << data[1]
0
+ end
0
         end
0
       end
0
       
0
- t = Ticket.new(base)
0
       t.ticket_id = tid
0
- t.ticket_name = ticket_name
0
       t
0
     end
0
     
0
+
0
+ def self.parse_ticket_name(name)
0
+ epoch, title, rand = name.split('-')
0
+ title = title.gsub('_', ' ')
0
+ return [title, Time.at(epoch.to_i)]
0
+ end
0
+
0
     # write this ticket to the git database
0
     def save_new
0
       base.in_branch do |wd|
0
         puts "saving #{ticket_name}"
0
-
0
- puts `pwd`
0
-
0
         Dir.chdir('open') do
0
           Dir.mkdir(ticket_name)
0
           Dir.chdir(ticket_name) do
0
             base.new_file('TICKET_ID', ticket_name)
0
+ base.new_file('ASSIGNED_' + email, ticket_name)
0
+
0
+ # add initial comment
0
+ #COMMENT_080315060503045__schacon_at_gmail
0
+ base.new_file(comment_name(email), opts[:comment]) if opts[:comment]
0
+
0
+ # add initial tags
0
+ if opts[:tags] && opts[:tags].size > 0
0
+ opts[:tags].each do |tag|
0
+ tag_filename = 'TAG_' + Ticket.clean_string(tag)
0
+ if !File.exists?(tag_filename)
0
+ base.new_file(tag_filename, tag_filename)
0
+ end
0
+ end
0
+ end
0
+
0
+ # !! TODO : add initial milestone
0
+
0
           end
0
         end
0
+
0
         base.git.add
0
         base.git.commit("added ticket #{ticket_name}")
0
       end
0
       # ticket_id
0
     end
0
+
0
+ def self.clean_string(string)
0
+ string.downcase.gsub(/[^a-z0-9]+/i, '_')
0
+ end
0
+
0
+ def add_comment(comment)
0
+ return false if !comment
0
+ base.in_branch do |wd|
0
+ Dir.chdir(File.join(state, ticket_name)) do
0
+ base.new_file(comment_name(email), comment)
0
+ end
0
+ base.git.add
0
+ base.git.commit("added comment to ticket #{ticket_name}")
0
+ end
0
+ end
0
 
0
+ def add_tag(tag)
0
+ return false if !tag
0
+ added = false
0
+ tags = tag.split(',').map { |t| t.strip }
0
+ base.in_branch do |wd|
0
+ Dir.chdir(File.join(state, ticket_name)) do
0
+ tags.each do |add_tag|
0
+ tag_filename = 'TAG_' + Ticket.clean_string(add_tag)
0
+ if !File.exists?(tag_filename)
0
+ base.new_file(tag_filename, tag_filename)
0
+ added = true
0
+ end
0
+ end
0
+ end
0
+ if added
0
+ base.git.add
0
+ base.git.commit("added tags (#{tag}) to ticket #{ticket_name}")
0
+ end
0
+ end
0
+ end
0
+
0
+ def remove_tag(tag)
0
+ return false if !tag
0
+ removed = false
0
+ tags = tag.split(',').map { |t| t.strip }
0
+ base.in_branch do |wd|
0
+ tags.each do |add_tag|
0
+ tag_filename = File.join(state, ticket_name, 'TAG_' + Ticket.clean_string(add_tag))
0
+ if File.exists?(tag_filename)
0
+ base.git.remove(tag_filename)
0
+ removed = true
0
+ end
0
+ end
0
+ if removed
0
+ base.git.commit("removed tags (#{tag}) from ticket #{ticket_name}")
0
+ end
0
+ end
0
+ end
0
+
0
+ def path
0
+ File.join(state, ticket_name)
0
+ end
0
+
0
+ def comment_name(email)
0
+ 'COMMENT_' + Time.now.to_i.to_s + '_' + email
0
+ end
0
+
0
+ def email
0
+ opts[:user_email] || 'anon'
0
+ end
0
+
0
+ def assigned_name
0
+ assigned.split('@').first rescue ''
0
+ end
0
+
0
     def self.create_ticket_name(title)
0
- [Time.now.to_i.to_s, title.downcase.gsub(/[^a-z0-9]+/i, '_'), rand(999).to_i.to_s].join('-')
0
+ [Time.now.to_i.to_s, Ticket.clean_string(title), rand(999).to_i.to_s].join('-')
0
     end
0
 
0
     

Comments

    No one has commented yet.