TicGit-ng 1.0.2.4 → 1.0.2.5

Sign up to get free protection for your applications and to get access to all the features.
data/README.mkd CHANGED
@@ -29,13 +29,9 @@ Required Ruby Gems: git
29
29
 
30
30
  To install these packages on a Debian system, or a Debian based system like Ubuntu, do
31
31
 
32
- sudo apt-get install git ruby rubygems
32
+ sudo aptitude install git ruby rubygems
33
33
  sudo gem install git
34
34
 
35
- After installing Gems it is necessary to update the PATH environment variable so that the scripts can be found. Issue the following command to the end of your .bachrc file or equivalent.
36
-
37
- PATH=$PATH:/var/lib/gems/1.8/bin
38
-
39
35
  **ticgitweb**
40
36
 
41
37
  Required Packages: git, ruby, rubygems
@@ -44,9 +40,11 @@ Required Ruby Gems: git, sinatra, haml, sass
44
40
 
45
41
  To install these packages on a Debian system, or a Debian based system like Ubuntu, do
46
42
 
47
- sudo apt-get install git ruby rubygems
48
- sudo gem install git sinatra haml
49
- sudo gem install sass --pre
43
+ sudo aptitude install git ruby rubygems
44
+ sudo gem install git sinatra haml sass
45
+
46
+
47
+
50
48
 
51
49
  **A Note about rubygems**
52
50
 
@@ -62,22 +60,19 @@ The git gem requires a git version of 1.6.0.0 or later, but on Debian stable, gi
62
60
 
63
61
  If these annoy you as they do me and you've set up [apt](http://jaqque.sbih.org/kplug/apt-pinning.html) [pinning](http://jeffwelling.github.com//2010/09/05/Apt-Pinning.html), you can do
64
62
 
65
- sudo apt-get -t testing install git-core
63
+ $ sudo aptitude -t testing install git-core
66
64
 
67
65
  And those notices should go away.
68
66
 
69
- **A Note about Ubuntu**
70
67
 
71
- NB At the time of writing (Ver 1.0.2.3) there are additional problems with TigGitWeb Ubuntu. The workaround is to add `/var/lib/gems/1.8/gems/TicGit-ng-1.0.2.3/bin` to start of PATH. viz
72
68
 
73
- PATH=/var/lib/gems/1.8/gems/TicGit-ng-1.0.2.3/bin:$PATH
74
69
 
75
70
  ### Installing ##
76
71
  Installation on a Debian stable system. Note that the command line interface for TicGit-ng can be run from Debian stable, but some of the gems required for the web interface may require you to use [apt](http://jaqque.sbih.org/kplug/apt-pinning.html) [pinning](http://jeffwelling.github.com//2010/09/05/Apt-Pinning.html) to run without errors. See below
77
72
 
78
73
  To install TicGit-ng on your system, you can go one of two ways,
79
74
 
80
- $ sudo gem install TicGit-ng
75
+ $ gem install TicGit-ng
81
76
 
82
77
  or, you can install it from source by downloading this repository building your own gem (see below).
83
78
 
@@ -206,11 +206,9 @@ module TicGitNG
206
206
  if ticket_id
207
207
  ticket_id = ticket_id.strip
208
208
 
209
- if /^[0-9]*$/ =~ ticket_id
210
- if t = @last_tickets[ticket_id.to_i - 1]
211
- return t
212
- end
213
- else # partial or full sha
209
+ if /^[0-9]*$/ =~ ticket_id && (t = @last_tickets[ticket_id.to_i - 1])
210
+ return t
211
+ elsif ticket_id.length > 4 # partial (5 characters or greater to be considered unique enough) or full sha
214
212
  regex = /^#{Regexp.escape(ticket_id)}/
215
213
  ch = tickets.select{|name, t|
216
214
  t['files'].assoc('TICKET_ID')[1] =~ regex }
data/lib/ticgit-ng/cli.rb CHANGED
@@ -20,10 +20,10 @@ module TicGitNG
20
20
  attr_accessor :out
21
21
 
22
22
  def initialize(args, path = '.', out = $stdout)
23
- @out = out
24
23
  @args = args.dup
25
24
  @tic = TicGitNG.open(path, :keep_state => true)
26
25
  @options = OpenStruct.new
26
+ @out = out
27
27
 
28
28
  @out.sync = true # so that Net::SSH prompts show up
29
29
  rescue NoRepoFound
@@ -9,7 +9,7 @@ module TicGitNG
9
9
  commands.each{|cmd| COMMANDS[cmd] = mod_name }
10
10
  end
11
11
 
12
- register 'Assign', 'Assigns a ticket to someone', 'assign'
12
+ register 'Assign', 'Assings a ticket to someone', 'assign'
13
13
  register 'Attach', 'Attach file to ticket', 'attach'
14
14
  register 'Checkout', 'Checkout a ticket', 'checkout', 'co'
15
15
  register 'Comment', 'Comment on a ticket', 'comment'
@@ -40,7 +40,10 @@ module TicGitNG
40
40
  o.top.append ' ', nil, nil
41
41
  o.top.append 'The available ticgit commands are:', nil, nil
42
42
 
43
- DOC.each do |commands, doc|
43
+ sorted_doc = DOC.sort_by do |cmds, doc|
44
+ cmds.sort_by{|cmd| cmd.size }.last
45
+ end
46
+ sorted_doc.each do |commands, doc|
44
47
  # get the longest version
45
48
  command = commands.sort_by{|cmd| cmd.size }.last
46
49
  o.top.append(" %-32s %s" % [command, doc], nil, nil)
@@ -0,0 +1,258 @@
1
+ module TicGitNG
2
+ class Ticket
3
+
4
+ attr_reader :base, :opts
5
+ attr_accessor :ticket_id, :ticket_name
6
+ attr_accessor :title, :state, :milestone, :assigned, :opened, :points
7
+ attr_accessor :comments, :tags, :attachments # arrays
8
+
9
+ def initialize(base, options = {})
10
+ # FIXME: what/where/who/how changed config to hash?
11
+ if (cfg = base.git.config).is_a? Hash
12
+ options[:user_name] ||= cfg["user.name"]
13
+ options[:user_email] ||= cfg["user.email"]
14
+ else
15
+ options[:user_name] ||= cfg("user.name")
16
+ options[:user_email] ||= cfg("user.email")
17
+ end
18
+
19
+ @base = base
20
+ @opts = options || {}
21
+
22
+ @state = 'open' # by default
23
+ @comments = []
24
+ @tags = []
25
+ @attachments = []
26
+ end
27
+
28
+ def self.create(base, title, options = {})
29
+ t = Ticket.new(base, options)
30
+ t.title = title
31
+ t.ticket_name = self.create_ticket_name(title)
32
+ t.save_new
33
+ t
34
+ end
35
+
36
+ def self.open(base, ticket_name, ticket_hash, options = {})
37
+ tid = nil
38
+
39
+ t = Ticket.new(base, options)
40
+ t.ticket_name = ticket_name
41
+
42
+ title, date = self.parse_ticket_name(ticket_name)
43
+ t.opened = date
44
+
45
+ ticket_hash['files'].each do |fname, value|
46
+ if fname == 'TICKET_ID'
47
+ tid = value
48
+ elsif fname == 'TICKET_TITLE'
49
+ t.title = base.git.gblob(value).contents
50
+ else
51
+ # matching
52
+ data = fname.split('_')
53
+
54
+ case data[0]
55
+ when 'ASSIGNED'
56
+ t.assigned = data[1]
57
+ when 'ATTACHMENT'
58
+ t.attachments << TicGitNG::Attachment.new(base, fname, value)
59
+ when 'COMMENT'
60
+ t.comments << TicGitNG::Comment.new(base, fname, value)
61
+ when 'POINTS'
62
+ t.points = base.git.gblob(value).contents.to_i
63
+ when 'STATE'
64
+ t.state = data[1]
65
+ when 'TAG'
66
+ t.tags << data[1]
67
+ when 'TITLE'
68
+ t.title = base.git.gblob(value).contents
69
+ end
70
+ end
71
+ end
72
+
73
+ t.ticket_id = tid
74
+ t
75
+ end
76
+
77
+
78
+ def self.parse_ticket_name(name)
79
+ epoch, title, rand = name.split('_')
80
+ title = title.gsub('-', ' ')
81
+ return [title, Time.at(epoch.to_i)]
82
+ end
83
+
84
+ # write this ticket to the git database
85
+ def save_new
86
+ base.in_branch do |wd|
87
+ files=[]
88
+ t=nil
89
+ base.logger.info "saving #{ticket_name}"
90
+
91
+ Dir.mkdir(ticket_name)
92
+ Dir.chdir(ticket_name) do
93
+ base.new_file('TICKET_ID', ticket_name)
94
+ files << File.join( ticket_name, 'TICKET_ID' )
95
+ base.new_file('TICKET_TITLE', title)
96
+ files << File.join( ticket_name, 'TICKET_TITLE' )
97
+ base.new_file( (t='ASSIGNED_'+email) , email)
98
+ files << File.join( ticket_name, t )
99
+ base.new_file( (t='STATE_'+state) , state)
100
+ files << File.join( ticket_name, t )
101
+ base.new_file('TITLE', title)
102
+ files << File.join( ticket_name, 'TITLE' )
103
+
104
+ # add initial comment
105
+ #COMMENT_080315060503045__schacon_at_gmail
106
+ if opts[:comment]
107
+ base.new_file(t=comment_name(email), opts[:comment])
108
+ files << File.join( ticket_name, t )
109
+ end
110
+
111
+ # add initial tags
112
+ if opts[:tags] && opts[:tags].size > 0
113
+ opts[:tags] = opts[:tags].map { |t| t.strip }.compact
114
+ opts[:tags].each do |tag|
115
+ if tag.size > 0
116
+ tag_filename = 'TAG_' + Ticket.clean_string(tag)
117
+ if !File.exists?(tag_filename)
118
+ base.new_file(tag_filename, tag_filename)
119
+ files << File.join( ticket_name, tag_filename )
120
+ end
121
+ end
122
+ end
123
+ end
124
+ end
125
+ files.each {|file|
126
+ base.git.add file
127
+ }
128
+ base.git.commit("added ticket #{ticket_name}")
129
+ end
130
+ # ticket_id
131
+ end
132
+
133
+ def self.clean_string(string)
134
+ string.downcase.gsub(/[^a-z0-9]+/i, '-')
135
+ end
136
+
137
+ def add_comment(comment)
138
+ return false if !comment
139
+ base.in_branch do |wd|
140
+ t=nil
141
+ Dir.chdir(ticket_name) do
142
+ base.new_file(t=comment_name(email), comment)
143
+ end
144
+ base.git.add File.join(ticket_name, t)
145
+ base.git.commit("added comment to ticket #{ticket_name}")
146
+ end
147
+ end
148
+
149
+ def change_state(new_state)
150
+ return false if !new_state
151
+ return false if new_state == state
152
+
153
+ base.in_branch do |wd|
154
+ Dir.chdir(ticket_name) do
155
+ base.new_file(t='STATE_' + new_state, new_state)
156
+ end
157
+ base.git.remove(File.join(ticket_name,'STATE_' + state))
158
+ base.git.add File.join(ticket_name, t)
159
+ base.git.commit("added state (#{new_state}) to ticket #{ticket_name}")
160
+ end
161
+ end
162
+
163
+ def change_assigned(new_assigned)
164
+ new_assigned ||= email
165
+ old_assigned= assigned || ''
166
+ return false if new_assigned == old_assigned
167
+
168
+ base.in_branch do |wd|
169
+ t=nil
170
+ Dir.chdir(ticket_name) do
171
+ base.new_file(t='ASSIGNED_' + new_assigned, new_assigned)
172
+ end
173
+ base.git.remove(File.join(ticket_name,'ASSIGNED_' + old_assigned))
174
+ base.git.add File.join(ticket_name,t)
175
+ base.git.commit("assigned #{new_assigned} to ticket #{ticket_name}")
176
+ end
177
+ end
178
+
179
+ def change_points(new_points)
180
+ return false if new_points == points
181
+
182
+ base.in_branch do |wd|
183
+ Dir.chdir(ticket_name) do
184
+ base.new_file('POINTS', new_points)
185
+ end
186
+ base.git.add File.join(ticket_name, 'POINTS')
187
+ base.git.commit("set points to #{new_points} for ticket #{ticket_name}")
188
+ end
189
+ end
190
+
191
+ def add_tag(tag)
192
+ return false if !tag
193
+ files=[]
194
+ added = false
195
+ tags = tag.split(',').map { |t| t.strip }
196
+ base.in_branch do |wd|
197
+ Dir.chdir(ticket_name) do
198
+ tags.each do |add_tag|
199
+ if add_tag.size > 0
200
+ tag_filename = 'TAG_' + Ticket.clean_string(add_tag)
201
+ if !File.exists?(tag_filename)
202
+ base.new_file(tag_filename, tag_filename)
203
+ files << File.join( ticket_name, tag_filename )
204
+ added = true
205
+ end
206
+ end
207
+ end
208
+ end
209
+ if added
210
+ files.each {|file|
211
+ base.git.add file
212
+ }
213
+ base.git.commit("added tags (#{tag}) to ticket #{ticket_name}")
214
+ end
215
+ end
216
+ end
217
+
218
+ def remove_tag(tag)
219
+ return false if !tag
220
+ removed = false
221
+ tags = tag.split(',').map { |t| t.strip }
222
+ base.in_branch do |wd|
223
+ tags.each do |add_tag|
224
+ tag_filename = File.join(ticket_name, 'TAG_' + Ticket.clean_string(add_tag))
225
+ if File.exists?(tag_filename)
226
+ base.git.remove(tag_filename)
227
+ removed = true
228
+ end
229
+ end
230
+ if removed
231
+ base.git.commit("removed tags (#{tag}) from ticket #{ticket_name}")
232
+ end
233
+ end
234
+ end
235
+
236
+ def path
237
+ File.join(state, ticket_name)
238
+ end
239
+
240
+ def comment_name(email)
241
+ 'COMMENT_' + Time.now.to_i.to_s + '_' + email
242
+ end
243
+
244
+ def email
245
+ opts[:user_email] || 'anon'
246
+ end
247
+
248
+ def assigned_name
249
+ assigned.split('@').first rescue ''
250
+ end
251
+
252
+ def self.create_ticket_name(title)
253
+ [Time.now.to_i.to_s, Ticket.clean_string(title), rand(999).to_i.to_s].join('_')
254
+ end
255
+
256
+
257
+ end
258
+ end
@@ -1,3 +1,3 @@
1
1
  module TicGitNG
2
- VERSION = '1.0.2.4'
2
+ VERSION = '1.0.2.5'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: TicGit-ng
3
3
  version: !ruby/object:Gem::Version
4
- hash: 95
4
+ hash: 93
5
5
  prerelease: false
6
6
  segments:
7
7
  - 1
8
8
  - 0
9
9
  - 2
10
- - 4
11
- version: 1.0.2.4
10
+ - 5
11
+ version: 1.0.2.5
12
12
  platform: ruby
13
13
  authors:
14
14
  - Scott Chacon
@@ -17,7 +17,7 @@ autorequire:
17
17
  bindir: bin
18
18
  cert_chain: []
19
19
 
20
- date: 2011-04-11 00:00:00 -04:00
20
+ date: 2011-05-26 00:00:00 -04:00
21
21
  default_executable:
22
22
  dependencies:
23
23
  - !ruby/object:Gem::Dependency
@@ -61,10 +61,10 @@ extra_rdoc_files: []
61
61
  files:
62
62
  - bin/ti
63
63
  - bin/ticgitweb
64
- - lib/ticgit-ng.rb_
65
64
  - lib/ticgit-ng.rb
66
65
  - lib/ticgit-ng/base.rb
67
66
  - lib/ticgit-ng/ticket.rb
67
+ - lib/ticgit-ng/ticket.rb_
68
68
  - lib/ticgit-ng/cli.rb
69
69
  - lib/ticgit-ng/version.rb
70
70
  - lib/ticgit-ng/command/assign.rb
data/lib/ticgit-ng.rb_ DELETED
@@ -1,35 +0,0 @@
1
- require 'fileutils'
2
- require 'logger'
3
- require 'optparse'
4
- require 'ostruct'
5
- require 'set'
6
- require 'yaml'
7
-
8
- # Add the directory containing this file to the start of the load path if it
9
- # isn't there already.
10
- $:.unshift(File.dirname(__FILE__)) unless
11
- $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
12
-
13
- require 'rubygems'
14
- # requires git >= 1.0.5
15
- require 'git'
16
- require 'ticgit-ng/base'
17
- require 'ticgit-ng/cli'
18
-
19
- module TicGitNG
20
- autoload :VERSION, 'ticgit-ng/version'
21
- autoload :Comment, 'ticgit-ng/comment'
22
- autoload :Ticket, 'ticgit-ng/ticket'
23
-
24
- # options
25
- # :logger => Logger.new(STDOUT)
26
- def self.open(git_dir, options = {})
27
- Base.new(git_dir, options)
28
- end
29
-
30
- class OpenStruct < ::OpenStruct
31
- def to_hash
32
- @table.dup
33
- end
34
- end
35
- end