gollum-lib 5.0.a.4 → 5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -1
  3. data/README.md +12 -7
  4. data/Rakefile +5 -5
  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 +73 -28
  43. data/ROADMAP +0 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 16e15f2728c7f9506c74ec5883137e962998c444a5891469c7eae14aa3f09485
4
- data.tar.gz: 9387c63c0f369902cf50439b750864fc2c4f86834da46576da7e1c8dc51464c6
3
+ metadata.gz: 9da40c6b458fcb087bcffc9d258cc0fc16d5ff751e64650f5ec9372a71addea4
4
+ data.tar.gz: 2e85e4321dafc1d5a51a3aa90cddfea17a7f3b675a08ccdd96f7859a39657942
5
5
  SHA512:
6
- metadata.gz: eef2301efb002a266600420ea073f5933c0a3ac7e23e613b39b492435383b3ded492b3756eb9e294683a7660a7d71be294c05e6e8ce8ce9a2a27338ba56dd092
7
- data.tar.gz: 29ac662c80e6b90fad991b7bb421486cf2b1a5b5a3838f342bbdfb0d26f23a6680a98cd6372077a5ed3e8e07578a9470600a4c9a427346fcc36700e735f8f9c5
6
+ metadata.gz: 2dd5df4f3a3ce1b8247ca8e8c67e746d67f9dd794ab28e06a2f9c72ec003afb996e58b5374b024d2c060cf6e23481e50c5e46b31962cb47bfb437c95a1d9980a
7
+ data.tar.gz: b09e3211137d7ad250dbbbd8f9168c328f70b018146a982869844ebcbfa4a32a859ed5bb79e1e0388db2b236c362d1f967aa231e58a08b3d7c0e75762731e150
data/Gemfile CHANGED
@@ -1,2 +1,3 @@
1
1
  source 'https://rubygems.org'
2
- gemspec :name => 'gollum-lib'
2
+
3
+ gemspec :name => 'gollum-lib'
data/README.md CHANGED
@@ -19,10 +19,9 @@ Gollum-lib follows the rules of [Semantic Versioning](http://semver.org/) and us
19
19
 
20
20
  ## SYSTEM REQUIREMENTS
21
21
 
22
- - Python 2.5+ (2.7.3 recommended)
23
- - Ruby 2.1.0+ (>= 2.3.3 recommended)
22
+ - Ruby 2.4.0+
24
23
  - Unix like operating system (OS X, Ubuntu, Debian, and more)
25
- - Will not work on Windows with the default [grit](https://github.com/github/grit) adapter, but might work via JRuby (please let us know!)
24
+ - Will not work on Windows with the default [rugged](https://github.com/github/grit) adapter, but works via JRuby.
26
25
 
27
26
  ## INSTALLATION
28
27
 
@@ -92,7 +91,13 @@ Note that `base_path` just modifies the links.
92
91
  Get the latest version of the given human or canonical page name:
93
92
 
94
93
  ```ruby
95
- page = wiki.page('page-name')
94
+ page = wiki.page('/page name') # Finds pages in the root directory of the wiki that are named 'page name' with a valid extension.
95
+ # => <Gollum::Page>
96
+
97
+ page = wiki.page('page name') # For convenience, you can leave out the '/' in front. Paths are assumed to be relative to '/'.
98
+ # => <Gollum::Page>
99
+
100
+ page = wiki.page('page name.md') # You can also specifiy the extension explicitly to disambiguate between pages with the same name, but different formats.
96
101
  # => <Gollum::Page>
97
102
 
98
103
  page.raw_data
@@ -141,7 +146,7 @@ vsns.first.authored_date
141
146
  Get a specific version of a given canonical page file:
142
147
 
143
148
  ```ruby
144
- wiki.page('page-name', '5ec521178e0eec4dc39741a8978a2ba6616d0f0a')
149
+ wiki.page('page name', '5ec521178e0eec4dc39741a8978a2ba6616d0f0a')
145
150
  ```
146
151
 
147
152
  Get the latest version of a given static file:
@@ -182,10 +187,10 @@ commit = { :message => 'commit message',
182
187
  ```
183
188
 
184
189
  Write a new version of a page (the file will be created if it does not already
185
- exist) and commit the change. The file will be written at the repo root.
190
+ exist) and commit the change. The file will be written at the repo root if no subdirectory is specified.
186
191
 
187
192
  ```ruby
188
- wiki.write_page('Page Name', :markdown, 'Page contents', commit)
193
+ wiki.write_page('Subdirectory/Page Name', :markdown, 'Page contents', commit)
189
194
  ```
190
195
 
191
196
  Update an existing page. If the format is different than the page's current
data/Rakefile CHANGED
@@ -107,7 +107,7 @@ end
107
107
 
108
108
  desc "Build and install"
109
109
  task :install => :build do
110
- sh "gem install --local --no-ri --no-rdoc pkg/#{name}-#{version}.gem"
110
+ sh "gem install --local --no-document pkg/#{name}-#{version}.gem"
111
111
  end
112
112
 
113
113
  #############################################################################
@@ -118,14 +118,14 @@ end
118
118
 
119
119
  desc 'Create a release build'
120
120
  task :release => :build do
121
- unless `git branch` =~ /gollum-lib-5.x/
122
- puts "You must be on the gollum-lib-5.x branch to release!"
121
+ unless `git branch` =~ /master/
122
+ puts "You must be on the master branch to release!"
123
123
  exit!
124
124
  end
125
125
  sh "git commit --allow-empty -a -m 'Release #{version}'"
126
- sh "git pull --rebase origin gollum-lib-5.x"
126
+ sh "git pull --rebase origin master"
127
127
  sh "git tag v#{version}"
128
- sh "git push origin gollum-lib-5.x"
128
+ sh "git push origin master"
129
129
  sh "git push origin v#{version}"
130
130
  sh "gem push pkg/#{name}-#{version}.gem"
131
131
  sh "gem push pkg/#{name}-#{version}-java.gem"
@@ -0,0 +1,7 @@
1
+ # Set the default git adapter for use in gollum-lib.gemspec and gollum-lib_java.gemspec
2
+
3
+ if RUBY_PLATFORM == 'java' then
4
+ DEFAULT_ADAPTER_REQ = ['gollum-rjgit_adapter', '>= 0.5.1', '~> 0.5.1']
5
+ else
6
+ DEFAULT_ADAPTER_REQ = ['gollum-rugged_adapter', '>= 0.99.4', '~> 0.99.4']
7
+ end
data/gemspec.rb CHANGED
@@ -3,12 +3,12 @@ def specification(version, default_adapter, platform = nil)
3
3
  s.specification_version = 2 if s.respond_to? :specification_version=
4
4
  s.required_rubygems_version = Gem::Requirement.new('>= 0') if s.respond_to? :required_rubygems_version=
5
5
  s.rubygems_version = '0.0.1'
6
- s.required_ruby_version = '>= 2.1'
6
+ s.required_ruby_version = '>= 2.4'
7
7
 
8
8
  s.name = 'gollum-lib'
9
9
  s.version = version
10
10
  s.platform = platform if platform
11
- s.date = '2018-09-17'
11
+ s.date = '2020-03-29'
12
12
  s.date = '2017-04-13'
13
13
  s.rubyforge_project = 'gollum-lib'
14
14
  s.license = 'MIT'
@@ -28,27 +28,29 @@ def specification(version, default_adapter, platform = nil)
28
28
  s.add_dependency *default_adapter
29
29
  s.add_dependency 'rouge', '~> 3.1'
30
30
  s.add_dependency 'nokogiri', '~> 1.8'
31
- s.add_dependency 'stringex', '~> 2.6'
32
- s.add_dependency 'sanitize', '~> 2.1'
33
- s.add_dependency 'github-markup', '~> 1.6'
34
- s.add_dependency 'gemojione', '~> 3.2'
31
+ s.add_dependency 'loofah', '~> 2.3'
32
+ s.add_dependency 'github-markup', '~> 3.0'
33
+ s.add_dependency 'gemojione', '~> 4.1'
34
+ s.add_dependency 'octicons', '~> 8.5'
35
35
  s.add_dependency 'twitter-text', '1.14.7'
36
36
 
37
37
  s.add_development_dependency 'org-ruby', '~> 0.9.9'
38
- s.add_development_dependency 'kramdown', '~> 1.13'
38
+ s.add_development_dependency 'kramdown', '~> 2.1.0'
39
+ s.add_development_dependency 'kramdown-parser-gfm', '~> 1.1.0'
39
40
  s.add_development_dependency 'RedCloth', '~> 4.2.9'
40
41
  s.add_development_dependency 'mocha', '~> 1.2.0'
41
42
  s.add_development_dependency 'shoulda', '~> 3.5.0'
42
43
  s.add_development_dependency 'wikicloth', '~> 0.8.3'
43
44
  s.add_development_dependency 'bibtex-ruby', '~> 4.3'
44
45
  s.add_development_dependency 'citeproc-ruby', '~> 1.1'
45
- s.add_development_dependency 'rake', '~> 10.4.0'
46
+ s.add_development_dependency 'unicode_utils', '~> 1.4.0' # required by citeproc-ruby on ruby < 2.4
47
+ s.add_development_dependency 'rake', '~> 12.3', '>= 12.3.3'
46
48
  s.add_development_dependency 'pry', '~> 0.10.1'
47
49
  # required by pry
48
50
  s.add_development_dependency 'rb-readline', '~> 0.5.1'
49
51
  # updating minitest-reporters requires a new minitest which fails with gollum's tests.
50
52
  s.add_development_dependency 'test-unit', '~> 3.1.5'
51
- s.add_development_dependency 'minitest-reporters', '~> 0.14.16'
53
+ s.add_development_dependency 'minitest-reporters', '~> 1.4'
52
54
  s.add_development_dependency 'nokogiri-diff', '~> 0.2.0'
53
55
  # required by guard
54
56
  s.add_development_dependency 'guard', '~> 2.8.2'
@@ -63,8 +65,8 @@ def specification(version, default_adapter, platform = nil)
63
65
  HISTORY.md
64
66
  LICENSE
65
67
  README.md
66
- ROADMAP
67
68
  Rakefile
69
+ adapter_dependencies.rb
68
70
  docs/sanitization.md
69
71
  gemspec.rb
70
72
  gollum-lib.gemspec
@@ -77,6 +79,7 @@ def specification(version, default_adapter, platform = nil)
77
79
  lib/gollum-lib/filter.rb
78
80
  lib/gollum-lib/filter/bibtex.rb
79
81
  lib/gollum-lib/filter/code.rb
82
+ lib/gollum-lib/filter/critic_markup.rb
80
83
  lib/gollum-lib/filter/emoji.rb
81
84
  lib/gollum-lib/filter/macro.rb
82
85
  lib/gollum-lib/filter/pandoc_bib.rb
@@ -93,14 +96,19 @@ def specification(version, default_adapter, platform = nil)
93
96
  lib/gollum-lib/hook.rb
94
97
  lib/gollum-lib/macro.rb
95
98
  lib/gollum-lib/macro/all_pages.rb
99
+ lib/gollum-lib/macro/audio.rb
96
100
  lib/gollum-lib/macro/global_toc.rb
97
101
  lib/gollum-lib/macro/navigation.rb
102
+ lib/gollum-lib/macro/note.rb
103
+ lib/gollum-lib/macro/octicon.rb
98
104
  lib/gollum-lib/macro/series.rb
99
105
  lib/gollum-lib/macro/video.rb
106
+ lib/gollum-lib/macro/warn.rb
100
107
  lib/gollum-lib/markup.rb
101
108
  lib/gollum-lib/markups.rb
102
109
  lib/gollum-lib/page.rb
103
110
  lib/gollum-lib/pagination.rb
111
+ lib/gollum-lib/redirects.rb
104
112
  lib/gollum-lib/sanitization.rb
105
113
  lib/gollum-lib/version.rb
106
114
  lib/gollum-lib/wiki.rb
data/gollum-lib.gemspec CHANGED
@@ -1,8 +1,4 @@
1
1
  require File.join(File.dirname(__FILE__), 'gemspec.rb')
2
+ require File.join(File.dirname(__FILE__), 'adapter_dependencies.rb')
2
3
  require File.join(File.dirname(__FILE__), 'lib', 'gollum-lib', 'version.rb')
3
- if RUBY_PLATFORM == 'java' then
4
- default_adapter = ['gollum-rjgit_adapter', '~> 0.3']
5
- else
6
- default_adapter = ['gollum-grit_adapter', '~> 1.0']
7
- end
8
- Gem::Specification.new &specification(Gollum::Lib::VERSION, default_adapter)
4
+ Gem::Specification.new &specification(Gollum::Lib::VERSION, DEFAULT_ADAPTER_REQ)
@@ -1,4 +1,4 @@
1
1
  require File.join(File.dirname(__FILE__), 'gemspec.rb')
2
+ require File.join(File.dirname(__FILE__), 'adapter_dependencies.rb')
2
3
  require File.join(File.dirname(__FILE__), 'lib', 'gollum-lib', 'version.rb')
3
- default_adapter = ['gollum-rjgit_adapter', '~> 0.3']
4
- Gem::Specification.new &specification(Gollum::Lib::VERSION, default_adapter, "java")
4
+ Gem::Specification.new &specification(Gollum::Lib::VERSION, DEFAULT_ADAPTER_REQ, "java")
data/lib/gollum-lib.rb CHANGED
@@ -5,15 +5,17 @@ require 'digest/sha1'
5
5
  require 'ostruct'
6
6
  require 'pathname'
7
7
 
8
- DEFAULT_ADAPTER = RUBY_PLATFORM == 'java' ? 'rjgit' : 'grit'
8
+ DEFAULT_ADAPTER = RUBY_PLATFORM == 'java' ? 'rjgit' : 'rugged'
9
9
 
10
+ module Gollum; end
10
11
  Gollum::GIT_ADAPTER = DEFAULT_ADAPTER if !defined?(Gollum::GIT_ADAPTER)
11
12
  require "#{Gollum::GIT_ADAPTER.downcase}_adapter"
12
13
 
13
14
  # external
14
15
  require 'github/markup'
15
- require 'sanitize'
16
+ require 'erb'
16
17
  require 'gemojione'
18
+ require 'loofah'
17
19
 
18
20
  # internal
19
21
  require File.expand_path('../gollum-lib/git_access', __FILE__)
@@ -22,9 +24,10 @@ require File.expand_path('../gollum-lib/committer', __FILE__)
22
24
  require File.expand_path('../gollum-lib/pagination', __FILE__)
23
25
  require File.expand_path('../gollum-lib/blob_entry', __FILE__)
24
26
  require File.expand_path('../gollum-lib/wiki', __FILE__)
27
+ require File.expand_path('../gollum-lib/redirects', __FILE__)
28
+ require File.expand_path('../gollum-lib/file', __FILE__)
25
29
  require File.expand_path('../gollum-lib/page', __FILE__)
26
30
  require File.expand_path('../gollum-lib/macro', __FILE__)
27
- require File.expand_path('../gollum-lib/file', __FILE__)
28
31
  require File.expand_path('../gollum-lib/file_view', __FILE__)
29
32
  require File.expand_path('../gollum-lib/markup', __FILE__)
30
33
  require File.expand_path('../gollum-lib/markups', __FILE__)
@@ -40,19 +43,16 @@ module Gollum
40
43
  class Error < StandardError; end
41
44
 
42
45
  class DuplicatePageError < Error
43
- attr_accessor :dir
44
- attr_accessor :existing_path
45
46
  attr_accessor :attempted_path
46
47
 
47
- def initialize(dir, existing, attempted, message = nil)
48
- @dir = dir
49
- @existing_path = existing
48
+ def initialize(attempted, message = nil)
50
49
  @attempted_path = attempted
51
- super(message || "Cannot write #{@dir}/#{@attempted_path}, found #{@dir}/#{@existing_path}.")
50
+ super(message || "Cannot write #{@attempted_path}: path already exists.")
52
51
  end
53
52
  end
54
53
 
55
54
  class InvalidGitRepositoryError < StandardError; end
56
55
  class NoSuchPathError < StandardError; end
56
+ class IllegalDirectoryPath < StandardError; end
57
57
 
58
58
  end
@@ -47,10 +47,7 @@ module Gollum
47
47
  #
48
48
  # Returns a Gollum::Page instance.
49
49
  def page(wiki, commit)
50
- blob = self.blob(wiki.repo)
51
- page = wiki.page_class.new(wiki).populate(blob, self.dir)
52
- page.version = commit
53
- page
50
+ ::Gollum::Page.new(wiki, self.blob(wiki.repo), self.dir, commit)
54
51
  end
55
52
 
56
53
  # Gets a File instance for this blob.
@@ -59,10 +56,7 @@ module Gollum
59
56
  #
60
57
  # Returns a Gollum::File instance.
61
58
  def file(wiki, commit)
62
- blob = self.blob(wiki.repo)
63
- file = wiki.file_class.new(wiki).populate(blob, self.dir)
64
- file.version = commit
65
- file
59
+ ::Gollum::File.new(wiki, self.blob(wiki.repo), self.dir, commit)
66
60
  end
67
61
 
68
62
  def inspect
@@ -30,7 +30,6 @@ module Gollum
30
30
  @wiki = wiki
31
31
  @options = options
32
32
  @callbacks = []
33
- after_commit { |*args| Hook.execute(:post_commit, *args) }
34
33
  end
35
34
 
36
35
  # Public: References the Git index for this commit.
@@ -71,82 +70,46 @@ module Gollum
71
70
  end
72
71
  end
73
72
 
74
- # Adds a page to the given Index.
73
+ # Adds a path to the Index.
75
74
  #
76
- # dir - The String subdirectory of the Gollum::Page without any
77
- # prefix or suffix slashes (e.g. "foo/bar").
78
- # name - The String Gollum::Page filename_stripped.
79
- # format - The Symbol Gollum::Page format.
75
+ # path - The String path to be added
80
76
  # data - The String wiki data to store in the tree map.
81
77
  #
82
- # Raises Gollum::DuplicatePageError if a matching filename already exists.
78
+ # Raises Gollum::DuplicatePageError if a matching filename already exists, unless force_overwrite is explicitly enabled.
83
79
  # This way, pages are not inadvertently overwritten.
84
80
  #
85
81
  # Returns nothing (modifies the Index in place).
86
- def add_to_index(dir, name, format, data)
87
- path = @wiki.page_file_name(name, format)
88
-
89
- dir = '/' if dir.strip.empty?
90
-
91
- fullpath = ::File.join(*[dir, path])
92
- fullpath = fullpath[1..-1] if fullpath =~ /^\//
93
-
94
- if index.current_tree && (tree = index.current_tree / (@wiki.page_file_dir || '/'))
95
- tree = tree / dir unless tree.nil?
96
- end
97
-
98
- if tree
99
- downpath = path.downcase.sub(/\.\w+$/, '')
100
-
101
- tree.blobs.each do |blob|
102
- next if page_path_scheduled_for_deletion?(index.tree, fullpath)
103
-
104
- existing_file = blob.name.downcase.sub(/\.\w+$/, '')
105
- existing_file_ext = ::File.extname(blob.name).sub(/^\./, '')
106
-
107
- new_file_ext = ::File.extname(path).sub(/^\./, '')
108
-
109
- if downpath == existing_file && (new_file_ext == existing_file_ext)
110
- raise DuplicatePageError.new(dir, blob.name, path)
111
- end
82
+ def add_to_index(path, data, options = {}, force_overwrite = false)
83
+ if tree = index.current_tree
84
+ unless page_path_scheduled_for_deletion?(index.tree, path) || force_overwrite
85
+ raise DuplicatePageError.new(path) if tree / path
112
86
  end
113
87
  end
114
88
 
115
- fullpath = fullpath.force_encoding('ascii-8bit') if fullpath.respond_to?(:force_encoding)
116
-
117
- begin
118
- data = @wiki.normalize(data)
119
- rescue ArgumentError => err
120
- # Swallow errors that arise from data being binary
121
- raise err unless err.message.include?('invalid byte sequence')
89
+ unless options[:normalize] == false
90
+ begin
91
+ data = @wiki.normalize(data)
92
+ rescue ArgumentError => err
93
+ # Swallow errors that arise from data being binary
94
+ raise err unless err.message.include?('invalid byte sequence')
95
+ end
122
96
  end
123
- index.add(fullpath, data)
97
+ index.add(path, data)
124
98
  end
125
99
 
126
100
  # Update the given file in the repository's working directory if there
127
101
  # is a working directory present.
128
102
  #
129
- # dir - The String directory in which the file lives.
130
- # name - The String name of the page or the stripped filename
131
- # (should be pre-canonicalized if required).
132
- # format - The Symbol format of the page.
103
+ # path - The String path to update
133
104
  #
134
105
  # Returns nothing.
135
- def update_working_dir(dir, name, format)
106
+ def update_working_dir(path)
136
107
  unless @wiki.repo.bare
137
- if @wiki.page_file_dir && dir !~ /^#{@wiki.page_file_dir}/
138
- dir = dir.size.zero? ? @wiki.page_file_dir : ::File.join(@wiki.page_file_dir, dir)
108
+ if @wiki.page_file_dir && !path.start_with?(@wiki.page_file_dir)
109
+ # Skip the path if it is not under the wiki's page file dir
110
+ return nil
139
111
  end
140
112
 
141
- path =
142
- if dir == ''
143
- @wiki.page_file_name(name, format)
144
- else
145
- ::File.join(dir, @wiki.page_file_name(name, format))
146
- end
147
-
148
- path = path.force_encoding('ascii-8bit') if path.respond_to?(:force_encoding)
149
-
150
113
  Dir.chdir(::File.join(@wiki.repo.path, '..')) do
151
114
  if file_path_scheduled_for_deletion?(index.tree, path)
152
115
  @wiki.repo.git.rm(path, :force => true)
@@ -165,6 +128,7 @@ module Gollum
165
128
  @callbacks.each do |cb|
166
129
  cb.call(self, sha1)
167
130
  end
131
+ Hook.execute(:post_commit, self, sha1)
168
132
  sha1
169
133
  end
170
134
 
@@ -192,8 +156,7 @@ module Gollum
192
156
  parts = path.split('/')
193
157
  if parts.size == 1
194
158
  deletions = map.keys.select { |k| !map[k] }
195
- downfile = parts.first.downcase.sub(/\.\w+$/, '')
196
- deletions.any? { |d| d.downcase.sub(/\.\w+$/, '') == downfile }
159
+ deletions.any? { |d| d == parts.first }
197
160
  else
198
161
  part = parts.shift
199
162
  if (rest = map[part])
@@ -230,7 +193,6 @@ module Gollum
230
193
 
231
194
  # Proxies methods t
232
195
  def method_missing(name, *args)
233
- args.map! { |item| item.respond_to?(:force_encoding) ? item.force_encoding('ascii-8bit') : item }
234
196
  index.send(name, *args)
235
197
  end
236
198
  end
@@ -2,55 +2,125 @@
2
2
 
3
3
  module Gollum
4
4
  class File
5
- Wiki.file_class = self
5
+
6
+ # Does the filesystem support reading symlinks?
7
+ FS_SUPPORT_SYMLINKS = !Gem.win_platform?
8
+
9
+ class << self
10
+
11
+ # For use with self.find: returns true if the given query corresponds to the in-repo path of the BlobEntry.
12
+ #
13
+ # query - The String path to match.
14
+ # entry - The BlobEntry to check against.
15
+ # global_match - (Not implemented for File, see Page.path_match)
16
+ # hyphened_tags - If true, replace spaces in match_path with hyphens.
17
+ # case_insensitive - If true, compare query and match_path case-insensitively
18
+ def path_match(query, entry, global_match = false, hyphened_tags = false, case_insensitive = false)
19
+ path_compare(query, ::File.join('/', entry.path), hyphened_tags, case_insensitive)
20
+ end
21
+
22
+ # For use with self.path_match: returns true if 'query' and 'match_path' match, strictly or taking account of the following parameters:
23
+ # hyphened_tags - If true, replace spaces in match_path with hyphens.
24
+ # case_insensitive - If true, compare query and match_path case-insensitively
25
+ def path_compare(query, match_path, hyphened_tags, case_insensitive)
26
+ if hyphened_tags
27
+ final_query = query.gsub(' ', '-')
28
+ final_match = match_path.gsub(' ', '-')
29
+ else
30
+ final_query = query
31
+ final_match = match_path
32
+ end
33
+ final_match.send(case_insensitive ? :casecmp? : :==, final_query)
34
+ end
35
+ end
36
+
37
+ # Find a file in the given Gollum wiki.
38
+ #
39
+ # wiki - The wiki.
40
+ # path - The full String path.
41
+ # version - The String version ID to find.
42
+ # try_on_disk - If true, try to return just a reference to a file
43
+ # that exists on the disk.
44
+ # global_match - If true, find a File matching path's filename, but not it's directory (so anywhere in the repo)
45
+ #
46
+ # Returns a Gollum::File or nil if the file could not be found. Note
47
+ # that if you specify try_on_disk=true, you may or may not get a file
48
+ # for which on_disk? is actually true.
49
+ def self.find(wiki, path, version, try_on_disk = false, global_match = false)
50
+ map = wiki.tree_map_for(version.to_s)
51
+
52
+ query_path = Pathname.new(::File.join(['/', wiki.page_file_dir, path].compact)).cleanpath.to_s
53
+ query_path.sub!(/^\/\//, '/') if Gem.win_platform? # On Windows, Pathname#cleanpath will leave double slashes at the start of a path intact, so sub them out.
54
+
55
+ begin
56
+ entry = map.detect do |entry|
57
+ path_match(query_path, entry, global_match, wiki.hyphened_tag_lookup, wiki.case_insensitive_tag_lookup)
58
+ end
59
+ entry ? self.new(wiki, entry.blob(wiki.repo), entry.dir, version, try_on_disk) : nil
60
+ rescue Gollum::Git::NoSuchShaFound
61
+ nil
62
+ end
63
+ end
6
64
 
7
65
  # Public: Initialize a file.
8
66
  #
9
- # wiki - The Gollum::Wiki in question.
67
+ # wiki - The Gollum::Wiki
68
+ # blob - The Gollum::Git::Blob
69
+ # path - The String path
70
+ # version - The String SHA or Gollum::Git::Commit version
71
+ # try_on_disk - If true, try to get an on disk reference for this file.
10
72
  #
11
73
  # Returns a newly initialized Gollum::File.
12
- def initialize(wiki)
74
+ def initialize(wiki, blob, path, version, try_on_disk = false)
13
75
  @wiki = wiki
14
- @blob = nil
15
- @path = nil
16
- @on_disk = false
17
- @on_disk_path = nil
76
+ @blob = blob
77
+ @path = "#{path}/#{blob.name}"[1..-1]
78
+ @version = version.is_a?(Gollum::Git::Commit) ? version : @wiki.commit_for(version)
79
+ get_disk_reference if try_on_disk
18
80
  end
19
81
 
20
- # Public: The url path required to reach this page within the repo.
82
+ # Public: The path of the page within the repo.
21
83
  #
22
- # Returns the String url_path
23
- def url_path
24
- path = self.path
25
- path = path.sub(/\/[^\/]+$/, '/') if path.include?('/')
26
- path
27
- end
84
+ # Returns the String path.
85
+ attr_reader :path
86
+
87
+ # Public: The Gollum::Git::Commit version of the file.
88
+ attr_accessor :version
28
89
 
29
- # Public: The SHA hash identifying this file
90
+ # Public: Whether the file can be read from disk.
91
+ attr_accessor :on_disk
92
+
93
+ # Public: The SHA hash identifying this page
30
94
  #
31
95
  # Returns the String SHA.
32
96
  def sha
33
97
  @blob && @blob.id
34
98
  end
35
99
 
36
- # Public: The url_path, but CGI escaped.
100
+ # Public: The on-disk filename of the page including extension.
37
101
  #
38
- # Returns the String url_path
39
- def escaped_url_path
40
- CGI.escape(self.url_path).gsub('%2F', '/')
102
+ # Returns the String name.
103
+ def filename
104
+ @blob && @blob.name
41
105
  end
106
+ alias :name :filename
42
107
 
43
- # Public: The on-disk filename of the file.
108
+ # Public: The url path required to reach this file within the repo.
44
109
  #
45
- # Returns the String name.
46
- def name
47
- return @path if on_disk?
48
- @blob && @blob.name
110
+ # Returns the String url_path
111
+ def url_path
112
+ # Chop off the page_file_dir and first slash if necessary
113
+ @wiki.page_file_dir ? self.path[@wiki.page_file_dir.length+1..-1] : self.path
49
114
  end
50
115
 
51
- alias filename name
116
+ # Public: The url_path, but URL encoded.
117
+ #
118
+ # Returns the String url_path
119
+ def escaped_url_path
120
+ ERB::Util.url_encode(self.url_path).gsub('%2F', '/').force_encoding('utf-8')
121
+ end
52
122
 
53
- # Public: The raw contents of the page.
123
+ # Public: The raw contents of the file.
54
124
  #
55
125
  # Returns the String data.
56
126
  def raw_data
@@ -69,7 +139,7 @@ module Gollum
69
139
  #
70
140
  # Returns true if this is a pointer to an on-disk file
71
141
  def on_disk?
72
- @on_disk
142
+ !!@on_disk
73
143
  end
74
144
 
75
145
  # Public: The path to this file on disk
@@ -79,48 +149,29 @@ module Gollum
79
149
  @on_disk_path
80
150
  end
81
151
 
82
- # Public: The Gollum::Git::Commit version of the file.
83
- attr_accessor :version
84
-
85
- # Public: The String path of the file.
86
- attr_reader :path
87
-
88
152
  # Public: The String mime type of the file.
89
153
  def mime_type
90
154
  @blob && @blob.mime_type
91
155
  end
92
156
 
93
- # Populate the File with information from the Blob.
94
- #
95
- # blob - The Gollum::Git::Blob that contains the info.
96
- # path - The String directory path of the file.
97
- #
98
- # Returns the populated Gollum::File.
99
- def populate(blob, path = nil)
100
- @blob = blob
101
- @path = "#{path}/#{blob.name}"[1..-1]
102
- @on_disk = false
103
- @on_disk_path = nil
104
- self
157
+ def self.protected_files
158
+ ['custom.css', 'custom.js', '.redirects.gollum']
105
159
  end
106
160
 
107
- #########################################################################
108
- #
109
- # Internal Methods
110
- #
111
- #########################################################################
161
+ private
112
162
 
113
163
  # Return the file path to this file on disk, if available.
114
164
  #
115
165
  # Returns nil if the file isn't available on disk. This can occur if the
116
166
  # repo is bare, if the commit isn't the HEAD, or if there are problems
117
167
  # resolving symbolic links.
118
- def get_disk_reference(name, commit)
168
+ def get_disk_reference
119
169
  return false if @wiki.repo.bare
120
- return false if commit.sha != @wiki.repo.head.commit.sha
170
+ return false if @version.sha != @wiki.repo.head.commit.sha
171
+ return false if @blob.is_symlink && !FS_SUPPORT_SYMLINKS
121
172
 
122
173
  # This will try to resolve symbolic links, as well
123
- pathname = Pathname.new(::File.expand_path(::File.join(@wiki.repo.path, '..', name)))
174
+ pathname = Pathname.new(::File.expand_path(::File.join(@wiki.repo.path, '..', @path)))
124
175
  if pathname.symlink?
125
176
  source = ::File.readlink(pathname.to_path)
126
177
  realpath = ::File.join(::File.dirname(pathname.to_path), source)
@@ -129,36 +180,8 @@ module Gollum
129
180
  else
130
181
  @on_disk_path = pathname.to_path
131
182
  end
132
- true
183
+ @on_disk = true
133
184
  end
134
185
 
135
- # Find a file in the given Gollum repo.
136
- #
137
- # name - The full String path.
138
- # version - The String version ID to find.
139
- # try_on_disk - If true, try to return just a reference to a file
140
- # that exists on the disk.
141
- #
142
- # Returns a Gollum::File or nil if the file could not be found. Note
143
- # that if you specify try_on_disk=true, you may or may not get a file
144
- # for which on_disk? is actually true.
145
- def find(name, version, try_on_disk = false)
146
- checked = name.downcase
147
- map = @wiki.tree_map_for(version)
148
- commit = version.is_a?(Gollum::Git::Commit) ? version : @wiki.commit_for(version)
149
-
150
- if (result = map.detect { |entry| entry.path.downcase == checked })
151
- @path = name
152
- @version = commit
153
-
154
- if try_on_disk && get_disk_reference(name, commit)
155
- @on_disk = true
156
- else
157
- @blob = result.blob(@wiki.repo)
158
- end
159
-
160
- self
161
- end
162
- end
163
186
  end
164
187
  end