gitlab-gollum-lib 1.1.0 → 4.2.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.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -3
  3. data/HISTORY.md +25 -0
  4. data/LICENSE +1 -1
  5. data/README.md +24 -312
  6. data/Rakefile +32 -16
  7. data/gemspec.rb +110 -0
  8. data/gollum-lib.gemspec +8 -75
  9. data/gollum-lib_java.gemspec +4 -0
  10. data/lib/gollum-lib.rb +18 -6
  11. data/lib/gollum-lib/blob_entry.rb +10 -9
  12. data/lib/gollum-lib/committer.rb +37 -30
  13. data/lib/gollum-lib/file.rb +71 -15
  14. data/lib/gollum-lib/file_view.rb +53 -48
  15. data/lib/gollum-lib/filter.rb +78 -0
  16. data/lib/gollum-lib/filter/code.rb +145 -0
  17. data/lib/gollum-lib/filter/emoji.rb +39 -0
  18. data/lib/gollum-lib/filter/macro.rb +57 -0
  19. data/lib/gollum-lib/filter/metadata.rb +29 -0
  20. data/lib/gollum-lib/filter/plain_text.rb +16 -0
  21. data/lib/gollum-lib/filter/plantuml.rb +176 -0
  22. data/lib/gollum-lib/filter/remote_code.rb +63 -0
  23. data/lib/gollum-lib/filter/render.rb +20 -0
  24. data/lib/gollum-lib/filter/sanitize.rb +18 -0
  25. data/lib/gollum-lib/filter/tags.rb +327 -0
  26. data/lib/gollum-lib/filter/toc.rb +134 -0
  27. data/lib/gollum-lib/filter/wsd.rb +54 -0
  28. data/lib/gollum-lib/git_access.rb +30 -32
  29. data/lib/gollum-lib/gitcode.rb +16 -16
  30. data/lib/gollum-lib/helpers.rb +3 -3
  31. data/lib/gollum-lib/hook.rb +35 -0
  32. data/lib/gollum-lib/macro.rb +43 -0
  33. data/lib/gollum-lib/macro/all_pages.rb +11 -0
  34. data/lib/gollum-lib/macro/global_toc.rb +12 -0
  35. data/lib/gollum-lib/macro/navigation.rb +20 -0
  36. data/lib/gollum-lib/macro/series.rb +48 -0
  37. data/lib/gollum-lib/markup.rb +95 -572
  38. data/lib/gollum-lib/markups.rb +9 -3
  39. data/lib/gollum-lib/page.rb +109 -80
  40. data/lib/gollum-lib/pagination.rb +1 -1
  41. data/lib/gollum-lib/sanitization.rb +75 -75
  42. data/lib/gollum-lib/version.rb +5 -0
  43. data/lib/gollum-lib/wiki.rb +287 -129
  44. metadata +237 -92
  45. data/CHANGELOG +0 -2
  46. data/VERSION +0 -1
  47. data/lib/gollum-lib/grit_ext.rb +0 -20
  48. data/lib/gollum-lib/remote_code.rb +0 -39
  49. data/lib/gollum-lib/web_sequence_diagram.rb +0 -44
@@ -0,0 +1,5 @@
1
+ module Gollum
2
+ module Lib
3
+ VERSION = '4.2.7'
4
+ end
5
+ end
@@ -14,16 +14,16 @@ module Gollum
14
14
  attr_writer :markup_classes
15
15
 
16
16
  # Sets the default ref for the wiki.
17
- attr_accessor :default_ref
17
+ attr_writer :default_ref
18
18
 
19
19
  # Sets the default name for commits.
20
- attr_accessor :default_committer_name
20
+ attr_writer :default_committer_name
21
21
 
22
22
  # Sets the default email for commits.
23
- attr_accessor :default_committer_email
23
+ attr_writer :default_committer_email
24
24
 
25
25
  # Array of chars to substitute whitespace for when trying to locate file in git repo.
26
- attr_accessor :default_ws_subs
26
+ attr_writer :default_ws_subs
27
27
 
28
28
  # Sets sanitization options. Set to false to deactivate
29
29
  # sanitization altogether.
@@ -35,39 +35,39 @@ module Gollum
35
35
 
36
36
  # Hash for setting different default wiki options
37
37
  # These defaults can be overridden by options passed directly to initialize()
38
- attr_accessor :default_options
38
+ attr_writer :default_options
39
39
 
40
40
  # Gets the page class used by all instances of this Wiki.
41
41
  # Default: Gollum::Page.
42
42
  def page_class
43
43
  @page_class ||
44
- if superclass.respond_to?(:page_class)
45
- superclass.page_class
46
- else
47
- ::Gollum::Page
48
- end
44
+ if superclass.respond_to?(:page_class)
45
+ superclass.page_class
46
+ else
47
+ ::Gollum::Page
48
+ end
49
49
  end
50
50
 
51
51
  # Gets the file class used by all instances of this Wiki.
52
52
  # Default: Gollum::File.
53
53
  def file_class
54
54
  @file_class ||
55
- if superclass.respond_to?(:file_class)
56
- superclass.file_class
57
- else
58
- ::Gollum::File
59
- end
55
+ if superclass.respond_to?(:file_class)
56
+ superclass.file_class
57
+ else
58
+ ::Gollum::File
59
+ end
60
60
  end
61
61
 
62
62
  # Gets the markup class used by all instances of this Wiki.
63
63
  # Default: Gollum::Markup
64
64
  def markup_classes
65
65
  @markup_classes ||=
66
- if superclass.respond_to?(:markup_classes)
67
- superclass.markup_classes
68
- else
69
- Hash.new(::Gollum::Markup)
70
- end
66
+ if superclass.respond_to?(:markup_classes)
67
+ superclass.markup_classes
68
+ else
69
+ Hash.new(::Gollum::Markup)
70
+ end
71
71
  end
72
72
 
73
73
  # Gets the default markup class used by all instances of this Wiki.
@@ -100,19 +100,32 @@ module Gollum
100
100
  def history_sanitization
101
101
  if @history_sanitization.nil?
102
102
  @history_sanitization = sanitization ?
103
- sanitization.history_sanitization :
104
- false
103
+ sanitization.history_sanitization :
104
+ false
105
105
  end
106
106
  @history_sanitization
107
107
  end
108
- end
109
108
 
110
- self.default_ref = 'master'
111
- self.default_committer_name = 'Anonymous'
112
- self.default_committer_email = 'anon@anon.com'
109
+ def default_ref
110
+ @default_ref || 'master'
111
+ end
112
+
113
+ def default_committer_name
114
+ @default_committer_name || 'Anonymous'
115
+ end
116
+
117
+ def default_committer_email
118
+ @default_committer_email || 'anon@anon.com'
119
+ end
120
+
121
+ def default_ws_subs
122
+ @default_ws_subs || ['_', '-']
123
+ end
113
124
 
114
- self.default_ws_subs = ['_','-']
115
- self.default_options = {}
125
+ def default_options
126
+ @default_options || {}
127
+ end
128
+ end
116
129
 
117
130
  # The String base path to prefix to internal links. For example, when set
118
131
  # to "/wiki", the page "Hobbit" will be linked as "/wiki/Hobbit". Defaults
@@ -144,13 +157,19 @@ module Gollum
144
157
  # Sets page title to value of first h1
145
158
  # Defaults to false
146
159
  attr_reader :h1_title
147
-
160
+
148
161
  # Gets the custom index page for / and subdirs (e.g. foo/)
149
162
  attr_reader :index_page
150
-
163
+
151
164
  # Gets side on which the sidebar should be shown
152
165
  attr_reader :bar_side
153
166
 
167
+ # An array of symbols which refer to classes under Gollum::Filter,
168
+ # each of which is an element in the "filtering chain". See
169
+ # the documentation for Gollum::Filter for more on how this chain
170
+ # works, and what filter classes need to implement.
171
+ attr_reader :filter_chain
172
+
154
173
  # Public: Initialize a new Gollum Repo.
155
174
  #
156
175
  # path - The String path to the Git repository that holds the Gollum
@@ -175,13 +194,19 @@ module Gollum
175
194
  # Default: false
176
195
  # :collapse_tree - Start with collapsed file view. Default: false
177
196
  # :css - Include the custom.css file from the repo.
197
+ # :emoji - Parse and interpret emoji tags (e.g. :heart:).
178
198
  # :h1_title - Concatenate all h1's on a page to form the
179
199
  # page title.
180
- # :index_page - The default page to retrieve or create if the
200
+ # :index_page - The default page to retrieve or create if the
181
201
  # a directory is accessed.
182
202
  # :bar_side - Where the sidebar should be displayed, may be:
183
203
  # - :left
184
204
  # - :right
205
+ # :allow_uploads - Set to true to allow file uploads.
206
+ # :per_page_uploads - Whether uploads should be stored in a central
207
+ # 'uploads' directory, or in a directory named for
208
+ # the page they were uploaded to.
209
+ # :filter_chain - Override the default filter chain with your own.
185
210
  #
186
211
  # Returns a fresh Gollum::Repo.
187
212
  def initialize(path, options = {})
@@ -216,11 +241,17 @@ module Gollum
216
241
  @show_all = options.fetch :show_all, false
217
242
  @collapse_tree = options.fetch :collapse_tree, false
218
243
  @css = options.fetch :css, false
244
+ @emoji = options.fetch :emoji, false
219
245
  @h1_title = options.fetch :h1_title, false
220
246
  @index_page = options.fetch :index_page, 'Home'
221
247
  @bar_side = options.fetch :sidebar, :right
222
- @user_icons = ['gravatar', 'identicon'].include?( options[:user_icons] ) ?
223
- options[:user_icons] : 'none'
248
+ @user_icons = ['gravatar', 'identicon'].include?(options[:user_icons]) ?
249
+ options[:user_icons] : 'none'
250
+ @allow_uploads = options.fetch :allow_uploads, false
251
+ @per_page_uploads = options.fetch :per_page_uploads, false
252
+ @filter_chain = options.fetch :filter_chain,
253
+ [:Metadata, :PlainText, :TOC, :RemoteCode, :Code, :Macro, :Emoji, :Sanitize, :WSD, :PlantUML, :Tags, :Render]
254
+ @filter_chain.delete(:Emoji) unless options.fetch :emoji, false
224
255
  end
225
256
 
226
257
  # Public: check whether the wiki's git repo exists on the filesystem.
@@ -257,10 +288,14 @@ module Gollum
257
288
  #
258
289
  # name - The full String pathname to the file.
259
290
  # version - The String version ID to find (default: @ref).
291
+ # try_on_disk - If true, try to return just a reference to a file
292
+ # that exists on the disk.
260
293
  #
261
- # Returns a Gollum::File or nil if no matching file was found.
262
- def file(name, version = @ref)
263
- @file_class.new(self).find(name, version)
294
+ # Returns a Gollum::File or nil if no matching file was found. Note
295
+ # that if you specify try_on_disk=true, you may or may not get a file
296
+ # for which on_disk? is actually true.
297
+ def file(name, version = @ref, try_on_disk = false)
298
+ @file_class.new(self).find(name, version, try_on_disk)
264
299
  end
265
300
 
266
301
  # Public: Create an in-memory Page with the given data and format. This
@@ -278,7 +313,7 @@ module Gollum
278
313
  name = @page_class.cname(name) + '.' + ext
279
314
  blob = OpenStruct.new(:name => name, :data => data, :is_symlink => false)
280
315
  page.populate(blob)
281
- page.version = @access.commit('master')
316
+ page.version = @access.commit(@ref)
282
317
  page
283
318
  end
284
319
 
@@ -291,7 +326,7 @@ module Gollum
291
326
  # :message - The String commit message.
292
327
  # :name - The String author full name.
293
328
  # :email - The String email address.
294
- # :parent - Optional Grit::Commit parent to this update.
329
+ # :parent - Optional Gollum::Git::Commit parent to this update.
295
330
  # :tree - Optional String SHA of the tree to create the
296
331
  # index from.
297
332
  # :committer - Optional Gollum::Committer instance. If provided,
@@ -303,25 +338,20 @@ module Gollum
303
338
  # Gollum::Committer instance if this is part of a batch update.
304
339
  def write_page(name, format, data, commit = {}, dir = '')
305
340
  # spaces must be dashes
306
- name.gsub!(' ', '-')
307
- dir.gsub!(' ', '-')
308
-
309
- multi_commit = false
341
+ sanitized_name = name.gsub(' ', '-')
342
+ sanitized_dir = dir.gsub(' ', '-')
343
+ sanitized_dir = ::File.join([@page_file_dir, sanitized_dir].compact)
310
344
 
311
- committer = if obj = commit[:committer]
312
- multi_commit = true
313
- obj
314
- else
315
- Committer.new(self, commit)
316
- end
345
+ multi_commit = !!commit[:committer]
346
+ committer = multi_commit ? commit[:committer] : Committer.new(self, commit)
317
347
 
318
- filename = Gollum::Page.cname(name)
348
+ filename = Gollum::Page.cname(sanitized_name)
319
349
 
320
- committer.add_to_index(dir, filename, format, data)
350
+ committer.add_to_index(sanitized_dir, filename, format, data)
321
351
 
322
- committer.after_commit do |index, sha|
352
+ committer.after_commit do |index, _sha|
323
353
  @access.refresh
324
- index.update_working_dir(dir, filename, format)
354
+ index.update_working_dir(sanitized_dir, filename, format)
325
355
  end
326
356
 
327
357
  multi_commit ? committer : committer.commit
@@ -335,7 +365,7 @@ module Gollum
335
365
  # :message - The String commit message.
336
366
  # :name - The String author full name.
337
367
  # :email - The String email address.
338
- # :parent - Optional Grit::Commit parent to this update.
368
+ # :parent - Optional Gollum::Git::Commit parent to this update.
339
369
  # :tree - Optional String SHA of the tree to create the
340
370
  # index from.
341
371
  # :committer - Optional Gollum::Committer instance. If provided,
@@ -347,34 +377,38 @@ module Gollum
347
377
  # Returns false if the operation is a NOOP.
348
378
  def rename_page(page, rename, commit = {})
349
379
  return false if page.nil?
350
- return false if rename.nil? or rename.empty?
380
+ return false if rename.nil? || rename.empty?
351
381
 
352
382
  (target_dir, target_name) = ::File.split(rename)
353
383
  (source_dir, source_name) = ::File.split(page.path)
354
- source_name = page.filename_stripped
384
+ source_name = page.filename_stripped
355
385
 
356
386
  # File.split gives us relative paths with ".", commiter.add_to_index doesn't like that.
357
- target_dir = '' if target_dir == '.'
358
- source_dir = '' if source_dir == '.'
359
- target_dir = target_dir.gsub(/^\//, '')
387
+ target_dir = '' if target_dir == '.'
388
+ source_dir = '' if source_dir == '.'
389
+ target_dir = target_dir.gsub(/^\//, '') # rubocop:disable Style/RegexpLiteral
360
390
 
361
391
  # if the rename is a NOOP, abort
362
- if source_dir == target_dir and source_name == target_name
392
+ if source_dir == target_dir && source_name == target_name
363
393
  return false
364
394
  end
365
395
 
366
- multi_commit = false
367
- committer = if obj = commit[:committer]
368
- multi_commit = true
369
- obj
370
- else
371
- Committer.new(self, commit)
372
- end
396
+ multi_commit = !!commit[:committer]
397
+ committer = multi_commit ? commit[:committer] : Committer.new(self, commit)
398
+
399
+ # This piece only works for multi_commit
400
+ # If we are in a commit batch and one of the previous operations
401
+ # has updated the page, any information we ask to the page can be outdated.
402
+ # Therefore, we should ask first to the current committer tree to see if
403
+ # there is any updated change.
404
+ raw_data = raw_data_in_committer(committer, source_dir, page.filename) ||
405
+ raw_data_in_committer(committer, source_dir, "#{target_name}.#{Page.format_to_ext(page.format)}") ||
406
+ page.raw_data
373
407
 
374
408
  committer.delete(page.path)
375
- committer.add_to_index(target_dir, target_name, page.format, page.raw_data, :allow_same_ext)
409
+ committer.add_to_index(target_dir, target_name, page.format, raw_data)
376
410
 
377
- committer.after_commit do |index, sha|
411
+ committer.after_commit do |index, _sha|
378
412
  @access.refresh
379
413
  index.update_working_dir(source_dir, source_name, page.format)
380
414
  index.update_working_dir(target_dir, target_name, page.format)
@@ -396,7 +430,7 @@ module Gollum
396
430
  # :message - The String commit message.
397
431
  # :name - The String author full name.
398
432
  # :email - The String email address.
399
- # :parent - Optional Grit::Commit parent to this update.
433
+ # :parent - Optional Gollum::Git::Commit parent to this update.
400
434
  # :tree - Optional String SHA of the tree to create the
401
435
  # index from.
402
436
  # :committer - Optional Gollum::Committer instance. If provided,
@@ -406,30 +440,23 @@ module Gollum
406
440
  # Returns the String SHA1 of the newly written version, or the
407
441
  # Gollum::Committer instance if this is part of a batch update.
408
442
  def update_page(page, name, format, data, commit = {})
409
- name ||= page.name
443
+ name = name ? ::File.basename(name) : page.name
410
444
  format ||= page.format
411
445
  dir = ::File.dirname(page.path)
412
446
  dir = '' if dir == '.'
413
- filename = (rename = page.name != name) ?
414
- Gollum::Page.cname(name) : page.filename_stripped
415
-
416
- multi_commit = false
447
+ filename = (rename = page.name != name) ? Gollum::Page.cname(name) : page.filename_stripped
417
448
 
418
- committer = if obj = commit[:committer]
419
- multi_commit = true
420
- obj
421
- else
422
- Committer.new(self, commit)
423
- end
449
+ multi_commit = !!commit[:committer]
450
+ committer = multi_commit ? commit[:committer] : Committer.new(self, commit)
424
451
 
425
452
  if !rename && page.format == format
426
453
  committer.add(page.path, normalize(data))
427
454
  else
428
455
  committer.delete(page.path)
429
- committer.add_to_index(dir, filename, format, data, :allow_same_ext)
456
+ committer.add_to_index(dir, filename, format, data)
430
457
  end
431
458
 
432
- committer.after_commit do |index, sha|
459
+ committer.after_commit do |index, _sha|
433
460
  @access.refresh
434
461
  index.update_working_dir(dir, page.filename_stripped, page.format)
435
462
  index.update_working_dir(dir, filename, format)
@@ -445,7 +472,7 @@ module Gollum
445
472
  # :message - The String commit message.
446
473
  # :name - The String author full name.
447
474
  # :email - The String email address.
448
- # :parent - Optional Grit::Commit parent to this update.
475
+ # :parent - Optional Gollum::Git::Commit parent to this update.
449
476
  # :tree - Optional String SHA of the tree to create the
450
477
  # index from.
451
478
  # :committer - Optional Gollum::Committer instance. If provided,
@@ -455,18 +482,13 @@ module Gollum
455
482
  # Returns the String SHA1 of the newly written version, or the
456
483
  # Gollum::Committer instance if this is part of a batch update.
457
484
  def delete_page(page, commit)
458
- multi_commit = false
459
485
 
460
- committer = if obj = commit[:committer]
461
- multi_commit = true
462
- obj
463
- else
464
- Committer.new(self, commit)
465
- end
486
+ multi_commit = !!commit[:committer]
487
+ committer = multi_commit ? commit[:committer] : Committer.new(self, commit)
466
488
 
467
489
  committer.delete(page.path)
468
490
 
469
- committer.after_commit do |index, sha|
491
+ committer.after_commit do |index, _sha|
470
492
  dir = ::File.dirname(page.path)
471
493
  dir = '' if dir == '.'
472
494
 
@@ -477,6 +499,43 @@ module Gollum
477
499
  multi_commit ? committer : committer.commit
478
500
  end
479
501
 
502
+ # Public: Delete a file.
503
+ #
504
+ # path - The path to the file to delete
505
+ # commit - The commit Hash details:
506
+ # :message - The String commit message.
507
+ # :name - The String author full name.
508
+ # :email - The String email address.
509
+ # :parent - Optional Gollum::Git::Commit parent to this update.
510
+ # :tree - Optional String SHA of the tree to create the
511
+ # index from.
512
+ # :committer - Optional Gollum::Committer instance. If provided,
513
+ # assume that this operation is part of batch of
514
+ # updates and the commit happens later.
515
+ #
516
+ # Returns the String SHA1 of the newly written version, or the
517
+ # Gollum::Committer instance if this is part of a batch update.
518
+ def delete_file(path, commit)
519
+ dir = ::File.dirname(path)
520
+ ext = ::File.extname(path)
521
+ format = ext.split('.').last || 'txt'
522
+ filename = ::File.basename(path, ext)
523
+
524
+ multi_commit = !!commit[:committer]
525
+ committer = multi_commit ? commit[:committer] : Committer.new(self, commit)
526
+
527
+ committer.delete(path)
528
+
529
+ committer.after_commit do |index, _sha|
530
+ dir = '' if dir == '.'
531
+
532
+ @access.refresh
533
+ index.update_working_dir(dir, filename, format)
534
+ end
535
+
536
+ multi_commit ? committer : committer.commit
537
+ end
538
+
480
539
  # Public: Applies a reverse diff for a given page. If only 1 SHA is given,
481
540
  # the reverse diff will be taken from its parent (^SHA...SHA). If two SHAs
482
541
  # are given, the reverse diff is taken from SHA1...SHA2.
@@ -489,7 +548,7 @@ module Gollum
489
548
  # :message - The String commit message.
490
549
  # :name - The String author full name.
491
550
  # :email - The String email address.
492
- # :parent - Optional Grit::Commit parent to this update.
551
+ # :parent - Optional Gollum::Git::Commit parent to this update.
493
552
  #
494
553
  # Returns a String SHA1 of the new commit, or nil if the reverse diff does
495
554
  # not apply.
@@ -504,7 +563,7 @@ module Gollum
504
563
  parent = committer.parents[0]
505
564
  committer.options[:tree] = @repo.git.apply_patch(parent.sha, patch)
506
565
  return false unless committer.options[:tree]
507
- committer.after_commit do |index, sha|
566
+ committer.after_commit do |index, _sha|
508
567
  @access.refresh
509
568
 
510
569
  files = []
@@ -513,11 +572,11 @@ module Gollum
513
572
  else
514
573
  # Grit::Diff can't parse reverse diffs.... yet
515
574
  patch.each_line do |line|
516
- if line =~ %r{^diff --git b/.+? a/(.+)$}
517
- path = $1
575
+ if line =~ %r(^diff --git b/.+? a/(.+)$)
576
+ path = Regexp.last_match[1]
518
577
  ext = ::File.extname(path)
519
578
  name = ::File.basename(path, ext)
520
- if format = ::Gollum::Page.format_for(ext)
579
+ if (format = ::Gollum::Page.format_for(ext))
521
580
  files << [path, name, format]
522
581
  end
523
582
  end
@@ -557,8 +616,8 @@ module Gollum
557
616
  # treeish - The String commit ID or ref to find (default: @ref)
558
617
  #
559
618
  # Returns an Array of Gollum::Page instances.
560
- def pages(treeish = nil)
561
- tree_list(treeish || @ref)
619
+ def pages(treeish = nil, limit: nil)
620
+ tree_list((treeish || @ref), limit: limit)
562
621
  end
563
622
 
564
623
  # Public: Lists all non-page files for this wiki.
@@ -579,7 +638,7 @@ module Gollum
579
638
  tree_map_for(ref || @ref).inject(0) do |num, entry|
580
639
  num + (@page_class.valid_page_name?(entry.name) ? 1 : 0)
581
640
  end
582
- rescue Grit::GitRuby::Repository::NoSuchShaFound
641
+ rescue Gollum::Git::NoSuchShaFound
583
642
  0
584
643
  end
585
644
 
@@ -589,33 +648,28 @@ module Gollum
589
648
  #
590
649
  # Returns an Array with Objects of page name and count of matches
591
650
  def search(query)
592
- args = [{}, '-i', '-c', query, @ref, '--']
593
- args << '--' << @page_file_dir if @page_file_dir
594
-
651
+ options = {:path => page_file_dir, :ref => ref}
595
652
  results = {}
596
-
597
- @repo.git.grep(*args).split("\n").each do |line|
598
- result = line.split(':')
599
- result_1 = result[1]
653
+ @repo.git.grep(query, options).each do |hit|
654
+ name = hit[:name]
655
+ count = hit[:count]
600
656
  # Remove ext only from known extensions.
601
657
  # test.pdf => test.pdf, test.md => test
602
- file_name = Page::valid_page_name?(result_1) ? result_1.chomp(::File.extname(result_1)) :
603
- result_1
604
- results[file_name] = result[2].to_i
658
+ file_name = Page::valid_page_name?(name) ? name.chomp(::File.extname(name)) : name
659
+ results[file_name] = count.to_i
605
660
  end
606
661
 
607
662
  # Use git ls-files '*query*' to search for file names. Grep only searches file content.
608
663
  # Spaces are converted to dashes when saving pages to disk.
609
- @repo.git.ls_files({}, "*#{ query.gsub(' ', '-') }*").split("\n").each do |line|
664
+ @repo.git.ls_files(query.gsub(' ','-'), options).each do |path|
610
665
  # Remove ext only from known extensions.
611
- file_name = Page::valid_page_name?(line) ? line.chomp(::File.extname(line)) :
612
- line
666
+ file_name = Page::valid_page_name?(path) ? path.chomp(::File.extname(path)) : path
613
667
  # If there's not already a result for file_name then
614
668
  # the value is nil and nil.to_i is 0.
615
669
  results[file_name] = results[file_name].to_i + 1;
616
670
  end
617
671
 
618
- results.map do |key,val|
672
+ results.map do |key, val|
619
673
  { :count => val, :name => key }
620
674
  end
621
675
  end
@@ -626,11 +680,22 @@ module Gollum
626
680
  # :page - The Integer page number (default: 1).
627
681
  # :per_page - The Integer max count of items to return.
628
682
  #
629
- # Returns an Array of Grit::Commit.
683
+ # Returns an Array of Gollum::Git::Commit.
630
684
  def log(options = {})
631
685
  @repo.log(@ref, nil, log_pagination_options(options))
632
686
  end
633
687
 
688
+ # Returns the latest changes in the wiki (globally)
689
+ #
690
+ # options - The options Hash:
691
+ # :max_count - The Integer number of items to return.
692
+ #
693
+ # Returns an Array of Gollum::Git::Commit.
694
+ def latest_changes(options={})
695
+ options[:max_count] = 10 unless options[:max_count]
696
+ @repo.log(@ref, nil, options)
697
+ end
698
+
634
699
  # Public: Refreshes just the cached Git reference data. This should
635
700
  # be called after every Gollum update.
636
701
  #
@@ -644,7 +709,7 @@ module Gollum
644
709
  #
645
710
  # Returns a Sanitize instance.
646
711
  def sanitizer
647
- if options = sanitization
712
+ if (options = sanitization)
648
713
  @sanitizer ||= options.to_sanitize
649
714
  end
650
715
  end
@@ -654,20 +719,88 @@ module Gollum
654
719
  #
655
720
  # Returns a Sanitize instance.
656
721
  def history_sanitizer
657
- if options = history_sanitization
722
+ if (options = history_sanitization)
658
723
  @history_sanitizer ||= options.to_sanitize
659
724
  end
660
725
  end
661
726
 
727
+ # Public: Add an additional link to the filter chain.
728
+ #
729
+ # name - A symbol which represents the name of a class under the
730
+ # Gollum::Render namespace to insert into the chain.
731
+ #
732
+ # loc - A "location specifier" -- that is, where to put the new
733
+ # filter in the chain. This can be one of `:first`, `:last`,
734
+ # `:before => :SomeElement`, or `:after => :SomeElement`, where
735
+ # `:SomeElement` (if specified) is a symbol already in the
736
+ # filter chain. A `:before` or `:after` which references a
737
+ # filter that doesn't exist will cause `ArgumentError` to be
738
+ # raised.
739
+ #
740
+ # Returns nothing.
741
+ def add_filter(name, loc)
742
+ unless name.is_a? Symbol
743
+ raise ArgumentError,
744
+ "Invalid filter name #{name.inspect} (must be a symbol)"
745
+ end
746
+
747
+ case loc
748
+ when :first
749
+ @filter_chain.unshift(name)
750
+ when :last
751
+ @filter_chain.push(name)
752
+ when Hash
753
+ if loc.length != 1
754
+ raise ArgumentError,
755
+ "Invalid location specifier"
756
+ end
757
+ if ([:before, :after] && loc.keys).empty?
758
+ raise ArgumentError,
759
+ "Invalid location specifier"
760
+ end
761
+
762
+ next_to = loc.values.first
763
+ relative = loc.keys.first
764
+
765
+ i = @filter_chain.index(next_to)
766
+ if i.nil?
767
+ raise ArgumentError,
768
+ "Unknown filter #{next_to.inspect}"
769
+ end
770
+
771
+ i += 1 if relative == :after
772
+ @filter_chain.insert(i, name)
773
+ else
774
+ raise ArgumentError,
775
+ "Invalid location specifier"
776
+ end
777
+ end
778
+
779
+ # Remove the named filter from the filter chain.
780
+ #
781
+ # Returns nothing. Raises `ArgumentError` if the named filter doesn't
782
+ # exist in the chain.
783
+ def remove_filter(name)
784
+ unless name.is_a? Symbol
785
+ raise ArgumentError,
786
+ "Invalid filter name #{name.inspect} (must be a symbol)"
787
+ end
788
+
789
+ unless @filter_chain.delete(name)
790
+ raise ArgumentError,
791
+ "#{name.inspect} not found in filter chain"
792
+ end
793
+ end
794
+
662
795
  #########################################################################
663
796
  #
664
797
  # Internal Methods
665
798
  #
666
799
  #########################################################################
667
800
 
668
- # The Grit::Repo associated with the wiki.
801
+ # The Gollum::Git::Repo associated with the wiki.
669
802
  #
670
- # Returns the Grit::Repo.
803
+ # Returns the Gollum::Git::Repo.
671
804
  attr_reader :repo
672
805
 
673
806
  # The String path to the Git repository that holds the Gollum site.
@@ -700,6 +833,13 @@ module Gollum
700
833
  # Start with collapsed file view. Default: false
701
834
  attr_reader :collapse_tree
702
835
 
836
+ # Toggles file upload functionality.
837
+ attr_reader :allow_uploads
838
+
839
+ # Toggles whether uploaded files go into 'uploads', or a directory
840
+ # named after the page they were uploaded to.
841
+ attr_reader :per_page_uploads
842
+
703
843
  # Normalize the data.
704
844
  #
705
845
  # data - The String data to be normalized.
@@ -724,12 +864,16 @@ module Gollum
724
864
  # ref - A String ref that is either a commit SHA or references one.
725
865
  #
726
866
  # Returns a flat Array of Gollum::Page instances.
727
- def tree_list(ref)
728
- if sha = @access.ref_to_sha(ref)
867
+ def tree_list(ref, limit: nil)
868
+ if (sha = @access.ref_to_sha(ref))
729
869
  commit = @access.commit(sha)
730
870
  tree_map_for(sha).inject([]) do |list, entry|
731
871
  next list unless @page_class.valid_page_name?(entry.name)
872
+
732
873
  list << entry.page(self, commit)
874
+ break list if limit && list.size >= limit
875
+
876
+ list
733
877
  end
734
878
  else
735
879
  []
@@ -742,7 +886,7 @@ module Gollum
742
886
  #
743
887
  # Returns a flat Array of Gollum::File instances.
744
888
  def file_list(ref)
745
- if sha = @access.ref_to_sha(ref)
889
+ if (sha = @access.ref_to_sha(ref))
746
890
  commit = @access.commit(sha)
747
891
  tree_map_for(sha).inject([]) do |list, entry|
748
892
  next list if entry.name.start_with?('_')
@@ -764,11 +908,11 @@ module Gollum
764
908
  # Returns a String of the reverse Diff to apply.
765
909
  def full_reverse_diff_for(page, sha1, sha2 = nil)
766
910
  sha1, sha2 = "#{sha1}^", sha1 if sha2.nil?
767
- args = [{:R => true}, sha1, sha2]
768
911
  if page
769
- args << '--' << (page.respond_to?(:path) ? page.path : page.to_s)
912
+ path = (page.respond_to?(:path) ? page.path : page.to_s)
913
+ return repo.diff(sha2, sha1, path).first.diff
770
914
  end
771
- repo.git.native(:diff, *args)
915
+ repo.diff(sha2, sha1).map { |d| d.diff }.join("\n")
772
916
  end
773
917
 
774
918
  # Creates a reverse diff for the given SHAs.
@@ -794,18 +938,19 @@ module Gollum
794
938
  #
795
939
  # Returns the String email address.
796
940
  def default_committer_email
797
- @default_committer_email ||= \
798
- @repo.config['user.email'] || self.class.default_committer_email
941
+ email = @repo.config['user.email']
942
+ email = email.delete('<>') if email
943
+ @default_committer_email ||= email || self.class.default_committer_email
799
944
  end
800
945
 
801
946
  # Gets the commit object for the given ref or sha.
802
947
  #
803
948
  # ref - A string ref or SHA pointing to a valid commit.
804
949
  #
805
- # Returns a Grit::Commit instance.
950
+ # Returns a Gollum::Git::Commit instance.
806
951
  def commit_for(ref)
807
952
  @access.commit(ref)
808
- rescue Grit::GitRuby::Repository::NoSuchShaFound
953
+ rescue Gollum::Git::NoSuchShaFound
809
954
  end
810
955
 
811
956
  # Finds a full listing of files and their blob SHA for a given ref. Each
@@ -822,12 +967,25 @@ module Gollum
822
967
  else
823
968
  @access.tree(ref)
824
969
  end
825
- rescue Grit::GitRuby::Repository::NoSuchShaFound
970
+ rescue Gollum::Git::NoSuchShaFound
826
971
  []
827
972
  end
828
973
 
829
974
  def inspect
830
975
  %(#<#{self.class.name}:#{object_id} #{@repo.path}>)
831
976
  end
977
+
978
+ private
979
+
980
+ def raw_data_in_committer(committer, dir, filename)
981
+ data = nil
982
+
983
+ [*dir.split(::File::SEPARATOR), filename].each do |key|
984
+ data = data ? data[key] : committer.tree[key]
985
+ break unless data
986
+ end
987
+
988
+ data
989
+ end
832
990
  end
833
991
  end