artemv-diff_to_html 1.0.2 → 1.0.3

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.
@@ -0,0 +1,175 @@
1
+ Index: app/models/issue.rb
2
+ ===================================================================
3
+ --- app/models/issue.rb (revision 1693)
4
+ +++ app/models/issue.rb (working copy)
5
+ @@ -254,4 +254,9 @@
6
+ def to_s
7
+ "#{tracker} ##{id}: #{subject}"
8
+ end
9
+ +
10
+ + def active_versions
11
+ + project.active_versions(:for => self)
12
+ + end
13
+ +
14
+ end
15
+ Index: app/models/project.rb
16
+ ===================================================================
17
+ --- app/models/project.rb (revision 1693)
18
+ +++ app/models/project.rb (working copy)
19
+ @@ -239,6 +239,14 @@
20
+ end
21
+ end
22
+
23
+ + def active_versions(options = {})
24
+ + issue = options[:for] if options[:for].is_a?(Issue)
25
+ + versions.select do |v|
26
+ + !v.completed? || issue && issue.fixed_version &&
27
+ + v.id == issue.fixed_version.id
28
+ + end
29
+ + end
30
+ +
31
+ protected
32
+ def validate
33
+ errors.add(parent_id, " must be a root project") if parent and parent.parent
34
+ Index: app/views/issues/_form.rhtml
35
+ ===================================================================
36
+ --- app/views/issues/_form.rhtml (revision 1693)
37
+ +++ app/views/issues/_form.rhtml (working copy)
38
+ @@ -30,7 +30,7 @@
39
+ {:controller => 'projects', :action => 'add_issue_category', :id => @project},
40
+ :class => 'small', :tabindex => 199) if authorize_for('projects', 'add_issue_category') %></p>
41
+ <%= content_tag('p', f.select(:fixed_version_id,
42
+ - (@project.versions.sort.collect {|v| [v.name, v.id]}),
43
+ + (@issue.active_versions.sort.collect {|v| [v.name, v.id]}),
44
+ { :include_blank => true })) unless @project.versions.empty? %>
45
+ </div>
46
+
47
+ Index: app/views/issues/_form_update.rhtml
48
+ ===================================================================
49
+ --- app/views/issues/_form_update.rhtml (revision 1693)
50
+ +++ app/views/issues/_form_update.rhtml (working copy)
51
+ @@ -5,6 +5,6 @@
52
+ <div class="splitcontentright">
53
+ <p><%= f.select :done_ratio, ((0..10).to_a.collect {|r| ["#{r*10} %", r*10] }) %></p>
54
+ <%= content_tag('p', f.select(:fixed_version_id,
55
+ - (@project.versions.sort.collect {|v| [v.name, v.id]}),
56
+ + (@issue.active_versions.sort.collect {|v| [v.name, v.id]}),
57
+ { :include_blank => true })) unless @project.versions.empty? %>
58
+ </div>
59
+ Index: app/views/issues/bulk_edit.rhtml
60
+ ===================================================================
61
+ --- app/views/issues/bulk_edit.rhtml (revision 1693)
62
+ +++ app/views/issues/bulk_edit.rhtml (working copy)
63
+ @@ -27,7 +27,7 @@
64
+ <label><%= l(:field_fixed_version) %>:
65
+ <%= select_tag('fixed_version_id', content_tag('option', l(:label_no_change_option), :value => '') +
66
+ content_tag('option', l(:label_none), :value => 'none') +
67
+ - options_from_collection_for_select(@project.versions, :id, :name)) %></label>
68
+ + options_from_collection_for_select(@project.active_versions, :id, :name)) %></label>
69
+ </p>
70
+
71
+ <p>
72
+ Index: app/views/issues/context_menu.rhtml
73
+ ===================================================================
74
+ --- app/views/issues/context_menu.rhtml (revision 1693)
75
+ +++ app/views/issues/context_menu.rhtml (working copy)
76
+ @@ -20,11 +20,11 @@
77
+ <% end -%>
78
+ </ul>
79
+ </li>
80
+ - <% unless @project.versions.empty? -%>
81
+ + <% unless @issue.active_versions.empty? -%>
82
+ <li class="folder">
83
+ <a href="#" class="submenu"><%= l(:field_fixed_version) %></a>
84
+ <ul>
85
+ - <% @project.versions.sort.each do |v| -%>
86
+ + <% @issue.active_versions.sort.each do |v| -%>
87
+ <li><%= context_menu_link v.name, {:controller => 'issues', :action => 'edit', :id => @issue, 'issue[fixed_version_id]' => v, :back_to => @back}, :method => :post,
88
+ :selected => (v == @issue.fixed_version), :disabled => !@can[:update] %></li>
89
+ <% end -%>
90
+ Index: test/fixtures/issues.yml
91
+ ===================================================================
92
+ --- test/fixtures/issues.yml (revision 1693)
93
+ +++ test/fixtures/issues.yml (working copy)
94
+ @@ -91,4 +91,19 @@
95
+ status_id: 1
96
+ start_date: <%= Date.today.to_s(:db) %>
97
+ due_date: <%= 1.days.from_now.to_date.to_s(:db) %>
98
+ -
99
+
100
+ +issues_007:
101
+ + created_on: 2006-07-19 21:04:21 +02:00
102
+ + project_id: 1
103
+ + updated_on: 2006-07-19 21:09:50 +02:00
104
+ + priority_id: 5
105
+ + subject: Some closed issue
106
+ + id: 7
107
+ + fixed_version_id: 1
108
+ + category_id:
109
+ + description: Some closed issue
110
+ + tracker_id: 2
111
+ + assigned_to_id: 3
112
+ + author_id: 2
113
+ + status_id: 5
114
+ + start_date: <%= 2.day.ago.to_date.to_s(:db) %>
115
+ + due_date:
116
+ Index: test/unit/issue_test.rb
117
+ ===================================================================
118
+ --- test/unit/issue_test.rb (revision 1693)
119
+ +++ test/unit/issue_test.rb (working copy)
120
+ @@ -181,4 +181,16 @@
121
+ assert_nil Issue.find_by_id(1)
122
+ assert_nil TimeEntry.find_by_issue_id(1)
123
+ end
124
+ +
125
+ + def test_active_versions_have_current_even_if_completed
126
+ + issue = issues(:issues_007)
127
+ + assert issue.fixed_version.completed?
128
+ + assert issue.active_versions.include?(issue.fixed_version),
129
+ + 'Even if version is completed it should be considered active for issue assigned to it'
130
+ + end
131
+ +
132
+ + def test_active_versions_work_for_new_issue
133
+ + issue = Issue.new(:project_id => projects(:projects_001).id)
134
+ + assert !issue.active_versions.empty?, 'there should be active versions for new issue'
135
+ + end
136
+ end
137
+ Index: test/unit/project_test.rb
138
+ ===================================================================
139
+ --- test/unit/project_test.rb (revision 1693)
140
+ +++ test/unit/project_test.rb (working copy)
141
+ @@ -18,7 +18,7 @@
142
+ require File.dirname(__FILE__) + '/../test_helper'
143
+
144
+ class ProjectTest < Test::Unit::TestCase
145
+ - fixtures :projects, :issues, :issue_statuses, :journals, :journal_details, :users, :members, :roles, :projects_trackers, :trackers, :boards
146
+ + fixtures :all
147
+
148
+ def setup
149
+ @ecookbook = Project.find(1)
150
+ @@ -130,4 +130,25 @@
151
+ assert_equal [1, 2, 3], parent.rolled_up_trackers.collect(&:id)
152
+ assert_equal [2, 3], child.rolled_up_trackers.collect(&:id)
153
+ end
154
+ +
155
+ + def test_active_versions_have_future_versions
156
+ + version = versions(:versions_003)
157
+ + assert !version.completed?
158
+ + assert projects(:projects_001).active_versions.include?(version),
159
+ + 'Future version (or one without effective date) should be included'
160
+ + end
161
+ +
162
+ + def test_active_versions_have_incomplete_versions
163
+ + version = versions(:versions_002)
164
+ + assert !version.completed?
165
+ + assert projects(:projects_001).active_versions.include?(version),
166
+ + 'Incomplete versions should be included'
167
+ + end
168
+ +
169
+ + def test_active_versions_dont_have_completed
170
+ + version = versions(:versions_001)
171
+ + assert version.completed?
172
+ + assert !projects(:projects_001).active_versions.include?(version),
173
+ + 'Completed versions shouldn\'t be included'
174
+ + end
175
+ end
@@ -1,18 +1,94 @@
1
- require 'rubygems'
2
- gem 'artemv-diff_to_html'
3
- require 'diff_to_html'
4
- #require '../lib/diff_to_html.rb'
5
- diff = `svn diff -r 46:47 svn://hamptoncatlin.com/haml --diff-cmd diff -x "-U 2"`
6
- #diff = `cat diff`
7
- puts <<EOF
8
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
9
- <html xmlns="http://www.w3.org/1999/xhtml">
10
- <head>
11
- <link type="text/css" rel="stylesheet" href="diff.css">
12
- <title>diff of HAML revision 47</title>
13
- </head>
14
- <body>
15
- #{DiffToHtml.new.get_diff(diff)}
16
- </body>
17
- </html>
18
- EOF
1
+ def out(diff, converter, title)
2
+ puts <<-EOF
3
+ <?xml version="1.0" encoding="UTF-8"?>
4
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd">
5
+ <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
6
+ <head>
7
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
8
+ <title>#{title}</title>
9
+ <style type="text/css">
10
+ <!--
11
+ body, p, ol, ul, td {
12
+ font-family:verdana,arial,helvetica,sans-serif;
13
+ font-size:13px;
14
+ }
15
+
16
+ a, a:link, a:visited {
17
+ color:#507EC0;
18
+ text-decoration:none;
19
+ }
20
+
21
+ ul.diff {
22
+ padding:0;
23
+ }
24
+
25
+ .diff table col.lineno {
26
+ width:4em;
27
+ }
28
+
29
+ .diff h2 {
30
+ color:#333333;
31
+ font-size:14px;
32
+ letter-spacing:normal;
33
+ margin:0pt auto;
34
+ padding:0.1em 0pt 0.25em 0.5em;
35
+ }
36
+
37
+ table.diff {
38
+ font-size : 9pt;
39
+ font-family : "lucida console", "courier new", monospace;
40
+ white-space : pre;
41
+ border : 1px solid #D7D7D7;
42
+ border-collapse : collapse;
43
+ line-height : 110%;
44
+ width: 100%;
45
+ }
46
+
47
+ .diff tr {
48
+ background: white;
49
+ }
50
+
51
+ .diff td {
52
+ border : none;
53
+ padding : 0px 10px;
54
+ margin : 0px;
55
+ }
56
+
57
+ .diff td a {
58
+ text-decoration: none;
59
+ }
60
+
61
+ tr.a { background : #ddffdd; }
62
+
63
+ tr.r { background : #ffdddd; }
64
+
65
+ tr.range { background : #EAF2F5; color : #999; }
66
+
67
+ td.ln {
68
+ background : #ECECEC;
69
+ color : #aaa;
70
+ border-top:1px solid #999988;
71
+ border-bottom:1px solid #999988;
72
+ border-right:1px solid #D7D7D7;
73
+ }
74
+
75
+ .diff li {
76
+ background:#F7F7F7 none repeat scroll 0%;
77
+ border:1px solid #D7D7D7;
78
+ list-style-type:none;
79
+ margin:0pt 0pt 2em;
80
+ padding:2px;
81
+ }
82
+
83
+ .ln a {
84
+ color: #aaa;
85
+ }
86
+ -->
87
+ </style>
88
+ </head>
89
+ <body>
90
+ #{converter.composite_to_html(diff)}
91
+ </body>
92
+ </html>
93
+ EOF
94
+ end
@@ -0,0 +1,5 @@
1
+ require File.join(File.dirname(__FILE__), '../lib/diff_to_html.rb')
2
+ require 'test.rb'
3
+ diff = `cat diff.git`
4
+ converter = GitDiffToHtml.new
5
+ out(diff, converter)
@@ -0,0 +1,8 @@
1
+ #require File.join(File.dirname(__FILE__), '../lib/diff_to_html.rb')
2
+ require 'rubygems'
3
+ require 'diff_to_html'
4
+ require File.join(File.dirname(__FILE__), 'test.rb')
5
+ filename = ARGV[0]
6
+ diff = `cat #{filename}`
7
+ converter = SvnDiffToHtml.new
8
+ out(diff, converter, filename)
@@ -3,10 +3,6 @@ require 'cgi'
3
3
  class DiffToHtml
4
4
 
5
5
  attr_accessor :file_prefix
6
-
7
- #
8
- # globals
9
- #
10
6
 
11
7
  def ln_cell(ln, side = nil)
12
8
  anchor = "f#{@filenum}#{side}#{ln}"
@@ -17,10 +13,10 @@ class DiffToHtml
17
13
  result += "</td>"
18
14
  result
19
15
  end
16
+
20
17
  #
21
18
  # helper for building the next row in the diff
22
19
  #
23
-
24
20
  def get_diff_row(left_ln, right_ln)
25
21
  result = []
26
22
  if @left.length > 0 or @right.length > 0
@@ -56,10 +52,6 @@ class DiffToHtml
56
52
  return result.join("\n"), left_ln, right_ln
57
53
  end
58
54
 
59
- #
60
- # build the diff
61
- #
62
-
63
55
  def range_row(range)
64
56
  "<tr class='range'><td>...</td<td>...</td><td>#{range}</td></tr>"
65
57
  end
@@ -72,16 +64,14 @@ class DiffToHtml
72
64
  end
73
65
 
74
66
  def begin_file(file)
75
- @filenum ||=0
76
67
  result = <<EOF
77
- <li><h2><a name="F#{@filenum}" href="#F#{@filenum}">#{@file_prefix}#{file}</a></h2><table class='diff'>
68
+ <li><h2><a name="F#{@filenum}" href="#F#{@filenum}">#{file}</a></h2><table class='diff'>
78
69
  <colgroup>
79
70
  <col class="lineno"/>
80
71
  <col class="lineno"/>
81
72
  <col class="content"/>
82
73
  </colgroup>
83
74
  EOF
84
- @filenum += 1
85
75
  result
86
76
  end
87
77
 
@@ -93,7 +83,7 @@ EOF
93
83
  return left_ln, right_ln
94
84
  end
95
85
 
96
- def get_diff(diff_file)
86
+ def get_single_file_diff(file_name, diff_file)
97
87
  @last_op = ' '
98
88
  @left = []
99
89
  @right = []
@@ -102,61 +92,118 @@ EOF
102
92
 
103
93
  diff = diff_file.split("\n")
104
94
 
105
- index = diff.shift
106
- file = index[7..-1]
107
- diff.shift #equals
108
- header1 = diff.shift
109
- if header1 =~ /^---/
110
- diff.shift
95
+ diff.shift #index
96
+ line = nil
97
+ while line !~ /^---/ && !diff.empty?
98
+ line = diff.shift
99
+ end
100
+ header_old = line
101
+ if line =~ /^---/
102
+ diff.shift #+++
111
103
 
112
- result << "<ul class='diff'>#{begin_file(file)}"
104
+ result << begin_file(file_name)
113
105
  range = diff.shift
114
106
  left_ln, right_ln = range_info(range)
115
107
  result << range_row(range)
116
108
 
117
- skip = 0
118
109
  diff.each do |line|
119
- if skip > 0
120
- skip -= 1
110
+ op = line[0,1]
111
+ line = line[1..-1] || ''
112
+ if op == '\\'
113
+ line = op + line
114
+ op = ' '
115
+ end
116
+
117
+ if ((@last_op != ' ' and op == ' ') or (@last_op == ' ' and op != ' '))
118
+ left_ln, right_ln = flush_changes(result, left_ln, right_ln)
119
+ end
120
+
121
+ # truncate and escape
122
+ line = CGI.escapeHTML(line)
123
+
124
+ case op
125
+ when ' '
126
+ @left.push(line)
127
+ @right.push(line)
128
+ when '-' then @left.push(line)
129
+ when '+' then @right.push(line)
130
+ when '@'
131
+ range = '@' + line
132
+ flush_changes(result, left_ln, right_ln)
133
+ left_ln, right_ln = range_info(range)
134
+ result << range_row(range)
121
135
  else
122
- op = line[0,1]
123
- line = line[1..-1]
124
-
125
- if ((@last_op != ' ' and op == ' ') or (@last_op == ' ' and op != ' '))
126
- left_ln, right_ln = flush_changes(result, left_ln, right_ln)
127
- end
128
-
129
- # truncate and escape
130
- line = CGI.escapeHTML(line)
131
-
132
- case op
133
- when ' '
134
- @left.push(line)
135
- @right.push(line)
136
- when '-' then @left.push(line)
137
- when '+' then @right.push(line)
138
- when '@'
139
- range = '@' + line
140
- flush_changes(result, left_ln, right_ln)
141
- left_ln, right_ln = range_info(range)
142
- result << range_row(range)
143
- when 'I'
144
- file = line[6..-1]
145
- flush_changes(result, left_ln, right_ln)
146
- result << "</table></li>#{begin_file(file)}"
147
- skip = 3
148
- end
149
- @last_op = op
136
+ flush_changes(result, left_ln, right_ln)
137
+ result << "</table></li>"
138
+ break
150
139
  end
140
+ @last_op = op
151
141
  end
152
142
 
153
143
  flush_changes(result, left_ln, right_ln)
154
- result << "</table></li></ul>"
144
+ result << "</table></li>"
155
145
  else
156
- result = "<div class='error'>#{header1}</div>"
146
+ #"<div class='error'>#{header_old}</div>"
147
+ result =%Q{<li><h2><a name="F#{@filenum}" href="#F#{@filenum}">#{file_name}</a></h2>#{header_old}</li>}
157
148
  end
158
149
 
159
150
  result
160
151
  end
161
152
 
153
+ def file_header_pattern
154
+ raise "Method to be implemented in VCS-specific class"
155
+ end
156
+
157
+ def get_diffs(composite_diff)
158
+ pattern = file_header_pattern
159
+ files = composite_diff.split(pattern)
160
+ headers = composite_diff.scan(pattern) #huh can't find a way to get both at once
161
+ files.shift if files[0] == '' #first one is junk usually
162
+ result = []
163
+ i = 0
164
+ files.each do |file|
165
+ result << {:filename => "#{file_prefix}#{get_filename(headers[i])}", :file => file}
166
+ i += 1
167
+ end
168
+ result
169
+ end
170
+
171
+ def diffs_to_html(diffs)
172
+ result = '<ul class="diff">'
173
+ @filenum = 0
174
+ diffs.each do |file_map|
175
+ result << get_single_file_diff(file_map[:filename], file_map[:file])
176
+ @filenum += 1
177
+ end
178
+ result << '</ul>'
179
+ result
180
+ end
181
+
182
+ def composite_to_html(composite_diff)
183
+ diffs_to_html get_diffs(composite_diff)
184
+ end
185
+ end
186
+
187
+ class GitDiffToHtml < DiffToHtml
188
+ def file_header_pattern
189
+ /^diff --git.+/
190
+ end
191
+
192
+ def get_filename(file_diff)
193
+ match = (file_diff =~ / b\/(.+)/)
194
+ raise "not matched!" if !match
195
+ $1
196
+ end
197
+ end
198
+
199
+ class SvnDiffToHtml < DiffToHtml
200
+ def file_header_pattern
201
+ /^Index: .+/
202
+ end
203
+
204
+ def get_filename(header)
205
+ match = (header =~ /^Index: (.+)/) #if we use this pattern file_header_pattern files split doesn't work
206
+ raise "header '#{header}' not matched!" if !match
207
+ $1
208
+ end
162
209
  end