ohac-ditz 0.5.1 → 0.5.2

Sign up to get free protection for your applications and to get access to all the features.
data/Changelog CHANGED
@@ -1,4 +1,4 @@
1
- == ohac-ditz 0.5.1 / 2010-01-16
1
+ == ohac-ditz 0.5.2 / 2010-01-16
2
2
  * add ditz shell (bin/coditz.rb)
3
3
  * performance hack (disabled issue name interpolation)
4
4
  * performance hack (call unchanged! when save)
@@ -40,7 +40,6 @@ share/ditz/yellow-bar.png
40
40
  man/man1/ditz.1
41
41
  setup.rb
42
42
  bin/coditz.rb
43
- bin/coditz_for_0.5.rb
44
43
  contrib/bookmarklet.js
45
44
  lib/ditz/plugins/icalendar.rb
46
45
  lib/ditz/plugins/mercurial.rb
data/Rakefile CHANGED
@@ -8,15 +8,15 @@ class Hoe
8
8
  def extra_dev_deps; @extra_dev_deps.reject { |x| x[0] == "hoe" } end
9
9
  end
10
10
 
11
- Hoe.new('ditz', Ditz::VERSION) do |p|
11
+ Hoe.new('ohac-ditz', Ditz::VERSION) do |p|
12
12
  p.rubyforge_name = 'ditz'
13
- p.author = "William Morgan"
13
+ p.author = "OHASHI Hideya"
14
14
  p.summary = "A simple issue tracker designed to integrate well with distributed version control systems like git and darcs. State is saved to a YAML file kept under version control, allowing issues to be closed/added/modified as part of a commit."
15
15
 
16
16
  p.description = p.paragraphs_of('README.txt', 4..11).join("\n\n").gsub(/== SYNOPSIS/, "Synopsis:")
17
17
  p.url = "http://ditz.rubyforge.org"
18
18
  p.changes = p.paragraphs_of('Changelog', 0..0).join("\n\n")
19
- p.email = "wmorgan-ditz@masanjin.net"
19
+ p.email = "ohachige@gmail.com"
20
20
  p.extra_deps = [['trollop', '>= 1.9'], ['yaml_waml', '>= 0.3']]
21
21
  end
22
22
 
@@ -1,3 +1,8 @@
1
+ 0.5.2 / ohac-ditz
2
+ ---
3
+
4
+ see Changelog
5
+
1
6
  0.5
2
7
  ---
3
8
 
@@ -0,0 +1,276 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- coding: utf-8 -*-
3
+
4
+ self_file =
5
+ if File.symlink?(__FILE__)
6
+ require 'pathname'
7
+ Pathname.new(__FILE__).realpath
8
+ else
9
+ __FILE__
10
+ end
11
+ $:.unshift(File.dirname(self_file) + "/../lib")
12
+
13
+ require 'rubygems'
14
+ require 'ditz'
15
+ require 'cinatra'
16
+
17
+ # FIXME see http://github.com/jugyo/cinatra/issues/#issue/4
18
+ begin
19
+
20
+ CONFIG_FN = ".ditz-config"
21
+ PLUGIN_FN = ".ditz-plugins"
22
+
23
+ def ditz_plugin_file
24
+ plugin_dir = Ditz::find_dir_containing PLUGIN_FN
25
+ File.join(plugin_dir || ".", PLUGIN_FN)
26
+ end
27
+
28
+ def ditz_config_file
29
+ config_dir = Ditz::find_dir_containing CONFIG_FN
30
+ File.join(config_dir || ".", CONFIG_FN)
31
+ end
32
+
33
+ def ditz_op(cmd, opts = [], project = nil)
34
+ config_file = ditz_config_file
35
+ unless File.exist?(config_file)
36
+ puts 'do init first.'
37
+ return
38
+ end
39
+ config = Ditz::Config.from config_file
40
+ config.use_editor_if_possible = false # overwrite
41
+ config.paginate = "never" # overwrite
42
+ issue_dir = Pathname.new(config.issue_dir)
43
+ unless issue_dir.exist?
44
+ puts 'something wrong.'
45
+ return
46
+ end
47
+ storage = Ditz::FileStorage.new issue_dir
48
+ project = storage.load if project.nil?
49
+ op = Ditz::Operator.new
50
+ op.do cmd, project, config, opts.clone
51
+ storage.save project
52
+ project
53
+ end
54
+
55
+ def get_name_from_mercurial
56
+ path = Ditz.find_dir_containing(".hg")
57
+ len = path ? path.to_s.size : 100
58
+ username = `hg show ui.username` || ''
59
+ username.chomp!
60
+ if username.size > 0
61
+ a = username.split(" ")
62
+ email = a.pop
63
+ email = email[1..-2]
64
+ name = a.join(" ")
65
+ [len, name, email]
66
+ end
67
+ end
68
+
69
+ def get_name_from_git
70
+ path = Ditz.find_dir_containing(".git")
71
+ len = path ? path.to_s.size : 100
72
+ [len, `git config user.name`.chomp, `git config user.email`.chomp]
73
+ end
74
+
75
+ def get_name
76
+ as = [get_name_from_mercurial, get_name_from_git].select{|a|!a.nil?}
77
+ as.min_by{|a|a[0]}
78
+ end
79
+
80
+ command 'ditz_help' do |arg|
81
+ ditz_op 'help'
82
+ end
83
+
84
+ command 'init' do |arg|
85
+ config_file = ditz_config_file
86
+ len, name, email = get_name
87
+ unless File.exist?(config_file)
88
+ config = Ditz::Config.create(
89
+ :name => name,
90
+ :email => email,
91
+ :issue_dir => ".ditz",
92
+ :use_editor_if_possible => false,
93
+ :paginate => "never"
94
+ )
95
+ config.save! config_file
96
+ issue_dir = Pathname.new(config.issue_dir)
97
+ issue_dir.mkdir
98
+ fn = issue_dir + Ditz::FileStorage::PROJECT_FN
99
+ project = Ditz::Project.create(
100
+ :name => "myproject",
101
+ :components => [ Ditz::Component.create(:name => "mycomponent") ]
102
+ )
103
+ project.save! fn
104
+ end
105
+ end
106
+
107
+ command 'todo' do |arg|
108
+ ditz_op 'todo'
109
+ end
110
+
111
+ command 'add' do |arg|
112
+ ditz_op 'add', ['-q', arg]
113
+ end
114
+
115
+ command 'bench' do |arg|
116
+ prj = nil
117
+ 10000.times do |i|
118
+ prj = ditz_op 'add', ['-q', "foo#{i}"], prj
119
+ end
120
+ end
121
+
122
+ command 'close' do |arg|
123
+ ditz_op 'close', ['-n', arg] # TODO select 1,2,3
124
+ end
125
+
126
+ command 'comment' do |arg|
127
+ args = arg.split(' ')
128
+ issue = args.shift
129
+ ditz_op 'comment', [issue, '-m', args.join(' ')]
130
+ end
131
+
132
+ command 'drop' do |arg|
133
+ ditz_op 'drop', [arg]
134
+ end
135
+
136
+ command 'show' do |arg|
137
+ ditz_op 'show', [arg]
138
+ end
139
+
140
+ command 'changelog' do |arg|
141
+ ditz_op 'changelog', [arg]
142
+ end
143
+
144
+ command 'log' do
145
+ ditz_op 'log'
146
+ end
147
+
148
+ command 'shortlog' do
149
+ ditz_op 'shortlog'
150
+ end
151
+
152
+ command 'html' do |arg|
153
+ opts = []
154
+ opts << arg if arg
155
+ ditz_op 'html', opts
156
+ end
157
+
158
+ command 'grep' do |arg|
159
+ opts = []
160
+ opts << arg if arg
161
+ ditz_op 'grep', opts # TODO support ignore case
162
+ end
163
+
164
+ command 'status' do |arg|
165
+ opts = []
166
+ opts << arg if arg
167
+ ditz_op 'status', opts
168
+ end
169
+
170
+ command 'releases' do
171
+ ditz_op 'releases'
172
+ end
173
+
174
+ command 'validate' do
175
+ ditz_op 'validate'
176
+ end
177
+
178
+ command 'release' do |arg|
179
+ opts = []
180
+ opts << arg if arg
181
+ ditz_op 'release', opts
182
+ end
183
+
184
+ command 'reconfigure' do
185
+ # TODO
186
+ end
187
+
188
+ command 'edit' do
189
+ # TODO
190
+ end
191
+
192
+ command 'add-reference' do |arg|
193
+ # TODO interactive only!
194
+ args = arg.split(' ')
195
+ issue = args.shift
196
+ comment = args.join(' ')
197
+ comment = nil if comment.size == 0
198
+ ditz_op 'add-reference', [issue] + (comment ? ['-m', comment] : ['-n'])
199
+ end
200
+
201
+ command 'add-component' do |arg|
202
+ # TODO interactive only!
203
+ ditz_op 'add-component'
204
+ end
205
+
206
+ command 'set-component' do |arg|
207
+ args = arg.split(' ')
208
+ issue = args.shift
209
+ component = args.shift
210
+ comment = args.join(' ')
211
+ comment = nil if comment.size == 0
212
+ ditz_op 'set-component', [issue, component] +
213
+ (comment ? ['-m', comment] : ['-n'])
214
+ end
215
+
216
+ command 'add-release' do |arg|
217
+ args = arg.split(' ')
218
+ name = args.shift
219
+ comment = args.join(' ')
220
+ comment = nil if comment.size == 0
221
+ ditz_op 'add-release', [name] + (comment ? ['-m', comment] : ['-n'])
222
+ end
223
+
224
+ command 'drop-release' do |arg|
225
+ ditz_op 'drop-release', [arg]
226
+ end
227
+
228
+ command 'assign' do |arg|
229
+ args = arg.split(' ')
230
+ issue = args.shift
231
+ release = args.shift
232
+ comment = args.join(' ')
233
+ comment = nil if comment.size == 0
234
+ ditz_op 'assign', [issue, release] + (comment ? ['-m', comment] : ['-n'])
235
+ end
236
+
237
+ command 'unassign' do |arg|
238
+ args = arg.split(' ')
239
+ issue = args.shift
240
+ comment = args.join(' ')
241
+ comment = nil if comment.size == 0
242
+ ditz_op 'unassign', [issue] + (comment ? ['-m', comment] : ['-n'])
243
+ end
244
+
245
+ command 'start' do |arg|
246
+ args = arg.split(' ')
247
+ issue = args.shift
248
+ comment = args.join(' ')
249
+ comment = nil if comment.size == 0
250
+ ditz_op 'start', [issue] + (comment ? ['-m', comment] : ['-n'])
251
+ end
252
+
253
+ command 'stop' do |arg|
254
+ args = arg.split(' ')
255
+ issue = args.shift
256
+ comment = args.join(' ')
257
+ comment = nil if comment.size == 0
258
+ ditz_op 'stop', [issue] + (comment ? ['-m', comment] : ['-n'])
259
+ end
260
+
261
+ =begin
262
+ bin/ditz
263
+ lib/ditz.rb
264
+ lib/ditz/operator.rb
265
+ lib/ditz/model-objects.rb
266
+ lib/ditz/model.rb
267
+ =end
268
+
269
+ command 'print_hooks' do |arg|
270
+ Ditz::HookManager.print_hooks
271
+ end
272
+
273
+ # FIXME see http://github.com/jugyo/cinatra/issues/#issue/4
274
+ rescue => x
275
+ puts x.backtrace
276
+ end
@@ -0,0 +1 @@
1
+ javascript:var%20d=document,w=window,e=w.getSelection,k=d.getSelection,x=d.selection,s=(e?e():(k)?k():(x?x.createRange().text:0)),f='http://localhost:1234/new',l=d.location,e=encodeURIComponent,p='?u='+e(l.href)%20+'&t='+e(d.title)%20+'&s='+e(s)+'&y=task&r='+e('First%20Last%20<foo@example.com>')+'&R=2010&c=idea',u=f+p;l.href=u;
@@ -3,7 +3,7 @@ require 'trollop'
3
3
 
4
4
  module Ditz
5
5
 
6
- VERSION = "0.5"
6
+ VERSION = "0.5.2"
7
7
  attr_accessor :verbose
8
8
  module_function :verbose, :verbose=
9
9
 
@@ -0,0 +1,64 @@
1
+ ## icalendar ditz plugin
2
+ ##
3
+ ## This plugin adds ability to export full todo list in iCalendar (RFC 2445) format.
4
+ ## It is useful for integration with different pim software like KOrganizer.
5
+ ##
6
+ ## Issues are converted to VTODO entries with completion status set to 50 if
7
+ ## its state is :in_progress, 100 if it's closed and 0 otherwise.
8
+ ## Progress for release is 100 if it's released otherwise it's 99 * closed/all
9
+ ## issues. So maximum for active release is 99 and it's not shown as done until
10
+ ## released.
11
+ ##
12
+ ## Commands added:
13
+ ## ditz todo-ics: generate full todo list in iCalendar format
14
+ ##
15
+ ## Usage:
16
+ ## 1. add a line "- icalendar" to the .ditz-plugins file in the project root
17
+
18
+ require 'vpim/icalendar'
19
+
20
+ module Ditz
21
+
22
+ class Operator
23
+ operation :todo_ics, "Generate full todo list in iCalendar format", :maybe_release
24
+ def todo_ics project, config, releases
25
+ cal = Vpim::Icalendar.create
26
+ releases ||= project.releases + [:unassigned]
27
+ releases = [*releases]
28
+ releases.each do |r|
29
+ issues = project.issues_for_release r
30
+ done = 0
31
+ done = (99 * (issues.select { |i| i.closed? }).length / issues.length).to_int if issues.length != 0
32
+ if r != :unassigned
33
+ done = 100 if r.released?
34
+ parent = "release-#{r.hash}"
35
+ title = "Release #{r.name} (#{r.status})"
36
+ else
37
+ parent = "release-unassigned"
38
+ title = "Unassigned"
39
+ end
40
+ cal.push Vpim::Icalendar::Vtodo.create("SUMMARY" => title, "UID" => parent, "PERCENT-COMPLETE" => "#{done}")
41
+ issues.each do |i|
42
+ cal.push todo2vtodo(i, parent)
43
+ end
44
+ end
45
+ puts cal.encode
46
+ end
47
+
48
+ def todo2vtodo todo, parent
49
+ h = {"SUMMARY" => "#{todo.title}", "UID" => "#{todo.type}-#{todo.id}"}
50
+ h["RELATED-TO"] = parent if parent
51
+ h["PRIORITY"] = "3" if todo.type == :bugfix
52
+ h["PERCENT-COMPLETE"] = case todo.status
53
+ when :closed
54
+ "100"
55
+ when :in_progress
56
+ "50"
57
+ else
58
+ "0"
59
+ end
60
+ return Vpim::Icalendar::Vtodo.create(h)
61
+ end
62
+ end
63
+
64
+ end
@@ -0,0 +1,52 @@
1
+ module Ditz
2
+
3
+ class Issue
4
+ alias :old_start_work :start_work
5
+ alias :old_stop_work :stop_work
6
+ field :time_spent, :generator => :get_time_spent
7
+ field :mark_time, :generator => :get_mark_time
8
+ def get_time_spent(config, project)
9
+ time_spent || 0
10
+ end
11
+ def get_mark_time(config, project)
12
+ self.mark_time || 0
13
+ end
14
+ def start_work(who, comment)
15
+ self.mark_time = Time.now
16
+ old_start_work(who, comment)
17
+ end
18
+ def stop_work(who, comment)
19
+ self.time_spent += Time.now - self.mark_time
20
+ self.mark_time = Time.now
21
+ old_stop_work(who, comment)
22
+ end
23
+ end
24
+
25
+ class ScreenView
26
+ def self.modulo(seconds, quotient)
27
+ result, remainder = seconds / quotient, seconds % quotient
28
+ end
29
+ def self.humanize(seconds)
30
+ result = ""
31
+ %w[year month day hour minute second].zip([3600*24*30*365, 3600*24*30, 3600*24, 3600, 60, 1]).inject(seconds) do |seconds, item|
32
+ num, seconds = modulo(seconds, item[1])
33
+ result << "#{item[0].pluralize(num)} " unless num == 0
34
+ seconds
35
+ end
36
+ result
37
+ end
38
+ def self.get_time_spent(issue)
39
+ if issue.status == :paused
40
+ issue.time_spent
41
+ elsif issue.time_spent && issue.mark_time
42
+ issue.time_spent + (Time.now - issue.mark_time)
43
+ else
44
+ 0
45
+ end
46
+ end
47
+ add_to_view :issue_summary do |issue, config|
48
+ " Time spent: #{humanize(get_time_spent(issue).to_i)}\n"
49
+ end
50
+ end
51
+
52
+ end