jekyll-filesystem-jail 0.1.0
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.
- checksums.yaml +7 -0
- data/.gitignore +22 -0
- data/.travis.yml +8 -0
- data/Gemfile +2 -0
- data/LICENSE.txt +22 -0
- data/README.md +35 -0
- data/Rakefile +2 -0
- data/jekyll-filesystem-jail.gemspec +24 -0
- data/lib/jekyll-filesystem-jail.rb +166 -0
- data/lib/jekyll-filesystem-jail/version.rb +7 -0
- data/script/bootstrap +3 -0
- data/script/cibuild +3 -0
- data/spec/jekyll_filesystem_adapter_spec.rb +231 -0
- data/spec/source/about/hansel.md +0 -0
- data/spec/source/about/index.md +0 -0
- data/spec/source/homepage.md +5 -0
- data/spec/source/symlink.md +5 -0
- data/spec/spec_helper.rb +83 -0
- metadata +123 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 7481a349425be49a0e0aded08ea090c07943ee8a
|
4
|
+
data.tar.gz: 1cf55342e19a7e77ac0a7ee0098fe090aa8783d3
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 99b3451809cf2840ed4382d62fb2892820624a70318fa4fde2c1e6173f5c962dcd327b01b2f968c7c815413f7d683b640ac6c4f11f5d6becf16d5b96ffa06f58
|
7
|
+
data.tar.gz: ce3ce74ecb72dc0eba15a38ebc8a0dabdbd208fa9e3ad2e14b63c4deb3d5aed4e151b1a1ae1a51ce03a6918a94b78944aa6615203cfa676e28d7b0b716d2a2d1
|
data/.gitignore
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
*.bundle
|
19
|
+
*.so
|
20
|
+
*.o
|
21
|
+
*.a
|
22
|
+
mkmf.log
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 GitHub, Inc.
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
# Jekyll File System Jail
|
2
|
+
|
3
|
+
How Jekyll accesses your file system (safely).
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'jekyll-filesystem-adapter'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install jekyll-filesystem-adapter
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
It's installed with Jekyll by default and accessible via `Jekyll.fs`.
|
22
|
+
Any and all plugins utilizing the file system must use Jekyll.fs to
|
23
|
+
be considered secure.
|
24
|
+
|
25
|
+
## Contributing
|
26
|
+
|
27
|
+
1. Fork it ( https://github.com/jekyll/jekyll-filesystem-jail/fork )
|
28
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
29
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
30
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
31
|
+
5. Create a new Pull Request
|
32
|
+
|
33
|
+
# Credit
|
34
|
+
|
35
|
+
Written by Parker Moore (@parkr).
|
data/Rakefile
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'jekyll-filesystem-jail/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "jekyll-filesystem-jail"
|
8
|
+
spec.version = Jekyll::FileSystem::Jail::VERSION
|
9
|
+
spec.authors = ["Parker Moore"]
|
10
|
+
spec.email = ["parkrmoore@gmail.com"]
|
11
|
+
spec.summary = %q{How Jekyll accesses your file system (safely).}
|
12
|
+
spec.homepage = "https://github.com/jekyll/jekyll-filesystem-jail"
|
13
|
+
spec.license = "MIT"
|
14
|
+
|
15
|
+
spec.files = `git ls-files -z`.split("\x0")
|
16
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
|
+
spec.require_paths = ["lib"]
|
19
|
+
|
20
|
+
spec.add_development_dependency "bundler", "~> 1.6"
|
21
|
+
spec.add_development_dependency "rake"
|
22
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
23
|
+
spec.add_development_dependency "jekyll", "~> 2.0"
|
24
|
+
end
|
@@ -0,0 +1,166 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require "jekyll-filesystem-jail/version"
|
3
|
+
require 'fileutils'
|
4
|
+
|
5
|
+
module Jekyll
|
6
|
+
module FileSystem
|
7
|
+
class Jail
|
8
|
+
|
9
|
+
class << self
|
10
|
+
def sanitized_path(base_directory, questionable_path)
|
11
|
+
clean_path = File.expand_path(questionable_path, "/")
|
12
|
+
clean_path.gsub!(/\A\w\:\//, '/')
|
13
|
+
|
14
|
+
unless clean_path.start_with?(base_directory)
|
15
|
+
File.join(base_directory, clean_path)
|
16
|
+
else
|
17
|
+
clean_path
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
attr_reader :base_dir, :safe, :site
|
23
|
+
|
24
|
+
def initialize(base_directory, options = {})
|
25
|
+
@base_dir = base_directory
|
26
|
+
@safe = options.fetch(:safe, false)
|
27
|
+
@site = options.fetch(:site, nil)
|
28
|
+
end
|
29
|
+
|
30
|
+
def safe?
|
31
|
+
@safe || (@site && @site.safe) || false
|
32
|
+
end
|
33
|
+
|
34
|
+
def sanitized_path(*paths)
|
35
|
+
case paths.size
|
36
|
+
when 2
|
37
|
+
self.class.sanitized_path(*paths)
|
38
|
+
when 1
|
39
|
+
self.class.sanitized_path(base_dir, paths.pop)
|
40
|
+
else
|
41
|
+
raise ArgumentError.new("FileSystemAdapter#sanitized_path takes 1 or 2 arguments.")
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def realpath(questionable_path)
|
46
|
+
File.realpath(questionable_path)
|
47
|
+
end
|
48
|
+
|
49
|
+
#
|
50
|
+
# Asking Questions
|
51
|
+
#
|
52
|
+
|
53
|
+
def symlink?(path_to_check)
|
54
|
+
File.symlink? path_to_check
|
55
|
+
end
|
56
|
+
|
57
|
+
def file?(path_to_check)
|
58
|
+
File.file? path_to_check
|
59
|
+
end
|
60
|
+
|
61
|
+
def directory?(path_to_check)
|
62
|
+
File.directory? path_to_check
|
63
|
+
end
|
64
|
+
|
65
|
+
def exist?(path_to_check)
|
66
|
+
File.exist? path_to_check
|
67
|
+
end
|
68
|
+
|
69
|
+
def file_allowed?(path_to_check)
|
70
|
+
!safe? || !symlink?(path_to_check)
|
71
|
+
end
|
72
|
+
|
73
|
+
#
|
74
|
+
# Directory Actions
|
75
|
+
#
|
76
|
+
|
77
|
+
def chdir(directory_to_go_to, &block)
|
78
|
+
Dir.chdir(directory_to_go_to, &block)
|
79
|
+
end
|
80
|
+
|
81
|
+
def glob(path_to_glob, flags = nil)
|
82
|
+
full_path = path_to_glob
|
83
|
+
if flags.nil?
|
84
|
+
Dir.glob(full_path)
|
85
|
+
else
|
86
|
+
Dir.glob(full_path, flags)
|
87
|
+
end.sort
|
88
|
+
end
|
89
|
+
|
90
|
+
def dir_entries(directory)
|
91
|
+
chdir(directory) do
|
92
|
+
glob(sanitized_path(directory, '*')).map do |entry|
|
93
|
+
relative_to(directory, entry)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def full_directory_glob(directory)
|
99
|
+
full_path = directory
|
100
|
+
Dir.glob(File.join(full_path, "**", "*"))
|
101
|
+
end
|
102
|
+
|
103
|
+
def rm_rf(file_or_files)
|
104
|
+
files = Array(file_or_files).map do |path|
|
105
|
+
sanitized_path(path)
|
106
|
+
end.select do |path|
|
107
|
+
exist?(path)
|
108
|
+
end
|
109
|
+
FileUtils.rm_r(files, { :secure => true })
|
110
|
+
end
|
111
|
+
|
112
|
+
def mkdir_p(dir_to_create)
|
113
|
+
directory = dir_to_create
|
114
|
+
FileUtils.mkdir_p(directory) unless exist?(directory)
|
115
|
+
end
|
116
|
+
|
117
|
+
#
|
118
|
+
# File Actions
|
119
|
+
#
|
120
|
+
|
121
|
+
def read(path, options = {})
|
122
|
+
File.open(path, 'rb') do |f|
|
123
|
+
if options[:bytes].nil?
|
124
|
+
f.read
|
125
|
+
else
|
126
|
+
f.read options[:bytes]
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def write(path, content, options = {})
|
132
|
+
File.open(path, 'wb') do |f|
|
133
|
+
f.write(content)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def relative_to(prefix, entry)
|
138
|
+
regexp = Regexp.new("")
|
139
|
+
if prefix.end_with?("/")
|
140
|
+
entry.sub(/\A#{Regexp.escape(prefix)}/, '')
|
141
|
+
else
|
142
|
+
entry.sub(/\A#{Regexp.escape(prefix)}\//, '')
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def sanitize_filename(name)
|
147
|
+
name.gsub(/[^\w\s-]+/, '')
|
148
|
+
.gsub(/(^|\b\s)\s+($|\s?\b)/, '\\1\\2')
|
149
|
+
.gsub(/\s+/, '_')
|
150
|
+
end
|
151
|
+
|
152
|
+
def mtime(path)
|
153
|
+
File.mtime path
|
154
|
+
end
|
155
|
+
|
156
|
+
def basename(path, suffix = '')
|
157
|
+
File.basename(path, suffix)
|
158
|
+
end
|
159
|
+
|
160
|
+
def dirname(path)
|
161
|
+
File.dirname(path)
|
162
|
+
end
|
163
|
+
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
data/script/bootstrap
ADDED
data/script/cibuild
ADDED
@@ -0,0 +1,231 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe(Jekyll::FileSystem::Jail) do
|
4
|
+
|
5
|
+
context "class methods" do
|
6
|
+
let(:base_dir) { source_dir }
|
7
|
+
let(:outside_file) { "/etc/passwd" }
|
8
|
+
let(:inside_file) { "resume/index.md" }
|
9
|
+
|
10
|
+
context ".sanitized_path" do
|
11
|
+
it "sanitizes a questionable path outside the base directory correctly" do
|
12
|
+
expect(described_class.sanitized_path(base_dir, outside_file)).to(
|
13
|
+
eql(source_dir('etc', 'passwd'))
|
14
|
+
)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "sanitizes a path inside the base directory correctly" do
|
18
|
+
expect(described_class.sanitized_path(base_dir, inside_file)).to(
|
19
|
+
eql(source_dir('resume', 'index.md'))
|
20
|
+
)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context "an instance" do
|
26
|
+
let(:source) { source_dir }
|
27
|
+
let(:safe) { false }
|
28
|
+
let(:site) { nil }
|
29
|
+
subject do
|
30
|
+
described_class.new(source_dir, { safe: safe, site: site })
|
31
|
+
end
|
32
|
+
|
33
|
+
context "#realpath" do
|
34
|
+
it "reads the destination of symlinks" do
|
35
|
+
expect(subject.realpath(source_dir('symlink.md'))).to eql(source_dir('homepage.md'))
|
36
|
+
end
|
37
|
+
|
38
|
+
it "errors if the file isn't there" do
|
39
|
+
expect(->{ subject.realpath(source_dir('non_existent_file.txt')) }).to raise_error
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context "#symlink?" do
|
44
|
+
it "knows that a symlink is a symlink" do
|
45
|
+
expect(subject.symlink?('symlink.md')).to be_truthy
|
46
|
+
end
|
47
|
+
|
48
|
+
it "knows that a regular file is not a symlink" do
|
49
|
+
expect(subject.symlink?('homepage.md')).to be_falsey
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context "#file?" do
|
54
|
+
it "knows a file is a file" do
|
55
|
+
expect(subject.file?('homepage.md')).to be_truthy
|
56
|
+
end
|
57
|
+
|
58
|
+
it "knows a directory is not a file" do
|
59
|
+
expect(subject.file?('about')).to be_falsey
|
60
|
+
end
|
61
|
+
|
62
|
+
it "knows a non-existent file is a not a file" do
|
63
|
+
expect(subject.file?('non_existent_file.md')).to be_falsey
|
64
|
+
end
|
65
|
+
|
66
|
+
it "prevents traversal outside base directory" do
|
67
|
+
expect(subject.file?('/etc/hosts')).to be_falsey
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context "#directory?" do
|
72
|
+
it "knows a file is not a directory" do
|
73
|
+
expect(subject.directory?('homepage.md')).to be_falsey
|
74
|
+
end
|
75
|
+
|
76
|
+
it "knows a directory is a directory" do
|
77
|
+
expect(subject.directory?('about')).to be_truthy
|
78
|
+
end
|
79
|
+
|
80
|
+
it "knows a non-existent directory is a not a directory" do
|
81
|
+
expect(subject.directory?('i-dont-exist')).to be_falsey
|
82
|
+
end
|
83
|
+
|
84
|
+
it "prevents traversal outside base directory" do
|
85
|
+
expect(subject.directory?('/etc')).to be_falsey
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
context "#sanitized_path" do
|
90
|
+
it "assumes the base path of the instance" do
|
91
|
+
expect(subject.sanitized_path('homepage.md')).to start_with(source_dir)
|
92
|
+
end
|
93
|
+
|
94
|
+
it "allows you to put through a base path if you want, too" do
|
95
|
+
expect(subject.sanitized_path(tmp_dir, 'homepage.md')).to start_with(tmp_dir)
|
96
|
+
end
|
97
|
+
|
98
|
+
it "errors with more than 2 arguments" do
|
99
|
+
expect(->{ subject.sanitized_path(tmp_dir, 'homepage', 'the thing.md') }).to raise_error
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
context "#read" do
|
104
|
+
it "reads in an entire existing file" do
|
105
|
+
expect(subject.read(source_dir('homepage.md'))).to eql(<<-FILE
|
106
|
+
---
|
107
|
+
title: Home Page
|
108
|
+
---
|
109
|
+
|
110
|
+
Welcome to my homepage!
|
111
|
+
FILE
|
112
|
+
)
|
113
|
+
end
|
114
|
+
|
115
|
+
it "reads in just some bytes of an existing file" do
|
116
|
+
expect(subject.read(source_dir('homepage.md'), { bytes: 5 })).to eql("---\nt")
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
context "#exist?" do
|
121
|
+
it "can tell if a file exists on the filesystem" do
|
122
|
+
expect(subject.exist?('homepage.md')).to be_truthy
|
123
|
+
end
|
124
|
+
|
125
|
+
it "can tell if a file doesn't exist" do
|
126
|
+
expect(subject.exist?('index.md')).to be_falsey
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
context "#glob" do
|
131
|
+
it "grabs the right number of files from a directory" do
|
132
|
+
expect(subject.glob('about/**/*').size).to eql(2)
|
133
|
+
end
|
134
|
+
|
135
|
+
it "grabs the right files" do
|
136
|
+
expect(
|
137
|
+
-> {
|
138
|
+
subject.chdir(source_dir('about')) do
|
139
|
+
subject.glob('about/**/*')
|
140
|
+
end
|
141
|
+
}.call
|
142
|
+
).to eql(
|
143
|
+
%w(hansel.md index.md)
|
144
|
+
)
|
145
|
+
end
|
146
|
+
|
147
|
+
it "can grab subdirectories" do
|
148
|
+
expect(
|
149
|
+
subject.glob('**/*')
|
150
|
+
).to eql(
|
151
|
+
%w(about about/hansel.md about/index.md homepage.md symlink.md)
|
152
|
+
)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
context "#dir_entries" do
|
157
|
+
it "grabs just the entries in the immediate folder" do
|
158
|
+
expect(subject.dir_entries(source_dir)).to eql(
|
159
|
+
%w(about homepage.md symlink.md)
|
160
|
+
)
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
context "#rm_rf" do
|
165
|
+
subject do
|
166
|
+
described_class.new(tmp_dir, { safe: safe, site: site })
|
167
|
+
end
|
168
|
+
let(:all_files) { [tmp_dir('not_exist')] + files_to_create }
|
169
|
+
let(:files_to_create) { [tmp_dir('exit'), tmp_dir('exist')] }
|
170
|
+
before(:each) do
|
171
|
+
FileUtils.touch files_to_create
|
172
|
+
end
|
173
|
+
|
174
|
+
it "deletes only the files that exist" do
|
175
|
+
expect(subject.rm_rf(all_files)).to eql(files_to_create)
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
context "#mkdir_p" do
|
180
|
+
after(:each) do
|
181
|
+
subject.rm_rf('etc')
|
182
|
+
end
|
183
|
+
|
184
|
+
it "creates a folder" do
|
185
|
+
expect(subject.mkdir_p('/etc/hosts')).to eql([source_dir('etc/hosts')])
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
context "safe mode turned on" do
|
190
|
+
let(:safe) { true }
|
191
|
+
|
192
|
+
context "#file_allowed?" do
|
193
|
+
it "reports that a symlinked file isn't allowed" do
|
194
|
+
expect(subject.file_allowed?('symlink.md')).to be_falsey
|
195
|
+
end
|
196
|
+
|
197
|
+
it "reports that a normal file is allowed" do
|
198
|
+
expect(subject.file_allowed?('homepage.md')).to be_truthy
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
context "#safe?" do
|
203
|
+
it "reports safe mode turned on" do
|
204
|
+
expect(subject.safe?).to be_truthy
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
context "safe mode turned off" do
|
210
|
+
let(:safe) { false }
|
211
|
+
|
212
|
+
context "#file_allowed?" do
|
213
|
+
it "reports that a symlinked file is allowed" do
|
214
|
+
expect(subject.file_allowed?('symlink.md')).to be_truthy
|
215
|
+
end
|
216
|
+
|
217
|
+
it "reports that a normal file is allowed" do
|
218
|
+
expect(subject.file_allowed?('homepage.md')).to be_truthy
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
context "#safe" do
|
223
|
+
it "reports safe mode turned off" do
|
224
|
+
expect(subject.safe?).to be_falsey
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
end
|
230
|
+
|
231
|
+
end
|
File without changes
|
File without changes
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
TEST_DIR = File.dirname(__FILE__)
|
2
|
+
PROJECT_DIR = File.dirname(TEST_DIR)
|
3
|
+
TMP_DIR = File.expand_path('tmp', PROJECT_DIR)
|
4
|
+
|
5
|
+
-> {
|
6
|
+
require 'fileutils'
|
7
|
+
FileUtils.mkdir(TMP_DIR) unless File.directory?(TMP_DIR)
|
8
|
+
}.call
|
9
|
+
|
10
|
+
require File.expand_path('lib/jekyll-filesystem-jail.rb', PROJECT_DIR)
|
11
|
+
|
12
|
+
RSpec.configure do |config|
|
13
|
+
# The settings below are suggested to provide a good initial experience
|
14
|
+
# with RSpec, but feel free to customize to your heart's content.
|
15
|
+
# These two settings work together to allow you to limit a spec run
|
16
|
+
# to individual examples or groups you care about by tagging them with
|
17
|
+
# `:focus` metadata. When nothing is tagged with `:focus`, all examples
|
18
|
+
# get run.
|
19
|
+
config.filter_run :focus
|
20
|
+
config.run_all_when_everything_filtered = true
|
21
|
+
|
22
|
+
# Many RSpec users commonly either run the entire suite or an individual
|
23
|
+
# file, and it's useful to allow more verbose output when running an
|
24
|
+
# individual spec file.
|
25
|
+
if config.files_to_run.one?
|
26
|
+
# Use the documentation formatter for detailed output,
|
27
|
+
# unless a formatter has already been configured
|
28
|
+
# (e.g. via a command-line flag).
|
29
|
+
config.default_formatter = 'doc'
|
30
|
+
end
|
31
|
+
|
32
|
+
# Print the 10 slowest examples and example groups at the
|
33
|
+
# end of the spec run, to help surface which specs are running
|
34
|
+
# particularly slow.
|
35
|
+
config.profile_examples = 10
|
36
|
+
|
37
|
+
# Run specs in random order to surface order dependencies. If you find an
|
38
|
+
# order dependency and want to debug it, you can fix the order by providing
|
39
|
+
# the seed, which is printed after each run.
|
40
|
+
# --seed 1234
|
41
|
+
config.order = :random
|
42
|
+
|
43
|
+
# Seed global randomization in this process using the `--seed` CLI option.
|
44
|
+
# Setting this allows you to use `--seed` to deterministically reproduce
|
45
|
+
# test failures related to randomization by passing the same `--seed` value
|
46
|
+
# as the one that triggered the failure.
|
47
|
+
Kernel.srand config.seed
|
48
|
+
|
49
|
+
# rspec-expectations config goes here. You can use an alternate
|
50
|
+
# assertion/expectation library such as wrong or the stdlib/minitest
|
51
|
+
# assertions if you prefer.
|
52
|
+
config.expect_with :rspec do |expectations|
|
53
|
+
# Enable only the newer, non-monkey-patching expect syntax.
|
54
|
+
# For more details, see:
|
55
|
+
# - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
|
56
|
+
expectations.syntax = :expect
|
57
|
+
end
|
58
|
+
|
59
|
+
# rspec-mocks config goes here. You can use an alternate test double
|
60
|
+
# library (such as bogus or mocha) by changing the `mock_with` option here.
|
61
|
+
config.mock_with :rspec do |mocks|
|
62
|
+
# Enable only the newer, non-monkey-patching expect syntax.
|
63
|
+
# For more details, see:
|
64
|
+
# - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
|
65
|
+
mocks.syntax = :expect
|
66
|
+
|
67
|
+
# Prevents you from mocking or stubbing a method that does not exist on
|
68
|
+
# a real object. This is generally recommended.
|
69
|
+
mocks.verify_partial_doubles = true
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_dir(*files)
|
73
|
+
File.join(TEST_DIR, *files)
|
74
|
+
end
|
75
|
+
|
76
|
+
def source_dir(*files)
|
77
|
+
test_dir('source', *files)
|
78
|
+
end
|
79
|
+
|
80
|
+
def tmp_dir(*files)
|
81
|
+
File.join(TMP_DIR, *files)
|
82
|
+
end
|
83
|
+
end
|
metadata
ADDED
@@ -0,0 +1,123 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: jekyll-filesystem-jail
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Parker Moore
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-06-18 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.6'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.6'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: jekyll
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '2.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '2.0'
|
69
|
+
description:
|
70
|
+
email:
|
71
|
+
- parkrmoore@gmail.com
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- ".gitignore"
|
77
|
+
- ".travis.yml"
|
78
|
+
- Gemfile
|
79
|
+
- LICENSE.txt
|
80
|
+
- README.md
|
81
|
+
- Rakefile
|
82
|
+
- jekyll-filesystem-jail.gemspec
|
83
|
+
- lib/jekyll-filesystem-jail.rb
|
84
|
+
- lib/jekyll-filesystem-jail/version.rb
|
85
|
+
- script/bootstrap
|
86
|
+
- script/cibuild
|
87
|
+
- spec/jekyll_filesystem_adapter_spec.rb
|
88
|
+
- spec/source/about/hansel.md
|
89
|
+
- spec/source/about/index.md
|
90
|
+
- spec/source/homepage.md
|
91
|
+
- spec/source/symlink.md
|
92
|
+
- spec/spec_helper.rb
|
93
|
+
homepage: https://github.com/jekyll/jekyll-filesystem-jail
|
94
|
+
licenses:
|
95
|
+
- MIT
|
96
|
+
metadata: {}
|
97
|
+
post_install_message:
|
98
|
+
rdoc_options: []
|
99
|
+
require_paths:
|
100
|
+
- lib
|
101
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
102
|
+
requirements:
|
103
|
+
- - ">="
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: '0'
|
106
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
requirements: []
|
112
|
+
rubyforge_project:
|
113
|
+
rubygems_version: 2.2.2
|
114
|
+
signing_key:
|
115
|
+
specification_version: 4
|
116
|
+
summary: How Jekyll accesses your file system (safely).
|
117
|
+
test_files:
|
118
|
+
- spec/jekyll_filesystem_adapter_spec.rb
|
119
|
+
- spec/source/about/hansel.md
|
120
|
+
- spec/source/about/index.md
|
121
|
+
- spec/source/homepage.md
|
122
|
+
- spec/source/symlink.md
|
123
|
+
- spec/spec_helper.rb
|