commit_filter 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (31) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/images/commit_filter/spinner.gif +0 -0
  3. data/app/assets/javascripts/commit_filter/file_commits.js.coffee +19 -0
  4. data/app/assets/javascripts/commit_filter/form.js.coffee +15 -0
  5. data/app/assets/javascripts/commit_filter/frameworks/twitter_bootstrap/3/filter_result.js.coffee +8 -0
  6. data/app/assets/stylesheets/commit_filter/base.css +15 -0
  7. data/app/assets/stylesheets/commit_filter/commit/diff.css +65 -0
  8. data/app/controllers/commit_filter/application_controller.rb +25 -0
  9. data/app/controllers/commit_filter/commit/diffs_controller.rb +24 -0
  10. data/app/controllers/commit_filter/commit/filters_controller.rb +28 -0
  11. data/app/helpers/commit_filter/application_helper.rb +55 -0
  12. data/app/models/commit_filter/model.rb +269 -0
  13. data/app/presenters/commit_filter/application_presenter.rb +9 -0
  14. data/app/presenters/commit_filter/presenter.rb +13 -0
  15. data/app/presenters/commit_filter/presenters/frameworks/twitter_bootstrap/version3_presenter.rb +51 -0
  16. data/app/views/commit_filter/frameworks/twitter_bootstrap/3/commit/filters/_categories.html.erb +28 -0
  17. data/app/views/commit_filter/frameworks/twitter_bootstrap/3/commit/filters/_file_commits.html.erb +68 -0
  18. data/app/views/commit_filter/frameworks/twitter_bootstrap/3/commit/filters/_files.html.erb +26 -0
  19. data/app/views/commit_filter/frameworks/twitter_bootstrap/3/commit/filters/_form.html.erb +80 -0
  20. data/app/views/commit_filter/frameworks/twitter_bootstrap/3/commit/filters/new.html.erb +24 -0
  21. data/app/views/commit_filter/frameworks/twitter_bootstrap/3/layouts/commit_filter/application.html.erb +34 -0
  22. data/app/views/layouts/commit_filter/shared/_foot.html.erb +13 -0
  23. data/app/views/layouts/commit_filter/shared/_head.html.erb +6 -0
  24. data/config/locales/en.yml +84 -0
  25. data/config/routes.rb +4 -0
  26. data/lib/commit_filter.rb +30 -1
  27. data/lib/commit_filter/engine.rb +9 -0
  28. data/lib/commit_filter/grit_extension.rb +15 -0
  29. data/lib/commit_filter/version.rb +1 -1
  30. metadata +123 -5
  31. data/app/views/layouts/commit_filter/application.html.erb +0 -14
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 44ebe1db3814ccc6cf18337f9d56d8f9f7f44f15
4
- data.tar.gz: 61c048d4025d5435db733f8d63a7b042a5a230fd
3
+ metadata.gz: dce75b40a6b4ffd88d564ad6ca5525581035ba7f
4
+ data.tar.gz: f0f32bc638eb7e982f5ef4adf0afb743d4065113
5
5
  SHA512:
6
- metadata.gz: 92f34814abda871cfdb5c8f4a6c5afc4ceb71d0f3090cc8220e98cfde50f2ce59900a6afc249abbd78b3afe0877ccd1d5a0ddf56f4c3a27bda301bf24554dd17
7
- data.tar.gz: 12ae9c8cfbf7ef42070e69c38002f67330d9aa56e680667ddfc3b529862a2d38aac7071608ddee2d06b49ba505ea40b0b0649697d6a81e5d650c56cd60ded95a
6
+ metadata.gz: 1a8a3f5d6d45fb3c9b320f6483f1ef582f421d90e2f0091a72dea70cf09f9391ad6db00fc82aedfb3356c23d4a0f1d7da97213c8e707a679c22c277feb7b11d2
7
+ data.tar.gz: 05333085b20f7257d60232d9edf9a38db7cd570cfb8b467e1ad8b620df84f830d2d479a95060ad710daa68cc43de254efc0f2db1a2db84e45797c953e231a698
@@ -0,0 +1,19 @@
1
+ jQuery ->
2
+ $('.file_commits input').change (event) ->
3
+ event.preventDefault()
4
+
5
+ fields = {}
6
+
7
+ $.each $(this.form).serializeArray(), (index, field) ->
8
+ fields[field.name] = field.value
9
+
10
+ $.each $(this.form).find('a.diff'), (index, link) ->
11
+ url = '#'
12
+
13
+ if fields['rev'] == fields['rev_to']
14
+ alert 'Not implemented!'
15
+ else
16
+ url = "#{diffPath}?repository_path=#{fields['repository_path']}&path=#{fields['path']}&rev=#{fields['rev']}&rev_to=#{fields['rev_to']}"
17
+
18
+ $(link).attr('href', url)
19
+ $(link).text('Diff')
@@ -0,0 +1,15 @@
1
+ jQuery ->
2
+ $('#filter_repository_provider').change (event) ->
3
+ event.preventDefault()
4
+
5
+ if $(this).val() == 'plan.io'
6
+ $('#plan_io_fields').show()
7
+ else
8
+ $('#plan_io_fields').hide()
9
+
10
+ if $(this).val() == 'GitHub'
11
+ $('#github_fields').show()
12
+ $('#issue_url_field').hide()
13
+ else
14
+ $('#github_fields').hide()
15
+ $('#issue_url_field').show()
@@ -0,0 +1,8 @@
1
+ jQuery ->
2
+ $(document.body).on 'click', '.commit_filter_diff_link', (event) ->
3
+ event.preventDefault()
4
+ url = $(this).attr('href')
5
+ $('.modal-title').text $(this).text()
6
+ $('.modal-body').html '<img src=\'' + spinnerImagePath + '\'/>'
7
+ $('#modal').modal('show')
8
+ $('.modal-body').load url
@@ -0,0 +1,15 @@
1
+ body {
2
+ padding-top: 10px;
3
+ }
4
+
5
+ #commit_filter_form fieldset {
6
+ padding:10px;
7
+ border:1px solid black;
8
+ }
9
+
10
+ #commit_filter_form legend {
11
+ width:auto;
12
+ margin-bottom:0px;
13
+ margin-top:0px;
14
+ border-width:0px;
15
+ }
@@ -0,0 +1,65 @@
1
+ ul.diff {
2
+ padding:0;
3
+ }
4
+
5
+ .diff table col.lineno {
6
+ width:4em;
7
+ }
8
+
9
+ .diff h2 {
10
+ color:#333333;
11
+ font-size:14px;
12
+ letter-spacing:normal;
13
+ margin:0pt auto;
14
+ padding:0.1em 0pt 0.25em 0.5em;
15
+ }
16
+
17
+ table.diff {
18
+ font-size : 9pt;
19
+ font-family : "lucida console", "courier new", monospace;
20
+ white-space : pre;
21
+ border : 1px solid #D7D7D7;
22
+ border-collapse : collapse;
23
+ line-height : 110%;
24
+ width: 100%;
25
+ }
26
+
27
+ .diff tr {
28
+ background: white;
29
+ }
30
+
31
+ .diff td {
32
+ border : none;
33
+ padding : 0px 10px;
34
+ margin : 0px;
35
+ }
36
+
37
+ .diff td a {
38
+ text-decoration: none;
39
+ }
40
+
41
+ table.diff tr.a { background : #ddffdd; }
42
+
43
+ table.diff tr.r { background : #ffdddd; }
44
+
45
+ table.diff tr.range { background : #EAF2F5; color : #999; }
46
+
47
+ table.diff td.ln {
48
+ background : #ECECEC;
49
+ color : #aaa;
50
+ border-top:1px solid #999988;
51
+ border-bottom:1px solid #999988;
52
+ border-right:1px solid #D7D7D7;
53
+ }
54
+
55
+ .diff li {
56
+ background:#F7F7F7 none repeat scroll 0%;
57
+ border:1px solid #D7D7D7;
58
+ list-style-type:none;
59
+ margin:0pt 0pt 2em;
60
+ padding:2px;
61
+ }
62
+
63
+ table.diff .ln a {
64
+ color: #aaa;
65
+ }
@@ -1,4 +1,29 @@
1
1
  module CommitFilter
2
2
  class ApplicationController < ActionController::Base
3
+ helper_method :framework_views_path, :commit_filter_stylesheets, :commit_filter_javascripts, :framework_presenter
4
+
5
+ def self.framework_views_path
6
+ "commit_filter/frameworks/#{CommitFilter.configuration.frontend_framework}"
7
+ end
8
+
9
+ def framework_views_path
10
+ self.class.framework_views_path
11
+ end
12
+
13
+ def commit_filter_stylesheets
14
+ @commit_filter_stylesheets || ['application', 'commit_filter/application']
15
+ end
16
+
17
+ def commit_filter_javascripts
18
+ @commit_filter_javascripts || ['application']
19
+ end
20
+
21
+ private
22
+
23
+ def framework_presenter
24
+ @framework_presenter ||= CommitFilter::Presenters::Frameworks::TwitterBootstrap::Version3Presenter.new(
25
+ self.view_context
26
+ )
27
+ end
3
28
  end
4
29
  end
@@ -0,0 +1,24 @@
1
+ class CommitFilter::Commit::DiffsController < CommitFilter::ApplicationController
2
+ def new
3
+ repository = Grit::Repo.new(params[:repository_path])
4
+
5
+ diff = repository.diff(
6
+ repository.commit(params[:rev_to]), repository.commit(params[:rev]), params[:path]
7
+ )
8
+
9
+ unless diff.length == 1
10
+ raise NotImplementedError.new(
11
+ t('commit_filter.diff.errors.diff_length_not_one', length: diff.length)
12
+ )
13
+ end
14
+
15
+ render text: DiffToHtml::GitConverter.new.get_single_file_diff_body(diff.first.diff)
16
+ rescue Exception => e
17
+ if Rails.env.development?
18
+ raise e.class.name + ': ' + e.message + ' ... ' + e.backtrace.join("\n")
19
+ else
20
+ logger.error e.class.name + ': ' + e.message + ' ... ' + e.backtrace.join("\n")
21
+ render text: t('commit_filter.general.errors.internal_server_error')
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,28 @@
1
+ class CommitFilter::Commit::FiltersController < CommitFilter::ApplicationController
2
+ layout "#{CommitFilter::ApplicationController.framework_views_path}/layouts/commit_filter/application"
3
+
4
+ def new
5
+ params[:filter] ||= {}
6
+ @filter = CommitFilter::Model.new(params[:filter].merge(logger: logger))
7
+ @commit_filter_javascripts = ['application', 'commit_filter/form']
8
+
9
+ render "#{framework_views_path}/commit/filters/new"
10
+ end
11
+
12
+ def create
13
+ params[:filter] ||= {}
14
+ @filter = CommitFilter::Model.create(params[:filter].merge(logger: logger))
15
+
16
+ if @filter.valid? && @filter.last_revision.blank?
17
+ flash[:alert] = I18n.t('commit_filter.filters.create.errors.nothing_found')
18
+ end
19
+
20
+ @commit_filter_stylesheets = ['application', 'commit_filter/application', 'commit_filter/commit/diff']
21
+ @commit_filter_javascripts = [
22
+ 'application', 'commit_filter/form', 'commit_filter/file_commits',
23
+ "#{CommitFilter::ApplicationController.framework_views_path}/filter_result"
24
+ ]
25
+
26
+ render "#{framework_views_path}/commit/filters/new"
27
+ end
28
+ end
@@ -1,4 +1,59 @@
1
1
  module CommitFilter
2
2
  module ApplicationHelper
3
+ def form_field(*args, &block)
4
+ framework_presenter.form_field *args, &block
5
+ end
6
+
7
+ def path_id(path)
8
+ path.gsub(/\/|\./, '_')
9
+ end
10
+
11
+ def message_with_issue_urls(message)
12
+ if @filter.repository_provider == 'GitHub'
13
+ @filter.issue_url = "https://github.com/#{@filter.user_or_organization}/#{@filter.repository}/issues/:id"
14
+ end
15
+
16
+ if @filter.issue_url.present?
17
+ message.gsub(/#([0-9]+)/) do |s|
18
+ issue_url = @filter.issue_url.split(':id')
19
+ s = s.gsub('#', '')
20
+ issue_url = "#{issue_url[0]}#{s}#{issue_url[1]}"
21
+ "<a href=\"#{issue_url}\">##{s}</a>"
22
+ end
23
+ else
24
+ message
25
+ end
26
+ end
27
+
28
+ def version_control_diff_link(path, rev)
29
+ rev = params['rev'] || rev
30
+ rev_to = params['rev_to'] || @filter.previous_revision_by_file[path]
31
+
32
+ url = if rev == rev_to
33
+ nil
34
+ else
35
+ "#{new_commit_diff_path}?repository_path=#{@filter.repository_path}&path=#{path}&rev=#{rev}&rev_to=#{rev_to}"
36
+ end
37
+
38
+ text = t('commit_filter.general.diff')
39
+
40
+ if url.present?
41
+ link_to text, url, class: 'diff commit_filter_diff_link'
42
+ else
43
+ text
44
+ end
45
+ end
46
+
47
+ def annotate_file_link(text, rev, path, options = {})
48
+ url = if @filter.repository_provider == 'GitHub'
49
+ "https://github.com/#{@filter.user_or_organization}/#{@filter.repository}/blame/#{rev}/#{path}"
50
+ elsif @filter.repository_provider == 'plan.io'
51
+ "#{@filter.repository_host}/projects/#{@filter.project_slug}/repository/revisions/#{rev}/annotate/#{path}"
52
+ end
53
+
54
+ text += " (your provider is not supported)" unless url.present?
55
+ url = '#' unless url.present?
56
+ link_to text, url, target: '_blank'
57
+ end
3
58
  end
4
59
  end
@@ -0,0 +1,269 @@
1
+ class CommitFilter::Model
2
+ HASHTAG_REGEX = /(?:\s|^)(#(?!([0-9]?:\d+|\w+?_|_\w+?)(?:\s|$))([a-z0-9\-_]+))/i
3
+
4
+ attr_accessor :workspace, :repository, :project_slug, :branch, :path, :author, :from, :to, :id, :hashtag
5
+ attr_accessor :message, :story, :tasks, :hide_merge_commits, :logger, :issue_url, :repository_provider, :user_or_organization
6
+ attr_accessor :repository_host, :group_by_rails_file_category
7
+ attr_reader :errors, :commits_count, :last_revision, :first_revision, :previous_revision, :previous_revision_by_file
8
+
9
+ def self.create(attributes = {})
10
+ resource = new(attributes)
11
+
12
+ if resource.valid?
13
+ begin
14
+ resource.commits_by_file
15
+ rescue Grit::Git::GitTimeout
16
+ @errors ||= {}
17
+ @errors['base'] = I18n.t('commit_filter.filters.create.errors.too_many_git_timeouts')
18
+ end
19
+ end
20
+
21
+ resource
22
+ end
23
+
24
+ def initialize(attributes = {})
25
+ @commits_count, @previous_revision_by_file = 0, {}
26
+
27
+ initialize_attributes(attributes)
28
+
29
+ self
30
+ end
31
+
32
+ def repository_path; self.workspace.to_s + '/' + self.repository.to_s; end
33
+
34
+ def valid?
35
+ @valid = _valid? ? true : false
36
+ end
37
+
38
+ def commits_by_file
39
+ return {} unless valid?
40
+
41
+ return @files if @files
42
+
43
+ if group_by_rails_file_category
44
+ @files = {
45
+ library: { paths: [/^lib\//, /^app\/mailers\//] },
46
+ model: { paths: [/^app\/models\//, /^db\//] },
47
+ controller: { paths: [/^app\/controllers\//] },
48
+ javascript: { paths: [/^app\/assets\/javascripts\//] },
49
+ view: {
50
+ paths: [
51
+ /^app\/assets\/stylesheets\//, /^app\/views\//, /^app\/helpers\//, /^app\/presenters\//,
52
+ /^public\//
53
+ ]
54
+ },
55
+ tests: { paths: [/^spec\//, /^features\//] },
56
+ configuration: { paths: [/^config\//] },
57
+ misc: { paths: [] }
58
+ }
59
+ else
60
+ @files = {}
61
+ end
62
+
63
+ catch(:done) do
64
+ commits do |page|
65
+ page.each do |commit|
66
+ add_commit_to_files(commit) if commit_attributes_match_criteria?(commit)
67
+ end
68
+ end
69
+ end
70
+
71
+ if group_by_rails_file_category
72
+ @files.each {|category, setting| @files.delete(category) unless setting[:files].try(:any?) }
73
+ end
74
+
75
+ @files
76
+ rescue Grit::NoSuchPathError
77
+ @errors ||= {}
78
+ @errors['base'] = I18n.t('commit_filter.filters.create.errors.repository_not_found')
79
+ end
80
+
81
+ def files_count; @previous_revision_by_file.keys.length; end
82
+
83
+ private
84
+
85
+ def initialize_attributes(attributes)
86
+ default_attributes = {
87
+ 'workspace' => CommitFilter.configuration.workspace,
88
+ 'repository' => CommitFilter.configuration.repository,
89
+ 'repository_provider' => CommitFilter.configuration.repository_provider,
90
+ 'user_or_organization' => CommitFilter.configuration.user_or_organization,
91
+ 'repository_host' => CommitFilter.configuration.repository_host,
92
+ 'project_slug' => CommitFilter.configuration.project_slug,
93
+ 'branch' => CommitFilter.configuration.branch,
94
+ 'issue_url' => CommitFilter.configuration.issue_url,
95
+ 'hide_merge_commits' => CommitFilter.configuration.hide_merge_commits
96
+ }
97
+
98
+ if CommitFilter.configuration.workspace_and_repository_from_rails_root
99
+ workspace = Rails.root.to_s.split('/')
100
+ default_attributes['repository'] = workspace.pop
101
+ default_attributes['workspace'] = workspace.join('/')
102
+ end
103
+
104
+ attributes = default_attributes.merge(attributes)
105
+ attributes['hide_merge_commits'] = false if attributes['hide_merge_commits'].to_s == '0'
106
+ attributes['to'] = 1.day.since.strftime('%Y-%m-%d') if attributes['from'].present? && attributes['to'].blank?
107
+
108
+ attributes.each {|attribute, value| self.send("#{attribute}=", value) }
109
+ end
110
+
111
+ def _valid?
112
+ @errors ||= {}
113
+
114
+ ['workspace', 'repository', 'branch'].each do |field|
115
+ @errors[field] = I18n.t('commit_filter.filters.create.errors.cannot_be_blank') if self.send(field).blank?
116
+ end
117
+
118
+ if repository_provider == 'GitHub'
119
+ @errors['user_or_organization'] = I18n.t('commit_filter.filters.create.errors.cannot_be_blank') if user_or_organization.blank?
120
+ elsif repository_provider == 'plan.io'
121
+ ['repository_host', 'project_slug'].each do |field|
122
+ @errors[field] = I18n.t('commit_filter.filters.create.errors.cannot_be_blank') if self.send(field).blank?
123
+ end
124
+ end
125
+
126
+ if path.blank? && author.blank? && id.blank? && hashtag.blank? && message.blank? && story.blank? && tasks.blank? && from.blank? && to.blank?
127
+ @errors['base'] = I18n.t('commit_filter.filters.create.errors.not_enough_criteria')
128
+ end
129
+
130
+ @errors.empty?
131
+ end
132
+
133
+ def repository_instance
134
+ @repository_instance ||= Grit::Repo.new(self.repository_path)
135
+ end
136
+
137
+ def commits
138
+ offset = 0
139
+
140
+ if id.present?
141
+ yield repository_instance.commits(id).select{|commit| commit.id == id }
142
+ else
143
+ while (page = try_two_times("Get commits from #{offset} to #{(offset + 100)}") { repository_instance.commits(self.branch, 100, offset) }).length > 0
144
+
145
+ yield page
146
+
147
+ offset += 100
148
+ end
149
+ end
150
+ end
151
+
152
+ def commit_attributes_match_criteria?(commit)
153
+ if hide_merge_commits && commit.message.match(/^Merge branch /)
154
+ false
155
+ elsif (
156
+ (message != '' && commit.message.match(message)) ||
157
+ commit_message_includes_hashtag(commit.message)
158
+ ) && (author.blank? || commit.author.name == author) && between_timespan?(commit.committed_date)
159
+ true
160
+ else
161
+ @previous_revision ||= commit.id
162
+
163
+ throw :done if from.present? && Time.parse(from) > commit.committed_date
164
+
165
+ false
166
+ end
167
+ end
168
+
169
+ def commit_message_includes_hashtag(commit_message)
170
+ hashtag.present? && commit_message.scan(HASHTAG_REGEX).map(&:first).include?(hashtag)
171
+ end
172
+
173
+ def add_commit_to_files(commit)
174
+ @previous_revision = nil
175
+
176
+ return if hide_merge_commits && commit.message.match(/^Merge branch /)
177
+
178
+ if commit.message.match(message) && (author.blank? || commit.author.name == author) && between_timespan?(commit.committed_date)
179
+ @previous_revision = nil
180
+ else
181
+ @previous_revision ||= commit.id
182
+
183
+ throw :done if from.present? && Time.parse(from) > commit.committed_date
184
+
185
+ return
186
+ end
187
+
188
+ files = try_two_times("Commit(id: #{commit.id})#stats") { commit.stats }.files.map(&:first).select do |file_path|
189
+ path.blank? || file_path.match(path)
190
+ end
191
+
192
+ return if files.none?
193
+
194
+ @first_revision = commit.id
195
+ @last_revision ||= commit.id
196
+ @commits_count += 1
197
+
198
+ files.each {|file_path| add_commit_to_file(file_path, commit) }
199
+ end
200
+
201
+ def between_timespan?(timestamp)
202
+ return true if from.blank? && to.blank?
203
+
204
+ from_valid = from.present? && Time.parse(from) <= timestamp
205
+ to_valid = to.present? && Time.parse(to) >= timestamp
206
+
207
+ valid = if from.present? && to.present? && from_valid && to_valid
208
+ true
209
+ elsif (from.blank? || to.blank?) && ((from.present? && from_valid) || (to.present? && to_valid))
210
+ true
211
+ else
212
+ false
213
+ end
214
+
215
+ valid
216
+ end
217
+
218
+ def add_commit_to_file(file_path, commit)
219
+ category = nil
220
+
221
+ if group_by_rails_file_category
222
+ category = :misc
223
+
224
+ if file_path.match(/\//)
225
+ @files.each do |current_category, setting|
226
+ if setting[:paths].select{|part| file_path.match(part) }.any?
227
+ category = current_category; break
228
+ end
229
+ end
230
+ end
231
+ end
232
+
233
+ if commit.parents.any?
234
+ @previous_revision_by_file[file_path] = commit.parents.first.id
235
+ else
236
+ # e.g. first commit has no parents
237
+ @previous_revision_by_file[file_path] = nil
238
+ end
239
+
240
+ @files[category][:files] ||= {} if category.present?
241
+
242
+ files = category.present? ? @files[category][:files] : @files
243
+
244
+ files[file_path] ||= []
245
+ files[file_path] << {
246
+ id: commit.id, committed_at: commit.committed_date.strftime('%d.%m.%y %H:%M'),
247
+ message: commit.message, author: commit.author.name
248
+ }
249
+ end
250
+
251
+ # alternative for Integer#tries to log try number and sleep between
252
+ def try_two_times(message = '')
253
+ tries ||= 1
254
+
255
+ if CommitFilter.configuration.git_debug_logging
256
+ logger.info "#{Time.now.strftime('%H:%M:%S')} #{message} (try ##{tries})"
257
+ end
258
+
259
+ yield
260
+ rescue Grit::Git::GitTimeout => e
261
+ if (tries += 1) == 2
262
+ sleep 2
263
+
264
+ retry
265
+ else
266
+ raise e
267
+ end
268
+ end
269
+ end
@@ -0,0 +1,9 @@
1
+ class CommitFilter::ApplicationPresenter < CommitFilter::Presenter
2
+ def flash_messages
3
+ raise NotImplementedError
4
+ end
5
+
6
+ def form_field(filter, name, options = {})
7
+ raise NotImplementedError
8
+ end
9
+ end
@@ -0,0 +1,13 @@
1
+ class CommitFilter::Presenter
2
+ attr_accessor :view
3
+
4
+ def initialize(working_view)
5
+ self.view = working_view
6
+ end
7
+
8
+ private
9
+
10
+ def method_missing(*args, &block)
11
+ view.send(*args, &block)
12
+ end
13
+ end
@@ -0,0 +1,51 @@
1
+ class CommitFilter::Presenters::Frameworks::TwitterBootstrap::Version3Presenter < CommitFilter::ApplicationPresenter
2
+ def flash_messages
3
+ flash_messages = []
4
+
5
+ flash.each do |type, message|
6
+ flash.delete(type)
7
+ content = content_tag(
8
+ :button,
9
+ content_tag(:span, raw('&times;'), 'aria-hidden' => 'true'),
10
+ class: 'close', 'data-dismiss' => 'alert', 'aria-label' => 'Close'
11
+ )
12
+ type = :success if ['notice'].include? type.to_s
13
+ type = :danger if ['alert'].include? type.to_s
14
+ content += raw(message)
15
+ text = content_tag(:div, content, class: "alert fade in alert-#{type}")
16
+ flash_messages << text if message
17
+ end
18
+
19
+ flash_messages.join('\n').html_safe
20
+ end
21
+
22
+ def form_field(filter, name, options = {})
23
+ options[:placeholder] = t("commit_filter.filters.form.fields.#{name}.placeholder", default: 'NULL')
24
+ options.delete :placeholder if options[:placeholder] == 'NULL'
25
+ hint = t("commit_filter.filters.form.fields.#{name}.hint", default: 'NULL')
26
+ hint = nil if hint == 'NULL'
27
+ error = (filter.errors || {})[name]
28
+ field = options.delete(:field)
29
+
30
+ content_tag :div, class: 'form-group' + (error ? ' has-error' : '') do
31
+ content = []
32
+ content << label_tag("filter[#{name}]", t("commit_filter.filters.form.fields.#{name}.title"), class: 'col-sm-3 control-label')
33
+
34
+ content << content_tag(:div, class: 'col-sm-8') do
35
+ controls = []
36
+
37
+ if field.present?
38
+ controls << field
39
+ else
40
+ controls << text_field_tag("filter[#{name}]", filter.send(name), { class: 'form-control' }.merge(options))
41
+ end
42
+
43
+ controls << content_tag(:p, hint, class: 'help-block') if hint
44
+ controls << content_tag(:span, error, class: 'help-inline') if error
45
+ raw controls.join(' ')
46
+ end
47
+
48
+ raw content.join(' ')
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,28 @@
1
+ <div class="panel-group" id="commit_filter_accordion" role="tablist" aria-multiselectable="true">
2
+ <div class="panel panel-default">
3
+ <% index = 0 %>
4
+ <% @filter.commits_by_file.each do |category, setting| %>
5
+ <div class="panel-heading" role="tab" id="heading<%= index + 1 %>">
6
+ <h4 class="panel-title">
7
+ <a
8
+ data-toggle="collapse" data-parent="#commit_filter_accordion"
9
+ href="#commit_category_<%= category %>" aria-expanded="true"
10
+ aria-controls="commit_category_<%= category %>"
11
+ >
12
+ <%= category %> (<%= setting[:files].keys.length %> <%= t('commit_filter.general.files') %>)
13
+ </a>
14
+ </h4>
15
+ </div>
16
+
17
+ <div
18
+ id="commit_category_<%= category %>" class="panel-collapse collapse<% if index == 0 %> in<% end %>"
19
+ role="tabpanel" aria-labelledby="heading<%= index + 1 %>"
20
+ >
21
+ <div class="panel-body" style="padding:15px 15px 0px 15px;">
22
+ <%= render partial: "#{framework_views_path}/commit/filters/files", locals: { commits_by_file: setting[:files], paths: setting[:paths] } %>
23
+ </div>
24
+ </div>
25
+ <% index += 1 %>
26
+ <% end %>
27
+ </div>
28
+ </div>
@@ -0,0 +1,68 @@
1
+ <% previous_file_rev = @filter.previous_revision_by_file[path] %>
2
+ <p>
3
+ <strong><%= t('commit_filter.filters.form.fields.path.title') %>:</strong> <%= path %>
4
+ </p>
5
+ <%= form_tag '#', method: 'post', class: 'file_commits' do %>
6
+ <%= hidden_field_tag :repository_path, @filter.repository_path %>
7
+ <%= hidden_field_tag :project_slug, @filter.project_slug %>
8
+ <%= hidden_field_tag :path, path %>
9
+ <table class='table table-striped table-condensed'>
10
+ <thead>
11
+ <tr>
12
+ <th colspan="2" style="width: 50px; text-align:center">
13
+ <%= version_control_diff_link path, commits.first[:id].try(:to_s) %>
14
+ </th>
15
+ <th style="width:150px;"><%= t('commit_filter.general.date') %></th>
16
+ <th style="width:150px;"><%= t('commit_filter.filters.form.fields.author.title') %></th>
17
+ <th><%= t('commit_filter.filters.form.fields.message.title') %></th>
18
+ </tr>
19
+ </thead>
20
+ <tbody>
21
+ <% param = params[path_id(path)] || {} %>
22
+ <% commits.each_with_index do |commit, commits_index| %>
23
+ <tr>
24
+ <td style="width:25px; text-align:center">
25
+ <% first_commit = previous_file_rev.blank? && commit[:id].try(:to_s) == commits.last[:id].try(:to_s) %>
26
+ <% unless first_commit %>
27
+ <% checked = param['rev'] == commit[:id].try(:to_s) ? true : false %>
28
+ <% checked = true if commits_index == 0 && !param.has_key?('rev') %>
29
+ <%= radio_button_tag :rev, commit[:id].try(:to_s), checked, id: '' %>
30
+ <% end %>
31
+ </td>
32
+ <td style="width:25px; text-align:center">
33
+ <% unless commits_index == 0 %>
34
+ <% checked = param['rev_to'] == commit[:id].try(:to_s) ? true : false %>
35
+ <% checked = true if commits_index == (commits.length - 1) && !param.has_key?('rev_to') %>
36
+ <%= radio_button_tag :rev_to, commit[:id].try(:to_s), checked, id: '' %>
37
+ <% end %>
38
+ </td>
39
+ <td style="width:150px;"><%= annotate_file_link commit[:committed_at], commit[:id], path %></td>
40
+ <td style="width:150px;"><%= commit[:author]%></td>
41
+ <td>
42
+ <%= raw message_with_issue_urls(commit[:message]) %>
43
+ </td>
44
+ </tr>
45
+ <% end %>
46
+ </tbody>
47
+ <tfoot>
48
+ <% if previous_file_rev.present? %>
49
+ <tr>
50
+ <td>
51
+ </td>
52
+ <td style="width:25px; text-align:center">
53
+ <% checked = param['rev_to'] == previous_file_rev ? true : false %>
54
+ <% checked = true unless param.has_key?('rev_to') %>
55
+ <%= radio_button_tag :rev_to, previous_file_rev, checked, id: '' %>
56
+ </td>
57
+ <th colspan="3"/>
58
+ </tr>
59
+ <% end %>
60
+ <tr>
61
+ <th colspan="2" style="text-align:center">
62
+ <%= version_control_diff_link path, commits.first[:id].try(:to_s) %>
63
+ </th>
64
+ <th colspan="3"/>
65
+ </tr>
66
+ </tfoot>
67
+ </table>
68
+ <% end %>
@@ -0,0 +1,26 @@
1
+ <% paths ||= nil %>
2
+
3
+ <div role="tabpanel">
4
+ <ul class="nav nav-tabs" role="tablist">
5
+ <% file_index = 0 %>
6
+ <% commits_by_file.keys.sort_by{ |x| x.downcase }.each do |path| %>
7
+ <% matching_part = paths.nil? ? nil : paths.select{|part| path.match(part) }.first %>
8
+ <li role="presentation"<% if file_index == 0 %> class="active"<% end %>>
9
+ <a href="#commit_file_<%= path.gsub(/\/|\./, '_') %>" aria-controls="commit_file_<%= path.gsub(/\/|\./, '_') %>" role="tab" data-toggle="tab">
10
+ <%= matching_part ? path.gsub(matching_part, '') : path %>
11
+ </a>
12
+ </li>
13
+ <% file_index += 1 %>
14
+ <% end %>
15
+ </ul>
16
+ <div class="tab-content">
17
+ <% file_index = 0 %>
18
+ <% commits_by_file.keys.sort_by{ |x| x.downcase }.each do |path| %>
19
+ <% commits = commits_by_file[path] %>
20
+ <div role="tabpanel" class="tab-pane<% if file_index == 0 %> active<% end %>" id="commit_file_<%= path.gsub(/\/|\./, '_') %>">
21
+ <%= render "#{framework_views_path}/commit/filters/file_commits", commits: commits, path: path %>
22
+ </div>
23
+ <% file_index += 1 %>
24
+ <% end %>
25
+ </div>
26
+ </div>
@@ -0,0 +1,80 @@
1
+ <%= form_tag commit_filter.commit_filters_path, method: 'post', class: 'form-horizontal', id: 'commit_filter_form' do %>
2
+ <% unless action_name == 'new' || @filter.valid? %>
3
+ <div class="alert fade in alert-danger">
4
+ <strong><%= t('commit_filter.filters.form.invalid') %></strong>
5
+ <ul>
6
+ <% @filter.errors.each do |field, error| %>
7
+ <li><%= field.humanize %>: <%=error %></li>
8
+ <% end %>
9
+ </ul>
10
+ </div>
11
+ <% end %>
12
+
13
+ <fieldset>
14
+ <legend>
15
+ <%= t('commit_filter.filters.form.tabs.basic.title') %>
16
+ </legend>
17
+
18
+ <%= form_field @filter, 'workspace', size: 45 %>
19
+ <%= form_field(
20
+ @filter, 'repository_provider', size: 45,
21
+ field: select_tag(
22
+ 'filter[repository_provider]', options_for_select(['', 'GitHub', 'plan.io'], @filter.repository_provider),
23
+ style: 'width:325px;'
24
+ )
25
+ ) %>
26
+ <div id="github_fields" style="display:<%= @filter.repository_provider == 'GitHub' ? 'block' : 'none' %>">
27
+ <%= form_field @filter, 'user_or_organization', size: 45 %>
28
+ </div>
29
+ <div id="plan_io_fields" style="display:<%= @filter.repository_provider == 'plan.io' ? 'block' : 'none' %>">
30
+ <%= form_field @filter, 'repository_host', size: 45 %>
31
+ <%= form_field @filter, 'project_slug', size: 45 %>
32
+ </div>
33
+ <%= form_field @filter, 'repository', size: 45 %>
34
+ <%= form_field @filter, 'branch', size: 45 %>
35
+
36
+ <div id="issue_url_field" style="display:<%= @filter.repository_provider == 'GitHub' ? 'none' : 'block' %>">
37
+ <%= form_field @filter, 'issue_url', size: 45 %>
38
+ </div>
39
+
40
+ <% field = capture do %>
41
+ <%= radio_button_tag 'filter[group_by_rails_file_category]', '1', @filter.group_by_rails_file_category ? true : false %>
42
+ <%= t('commit_filter.general.yes') %>
43
+ <%= radio_button_tag 'filter[group_by_rails_file_category]', '0', @filter.group_by_rails_file_category ? false : true %>
44
+ <%= t('commit_filter.general.no') %>
45
+ <% end %>
46
+ <%= form_field @filter, 'group_by_rails_file_category', size: 45, field: field %>
47
+ </fieldset>
48
+ <fieldset>
49
+ <legend><%= t('commit_filter.filters.form.tabs.time_span.title') %></legend>
50
+
51
+ <%= form_field @filter, 'from', size: 45, class: 'datepicker' %>
52
+ <%= form_field @filter, 'to', size: 45, class: 'datepicker' %>
53
+ </fieldset>
54
+ <fieldset>
55
+ <legend><%= t('commit_filter.filters.form.tabs.commit.title') %></legend>
56
+
57
+ <%= form_field @filter, 'id', size: 45 %>
58
+ <%= form_field @filter, 'hashtag', size: 45 %>
59
+ <%= form_field @filter, 'message', size: 45 %>
60
+ <%= form_field @filter, 'path', size: 45 %>
61
+ <%= form_field @filter, 'author', size: 45 %>
62
+
63
+ <% field = capture do %>
64
+ <%= radio_button_tag 'filter[hide_merge_commits]', '1', @filter.hide_merge_commits ? true : false %>
65
+ <%= t('commit_filter.general.yes') %>
66
+ <%= radio_button_tag 'filter[hide_merge_commits]', '0', @filter.hide_merge_commits ? false : true %>
67
+ <%= t('commit_filter.general.no') %>
68
+ <% end %>
69
+ <%= form_field @filter, 'hide_merge_commits', size: 45, field: field %>
70
+ </fieldset>
71
+
72
+ <p>
73
+ </p>
74
+
75
+ <div class="form-group">
76
+ <div class="col-sm-offset-3 col-sm-10">
77
+ <button type="submit" class="btn btn-primary"><%= t('commit_filter.filters.form.submit')%></button>
78
+ </div>
79
+ </div>
80
+ <% end %>
@@ -0,0 +1,24 @@
1
+ <div class="row">
2
+ <div class="col-sm-4 col-md-4">
3
+ <%= render "#{framework_views_path}/commit/filters/form" %>
4
+ </div>
5
+ <div class="col-sm-8 col-md-8">
6
+ <% if @filter.valid? && @filter.last_revision.present? %>
7
+ <p>
8
+ <strong><%= t('commit_filter.general.commits') %>:</strong> <%= @filter.commits_count %>
9
+ <strong><%= t('commit_filter.general.files') %>:</strong> <%= @filter.files_count %>
10
+ </p>
11
+
12
+ <% if @filter.group_by_rails_file_category %>
13
+ <%= render partial: "#{framework_views_path}/commit/filters/categories" %>
14
+ <% else %>
15
+ <%= render partial: "#{framework_views_path}/commit/filters/files", locals: { commits_by_file: @filter.commits_by_file } %>
16
+ <% end %>
17
+ <% end %>
18
+ </div>
19
+ </div>
20
+
21
+ <% content_for :top_javascript do %>
22
+ var repositoryProvider = "<%= @filter.repository_provider %>";
23
+ var repositoryHost = "<%= @filter.repository_host %>";
24
+ <% end %>
@@ -0,0 +1,34 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <%= render partial: 'layouts/commit_filter/shared/head' %>
5
+ </head>
6
+ <body>
7
+ <div class="modal fade" id="modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
8
+ <div class="modal-dialog" style="width:800px; height:500px;">
9
+ <div class="modal-content">
10
+ <div class="modal-header">
11
+ <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
12
+ <h4 class="modal-title" id="myModalLabel"><%= t('general.loading') %></h4>
13
+ </div>
14
+ <div class="modal-body" style="height:400px; overflow:scroll;">
15
+ <%= image_tag 'commit_filter/spinner.gif' %>
16
+ </div>
17
+ <div class="modal-footer">
18
+ <button type="button" class="btn btn-default" data-dismiss="modal"><%= t('general.close') %></button>
19
+ </div>
20
+ </div>
21
+ </div>
22
+ </div>
23
+
24
+ <div class="container-fluid">
25
+ <div id="flash">
26
+ <%= framework_presenter.flash_messages %>
27
+ </div>
28
+
29
+ <%= yield %>
30
+ </div>
31
+
32
+ <%= render partial: 'layouts/commit_filter/shared/foot' %>
33
+ </body>
34
+ </html>
@@ -0,0 +1,13 @@
1
+ <%= javascript_include_tag *commit_filter_javascripts %>
2
+ <%= yield :javascript_includes %>
3
+
4
+ <%= javascript_tag do %>
5
+ var diffPath = "<%= new_commit_diff_path %>";
6
+ var spinnerImagePath = "<%= asset_path('home_page/spinner.gif') %>";
7
+
8
+ <%= yield :top_javascript %>
9
+
10
+ $(function() {
11
+ <%= yield(:document_ready) %>
12
+ });
13
+ <% end %>
@@ -0,0 +1,6 @@
1
+ <meta charset="utf-8">
2
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
3
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
4
+ <title><%= t('commit_filter.general.title') %></title>
5
+ <%= stylesheet_link_tag *commit_filter_stylesheets, media: 'all' %>
6
+ <%= csrf_meta_tags %>
@@ -0,0 +1,84 @@
1
+ en:
2
+ commit_filter:
3
+ general:
4
+ title: Commit Filter
5
+ commits: Commits
6
+ files: Files
7
+ yes: Yes
8
+ no: No
9
+ date: Date
10
+ loading: Loading
11
+ diff: Diff
12
+ close: Close
13
+ errors:
14
+ internal_server_error: Internal server error.
15
+
16
+ filters:
17
+ form:
18
+ invalid: Filter is invalid!
19
+
20
+ tabs:
21
+ basic:
22
+ title: Basic
23
+ time_span:
24
+ title: Time Span
25
+ commit:
26
+ title: Commit
27
+
28
+ fields:
29
+ workspace:
30
+ title: Workspace
31
+ placeholder: e.g. /users/user_name/workspace
32
+ repository:
33
+ title: Repository
34
+ repository_provider:
35
+ title: Repository Provider
36
+ user_or_organization:
37
+ title: User or Organization
38
+ repository_host:
39
+ title: Repository Host
40
+ project_slug:
41
+ title: Project slug
42
+ branch:
43
+ title: Branch
44
+ issue_url:
45
+ title: Issue URL
46
+ placeholder: e.g. https://host/repository_path/issues/:id
47
+ group_by_rails_file_category:
48
+ title: Group by File Category
49
+ hint: Only for Rails apps.
50
+ path:
51
+ title: Path
52
+ author:
53
+ title: Author
54
+ from:
55
+ title: From
56
+ placeholder: e.g. 2015-01-01
57
+ to:
58
+ title: To
59
+ placeholder: e.g. 2015-01-01
60
+ id:
61
+ title: ID
62
+ hashtag:
63
+ title: Hashtag
64
+ hint: Including "#".
65
+ message:
66
+ title: Message
67
+ hide_merge_commits:
68
+ title: Hide merge commits
69
+ hint: Message matches "^Merge branch "
70
+
71
+ submit: Submit
72
+
73
+ create:
74
+ diff_from_last_to_previous_revision: Diff from last to previous revision (currently includes commits not matching the current filter)
75
+
76
+ errors:
77
+ nothing_found: Nothing found.
78
+ repository_not_found: Repository not found.
79
+ cannot_be_blank: can't be blank.
80
+ not_enough_criteria: "Please set at least one of these: path, author, id, hashtag, message, story, tasks, from, to."
81
+ too_many_git_timeouts: Too many timeouts for git connection!
82
+ diff:
83
+ errors:
84
+ diff_length_not_one: "Not implemented error: diff length is not 1 but %{diff.length}."
data/config/routes.rb CHANGED
@@ -1,2 +1,6 @@
1
1
  CommitFilter::Engine.routes.draw do
2
+ namespace :commit do
3
+ resources :filters, only: [:new, :create]
4
+ resources :diffs, only: [:new]
5
+ end
2
6
  end
data/lib/commit_filter.rb CHANGED
@@ -1,4 +1,33 @@
1
- require "commit_filter/engine"
1
+ # misc
2
+ require 'gem_config'
3
+ require 'grit'
4
+
5
+ # view
6
+ require 'jquery-rails'
7
+ require 'coffee_script'
8
+ require 'diff_to_html'
9
+ require 'pygments'
10
+
11
+ require 'commit_filter/grit_extension'
12
+
13
+ require 'commit_filter/engine'
2
14
 
3
15
  module CommitFilter
16
+ include GemConfig::Base
17
+
18
+ with_configuration do
19
+ has :frontend_framework, classes: String, values: ['twitter_bootstrap/3'], default: 'twitter_bootstrap/3'
20
+ has :workspace_and_repository_from_rails_root, classes: [TrueClass, FalseClass], default: true
21
+ has :workspace, classes: String
22
+ has :repository, classes: String
23
+ has :repository_provider, classes: String
24
+ has :user_or_organization, classes: String
25
+ has :repository_host, classes: String
26
+ has :project_slug, classes: String
27
+ has :branch, classes: String, default: 'master'
28
+ has :issue_url, classes: String
29
+ has :group_by_rails_file_category, classes: [TrueClass, FalseClass], default: false
30
+ has :hide_merge_commits, classes: [TrueClass, FalseClass], default: true
31
+ has :git_debug_logging, classes: [TrueClass, FalseClass], default: false
32
+ end
4
33
  end
@@ -1,5 +1,14 @@
1
1
  module CommitFilter
2
2
  class Engine < ::Rails::Engine
3
3
  isolate_namespace CommitFilter
4
+
5
+ config.to_prepare do
6
+ Rails.application.config.assets.precompile += %w(
7
+ commit_filter/commit/diff.css
8
+ commit_filter/form.js
9
+ commit_filter/file_commits.js
10
+ commit_filter/frameworks/twitter_bootstrap/3/filter_result.js
11
+ )
12
+ end
4
13
  end
5
14
  end
@@ -0,0 +1,15 @@
1
+ module Grit
2
+ class Repo
3
+ def diff(a, b, *paths)
4
+ diff = self.git.native('diff', { 'no-ext-diff' => true }, a, b, '--', *paths)
5
+
6
+ if diff =~ /diff --git a/
7
+ diff = diff.sub(/.*?(diff --git a)/m, '\1')
8
+ else
9
+ diff = ''
10
+ end
11
+
12
+ Diff.list_from_string(self, diff)
13
+ end
14
+ end
15
+ end
@@ -1,3 +1,3 @@
1
1
  module CommitFilter
2
- VERSION = "0.0.1"
2
+ VERSION = "0.1.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: commit_filter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mathias Gawlista
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-16 00:00:00.000000000 Z
11
+ date: 2015-03-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -24,8 +24,105 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: 4.2.0
27
- description: "#Ruby on #Rails engine which renders a view about (#Git) commits with
28
- given criteria grouped by category (e.g. model) and file name."
27
+ - !ruby/object:Gem::Dependency
28
+ name: gem_config
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.3.1
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.3.1
41
+ - !ruby/object:Gem::Dependency
42
+ name: sqlite3
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 1.3.10
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 1.3.10
55
+ - !ruby/object:Gem::Dependency
56
+ name: gitlab-grit
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 2.7.3
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 2.7.3
69
+ - !ruby/object:Gem::Dependency
70
+ name: coffee-script
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 2.3.0
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 2.3.0
83
+ - !ruby/object:Gem::Dependency
84
+ name: jquery-rails
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 4.0.3
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 4.0.3
97
+ - !ruby/object:Gem::Dependency
98
+ name: diff_to_html
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 0.0.1
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 0.0.1
111
+ - !ruby/object:Gem::Dependency
112
+ name: pygments.rb
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: 0.6.2
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: 0.6.2
125
+ description: "& grouping by category + file http://bit.ly/commit-filter-0-1-0"
29
126
  email:
30
127
  - gawlista@gmail.com
31
128
  executables: []
@@ -35,13 +132,34 @@ files:
35
132
  - MIT-LICENSE
36
133
  - README.md
37
134
  - Rakefile
135
+ - app/assets/images/commit_filter/spinner.gif
136
+ - app/assets/javascripts/commit_filter/file_commits.js.coffee
137
+ - app/assets/javascripts/commit_filter/form.js.coffee
138
+ - app/assets/javascripts/commit_filter/frameworks/twitter_bootstrap/3/filter_result.js.coffee
38
139
  - app/assets/stylesheets/commit_filter/application.css
140
+ - app/assets/stylesheets/commit_filter/base.css
141
+ - app/assets/stylesheets/commit_filter/commit/diff.css
39
142
  - app/controllers/commit_filter/application_controller.rb
143
+ - app/controllers/commit_filter/commit/diffs_controller.rb
144
+ - app/controllers/commit_filter/commit/filters_controller.rb
40
145
  - app/helpers/commit_filter/application_helper.rb
41
- - app/views/layouts/commit_filter/application.html.erb
146
+ - app/models/commit_filter/model.rb
147
+ - app/presenters/commit_filter/application_presenter.rb
148
+ - app/presenters/commit_filter/presenter.rb
149
+ - app/presenters/commit_filter/presenters/frameworks/twitter_bootstrap/version3_presenter.rb
150
+ - app/views/commit_filter/frameworks/twitter_bootstrap/3/commit/filters/_categories.html.erb
151
+ - app/views/commit_filter/frameworks/twitter_bootstrap/3/commit/filters/_file_commits.html.erb
152
+ - app/views/commit_filter/frameworks/twitter_bootstrap/3/commit/filters/_files.html.erb
153
+ - app/views/commit_filter/frameworks/twitter_bootstrap/3/commit/filters/_form.html.erb
154
+ - app/views/commit_filter/frameworks/twitter_bootstrap/3/commit/filters/new.html.erb
155
+ - app/views/commit_filter/frameworks/twitter_bootstrap/3/layouts/commit_filter/application.html.erb
156
+ - app/views/layouts/commit_filter/shared/_foot.html.erb
157
+ - app/views/layouts/commit_filter/shared/_head.html.erb
158
+ - config/locales/en.yml
42
159
  - config/routes.rb
43
160
  - lib/commit_filter.rb
44
161
  - lib/commit_filter/engine.rb
162
+ - lib/commit_filter/grit_extension.rb
45
163
  - lib/commit_filter/version.rb
46
164
  - lib/tasks/commit_filter_tasks.rake
47
165
  homepage: http://GitHub.com/volontarian/commit_filter
@@ -1,14 +0,0 @@
1
- <!DOCTYPE html>
2
- <html>
3
- <head>
4
- <title>CommitFilter</title>
5
- <%= stylesheet_link_tag "commit_filter/application", media: "all" %>
6
- <%= javascript_include_tag "commit_filter/application" %>
7
- <%= csrf_meta_tags %>
8
- </head>
9
- <body>
10
-
11
- <%= yield %>
12
-
13
- </body>
14
- </html>