flurin-ticgit 0.3.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/bin/ti ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # This is a command line client that does all the actual tic commands
4
+ #
5
+ # authors: Scott Chacon <schacon@gmail.com>
6
+ # Mislav Marohnić <mislav.marohnic@gmail.com>
7
+
8
+ require File.dirname(__FILE__) + "/../lib/ticgit"
9
+
10
+ TicGit::CLI::start()
data/bin/ticgitweb ADDED
@@ -0,0 +1,517 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # starts a sinatra based web server that provides an interface to
4
+ # your ticgit tickets
5
+ #
6
+ # some of the sinatra code borrowed from sr's git-wiki
7
+ #
8
+ # author: Flurin Egger
9
+ # original author : Scott Chacon (schacon@gmail.com)
10
+ #
11
+
12
+ def require_dependency_with_check(dependency)
13
+ begin
14
+ require dependency
15
+ rescue LoadError => e
16
+ puts "You need to install #{dependency} before we can proceed"
17
+ end
18
+ end
19
+
20
+ require_dependency_with_check 'rubygems'
21
+
22
+ # We need a sinatra version bigger than 0.3.1
23
+ gem 'sinatra', "~> 0.3.1"
24
+
25
+ %w(sinatra git ticgit haml sass).each do |dependency|
26
+ require_dependency_with_check dependency
27
+ end
28
+
29
+
30
+ configure do
31
+ enable :sessions
32
+ end
33
+ use_in_file_templates!
34
+
35
+ # !! TODO : if ARGV[1] is a path to a git repo, use that
36
+ # otherwise, look in ~/.ticgit
37
+
38
+ $ticgit = TicGit.open('.')
39
+
40
+ # Always load saved searches. (used in navigation)
41
+ before do
42
+ @saved = $ticgit.config['list_options'].keys rescue []
43
+ end
44
+
45
+ # Stylesheets
46
+ get('/_stylesheet.css') do
47
+ header("Content-Type" => "text/css;charset=utf-8")
48
+ sass :stylesheet_all
49
+ end
50
+ get('/_print.css') do
51
+ header("Content-Type" => "text/css;charset=utf-8")
52
+ sass :stylesheet_print
53
+ end
54
+
55
+ # ticket list view
56
+ get '/' do
57
+ @tickets = $ticgit.ticket_list(:order => 'date.desc')
58
+ store_list_url!
59
+ haml :list, :locals => {:title => "All tickets"}
60
+ end
61
+
62
+ get '/fs/:state' do
63
+ @tickets = $ticgit.ticket_list(:state => params[:state], :order => 'date.desc')
64
+ store_list_url!
65
+ haml :list, :locals => {:title => "#{params[:state].to_s.capitalize} tickets"}
66
+ end
67
+
68
+ get '/tag/:tag' do
69
+ @tickets = $ticgit.ticket_list(:tag => params[:tag], :order => 'date.desc')
70
+ store_list_url!
71
+ haml :list, :locals => {:title => "All tickets with tag '#{params[:tag]}'"}
72
+ end
73
+
74
+ get '/sv/:saved_view' do
75
+ @tickets = $ticgit.ticket_list(:saved => params[:saved_view])
76
+ store_list_url!
77
+ haml :list, :locals => {:title => "All tickets in view '#{params[:saved_view]}'"}
78
+ end
79
+
80
+
81
+ # new ticket
82
+ get '/tickets/new' do
83
+ haml :new, :locals => {:title => "Create new ticket"}
84
+ end
85
+
86
+ # create ticket
87
+ post '/tickets' do
88
+ title = params[:title].to_s.strip
89
+ if title.size > 1
90
+ tags = params[:tags].split(',').map { |t| t.strip } rescue nil
91
+ t = $ticgit.ticket_new(title, {:description => params[:description].strip, :tags => tags})
92
+ if params[:addmore]
93
+ redirect '/tickets/new?addmore=true'
94
+ else
95
+ redirect session[:recent_list_url] || "/"
96
+ end
97
+ else
98
+ redirect '/tickets/new'
99
+ end
100
+ end
101
+
102
+ # show ticket
103
+ get '/tickets/:ticket' do
104
+ @ticket = $ticgit.ticket_show(params[:ticket])
105
+ haml :show, :locals => {:title => "Ticket #{@ticket.ticket_id}"}
106
+ end
107
+
108
+ # update ticket
109
+ put '/tickets/:ticket' do
110
+ @ticket = $ticgit.ticket_show(params[:ticket])
111
+ orig_state = nil
112
+ new_state = nil
113
+ new_tags = nil
114
+ if params[:state] && $ticgit.tic_states.include?(params[:state]) && @ticket.state != params[:state]
115
+ orig_state = @ticket.state
116
+ new_state = params[:state]
117
+ @ticket.change_state(params[:state])
118
+ end
119
+ if params[:tags]
120
+ current_tags = @ticket.tags
121
+ posted_tags = params[:tags].split(",").map{|s| s.strip }
122
+ tags_to_remove = current_tags - posted_tags
123
+ tags_to_add = posted_tags - current_tags
124
+ tags_to_remove.each{|t| @ticket.remove_tag(t) }
125
+ tags_to_add.each{|t| @ticket.add_tag(t) }
126
+ new_tags = posted_tags if tags_to_remove.any? || tags_to_add.any?
127
+ end
128
+
129
+ if params[:comment] && params[:comment].strip != ""
130
+ comment = ""
131
+ comment = "Set state from #{orig_state} to #{new_state}\n\n" if new_state
132
+ @ticket.add_comment(comment + params[:comment])
133
+ end
134
+
135
+ $ticgit.reset_ticgit
136
+
137
+ if ["resolved","invalid"].include?(params[:state]) && session[:recent_list_url]
138
+ # If the ticket is resolved or invalid return to the last listview
139
+ redirect session[:recent_list_url]
140
+ else
141
+ redirect "/tickets/#{@ticket.ticket_id}"
142
+ end
143
+ end
144
+
145
+
146
+ ## Helper methods
147
+
148
+ #
149
+ def store_list_url!
150
+ session[:recent_list_url] = request.fullpath
151
+ end
152
+
153
+
154
+ __END__
155
+ @@ layout
156
+ :plain
157
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
158
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
159
+ %html{:xmlns => "http://www.w3.org/1999/xhtml", "xml:lang" => "en", :lang=>"en"}
160
+ %head
161
+ %title= title
162
+ %link{:rel => 'stylesheet', :href => '/_stylesheet.css', :type => 'text/css', :media => 'all'}
163
+ %link{:rel => 'stylesheet', :href => '/_print.css', :type => 'text/css', :media => 'print'}
164
+ %meta{'http-equiv' => 'Content-Type', :content => 'text/html; charset=utf-8'}
165
+ %body
166
+ #wrapper
167
+ #action
168
+ %a{:href => '/tickets/new'} New Ticket
169
+ %ul#navigation
170
+ %li
171
+ %a{:href => '/'} All
172
+ %li
173
+ %a{:href => '/fs/open'} Open
174
+ %li
175
+ %a{:href => '/fs/resolved'} Resolved
176
+ %li
177
+ %a{:href => '/fs/hold'} Hold
178
+ %li
179
+ %a{:href => '/fs/invalid'} Invalid
180
+ - if @saved && !@saved.empty?
181
+ %li | Saved:
182
+ %ul.saved
183
+ - @saved.each do |s|
184
+ %li
185
+ %a{:href => "/sv/\#{s}"}= s
186
+
187
+ = yield
188
+
189
+ @@ list
190
+ %h1= title
191
+ - if @tickets.empty?
192
+ %p No tickets found.
193
+ - else
194
+ %table.long
195
+ %thead
196
+ %tr
197
+ %th SHA
198
+ %th.ticket Ticket
199
+ %th State
200
+ %th Created&nbsp;at
201
+ %th Created&nbsp;by
202
+ %th Tags
203
+ %tbody
204
+ - c = 'even'
205
+ - @tickets.each do |t|
206
+ %tr{:class => (c == 'even' ? c = 'odd' : c = 'even') }
207
+ %td
208
+ %a{:href => "/tickets/#{t.ticket_id}" }
209
+ %code= t.ticket_id[0,6]
210
+ %td
211
+ %strong
212
+ %a{:href => "/tickets/#{t.ticket_id}" }= t.title
213
+ .content~ t.description
214
+ %td
215
+ %span{:class => "state " + t.state, :style => "float: left;"}= t.state
216
+ %td= t.opened.strftime("%m/%d")
217
+ %td= t.assigned_name
218
+ %td
219
+ - t.tags.each do |tag|
220
+ %a.tag{:href => "/tag/#{tag}"}= tag
221
+
222
+ @@ show
223
+ %h1
224
+ = @ticket.title
225
+ .meta
226
+ %span{:class => "state " + @ticket.state}= @ticket.state
227
+ Ticket:
228
+ = @ticket.ticket_id
229
+ %br
230
+ opened at
231
+ %em= @ticket.opened.strftime("%Y-%m-%d")
232
+ assigned to
233
+ %em= @ticket.assigned
234
+ tagged with
235
+ - @ticket.tags.each do |t|
236
+ %a.tag{:href => "/tag/#{t}"}= t
237
+
238
+ .content~ @ticket.description
239
+ %hr/
240
+ %form{:action => "/tickets/#{@ticket.ticket_id}", :method => 'post'}
241
+ %input{:type => "hidden", :name => "_method", :value => "put"}
242
+ %table.twocol
243
+ %tr
244
+ %th State
245
+ %td
246
+ %select{:name => "state", :id => "ticket_state"}
247
+ - $ticgit.tic_states.each do |ts|
248
+ %option{:value => ts , :selected => (@ticket.state == ts ? "selected" : nil)}= ts
249
+ %tr
250
+ %th
251
+ Tags
252
+ %small (comma delimited)
253
+ %td
254
+ %textarea{:rows => 2, :name => "tags", :style => "width: 50%"}= @ticket.tags.join(", ")
255
+ %tr
256
+ %th
257
+ Comment
258
+ %small (optional)
259
+ %td
260
+ %textarea{:rows => 3, :name => "comment", :style => "width: 100%"}
261
+ %tr
262
+ %th
263
+ %td
264
+ %div.submit
265
+ %input{:type => 'submit', :value => 'Update ticket'}
266
+
267
+ %h3 Comments
268
+
269
+ %div.comments
270
+ - @ticket.comments.reverse.each do |t|
271
+ %div.comment
272
+ %span.head
273
+ Added
274
+ = t.added.strftime("%m/%d %H:%M")
275
+ by
276
+ = t.user
277
+ %div.comment-text
278
+ = t.comment.gsub("\n","<br/>")
279
+
280
+ @@ new
281
+ %h1 Create a New Ticket
282
+ %form{:action => '/tickets/new', :method => 'post'}
283
+ %table
284
+ %tr
285
+ %th Title
286
+ %td
287
+ %input{:type => 'text', :name => 'title', :size => 30, :style => "width: 100%"}
288
+ %tr
289
+ %th Description
290
+ %td
291
+ %textarea{:rows => 15, :cols => 30, :name => 'description', :style => "width: 100%"}
292
+ %tr
293
+ %th
294
+ %span Tags
295
+ %small (comma delimited)
296
+ %td
297
+ %textarea{:name => 'tags', :rows => 2, :style => "width: 50%"}
298
+ %tr
299
+ %th
300
+ %td
301
+ %label{:for => "addmore"}
302
+ %input{:type => "checkbox", :value => "1",:id => "addmore", :name => "addmore", :checked => (params["addmore"] ? "checked" : nil)}
303
+ %span Add another ticket
304
+ %tr
305
+ %td
306
+ %td
307
+ %input{:type => 'submit', :value => 'Create Ticket'}
308
+
309
+ @@ stylesheet_all
310
+ body
311
+ :font
312
+ family: Verdana, Arial, "Bitstream Vera Sans", Helvetica, sans-serif
313
+ color: black
314
+ size: 62.5%
315
+ line-height: 1.2
316
+ background-color: white
317
+ margin: 2em
318
+
319
+ #wrapper
320
+ font-size: 1.2em
321
+ width: 90%
322
+ margin: 0 auto
323
+
324
+ // Autoclearing
325
+ #navigation:after
326
+ content: "."
327
+ visibility: hidden
328
+ clear: both
329
+ display: block
330
+ height: 0px
331
+
332
+ // IE autoclearing
333
+ #navigation
334
+ zoom: 1
335
+
336
+ #navigation
337
+ li
338
+ float: left
339
+ margin-right: 0.5em
340
+ a
341
+ background-color: #e0e0e0
342
+ color: black
343
+ text-decoration: none
344
+ padding: 2px
345
+ margin: 0
346
+ list-style: none
347
+ padding: 5px
348
+ border-bottom: 1px black solid
349
+
350
+ #action
351
+ text-align: right
352
+ float: right
353
+ a
354
+ background: #005
355
+ padding: 5px 10px
356
+ font-weight: bold
357
+ color: #fff
358
+ float: left
359
+
360
+ .addtag
361
+ padding: 5px 0
362
+ clear: both
363
+
364
+ h1
365
+ display: block
366
+ padding-bottom: 5px
367
+ margin-bottom: 0
368
+
369
+ h4
370
+ margin: 0 0 0.5em 0
371
+
372
+ div.meta
373
+ margin-bottom: 1em
374
+ display: block
375
+ font-size: 0.9em
376
+ font-weight: normal
377
+ color: #666
378
+ em
379
+ color: #000
380
+ font-style: normal
381
+ font-weight: bold
382
+ a.tag
383
+ font-size: 1em
384
+ float: none
385
+ background: #eee
386
+ color: #000
387
+ span.state
388
+ float: left
389
+ margin-right: 1em
390
+ color: #000
391
+
392
+ div.content
393
+ padding-top: 1em
394
+ clear: both
395
+
396
+ form
397
+ padding: 10px
398
+ background: #f2f2f2
399
+ table
400
+ width: 100%
401
+ tr
402
+ th
403
+ width: 20%
404
+ th,td
405
+ border-bottom: none
406
+ .submit
407
+ margin: 0.5em 0 0 0
408
+
409
+ a
410
+ color: black
411
+ a.exists
412
+ font-weight: bold
413
+ a.unknown
414
+ font-style: italic
415
+
416
+ a.tag
417
+ padding: 2px 5px
418
+ background: #888
419
+ color: #fff
420
+ font-weight: normal
421
+ font-size: 80%
422
+ float: left
423
+ margin: 1px 2px
424
+ text-decoration: none
425
+
426
+ .comments
427
+ margin: 10px 0px
428
+ .comment
429
+ .head
430
+ font-weight: bold
431
+ display: block
432
+ padding: 4px
433
+ .comment-text
434
+ padding: 4px
435
+ padding-bottom: 10px
436
+ margin-bottom: 10px
437
+ color: #333
438
+ border-bottom: 1px solid #aaa
439
+
440
+ table.long
441
+ width: 100%
442
+ .content
443
+ padding: 0
444
+
445
+
446
+ // States
447
+ span.state
448
+ padding: 3px
449
+
450
+ span.open
451
+ background: #ada
452
+ span.resolved
453
+ background: #abd
454
+ span.hold
455
+ background: #dda
456
+ span.invalid
457
+ background: #aaa
458
+
459
+
460
+ table
461
+ font-size: 100%
462
+ border-collapse: collapse
463
+ th
464
+ small
465
+ font-weight: normal
466
+ td,th
467
+ vertical-align: top
468
+ tr.even
469
+ td
470
+ background: #eee
471
+ tr.odd
472
+ td
473
+ background: #fff
474
+
475
+ table
476
+ tr
477
+ td,th
478
+ padding: 3px 5px
479
+ border-bottom: 1px solid #fff
480
+ th
481
+ text-align: left
482
+ vertical-align: top
483
+ th.ticket
484
+ width: 50%
485
+
486
+ strong a
487
+ text-decoration: none
488
+
489
+ table
490
+ thead
491
+ tr
492
+ td,th
493
+ border-bottom: 1px solid #000
494
+
495
+ .submit
496
+ font-size: large
497
+ font-weight: bold
498
+
499
+ .page_title
500
+ font-size: xx-large
501
+
502
+ .edit_link
503
+ color: black
504
+ font-size: 14px
505
+ font-weight: bold
506
+ background-color: #e0e0e0
507
+ font-variant: small-caps
508
+ text-decoration: none
509
+
510
+ @@ stylesheet_print
511
+ #navigation, #action
512
+ display: none
513
+
514
+ table
515
+ tr.odd, tr.even
516
+ td
517
+ border-bottom: 1px solid #ddd