gollum-lib 5.0.a.4-java → 5.0.1-java

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 (43) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -1
  3. data/README.md +12 -7
  4. data/Rakefile +7 -7
  5. data/adapter_dependencies.rb +7 -0
  6. data/gemspec.rb +18 -10
  7. data/gollum-lib.gemspec +2 -6
  8. data/gollum-lib_java.gemspec +2 -2
  9. data/lib/gollum-lib.rb +9 -9
  10. data/lib/gollum-lib/blob_entry.rb +2 -8
  11. data/lib/gollum-lib/committer.rb +22 -60
  12. data/lib/gollum-lib/file.rb +105 -82
  13. data/lib/gollum-lib/file_view.rb +8 -4
  14. data/lib/gollum-lib/filter.rb +12 -0
  15. data/lib/gollum-lib/filter/code.rb +9 -13
  16. data/lib/gollum-lib/filter/critic_markup.rb +97 -0
  17. data/lib/gollum-lib/filter/emoji.rb +10 -8
  18. data/lib/gollum-lib/filter/macro.rb +5 -2
  19. data/lib/gollum-lib/filter/plantuml.rb +1 -1
  20. data/lib/gollum-lib/filter/remote_code.rb +3 -2
  21. data/lib/gollum-lib/filter/render.rb +25 -2
  22. data/lib/gollum-lib/filter/sanitize.rb +1 -8
  23. data/lib/gollum-lib/filter/tags.rb +57 -47
  24. data/lib/gollum-lib/filter/toc.rb +17 -21
  25. data/lib/gollum-lib/filter/yaml.rb +1 -1
  26. data/lib/gollum-lib/git_access.rb +0 -25
  27. data/lib/gollum-lib/helpers.rb +13 -3
  28. data/lib/gollum-lib/macro/audio.rb +9 -0
  29. data/lib/gollum-lib/macro/global_toc.rb +2 -1
  30. data/lib/gollum-lib/macro/navigation.rb +8 -6
  31. data/lib/gollum-lib/macro/note.rb +19 -0
  32. data/lib/gollum-lib/macro/octicon.rb +12 -0
  33. data/lib/gollum-lib/macro/warn.rb +11 -0
  34. data/lib/gollum-lib/markup.rb +17 -32
  35. data/lib/gollum-lib/markups.rb +11 -7
  36. data/lib/gollum-lib/page.rb +79 -165
  37. data/lib/gollum-lib/pagination.rb +7 -6
  38. data/lib/gollum-lib/redirects.rb +38 -0
  39. data/lib/gollum-lib/sanitization.rb +32 -357
  40. data/lib/gollum-lib/version.rb +1 -1
  41. data/lib/gollum-lib/wiki.rb +216 -404
  42. metadata +125 -79
  43. data/ROADMAP +0 -6
@@ -1,5 +1,5 @@
1
1
  module Gollum
2
2
  module Lib
3
- VERSION = '5.0.a.4'
3
+ VERSION = '5.0.1'
4
4
  end
5
5
  end
@@ -1,18 +1,11 @@
1
1
  # ~*~ encoding: utf-8 ~*~
2
+ require 'pathname'
3
+
2
4
  module Gollum
3
5
  class Wiki
4
6
  include Pagination
5
7
 
6
8
  class << self
7
- # Sets the page class used by all instances of this Wiki.
8
- attr_writer :page_class
9
-
10
- # Sets the file class used by all instances of this Wiki.
11
- attr_writer :file_class
12
-
13
- # Sets the markup class used by all instances of this Wiki.
14
- attr_writer :markup_classes
15
-
16
9
  # Sets the default ref for the wiki.
17
10
  attr_writer :default_ref
18
11
 
@@ -22,87 +15,10 @@ module Gollum
22
15
  # Sets the default email for commits.
23
16
  attr_writer :default_committer_email
24
17
 
25
- # Sets sanitization options. Set to false to deactivate
26
- # sanitization altogether.
27
- attr_writer :sanitization
28
-
29
- # Sets sanitization options. Set to false to deactivate
30
- # sanitization altogether.
31
- attr_writer :history_sanitization
32
-
33
18
  # Hash for setting different default wiki options
34
19
  # These defaults can be overridden by options passed directly to initialize()
35
20
  attr_writer :default_options
36
21
 
37
- # Gets the page class used by all instances of this Wiki.
38
- # Default: Gollum::Page.
39
- def page_class
40
- @page_class ||
41
- if superclass.respond_to?(:page_class)
42
- superclass.page_class
43
- else
44
- ::Gollum::Page
45
- end
46
- end
47
-
48
- # Gets the file class used by all instances of this Wiki.
49
- # Default: Gollum::File.
50
- def file_class
51
- @file_class ||
52
- if superclass.respond_to?(:file_class)
53
- superclass.file_class
54
- else
55
- ::Gollum::File
56
- end
57
- end
58
-
59
- # Gets the markup class used by all instances of this Wiki.
60
- # Default: Gollum::Markup
61
- def markup_classes
62
- @markup_classes ||=
63
- if superclass.respond_to?(:markup_classes)
64
- superclass.markup_classes
65
- else
66
- Hash.new(::Gollum::Markup)
67
- end
68
- end
69
-
70
- # Gets the default markup class used by all instances of this Wiki.
71
- # Kept for backwards compatibility until Gollum v2.x
72
- def markup_class(language=:default)
73
- markup_classes[language]
74
- end
75
-
76
- # Sets the default markup class used by all instances of this Wiki.
77
- # Kept for backwards compatibility until Gollum v2.x
78
- def markup_class=(default)
79
- @markup_classes = Hash.new(default).update(markup_classes)
80
- default
81
- end
82
-
83
- alias_method :default_markup_class, :markup_class
84
- alias_method :default_markup_class=, :markup_class=
85
-
86
- # Gets the default sanitization options for current pages used by
87
- # instances of this Wiki.
88
- def sanitization
89
- if @sanitization.nil?
90
- @sanitization = Sanitization.new
91
- end
92
- @sanitization
93
- end
94
-
95
- # Gets the default sanitization options for older page revisions used by
96
- # instances of this Wiki.
97
- def history_sanitization
98
- if @history_sanitization.nil?
99
- @history_sanitization = sanitization ?
100
- sanitization.history_sanitization :
101
- false
102
- end
103
- @history_sanitization
104
- end
105
-
106
22
  def default_ref
107
23
  @default_ref || 'master'
108
24
  end
@@ -131,21 +47,12 @@ module Gollum
131
47
  # to "/".
132
48
  attr_reader :base_path
133
49
 
134
- # Gets the sanitization options for current pages used by this Wiki.
135
- attr_reader :sanitization
136
-
137
- # Gets the sanitization options for older page revisions used by this Wiki.
138
- attr_reader :history_sanitization
139
-
140
50
  # Gets the String ref in which all page files reside.
141
51
  attr_reader :ref
142
52
 
143
53
  # Gets the String directory in which all page files reside.
144
54
  attr_reader :page_file_dir
145
55
 
146
- # Gets the boolean live preview value.
147
- attr_reader :live_preview
148
-
149
56
  # Injects custom css from custom.css in root repo.
150
57
  # Defaults to false
151
58
  attr_reader :css
@@ -170,28 +77,25 @@ module Gollum
170
77
  # works, and what filter classes need to implement.
171
78
  attr_reader :filter_chain
172
79
 
80
+ # Global metadata to be merged into the metadata for each page
81
+ attr_reader :metadata
82
+
173
83
  # Public: Initialize a new Gollum Repo.
174
84
  #
175
85
  # path - The String path to the Git repository that holds the Gollum
176
86
  # site.
177
87
  # options - Optional Hash:
178
88
  # :universal_toc - Table of contents on all pages. Default: false
179
- # :live_preview - Livepreview editing for markdown files. Default: true
180
89
  # :base_path - String base path for all Wiki links.
181
90
  # Default: "/"
182
- # :page_class - The page Class. Default: Gollum::Page
183
- # :file_class - The file Class. Default: Gollum::File
184
- # :markup_classes - A hash containing the markup Classes for each
185
- # document type. Default: { Gollum::Markup }
186
- # :sanitization - An instance of Sanitization.
187
91
  # :page_file_dir - String the directory in which all page files reside
188
92
  # :ref - String the repository ref to retrieve pages from
189
93
  # :mathjax - Set to false to disable mathjax.
190
94
  # :user_icons - Enable user icons on the history page. [gravatar, identicon, none].
191
95
  # Default: none
192
- # :show_all - Show all files in file view, not just valid pages.
193
- # Default: false
194
- # :collapse_tree - Start with collapsed file view. Default: false
96
+ # :global_tag_lookup - Enable 4.x compatibility behavior for links
97
+ # :hyphened_tag_lookup - Spaces in tag paths are treated as dashes (-)
98
+ # :case_insensitive_tag_lookup - Paths in tags are compared case_insensitively
195
99
  # :css - Include the custom.css file from the repo.
196
100
  # :emoji - Parse and interpret emoji tags (e.g. :heart:).
197
101
  # :h1_title - Concatenate all h1's on a page to form the
@@ -216,31 +120,22 @@ module Gollum
216
120
  path = path.path
217
121
  end
218
122
 
219
- # Use .fetch instead of ||
220
- #
221
- # o = { :a => false }
222
- # o[:a] || true # => true
223
- # o.fetch :a, true # => false
224
-
225
123
  @path = path
226
124
  @repo_is_bare = options.fetch :repo_is_bare, nil
227
125
  @page_file_dir = options.fetch :page_file_dir, nil
126
+ @page_file_dir = Pathname.new("/#{@page_file_dir}").cleanpath.to_s[1..-1] if @page_file_dir
228
127
  @access = options.fetch :access, GitAccess.new(path, @page_file_dir, @repo_is_bare)
229
128
  @base_path = options.fetch :base_path, "/"
230
- @page_class = options.fetch :page_class, self.class.page_class
231
- @file_class = options.fetch :file_class, self.class.file_class
232
- @markup_classes = options.fetch :markup_classes, self.class.markup_classes
233
129
  @repo = @access.repo
234
130
  @ref = options.fetch :ref, self.class.default_ref
235
- @sanitization = options.fetch :sanitization, self.class.sanitization
236
- @history_sanitization = options.fetch :history_sanitization, self.class.history_sanitization
237
- @live_preview = options.fetch :live_preview, true
238
131
  @universal_toc = options.fetch :universal_toc, false
239
132
  @mathjax = options.fetch :mathjax, false
240
- @show_all = options.fetch :show_all, false
241
- @collapse_tree = options.fetch :collapse_tree, false
133
+ @global_tag_lookup = options.fetch :global_tag_lookup, false
134
+ @hyphened_tag_lookup = options.fetch :hyphened_tag_lookup, false
135
+ @case_insensitive_tag_lookup = options.fetch :case_insensitive_tag_lookup, false
242
136
  @css = options.fetch :css, false
243
137
  @emoji = options.fetch :emoji, false
138
+ @critic_markup = options.fetch :critic_markup, false
244
139
  @h1_title = options.fetch :h1_title, false
245
140
  @display_metadata = options.fetch :display_metadata, true
246
141
  @index_page = options.fetch :index_page, 'Home'
@@ -249,10 +144,12 @@ module Gollum
249
144
  options[:user_icons] : 'none'
250
145
  @allow_uploads = options.fetch :allow_uploads, false
251
146
  @per_page_uploads = options.fetch :per_page_uploads, false
147
+ @metadata = options.fetch :metadata, {}
252
148
  @filter_chain = options.fetch :filter_chain,
253
- [:YAML, :BibTeX, :PlainText, :TOC, :RemoteCode, :Code, :Macro, :Emoji, :Sanitize, :PlantUML, :Tags, :PandocBib, :Render]
149
+ [:YAML, :BibTeX, :PlainText, :CriticMarkup, :TOC, :RemoteCode, :Code, :Macro, :Emoji, :Sanitize, :PlantUML, :Tags, :PandocBib, :Render]
254
150
  @filter_chain.delete(:Emoji) unless options.fetch :emoji, false
255
151
  @filter_chain.delete(:PandocBib) unless ::Gollum::MarkupRegisterUtils.using_pandoc?
152
+ @filter_chain.delete(:CriticMarkup) unless options.fetch :critic_markup, false
256
153
  end
257
154
 
258
155
  # Public: check whether the wiki's git repo exists on the filesystem.
@@ -264,25 +161,13 @@ module Gollum
264
161
 
265
162
  # Public: Get the formatted page for a given page name, version, and dir.
266
163
  #
267
- # name - The human or canonical String page name of the wiki page.
164
+ # path - The String path to the the wiki page (may or may not include file extension).
268
165
  # version - The String version ID to find (default: @ref).
269
- # dir - The directory String relative to the repo.
166
+ # global_match - If true, find a File matching path's filename, but not it's directory (so anywhere in the repo)
270
167
  #
271
168
  # Returns a Gollum::Page or nil if no matching page was found.
272
- def page(name, version = @ref, dir = nil, exact = false)
273
- version = @ref if version.nil?
274
- @page_class.new(self).find(name, version, dir, exact)
275
- end
276
-
277
- # Public: Convenience method instead of calling page(name, nil, dir).
278
- #
279
- # name - The human or canonical String page name of the wiki page.
280
- # version - The String version ID to find (default: @ref).
281
- # dir - The directory String relative to the repo.
282
- #
283
- # Returns a Gollum::Page or nil if no matching page was found.
284
- def paged(name, dir = nil, exact = false, version = @ref)
285
- page(name, version, dir, exact)
169
+ def page(path, version = nil, global_match = false)
170
+ ::Gollum::Page.find(self, path, version.nil? ? @ref : version, false, global_match)
286
171
  end
287
172
 
288
173
  # Public: Get the static file for a given name.
@@ -295,8 +180,8 @@ module Gollum
295
180
  # Returns a Gollum::File or nil if no matching file was found. Note
296
181
  # that if you specify try_on_disk=true, you may or may not get a file
297
182
  # for which on_disk? is actually true.
298
- def file(name, version = @ref, try_on_disk = false)
299
- @file_class.new(self).find(name, version, try_on_disk)
183
+ def file(name, version = nil, try_on_disk = false)
184
+ ::Gollum::File.find(self, name, version.nil? ? @ref : version, try_on_disk)
300
185
  end
301
186
 
302
187
  # Public: Create an in-memory Page with the given data and format. This
@@ -309,18 +194,12 @@ module Gollum
309
194
  #
310
195
  # Returns the in-memory Gollum::Page.
311
196
  def preview_page(name, data, format)
312
- page = @page_class.new(self)
313
- ext = @page_class.format_to_ext(format.to_sym)
314
- filename = "#{name}.#{ext}"
315
- blob = OpenStruct.new(:name => filename, :data => data, :is_symlink => false)
316
- page.populate(blob)
317
- page.version = @access.commit(@ref)
318
- page
197
+ ::Gollum::PreviewPage.new(self, "#{name}.#{::Gollum::Page.format_to_ext(format.to_sym)}", data, @access.commit(@ref))
319
198
  end
320
199
 
321
200
  # Public: Write a new version of a page to the Gollum repo root.
322
201
  #
323
- # name - The String name of the page.
202
+ # path - The String path where the page will be written.
324
203
  # format - The Symbol format of the page.
325
204
  # data - The new String contents of the page.
326
205
  # commit - The commit Hash details:
@@ -333,23 +212,50 @@ module Gollum
333
212
  # :committer - Optional Gollum::Committer instance. If provided,
334
213
  # assume that this operation is part of batch of
335
214
  # updates and the commit happens later.
336
- # dir - The String subdirectory of the Gollum::Page without any
337
- # prefix or suffix slashes (e.g. "foo/bar").
338
215
  # Returns the String SHA1 of the newly written version, or the
339
216
  # Gollum::Committer instance if this is part of a batch update.
340
- def write_page(name, format, data, commit = {}, dir = '')
341
- sanitized_dir = ::File.join([@page_file_dir, dir].compact)
342
-
343
- multi_commit = !!commit[:committer]
344
- committer = multi_commit ? commit[:committer] : Committer.new(self, commit)
345
- committer.add_to_index(sanitized_dir, name, format, data)
217
+ def write_page(path, format, data, commit = {})
218
+ write(merge_path_elements(nil, path, format), data, commit)
219
+ end
346
220
 
347
- committer.after_commit do |index, _sha|
348
- @access.refresh
349
- index.update_working_dir(sanitized_dir, name, format)
350
- end
221
+ # Public: Write a new version of a file to the Gollum repo.
222
+ #
223
+ # path - The String path where the file will be written.
224
+ # data - The new String contents of the page.
225
+ # commit - The commit Hash details:
226
+ # :message - The String commit message.
227
+ # :name - The String author full name.
228
+ # :email - The String email address.
229
+ # :parent - Optional Gollum::Git::Commit parent to this update.
230
+ # :tree - Optional String SHA of the tree to create the
231
+ # index from.
232
+ # :committer - Optional Gollum::Committer instance. If provided,
233
+ # assume that this operation is part of batch of
234
+ # updates and the commit happens later.
235
+ # Returns the String SHA1 of the newly written version, or the
236
+ # Gollum::Committer instance if this is part of a batch update
237
+ def write_file(name, data, commit = {})
238
+ write(merge_path_elements(nil, name, nil), data, commit)
239
+ end
351
240
 
352
- multi_commit ? committer : committer.commit
241
+ # Public: Write a file to the Gollum repo regardless of existing versions.
242
+ #
243
+ # path - The String path where the file will be written.
244
+ # data - The new String contents of the page.
245
+ # commit - The commit Hash details:
246
+ # :message - The String commit message.
247
+ # :name - The String author full name.
248
+ # :email - The String email address.
249
+ # :parent - Optional Gollum::Git::Commit parent to this update.
250
+ # :tree - Optional String SHA of the tree to create the
251
+ # index from.
252
+ # :committer - Optional Gollum::Committer instance. If provided,
253
+ # assume that this operation is part of batch of
254
+ # updates and the commit happens later.
255
+ # Returns the String SHA1 of the newly written version, or the
256
+ # Gollum::Committer instance if this is part of a batch update
257
+ def overwrite_file(name, data, commit = {})
258
+ write(merge_path_elements(nil, name, nil), data, commit, force_overwrite = true)
353
259
  end
354
260
 
355
261
  # Public: Rename an existing page without altering content.
@@ -392,12 +298,12 @@ module Gollum
392
298
  committer = multi_commit ? commit[:committer] : Committer.new(self, commit)
393
299
 
394
300
  committer.delete(page.path)
395
- committer.add_to_index(target_dir, target_name, page.format, page.raw_data)
301
+ committer.add_to_index(merge_path_elements(target_dir, target_name, page.format), page.raw_data)
396
302
 
397
303
  committer.after_commit do |index, _sha|
398
304
  @access.refresh
399
- index.update_working_dir(source_dir, source_name, page.format)
400
- index.update_working_dir(target_dir, target_name, page.format)
305
+ index.update_working_dir(merge_path_elements(source_dir, source_name, page.format))
306
+ index.update_working_dir(merge_path_elements(target_dir, target_name, page.format))
401
307
  end
402
308
 
403
309
  multi_commit ? committer : committer.commit
@@ -429,24 +335,24 @@ module Gollum
429
335
  name ||= page.name
430
336
  format ||= page.format
431
337
  dir = ::File.dirname(page.path)
432
- dir = '' if dir == '.'
433
- filename = (rename = page.name != name) ?
434
- name : page.filename_stripped
338
+ dir = nil if dir == '.'
339
+ rename = (page.name != name || page.format != format)
340
+ new_path = ::File.join([dir, self.page_file_name(name, format)].compact) if rename
435
341
 
436
342
  multi_commit = !!commit[:committer]
437
343
  committer = multi_commit ? commit[:committer] : Committer.new(self, commit)
438
344
 
439
- if !rename && page.format == format
345
+ if !rename
440
346
  committer.add(page.path, normalize(data))
441
347
  else
442
348
  committer.delete(page.path)
443
- committer.add_to_index(dir, filename, format, data)
349
+ committer.add_to_index(new_path, data)
444
350
  end
445
351
 
446
352
  committer.after_commit do |index, _sha|
447
353
  @access.refresh
448
- index.update_working_dir(dir, page.filename_stripped, page.format)
449
- index.update_working_dir(dir, filename, format)
354
+ index.update_working_dir(page.path)
355
+ index.update_working_dir(new_path) if rename
450
356
  end
451
357
 
452
358
  multi_commit ? committer : committer.commit
@@ -469,21 +375,7 @@ module Gollum
469
375
  # Returns the String SHA1 of the newly written version, or the
470
376
  # Gollum::Committer instance if this is part of a batch update.
471
377
  def delete_page(page, commit)
472
-
473
- multi_commit = !!commit[:committer]
474
- committer = multi_commit ? commit[:committer] : Committer.new(self, commit)
475
-
476
- committer.delete(page.path)
477
-
478
- committer.after_commit do |index, _sha|
479
- dir = ::File.dirname(page.path)
480
- dir = '' if dir == '.'
481
-
482
- @access.refresh
483
- index.update_working_dir(dir, page.filename_stripped, page.format)
484
- end
485
-
486
- multi_commit ? committer : committer.commit
378
+ delete_file(page.url_path, commit)
487
379
  end
488
380
 
489
381
  # Public: Delete a file.
@@ -503,21 +395,16 @@ module Gollum
503
395
  # Returns the String SHA1 of the newly written version, or the
504
396
  # Gollum::Committer instance if this is part of a batch update.
505
397
  def delete_file(path, commit)
506
- dir = ::File.dirname(path)
507
- ext = ::File.extname(path)
508
- format = ext.split('.').last || 'txt'
509
- filename = ::File.basename(path, ext)
510
-
398
+ fullpath = ::File.join([page_file_dir, path].compact)
511
399
  multi_commit = !!commit[:committer]
512
400
  committer = multi_commit ? commit[:committer] : Committer.new(self, commit)
513
401
 
514
- committer.delete(path)
402
+ committer.delete(fullpath)
515
403
 
516
404
  committer.after_commit do |index, _sha|
517
405
  dir = '' if dir == '.'
518
-
519
406
  @access.refresh
520
- index.update_working_dir(dir, filename, format)
407
+ index.update_working_dir(fullpath)
521
408
  end
522
409
 
523
410
  multi_commit ? committer : committer.commit
@@ -536,48 +423,12 @@ module Gollum
536
423
  # :name - The String author full name.
537
424
  # :email - The String email address.
538
425
  # :parent - Optional Gollum::Git::Commit parent to this update.
539
- #
540
426
  # Returns a String SHA1 of the new commit, or nil if the reverse diff does
541
427
  # not apply.
542
428
  def revert_page(page, sha1, sha2 = nil, commit = {})
543
- if sha2.is_a?(Hash)
544
- commit = sha2
545
- sha2 = nil
546
- end
547
-
548
- patch = full_reverse_diff_for(page, sha1, sha2)
549
- committer = Committer.new(self, commit)
550
- parent = committer.parents[0]
551
- committer.options[:tree] = @repo.git.apply_patch(parent.sha, patch)
552
- return false unless committer.options[:tree]
553
- committer.after_commit do |index, _sha|
554
- @access.refresh
555
-
556
- files = []
557
- if page
558
- files << [page.path, page.filename_stripped, page.format]
559
- else
560
- # Grit::Diff can't parse reverse diffs.... yet
561
- patch.each_line do |line|
562
- if line =~ %r(^diff --git b/.+? a/(.+)$)
563
- path = Regexp.last_match[1]
564
- ext = ::File.extname(path)
565
- name = ::File.basename(path, ext)
566
- if (format = ::Gollum::Page.format_for(ext))
567
- files << [path, name, format]
568
- end
569
- end
570
- end
571
- end
572
-
573
- files.each do |(path, name, format)|
574
- dir = ::File.dirname(path)
575
- dir = '' if dir == '.'
576
- index.update_working_dir(dir, name, format)
577
- end
578
- end
579
-
580
- committer.commit
429
+ return false unless page
430
+ left, right, options = parse_revert_options(sha1, sha2, commit)
431
+ commit_and_update_paths(@repo.git.revert_path(page.path, left, right), [page.path], options)
581
432
  end
582
433
 
583
434
  # Public: Applies a reverse diff to the repo. If only 1 SHA is given,
@@ -595,7 +446,9 @@ module Gollum
595
446
  # Returns a String SHA1 of the new commit, or nil if the reverse diff does
596
447
  # not apply.
597
448
  def revert_commit(sha1, sha2 = nil, commit = {})
598
- revert_page(nil, sha1, sha2, commit)
449
+ left, right, options = parse_revert_options(sha1, sha2, commit)
450
+ tree, files = repo.git.revert_commit(left, right)
451
+ commit_and_update_paths(tree, files, options)
599
452
  end
600
453
 
601
454
  # Public: Lists all pages for this wiki.
@@ -604,7 +457,7 @@ module Gollum
604
457
  #
605
458
  # Returns an Array of Gollum::Page instances.
606
459
  def pages(treeish = nil)
607
- tree_list(treeish || @ref)
460
+ tree_list(treeish || @ref, true, false)
608
461
  end
609
462
 
610
463
  # Public: Lists all non-page files for this wiki.
@@ -613,7 +466,7 @@ module Gollum
613
466
  #
614
467
  # Returns an Array of Gollum::File instances.
615
468
  def files(treeish = nil)
616
- file_list(treeish || @ref)
469
+ tree_list(treeish || @ref, false, true)
617
470
  end
618
471
 
619
472
  # Public: Returns the number of pages accessible from a commit
@@ -623,7 +476,7 @@ module Gollum
623
476
  # Returns a Fixnum
624
477
  def size(ref = nil)
625
478
  tree_map_for(ref || @ref).inject(0) do |num, entry|
626
- num + (@page_class.valid_page_name?(entry.name) ? 1 : 0)
479
+ num + (::Gollum::Page.valid_page_name?(entry.name) ? 1 : 0)
627
480
  end
628
481
  rescue Gollum::Git::NoSuchShaFound
629
482
  0
@@ -636,36 +489,34 @@ module Gollum
636
489
  # Returns an Array with Objects of page name and count of matches
637
490
  def search(query)
638
491
  options = {:path => page_file_dir, :ref => ref}
639
- results = {}
640
- @repo.git.grep(query, options).each do |hit|
641
- name = hit[:name]
642
- count = hit[:count]
643
- # Remove ext only from known extensions.
644
- # test.pdf => test.pdf, test.md => test
645
- file_name = Page::valid_page_name?(name) ? name.chomp(::File.extname(name)) : name
646
- results[file_name] = count.to_i
647
- end
648
-
649
- # Use ls_files '*query*' to search for file names. Grep only searches file content.
650
- # Spaces are converted to dashes when saving pages to disk.
651
- @repo.git.ls_files(query, options).each do |path|
652
- # Remove ext only from known extensions.
653
- file_name = Page::valid_page_name?(path) ? path.chomp(::File.extname(path)) : path
654
- # If there's not already a result for file_name then
655
- # the value is nil and nil.to_i is 0.
656
- results[file_name] = results[file_name].to_i + 1;
657
- end
658
-
659
- results.map do |key, val|
660
- { :count => val, :name => key }
492
+ search_terms = query.scan(/"([^"]+)"|(\S+)/).flatten.compact.map {|term| Regexp.escape(term)}
493
+ search_terms_regex = search_terms.join('|')
494
+ query = /^(.*(?:#{search_terms_regex}).*)$/i
495
+ results = @repo.git.grep(search_terms, options) do |name, data|
496
+ result = {:count => 0}
497
+ result[:name] = extract_page_file_dir(name)
498
+ result[:filename_count] = result[:name].scan(/#{search_terms_regex}/i).size
499
+ result[:context] = []
500
+ if data
501
+ begin
502
+ data.scan(query) do |match|
503
+ result[:context] << match.first
504
+ result[:count] += match.first.scan(/#{search_terms_regex}/i).size
505
+ end
506
+ rescue ArgumentError # https://github.com/gollum/gollum/issues/1491
507
+ next
508
+ end
509
+ end
510
+ ((result[:count] + result[:filename_count]) == 0) ? nil : result
661
511
  end
512
+ [results, search_terms]
662
513
  end
663
514
 
664
515
  # Public: All of the versions that have touched the Page.
665
516
  #
666
517
  # options - The options Hash:
667
- # :page - The Integer page number (default: 1).
668
- # :per_page - The Integer max count of items to return.
518
+ # :page_num - The Integer page number (default: 1).
519
+ # :per_page - The Integer max count of items to return.
669
520
  #
670
521
  # Returns an Array of Gollum::Git::Commit.
671
522
  def log(options = {})
@@ -680,7 +531,7 @@ module Gollum
680
531
  # Returns an Array of Gollum::Git::Commit.
681
532
  def latest_changes(options={})
682
533
  options[:max_count] = 10 unless options[:max_count]
683
- @repo.log(@ref, nil, options)
534
+ @repo.log(@ref, page_file_dir, options)
684
535
  end
685
536
 
686
537
  # Public: Refreshes just the cached Git reference data. This should
@@ -691,92 +542,23 @@ module Gollum
691
542
  @access.refresh
692
543
  end
693
544
 
694
- # Public: Creates a Sanitize instance using the Wiki's sanitization
695
- # options.
696
- #
697
- # Returns a Sanitize instance.
698
- def sanitizer
699
- if (options = sanitization)
700
- @sanitizer ||= options.to_sanitize
701
- end
702
- end
703
-
704
- # Public: Creates a Sanitize instance using the Wiki's history sanitization
705
- # options.
706
- #
707
- # Returns a Sanitize instance.
708
- def history_sanitizer
709
- if (options = history_sanitization)
710
- @history_sanitizer ||= options.to_sanitize
545
+ def redirects
546
+ if @redirects.nil? || @redirects.stale?
547
+ @redirects = {}.extend(::Gollum::Redirects)
548
+ @redirects.init(self)
549
+ @redirects.load
711
550
  end
551
+ @redirects
712
552
  end
713
553
 
714
- # Public: Add an additional link to the filter chain.
715
- #
716
- # name - A symbol which represents the name of a class under the
717
- # Gollum::Render namespace to insert into the chain.
718
- #
719
- # loc - A "location specifier" -- that is, where to put the new
720
- # filter in the chain. This can be one of `:first`, `:last`,
721
- # `:before => :SomeElement`, or `:after => :SomeElement`, where
722
- # `:SomeElement` (if specified) is a symbol already in the
723
- # filter chain. A `:before` or `:after` which references a
724
- # filter that doesn't exist will cause `ArgumentError` to be
725
- # raised.
726
- #
727
- # Returns nothing.
728
- def add_filter(name, loc)
729
- unless name.is_a? Symbol
730
- raise ArgumentError,
731
- "Invalid filter name #{name.inspect} (must be a symbol)"
732
- end
733
-
734
- case loc
735
- when :first
736
- @filter_chain.unshift(name)
737
- when :last
738
- @filter_chain.push(name)
739
- when Hash
740
- if loc.length != 1
741
- raise ArgumentError,
742
- "Invalid location specifier"
743
- end
744
- if ([:before, :after] && loc.keys).empty?
745
- raise ArgumentError,
746
- "Invalid location specifier"
747
- end
748
-
749
- next_to = loc.values.first
750
- relative = loc.keys.first
751
-
752
- i = @filter_chain.index(next_to)
753
- if i.nil?
754
- raise ArgumentError,
755
- "Unknown filter #{next_to.inspect}"
756
- end
757
-
758
- i += 1 if relative == :after
759
- @filter_chain.insert(i, name)
760
- else
761
- raise ArgumentError,
762
- "Invalid location specifier"
763
- end
554
+ def add_redirect(old_path, new_path)
555
+ redirects[old_path] = new_path
556
+ redirects.dump
764
557
  end
765
558
 
766
- # Remove the named filter from the filter chain.
767
- #
768
- # Returns nothing. Raises `ArgumentError` if the named filter doesn't
769
- # exist in the chain.
770
- def remove_filter(name)
771
- unless name.is_a? Symbol
772
- raise ArgumentError,
773
- "Invalid filter name #{name.inspect} (must be a symbol)"
774
- end
775
-
776
- unless @filter_chain.delete(name)
777
- raise ArgumentError,
778
- "#{name.inspect} not found in filter chain"
779
- end
559
+ def remove_redirect(path)
560
+ redirects.tap{|k| k.delete(path)}
561
+ redirects.dump
780
562
  end
781
563
 
782
564
  #########################################################################
@@ -795,15 +577,6 @@ module Gollum
795
577
  # Returns the String path.
796
578
  attr_reader :path
797
579
 
798
- # Gets the page class used by all instances of this Wiki.
799
- attr_reader :page_class
800
-
801
- # Gets the file class used by all instances of this Wiki.
802
- attr_reader :file_class
803
-
804
- # Gets the markup class used by all instances of this Wiki.
805
- attr_reader :markup_classes
806
-
807
580
  # Toggles display of universal table of contents
808
581
  attr_reader :universal_toc
809
582
 
@@ -817,8 +590,14 @@ module Gollum
817
590
  # When false, only valid pages in the git repo are displayed.
818
591
  attr_reader :show_all
819
592
 
820
- # Start with collapsed file view. Default: false
821
- attr_reader :collapse_tree
593
+ # Enable 4.x compatibility behavior for links
594
+ attr_reader :global_tag_lookup
595
+
596
+ # Enable 4.x compatibility for case-case_insensitive links
597
+ attr_reader :case_insensitive_tag_lookup
598
+
599
+ # Spaces in tag paths are treated as dashes (-)
600
+ attr_reader :hyphened_tag_lookup
822
601
 
823
602
  # Toggles file upload functionality.
824
603
  attr_reader :allow_uploads
@@ -843,72 +622,30 @@ module Gollum
843
622
  #
844
623
  # Returns the String filename.
845
624
  def page_file_name(name, format)
846
- "#{name}.#{@page_class.format_to_ext(format)}"
847
- end
848
-
849
- # Fill an array with a list of pages.
850
- #
851
- # ref - A String ref that is either a commit SHA or references one.
852
- #
853
- # Returns a flat Array of Gollum::Page instances.
854
- def tree_list(ref)
855
- if (sha = @access.ref_to_sha(ref))
856
- commit = @access.commit(sha)
857
- tree_map_for(sha).inject([]) do |list, entry|
858
- next list unless @page_class.valid_page_name?(entry.name)
859
- list << entry.page(self, commit)
860
- end
861
- else
862
- []
863
- end
625
+ format.nil? ? name : "#{name}.#{::Gollum::Page.format_to_ext(format)}"
864
626
  end
865
627
 
866
- # Fill an array with a list of files.
628
+ # Fill an array with a list of pages and files in the wiki.
867
629
  #
868
630
  # ref - A String ref that is either a commit SHA or references one.
869
631
  #
870
- # Returns a flat Array of Gollum::File instances.
871
- def file_list(ref)
632
+ # Returns a flat Array of Gollum::Page and Gollum::File instances.
633
+ def tree_list(ref = @ref, pages=true, files=true)
872
634
  if (sha = @access.ref_to_sha(ref))
873
635
  commit = @access.commit(sha)
874
636
  tree_map_for(sha).inject([]) do |list, entry|
875
- next list if entry.name.start_with?('_')
876
- next list if @page_class.valid_page_name?(entry.name)
877
- list << entry.file(self, commit)
637
+ if ::Gollum::Page.valid_page_name?(entry.name)
638
+ list << entry.page(self, commit) if pages
639
+ elsif files && !entry.name.start_with?('_') && !::Gollum::Page.protected_files.include?(entry.name)
640
+ list << entry.file(self, commit)
641
+ end
642
+ list
878
643
  end
879
644
  else
880
645
  []
881
646
  end
882
647
  end
883
648
 
884
- # Creates a reverse diff for the given SHAs on the given Gollum::Page.
885
- #
886
- # page - The Gollum::Page to scope the patch to, or a String Path.
887
- # sha1 - String SHA1 of the earlier parent if two SHAs are given,
888
- # or the child.
889
- # sha2 - Optional String SHA1 of the child.
890
- #
891
- # Returns a String of the reverse Diff to apply.
892
- def full_reverse_diff_for(page, sha1, sha2 = nil)
893
- sha1, sha2 = "#{sha1}^", sha1 if sha2.nil?
894
- if page
895
- path = (page.respond_to?(:path) ? page.path : page.to_s)
896
- return repo.diff(sha2, sha1, path).first.diff
897
- end
898
- repo.diff(sha2, sha1).map { |d| d.diff }.join("\n")
899
- end
900
-
901
- # Creates a reverse diff for the given SHAs.
902
- #
903
- # sha1 - String SHA1 of the earlier parent if two SHAs are given,
904
- # or the child.
905
- # sha2 - Optional String SHA1 of the child.
906
- #
907
- # Returns a String of the reverse Diff to apply.
908
- def full_reverse_diff(sha1, sha2 = nil)
909
- full_reverse_diff_for(nil, sha1, sha2)
910
- end
911
-
912
649
  # Gets the default name for commits.
913
650
  #
914
651
  # Returns the String name.
@@ -943,7 +680,7 @@ module Gollum
943
680
  # ignore_page_file_dir - Boolean, if true, searches all files within the git repo, regardless of dir/subdir
944
681
  #
945
682
  # Returns an Array of BlobEntry instances.
946
- def tree_map_for(ref, ignore_page_file_dir=false)
683
+ def tree_map_for(ref, ignore_page_file_dir = false)
947
684
  if ignore_page_file_dir && !@page_file_dir.nil?
948
685
  @root_access ||= GitAccess.new(path, nil, @repo_is_bare)
949
686
  @root_access.tree(ref)
@@ -957,5 +694,80 @@ module Gollum
957
694
  def inspect
958
695
  %(#<#{self.class.name}:#{object_id} #{@repo.path}>)
959
696
  end
697
+
698
+ # Public: Creates a Sanitize instance
699
+ #
700
+ # Returns a Sanitize instance.
701
+ def sanitizer
702
+ @sanitizer ||= Gollum::Sanitization.new(Gollum::Markup.to_xml_opts)
703
+ end
704
+
705
+ private
706
+
707
+ def parse_revert_options(sha1, sha2, commit = {})
708
+ if sha2.is_a?(Hash)
709
+ return "#{sha1}^", sha1, sha2
710
+ elsif sha2.nil?
711
+ return "#{sha1}^", sha1, commit
712
+ else
713
+ return sha1, sha2, commit
714
+ end
715
+ end
716
+
717
+ def commit_and_update_paths(tree, paths, options)
718
+ return false unless tree
719
+ committer = Committer.new(self, options)
720
+ parent = committer.parents[0]
721
+
722
+ committer.options[:tree] = tree
723
+
724
+ committer.after_commit do |index, _sha|
725
+ @access.refresh
726
+
727
+ paths.each do |path|
728
+ index.update_working_dir(path)
729
+ end
730
+ end
731
+
732
+ committer.commit
733
+ end
734
+
735
+ # Conjoins elements of a page or file path and prefixes the page_file_dir.
736
+ # Throws Gollum::IllegalDirectoryPath if page_file_dir is set, and the resulting
737
+ # path is not below it (e.g. if the dir or name contained '../')
738
+ #
739
+ # dir - The String directory path
740
+ # name - The String name of the Page or File
741
+ # format - The Symbol format of the page. Should be nil for Files.
742
+ #
743
+ # Returns a String path. .
744
+ def merge_path_elements(dir, name, format)
745
+ result = ::File.join([@page_file_dir, dir, self.page_file_name(name, format)].compact)
746
+ result = Pathname.new(result).cleanpath.to_s
747
+ if @page_file_dir
748
+ raise Gollum::IllegalDirectoryPath unless result.start_with?("#{@page_file_dir}/")
749
+ result
750
+ else
751
+ result[0] == '/' ? result[1..-1] : result
752
+ end
753
+ end
754
+
755
+ def extract_page_file_dir(path)
756
+ @page_file_dir ? path[@page_file_dir.length+1..-1] : path
757
+ end
758
+
759
+ def write(path, data, commit = {}, force_overwrite = false)
760
+ multi_commit = !!commit[:committer]
761
+ committer = multi_commit ? commit[:committer] : Committer.new(self, commit)
762
+ committer.add_to_index(path, data, commit, force_overwrite)
763
+
764
+ committer.after_commit do |index, _sha|
765
+ @access.refresh
766
+ index.update_working_dir(path)
767
+ end
768
+
769
+ multi_commit ? committer : committer.commit
770
+ end
771
+
960
772
  end
961
773
  end