jekyll 3.9.3 → 4.4.1
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 +4 -4
- data/.rubocop.yml +511 -89
- data/LICENSE +1 -1
- data/README.markdown +48 -27
- data/lib/blank_template/_config.yml +3 -0
- data/lib/blank_template/_layouts/default.html +12 -0
- data/lib/blank_template/_sass/base.scss +9 -0
- data/lib/blank_template/assets/css/main.scss +4 -0
- data/lib/blank_template/index.md +8 -0
- data/lib/jekyll/cache.rb +186 -0
- data/lib/jekyll/cleaner.rb +8 -7
- data/lib/jekyll/collection.rb +84 -11
- data/lib/jekyll/command.rb +33 -6
- data/lib/jekyll/commands/build.rb +8 -28
- data/lib/jekyll/commands/clean.rb +3 -2
- data/lib/jekyll/commands/doctor.rb +46 -35
- data/lib/jekyll/commands/help.rb +1 -1
- data/lib/jekyll/commands/new.rb +44 -50
- data/lib/jekyll/commands/new_theme.rb +27 -28
- data/lib/jekyll/commands/serve/live_reload_reactor.rb +9 -16
- data/lib/jekyll/commands/serve/servlet.rb +21 -22
- data/lib/jekyll/commands/serve/websockets.rb +1 -1
- data/lib/jekyll/commands/serve.rb +75 -97
- data/lib/jekyll/configuration.rb +66 -158
- data/lib/jekyll/converters/identity.rb +18 -0
- data/lib/jekyll/converters/markdown/kramdown_parser.rb +83 -33
- data/lib/jekyll/converters/markdown.rb +49 -40
- data/lib/jekyll/converters/smartypants.rb +34 -14
- data/lib/jekyll/convertible.rb +36 -34
- data/lib/jekyll/deprecator.rb +2 -4
- data/lib/jekyll/document.rb +107 -72
- data/lib/jekyll/drops/collection_drop.rb +3 -4
- data/lib/jekyll/drops/document_drop.rb +9 -3
- data/lib/jekyll/drops/drop.rb +115 -33
- data/lib/jekyll/drops/excerpt_drop.rb +8 -0
- data/lib/jekyll/drops/site_drop.rb +9 -8
- data/lib/jekyll/drops/static_file_drop.rb +4 -4
- data/lib/jekyll/drops/theme_drop.rb +39 -0
- data/lib/jekyll/drops/unified_payload_drop.rb +7 -2
- data/lib/jekyll/drops/url_drop.rb +55 -3
- data/lib/jekyll/entry_filter.rb +42 -51
- data/lib/jekyll/excerpt.rb +48 -38
- data/lib/jekyll/external.rb +20 -19
- data/lib/jekyll/filters/date_filters.rb +6 -3
- data/lib/jekyll/filters/grouping_filters.rb +1 -2
- data/lib/jekyll/filters/url_filters.rb +50 -15
- data/lib/jekyll/filters.rb +211 -50
- data/lib/jekyll/frontmatter_defaults.rb +45 -36
- data/lib/jekyll/hooks.rb +26 -26
- data/lib/jekyll/inclusion.rb +32 -0
- data/lib/jekyll/layout.rb +12 -19
- data/lib/jekyll/liquid_extensions.rb +0 -2
- data/lib/jekyll/liquid_renderer/file.rb +24 -3
- data/lib/jekyll/liquid_renderer/table.rb +26 -77
- data/lib/jekyll/liquid_renderer.rb +31 -16
- data/lib/jekyll/log_adapter.rb +5 -1
- data/lib/jekyll/page.rb +51 -23
- data/lib/jekyll/page_excerpt.rb +25 -0
- data/lib/jekyll/page_without_a_file.rb +0 -4
- data/lib/jekyll/path_manager.rb +74 -0
- data/lib/jekyll/plugin.rb +5 -11
- data/lib/jekyll/plugin_manager.rb +15 -5
- data/lib/jekyll/profiler.rb +51 -0
- data/lib/jekyll/reader.rb +65 -10
- data/lib/jekyll/readers/collection_reader.rb +1 -0
- data/lib/jekyll/readers/data_reader.rb +48 -10
- data/lib/jekyll/readers/layout_reader.rb +3 -12
- data/lib/jekyll/readers/page_reader.rb +5 -5
- data/lib/jekyll/readers/post_reader.rb +32 -19
- data/lib/jekyll/readers/static_file_reader.rb +4 -4
- data/lib/jekyll/readers/theme_assets_reader.rb +8 -5
- data/lib/jekyll/regenerator.rb +4 -12
- data/lib/jekyll/related_posts.rb +1 -1
- data/lib/jekyll/renderer.rb +34 -49
- data/lib/jekyll/site.rb +151 -58
- data/lib/jekyll/static_file.rb +64 -28
- data/lib/jekyll/stevenson.rb +4 -8
- data/lib/jekyll/tags/highlight.rb +44 -57
- data/lib/jekyll/tags/include.rb +114 -80
- data/lib/jekyll/tags/link.rb +12 -7
- data/lib/jekyll/tags/post_url.rb +33 -30
- data/lib/jekyll/theme.rb +20 -18
- data/lib/jekyll/theme_builder.rb +91 -89
- data/lib/jekyll/url.rb +18 -10
- data/lib/jekyll/utils/ansi.rb +2 -2
- data/lib/jekyll/utils/exec.rb +0 -1
- data/lib/jekyll/utils/internet.rb +2 -4
- data/lib/jekyll/utils/platforms.rb +37 -52
- data/lib/jekyll/utils/thread_event.rb +1 -5
- data/lib/jekyll/utils.rb +29 -28
- data/lib/jekyll/version.rb +1 -1
- data/lib/jekyll.rb +9 -14
- data/lib/site_template/.gitignore +2 -0
- data/lib/site_template/404.html +2 -1
- data/lib/site_template/_config.yml +17 -5
- data/lib/site_template/_posts/0000-00-00-welcome-to-jekyll.markdown.erb +5 -1
- data/lib/theme_template/README.md.erb +1 -3
- data/lib/theme_template/gitignore.erb +1 -0
- data/lib/theme_template/theme.gemspec.erb +1 -4
- data/rubocop/jekyll/assert_equal_literal_actual.rb +150 -0
- data/rubocop/jekyll/no_p_allowed.rb +5 -6
- data/rubocop/jekyll/no_puts_allowed.rb +5 -6
- metadata +149 -37
- data/lib/jekyll/converters/markdown/rdiscount_parser.rb +0 -37
- data/lib/jekyll/converters/markdown/redcarpet_parser.rb +0 -112
- data/lib/jekyll/utils/rouge.rb +0 -22
- /data/lib/site_template/{about.md → about.markdown} +0 -0
- /data/lib/site_template/{index.md → index.markdown} +0 -0
data/lib/jekyll/utils.rb
CHANGED
|
@@ -7,25 +7,17 @@ module Jekyll
|
|
|
7
7
|
autoload :Exec, "jekyll/utils/exec"
|
|
8
8
|
autoload :Internet, "jekyll/utils/internet"
|
|
9
9
|
autoload :Platforms, "jekyll/utils/platforms"
|
|
10
|
-
autoload :Rouge, "jekyll/utils/rouge"
|
|
11
10
|
autoload :ThreadEvent, "jekyll/utils/thread_event"
|
|
12
11
|
autoload :WinTZ, "jekyll/utils/win_tz"
|
|
13
12
|
|
|
14
13
|
# Constants for use in #slugify
|
|
15
14
|
SLUGIFY_MODES = %w(raw default pretty ascii latin).freeze
|
|
16
15
|
SLUGIFY_RAW_REGEXP = Regexp.new('\\s+').freeze
|
|
17
|
-
SLUGIFY_DEFAULT_REGEXP = Regexp.new("[
|
|
18
|
-
SLUGIFY_PRETTY_REGEXP = Regexp.new("[
|
|
16
|
+
SLUGIFY_DEFAULT_REGEXP = Regexp.new("[^\\p{M}\\p{L}\\p{Nd}]+").freeze
|
|
17
|
+
SLUGIFY_PRETTY_REGEXP = Regexp.new("[^\\p{M}\\p{L}\\p{Nd}._~!$&'()+,;=@]+").freeze
|
|
19
18
|
SLUGIFY_ASCII_REGEXP = Regexp.new("[^[A-Za-z0-9]]+").freeze
|
|
20
19
|
|
|
21
|
-
# Takes an indented string and removes the preceding spaces on each line
|
|
22
|
-
|
|
23
|
-
def strip_heredoc(str)
|
|
24
|
-
str.gsub(%r!^[ \t]{#{(str.scan(%r!^[ \t]*(?=\S)!).min || "").size}}!, "")
|
|
25
|
-
end
|
|
26
|
-
|
|
27
20
|
# Takes a slug and turns it into a simple title.
|
|
28
|
-
|
|
29
21
|
def titleize_slug(slug)
|
|
30
22
|
slug.split("-").map!(&:capitalize).join(" ")
|
|
31
23
|
end
|
|
@@ -76,11 +68,14 @@ module Jekyll
|
|
|
76
68
|
#
|
|
77
69
|
# Returns an array
|
|
78
70
|
def pluralized_array_from_hash(hash, singular_key, plural_key)
|
|
79
|
-
[]
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
71
|
+
array = []
|
|
72
|
+
value = value_from_singular_key(hash, singular_key)
|
|
73
|
+
value ||= value_from_plural_key(hash, plural_key)
|
|
74
|
+
|
|
75
|
+
array << value
|
|
76
|
+
array.flatten!
|
|
77
|
+
array.compact!
|
|
78
|
+
array
|
|
84
79
|
end
|
|
85
80
|
|
|
86
81
|
def value_from_singular_key(hash, key)
|
|
@@ -133,7 +128,8 @@ module Jekyll
|
|
|
133
128
|
# Returns the parsed date if successful, throws a FatalException
|
|
134
129
|
# if not
|
|
135
130
|
def parse_date(input, msg = "Input could not be parsed.")
|
|
136
|
-
|
|
131
|
+
@parse_date_cache ||= {}
|
|
132
|
+
@parse_date_cache[input] ||= Time.parse(input).localtime
|
|
137
133
|
rescue ArgumentError
|
|
138
134
|
raise Errors::InvalidDateError, "Invalid date '#{input}': #{msg}"
|
|
139
135
|
end
|
|
@@ -141,21 +137,22 @@ module Jekyll
|
|
|
141
137
|
# Determines whether a given file has
|
|
142
138
|
#
|
|
143
139
|
# Returns true if the YAML front matter is present.
|
|
144
|
-
# rubocop: disable PredicateName
|
|
140
|
+
# rubocop: disable Naming/PredicateName
|
|
145
141
|
def has_yaml_header?(file)
|
|
146
|
-
|
|
142
|
+
File.open(file, "rb", &:readline).match? %r!\A---\s*\r?\n!
|
|
147
143
|
rescue EOFError
|
|
148
144
|
false
|
|
149
145
|
end
|
|
150
146
|
|
|
151
|
-
# Determine whether the given content string contains Liquid Tags or
|
|
147
|
+
# Determine whether the given content string contains Liquid Tags or Variables
|
|
152
148
|
#
|
|
153
149
|
# Returns true is the string contains sequences of `{%` or `{{`
|
|
154
150
|
def has_liquid_construct?(content)
|
|
155
151
|
return false if content.nil? || content.empty?
|
|
152
|
+
|
|
156
153
|
content.include?("{%") || content.include?("{{")
|
|
157
154
|
end
|
|
158
|
-
# rubocop: enable PredicateName
|
|
155
|
+
# rubocop: enable Naming/PredicateName
|
|
159
156
|
|
|
160
157
|
# Slugify a filename or title.
|
|
161
158
|
#
|
|
@@ -219,9 +216,10 @@ module Jekyll
|
|
|
219
216
|
slug = replace_character_sequence_with_hyphen(string, :mode => mode)
|
|
220
217
|
|
|
221
218
|
# Remove leading/trailing hyphen
|
|
222
|
-
slug.gsub!(%r
|
|
219
|
+
slug.gsub!(%r!^-|-$!i, "")
|
|
223
220
|
|
|
224
221
|
slug.downcase! unless cased
|
|
222
|
+
Jekyll.logger.warn("Warning:", "Empty `slug` generated for '#{string}'.") if slug.empty?
|
|
225
223
|
slug
|
|
226
224
|
end
|
|
227
225
|
|
|
@@ -268,7 +266,7 @@ module Jekyll
|
|
|
268
266
|
template
|
|
269
267
|
end
|
|
270
268
|
|
|
271
|
-
# Work the same way as Dir.glob but
|
|
269
|
+
# Work the same way as Dir.glob but separating the input into two parts
|
|
272
270
|
# ('dir' + '/' + 'pattern') to make sure the first part('dir') does not act
|
|
273
271
|
# as a pattern.
|
|
274
272
|
#
|
|
@@ -290,11 +288,13 @@ module Jekyll
|
|
|
290
288
|
# patterns - the patterns (or the pattern) which will be applied under the dir
|
|
291
289
|
# flags - the flags which will be applied to the pattern
|
|
292
290
|
#
|
|
293
|
-
# Returns matched
|
|
291
|
+
# Returns matched paths
|
|
294
292
|
def safe_glob(dir, patterns, flags = 0)
|
|
295
293
|
return [] unless Dir.exist?(dir)
|
|
294
|
+
|
|
296
295
|
pattern = File.join(Array(patterns))
|
|
297
296
|
return [dir] if pattern.empty?
|
|
297
|
+
|
|
298
298
|
Dir.chdir(dir) do
|
|
299
299
|
Dir.glob(pattern, flags).map { |f| File.join(dir, f) }
|
|
300
300
|
end
|
|
@@ -304,16 +304,20 @@ module Jekyll
|
|
|
304
304
|
# and a given param
|
|
305
305
|
def merged_file_read_opts(site, opts)
|
|
306
306
|
merged = (site ? site.file_read_opts : {}).merge(opts)
|
|
307
|
-
|
|
307
|
+
|
|
308
|
+
# always use BOM when reading UTF-encoded files
|
|
309
|
+
if merged[:encoding]&.downcase&.start_with?("utf-")
|
|
308
310
|
merged[:encoding] = "bom|#{merged[:encoding]}"
|
|
309
311
|
end
|
|
310
|
-
if merged["encoding"]
|
|
312
|
+
if merged["encoding"]&.downcase&.start_with?("utf-")
|
|
311
313
|
merged["encoding"] = "bom|#{merged["encoding"]}"
|
|
312
314
|
end
|
|
315
|
+
|
|
313
316
|
merged
|
|
314
317
|
end
|
|
315
318
|
|
|
316
319
|
private
|
|
320
|
+
|
|
317
321
|
def merge_values(target, overwrite)
|
|
318
322
|
target.merge!(overwrite) do |_key, old_val, new_val|
|
|
319
323
|
if new_val.nil?
|
|
@@ -326,14 +330,12 @@ module Jekyll
|
|
|
326
330
|
end
|
|
327
331
|
end
|
|
328
332
|
|
|
329
|
-
private
|
|
330
333
|
def merge_default_proc(target, overwrite)
|
|
331
334
|
if target.is_a?(Hash) && overwrite.is_a?(Hash) && target.default_proc.nil?
|
|
332
335
|
target.default_proc = overwrite.default_proc
|
|
333
336
|
end
|
|
334
337
|
end
|
|
335
338
|
|
|
336
|
-
private
|
|
337
339
|
def duplicate_frozen_values(target)
|
|
338
340
|
target.each do |key, val|
|
|
339
341
|
target[key] = val.dup if val.frozen? && duplicable?(val)
|
|
@@ -344,7 +346,6 @@ module Jekyll
|
|
|
344
346
|
#
|
|
345
347
|
# See Utils#slugify for a description of the character sequence specified
|
|
346
348
|
# by each mode.
|
|
347
|
-
private
|
|
348
349
|
def replace_character_sequence_with_hyphen(string, mode: "default")
|
|
349
350
|
replaceable_char =
|
|
350
351
|
case mode
|
data/lib/jekyll/version.rb
CHANGED
data/lib/jekyll.rb
CHANGED
|
@@ -50,10 +50,13 @@ module Jekyll
|
|
|
50
50
|
autoload :EntryFilter, "jekyll/entry_filter"
|
|
51
51
|
autoload :Errors, "jekyll/errors"
|
|
52
52
|
autoload :Excerpt, "jekyll/excerpt"
|
|
53
|
+
autoload :PageExcerpt, "jekyll/page_excerpt"
|
|
53
54
|
autoload :External, "jekyll/external"
|
|
54
55
|
autoload :FrontmatterDefaults, "jekyll/frontmatter_defaults"
|
|
55
56
|
autoload :Hooks, "jekyll/hooks"
|
|
56
57
|
autoload :Layout, "jekyll/layout"
|
|
58
|
+
autoload :Inclusion, "jekyll/inclusion"
|
|
59
|
+
autoload :Cache, "jekyll/cache"
|
|
57
60
|
autoload :CollectionReader, "jekyll/readers/collection_reader"
|
|
58
61
|
autoload :DataReader, "jekyll/readers/data_reader"
|
|
59
62
|
autoload :LayoutReader, "jekyll/readers/layout_reader"
|
|
@@ -64,8 +67,10 @@ module Jekyll
|
|
|
64
67
|
autoload :LogAdapter, "jekyll/log_adapter"
|
|
65
68
|
autoload :Page, "jekyll/page"
|
|
66
69
|
autoload :PageWithoutAFile, "jekyll/page_without_a_file"
|
|
70
|
+
autoload :PathManager, "jekyll/path_manager"
|
|
67
71
|
autoload :PluginManager, "jekyll/plugin_manager"
|
|
68
72
|
autoload :Publisher, "jekyll/publisher"
|
|
73
|
+
autoload :Profiler, "jekyll/profiler"
|
|
69
74
|
autoload :Reader, "jekyll/reader"
|
|
70
75
|
autoload :Regenerator, "jekyll/regenerator"
|
|
71
76
|
autoload :RelatedPosts, "jekyll/related_posts"
|
|
@@ -143,7 +148,7 @@ module Jekyll
|
|
|
143
148
|
|
|
144
149
|
# Public: Set the log writer.
|
|
145
150
|
# New log writer must respond to the same methods
|
|
146
|
-
# as Ruby's
|
|
151
|
+
# as Ruby's internal Logger.
|
|
147
152
|
#
|
|
148
153
|
# writer - the new Logger-compatible log transport
|
|
149
154
|
#
|
|
@@ -168,23 +173,13 @@ module Jekyll
|
|
|
168
173
|
# Returns the sanitized path.
|
|
169
174
|
def sanitized_path(base_directory, questionable_path)
|
|
170
175
|
return base_directory if base_directory.eql?(questionable_path)
|
|
176
|
+
return base_directory if questionable_path.nil?
|
|
171
177
|
|
|
172
|
-
|
|
173
|
-
clean_path.insert(0, "/") if clean_path.start_with?("~")
|
|
174
|
-
clean_path = File.expand_path(clean_path, "/")
|
|
175
|
-
|
|
176
|
-
return clean_path if clean_path.eql?(base_directory)
|
|
177
|
-
|
|
178
|
-
if clean_path.start_with?(base_directory.sub(%r!\z!, "/"))
|
|
179
|
-
clean_path
|
|
180
|
-
else
|
|
181
|
-
clean_path.sub!(%r!\A\w:/!, "/")
|
|
182
|
-
File.join(base_directory, clean_path)
|
|
183
|
-
end
|
|
178
|
+
+Jekyll::PathManager.sanitized_path(base_directory, questionable_path)
|
|
184
179
|
end
|
|
185
180
|
|
|
186
181
|
# Conditional optimizations
|
|
187
|
-
Jekyll::External.require_if_present("liquid
|
|
182
|
+
Jekyll::External.require_if_present("liquid/c")
|
|
188
183
|
end
|
|
189
184
|
end
|
|
190
185
|
|
data/lib/site_template/404.html
CHANGED
|
@@ -7,12 +7,17 @@
|
|
|
7
7
|
#
|
|
8
8
|
# For technical reasons, this file is *NOT* reloaded automatically when you use
|
|
9
9
|
# 'bundle exec jekyll serve'. If you change this file, please restart the server process.
|
|
10
|
-
|
|
10
|
+
#
|
|
11
|
+
# If you need help with YAML syntax, here are some quick references for you:
|
|
12
|
+
# https://learn-the-web.algonquindesign.ca/topics/markdown-yaml-cheat-sheet/#yaml
|
|
13
|
+
# https://learnxinyminutes.com/docs/yaml/
|
|
14
|
+
#
|
|
11
15
|
# Site settings
|
|
12
16
|
# These are used to personalize your new site. If you look in the HTML files,
|
|
13
17
|
# you will see them accessed via {{ site.title }}, {{ site.email }}, and so on.
|
|
14
18
|
# You can create any custom variable you would like, and they will be accessible
|
|
15
19
|
# in the templates via {{ site.myvariable }}.
|
|
20
|
+
|
|
16
21
|
title: Your awesome title
|
|
17
22
|
email: your-email@example.com
|
|
18
23
|
description: >- # this means to ignore newlines until "baseurl:"
|
|
@@ -25,18 +30,25 @@ twitter_username: jekyllrb
|
|
|
25
30
|
github_username: jekyll
|
|
26
31
|
|
|
27
32
|
# Build settings
|
|
28
|
-
markdown: kramdown
|
|
29
33
|
theme: minima
|
|
30
34
|
plugins:
|
|
31
35
|
- jekyll-feed
|
|
32
36
|
|
|
33
37
|
# Exclude from processing.
|
|
34
|
-
# The following items will not be processed, by default.
|
|
35
|
-
#
|
|
38
|
+
# The following items will not be processed, by default.
|
|
39
|
+
# Any item listed under the `exclude:` key here will be automatically added to
|
|
40
|
+
# the internal "default list".
|
|
41
|
+
#
|
|
42
|
+
# Excluded items can be processed by explicitly listing the directories or
|
|
43
|
+
# their entries' file path in the `include:` list.
|
|
44
|
+
#
|
|
36
45
|
# exclude:
|
|
46
|
+
# - .sass-cache/
|
|
47
|
+
# - .jekyll-cache/
|
|
48
|
+
# - gemfiles/
|
|
37
49
|
# - Gemfile
|
|
38
50
|
# - Gemfile.lock
|
|
39
|
-
# - node_modules
|
|
51
|
+
# - node_modules/
|
|
40
52
|
# - vendor/bundle/
|
|
41
53
|
# - vendor/cache/
|
|
42
54
|
# - vendor/gems/
|
|
@@ -6,7 +6,11 @@ categories: jekyll update
|
|
|
6
6
|
---
|
|
7
7
|
You’ll find this post in your `_posts` directory. Go ahead and edit it and re-build the site to see your changes. You can rebuild the site in many different ways, but the most common way is to run `jekyll serve`, which launches a web server and auto-regenerates your site when a file is updated.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Jekyll requires blog post files to be named according to the following format:
|
|
10
|
+
|
|
11
|
+
`YEAR-MONTH-DAY-title.MARKUP`
|
|
12
|
+
|
|
13
|
+
Where `YEAR` is a four-digit number, `MONTH` and `DAY` are both two-digit numbers, and `MARKUP` is the file extension representing the format used in the file. After that, include the necessary front matter. Take a look at the source for this post to get an idea about how it works.
|
|
10
14
|
|
|
11
15
|
Jekyll also offers powerful support for code snippets:
|
|
12
16
|
|
|
@@ -6,7 +6,6 @@ To experiment with this code, add some sample content and run `bundle exec jekyl
|
|
|
6
6
|
|
|
7
7
|
TODO: Delete this and the text above, and describe your gem
|
|
8
8
|
|
|
9
|
-
|
|
10
9
|
## Installation
|
|
11
10
|
|
|
12
11
|
Add this line to your Jekyll site's `Gemfile`:
|
|
@@ -35,7 +34,7 @@ TODO: Write usage instructions here. Describe your available layouts, includes,
|
|
|
35
34
|
|
|
36
35
|
## Contributing
|
|
37
36
|
|
|
38
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]
|
|
37
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/<%= theme_name %>. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](https://www.contributor-covenant.org/) code of conduct.
|
|
39
38
|
|
|
40
39
|
## Development
|
|
41
40
|
|
|
@@ -49,4 +48,3 @@ To add a custom directory to your theme-gem, please edit the regexp in `<%= them
|
|
|
49
48
|
## License
|
|
50
49
|
|
|
51
50
|
The theme is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
|
52
|
-
|
|
@@ -10,10 +10,7 @@ Gem::Specification.new do |spec|
|
|
|
10
10
|
spec.homepage = "TODO: Put your gem's website or public repo URL here."
|
|
11
11
|
spec.license = "MIT"
|
|
12
12
|
|
|
13
|
-
spec.files = `git ls-files -z`.split("\x0").select { |f| f.match(%r!^(<%= theme_directories.join("|") %>|LICENSE|README)!i) }
|
|
13
|
+
spec.files = `git ls-files -z`.split("\x0").select { |f| f.match(%r!^(<%= theme_directories.join("|") %>|LICENSE|README|_config\.yml)!i) }
|
|
14
14
|
|
|
15
15
|
spec.add_runtime_dependency "jekyll", "~> <%= jekyll_version_with_minor %>"
|
|
16
|
-
|
|
17
|
-
spec.add_development_dependency "bundler", "~> 1.16"
|
|
18
|
-
spec.add_development_dependency "rake", "~> 12.0"
|
|
19
16
|
end
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module Jekyll
|
|
6
|
+
# Checks for `assert_equal(exp, act, msg = nil)` calls containing literal values as
|
|
7
|
+
# second argument. The second argument should ideally be a method called on the tested
|
|
8
|
+
# instance.
|
|
9
|
+
#
|
|
10
|
+
# @example
|
|
11
|
+
# # bad
|
|
12
|
+
# assert_equal @foo.bar, "foobar"
|
|
13
|
+
# assert_equal @alpha.beta, { "foo" => "bar", "lorem" => "ipsum" }
|
|
14
|
+
# assert_equal @alpha.omega, ["foobar", "lipsum"]
|
|
15
|
+
#
|
|
16
|
+
# # good
|
|
17
|
+
# assert_equal "foobar", @foo.bar
|
|
18
|
+
#
|
|
19
|
+
# assert_equal(
|
|
20
|
+
# { "foo" => "bar", "lorem" => "ipsum" },
|
|
21
|
+
# @alpha.beta
|
|
22
|
+
# )
|
|
23
|
+
#
|
|
24
|
+
# assert_equal(
|
|
25
|
+
# ["foobar", "lipsum"],
|
|
26
|
+
# @alpha.omega
|
|
27
|
+
# )
|
|
28
|
+
#
|
|
29
|
+
class AssertEqualLiteralActual < Base
|
|
30
|
+
extend AutoCorrector
|
|
31
|
+
|
|
32
|
+
MSG = "Provide the 'expected value' as the first argument to `assert_equal`."
|
|
33
|
+
RESTRICT_ON_SEND = %i[assert_equal].freeze
|
|
34
|
+
|
|
35
|
+
SIMPLE_LITERALS = %i(
|
|
36
|
+
true
|
|
37
|
+
false
|
|
38
|
+
nil
|
|
39
|
+
int
|
|
40
|
+
float
|
|
41
|
+
str
|
|
42
|
+
sym
|
|
43
|
+
complex
|
|
44
|
+
rational
|
|
45
|
+
regopt
|
|
46
|
+
).freeze
|
|
47
|
+
|
|
48
|
+
COMPLEX_LITERALS = %i(
|
|
49
|
+
array
|
|
50
|
+
hash
|
|
51
|
+
pair
|
|
52
|
+
irange
|
|
53
|
+
erange
|
|
54
|
+
regexp
|
|
55
|
+
).freeze
|
|
56
|
+
|
|
57
|
+
def_node_matcher :literal_actual?, <<-PATTERN
|
|
58
|
+
(send nil? :assert_equal $(send ...) $#literal?)
|
|
59
|
+
PATTERN
|
|
60
|
+
|
|
61
|
+
def_node_matcher :literal_actual_with_msg?, <<-PATTERN
|
|
62
|
+
(send nil? :assert_equal $(send ...) $#literal? $#opt_msg?)
|
|
63
|
+
PATTERN
|
|
64
|
+
|
|
65
|
+
def on_send(node)
|
|
66
|
+
return unless literal_actual?(node) || literal_actual_with_msg?(node)
|
|
67
|
+
|
|
68
|
+
range = node.loc.expression
|
|
69
|
+
add_offense(range) do |corrector|
|
|
70
|
+
corrector.replace(range, replacement(node))
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
private
|
|
75
|
+
|
|
76
|
+
def opt_msg?(node)
|
|
77
|
+
node&.source
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# This is not implement using a NodePattern because it seems
|
|
81
|
+
# to not be able to match against an explicit (nil) sexp
|
|
82
|
+
def literal?(node)
|
|
83
|
+
node && (simple_literal?(node) || complex_literal?(node))
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def simple_literal?(node)
|
|
87
|
+
SIMPLE_LITERALS.include?(node.type)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def complex_literal?(node)
|
|
91
|
+
COMPLEX_LITERALS.include?(node.type) &&
|
|
92
|
+
node.each_child_node.all?(&method(:literal?))
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def replacement(node)
|
|
96
|
+
_, _, first_param, second_param, optional_param = *node
|
|
97
|
+
|
|
98
|
+
replaced_text = \
|
|
99
|
+
if second_param.type == :hash
|
|
100
|
+
replace_hash_with_variable(first_param.source, second_param.source)
|
|
101
|
+
elsif second_param.type == :array && second_param.source != "[]"
|
|
102
|
+
replace_array_with_variable(first_param.source, second_param.source)
|
|
103
|
+
else
|
|
104
|
+
replace_based_on_line_length(first_param.source, second_param.source)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
return "#{replaced_text}, #{optional_param.source}" if optional_param
|
|
108
|
+
replaced_text
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def replace_based_on_line_length(first_expression, second_expression)
|
|
112
|
+
result = "assert_equal #{second_expression}, #{first_expression}"
|
|
113
|
+
return result if result.length < 80
|
|
114
|
+
|
|
115
|
+
# fold long lines independent of Rubocop configuration for better readability
|
|
116
|
+
<<~TEXT
|
|
117
|
+
assert_equal(
|
|
118
|
+
#{second_expression},
|
|
119
|
+
#{first_expression}
|
|
120
|
+
)
|
|
121
|
+
TEXT
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def replace_hash_with_variable(first_expression, second_expression)
|
|
125
|
+
expect_expression = if second_expression.start_with?("{")
|
|
126
|
+
second_expression
|
|
127
|
+
else
|
|
128
|
+
"{#{second_expression}}"
|
|
129
|
+
end
|
|
130
|
+
<<~TEXT
|
|
131
|
+
expected = #{expect_expression}
|
|
132
|
+
assert_equal expected, #{first_expression}
|
|
133
|
+
TEXT
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def replace_array_with_variable(first_expression, second_expression)
|
|
137
|
+
expect_expression = if second_expression.start_with?("%")
|
|
138
|
+
second_expression
|
|
139
|
+
else
|
|
140
|
+
Array(second_expression)
|
|
141
|
+
end
|
|
142
|
+
<<~TEXT
|
|
143
|
+
expected = #{expect_expression}
|
|
144
|
+
assert_equal expected, #{first_expression}
|
|
145
|
+
TEXT
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
end
|
|
@@ -1,20 +1,19 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "rubocop"
|
|
4
|
-
|
|
5
3
|
module RuboCop
|
|
6
4
|
module Cop
|
|
7
5
|
module Jekyll
|
|
8
|
-
class NoPAllowed <
|
|
9
|
-
MSG = "Avoid using `p` to print things. Use `Jekyll.logger` instead."
|
|
6
|
+
class NoPAllowed < Base
|
|
7
|
+
MSG = "Avoid using `p` to print things. Use `Jekyll.logger` instead."
|
|
8
|
+
RESTRICT_ON_SEND = %i[p].freeze
|
|
10
9
|
|
|
11
10
|
def_node_search :p_called?, <<-PATTERN
|
|
12
|
-
|
|
11
|
+
(send _ :p _)
|
|
13
12
|
PATTERN
|
|
14
13
|
|
|
15
14
|
def on_send(node)
|
|
16
15
|
if p_called?(node)
|
|
17
|
-
add_offense(node
|
|
16
|
+
add_offense(node.loc.selector)
|
|
18
17
|
end
|
|
19
18
|
end
|
|
20
19
|
end
|
|
@@ -1,20 +1,19 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "rubocop"
|
|
4
|
-
|
|
5
3
|
module RuboCop
|
|
6
4
|
module Cop
|
|
7
5
|
module Jekyll
|
|
8
|
-
class NoPutsAllowed <
|
|
9
|
-
MSG = "Avoid using `puts` to print things. Use `Jekyll.logger` instead."
|
|
6
|
+
class NoPutsAllowed < Base
|
|
7
|
+
MSG = "Avoid using `puts` to print things. Use `Jekyll.logger` instead."
|
|
8
|
+
RESTRICT_ON_SEND = %i[puts].freeze
|
|
10
9
|
|
|
11
10
|
def_node_search :puts_called?, <<-PATTERN
|
|
12
|
-
|
|
11
|
+
(send nil? :puts _)
|
|
13
12
|
PATTERN
|
|
14
13
|
|
|
15
14
|
def on_send(node)
|
|
16
15
|
if puts_called?(node)
|
|
17
|
-
add_offense(node
|
|
16
|
+
add_offense(node.loc.selector)
|
|
18
17
|
end
|
|
19
18
|
end
|
|
20
19
|
end
|