jekyll 4.2.1 → 4.3.2

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 (126) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +474 -350
  3. data/LICENSE +21 -21
  4. data/README.markdown +83 -86
  5. data/exe/jekyll +57 -57
  6. data/lib/blank_template/_config.yml +3 -3
  7. data/lib/blank_template/_layouts/default.html +12 -12
  8. data/lib/blank_template/_sass/{main.scss → base.scss} +9 -9
  9. data/lib/blank_template/assets/css/main.scss +4 -4
  10. data/lib/blank_template/index.md +8 -8
  11. data/lib/jekyll/cache.rb +186 -190
  12. data/lib/jekyll/cleaner.rb +111 -111
  13. data/lib/jekyll/collection.rb +310 -309
  14. data/lib/jekyll/command.rb +105 -105
  15. data/lib/jekyll/commands/build.rb +82 -93
  16. data/lib/jekyll/commands/clean.rb +44 -45
  17. data/lib/jekyll/commands/doctor.rb +177 -177
  18. data/lib/jekyll/commands/help.rb +34 -34
  19. data/lib/jekyll/commands/new.rb +168 -169
  20. data/lib/jekyll/commands/new_theme.rb +39 -40
  21. data/lib/jekyll/commands/serve/live_reload_reactor.rb +119 -122
  22. data/lib/jekyll/commands/serve/livereload_assets/livereload.js +1183 -1183
  23. data/lib/jekyll/commands/serve/mime_types_charset.json +71 -0
  24. data/lib/jekyll/commands/serve/servlet.rb +206 -202
  25. data/lib/jekyll/commands/serve/websockets.rb +81 -81
  26. data/lib/jekyll/commands/serve.rb +367 -362
  27. data/lib/jekyll/configuration.rb +313 -313
  28. data/lib/jekyll/converter.rb +54 -54
  29. data/lib/jekyll/converters/identity.rb +41 -41
  30. data/lib/jekyll/converters/markdown/kramdown_parser.rb +197 -199
  31. data/lib/jekyll/converters/markdown.rb +113 -113
  32. data/lib/jekyll/converters/smartypants.rb +70 -70
  33. data/lib/jekyll/convertible.rb +257 -257
  34. data/lib/jekyll/deprecator.rb +50 -50
  35. data/lib/jekyll/document.rb +543 -544
  36. data/lib/jekyll/drops/collection_drop.rb +20 -20
  37. data/lib/jekyll/drops/document_drop.rb +74 -70
  38. data/lib/jekyll/drops/drop.rb +293 -293
  39. data/lib/jekyll/drops/excerpt_drop.rb +23 -19
  40. data/lib/jekyll/drops/jekyll_drop.rb +32 -32
  41. data/lib/jekyll/drops/site_drop.rb +66 -66
  42. data/lib/jekyll/drops/static_file_drop.rb +14 -14
  43. data/lib/jekyll/drops/theme_drop.rb +36 -0
  44. data/lib/jekyll/drops/unified_payload_drop.rb +30 -26
  45. data/lib/jekyll/drops/url_drop.rb +140 -140
  46. data/lib/jekyll/entry_filter.rb +117 -121
  47. data/lib/jekyll/errors.rb +20 -20
  48. data/lib/jekyll/excerpt.rb +200 -201
  49. data/lib/jekyll/external.rb +75 -79
  50. data/lib/jekyll/filters/date_filters.rb +110 -110
  51. data/lib/jekyll/filters/grouping_filters.rb +64 -64
  52. data/lib/jekyll/filters/url_filters.rb +98 -98
  53. data/lib/jekyll/filters.rb +532 -535
  54. data/lib/jekyll/frontmatter_defaults.rb +238 -240
  55. data/lib/jekyll/generator.rb +5 -5
  56. data/lib/jekyll/hooks.rb +107 -107
  57. data/lib/jekyll/inclusion.rb +32 -32
  58. data/lib/jekyll/layout.rb +55 -67
  59. data/lib/jekyll/liquid_extensions.rb +22 -22
  60. data/lib/jekyll/liquid_renderer/file.rb +77 -77
  61. data/lib/jekyll/liquid_renderer/table.rb +45 -55
  62. data/lib/jekyll/liquid_renderer.rb +80 -80
  63. data/lib/jekyll/log_adapter.rb +151 -151
  64. data/lib/jekyll/mime.types +939 -866
  65. data/lib/jekyll/page.rb +215 -217
  66. data/lib/jekyll/page_excerpt.rb +25 -25
  67. data/lib/jekyll/page_without_a_file.rb +14 -14
  68. data/lib/jekyll/path_manager.rb +74 -74
  69. data/lib/jekyll/plugin.rb +92 -92
  70. data/lib/jekyll/plugin_manager.rb +123 -115
  71. data/lib/jekyll/profiler.rb +51 -58
  72. data/lib/jekyll/publisher.rb +23 -23
  73. data/lib/jekyll/reader.rb +209 -192
  74. data/lib/jekyll/readers/collection_reader.rb +23 -23
  75. data/lib/jekyll/readers/data_reader.rb +113 -79
  76. data/lib/jekyll/readers/layout_reader.rb +62 -62
  77. data/lib/jekyll/readers/page_reader.rb +25 -25
  78. data/lib/jekyll/readers/post_reader.rb +85 -85
  79. data/lib/jekyll/readers/static_file_reader.rb +25 -25
  80. data/lib/jekyll/readers/theme_assets_reader.rb +52 -52
  81. data/lib/jekyll/regenerator.rb +195 -195
  82. data/lib/jekyll/related_posts.rb +52 -52
  83. data/lib/jekyll/renderer.rb +263 -265
  84. data/lib/jekyll/site.rb +576 -551
  85. data/lib/jekyll/static_file.rb +205 -208
  86. data/lib/jekyll/stevenson.rb +60 -60
  87. data/lib/jekyll/tags/highlight.rb +114 -110
  88. data/lib/jekyll/tags/include.rb +275 -275
  89. data/lib/jekyll/tags/link.rb +42 -42
  90. data/lib/jekyll/tags/post_url.rb +106 -106
  91. data/lib/jekyll/theme.rb +90 -86
  92. data/lib/jekyll/theme_builder.rb +121 -121
  93. data/lib/jekyll/url.rb +167 -167
  94. data/lib/jekyll/utils/ansi.rb +57 -57
  95. data/lib/jekyll/utils/exec.rb +26 -26
  96. data/lib/jekyll/utils/internet.rb +37 -37
  97. data/lib/jekyll/utils/platforms.rb +67 -67
  98. data/lib/jekyll/utils/thread_event.rb +31 -31
  99. data/lib/jekyll/utils/win_tz.rb +46 -75
  100. data/lib/jekyll/utils.rb +371 -367
  101. data/lib/jekyll/version.rb +5 -5
  102. data/lib/jekyll.rb +195 -195
  103. data/lib/site_template/.gitignore +5 -5
  104. data/lib/site_template/404.html +25 -25
  105. data/lib/site_template/_config.yml +55 -55
  106. data/lib/site_template/_posts/0000-00-00-welcome-to-jekyll.markdown.erb +29 -29
  107. data/lib/site_template/about.markdown +18 -18
  108. data/lib/site_template/index.markdown +6 -6
  109. data/lib/theme_template/CODE_OF_CONDUCT.md.erb +74 -74
  110. data/lib/theme_template/Gemfile +4 -4
  111. data/lib/theme_template/LICENSE.txt.erb +21 -21
  112. data/lib/theme_template/README.md.erb +50 -52
  113. data/lib/theme_template/_layouts/default.html +1 -1
  114. data/lib/theme_template/_layouts/page.html +5 -5
  115. data/lib/theme_template/_layouts/post.html +5 -5
  116. data/lib/theme_template/example/_config.yml.erb +1 -1
  117. data/lib/theme_template/example/_post.md +12 -12
  118. data/lib/theme_template/example/index.html +14 -14
  119. data/lib/theme_template/example/style.scss +7 -7
  120. data/lib/theme_template/gitignore.erb +6 -6
  121. data/lib/theme_template/theme.gemspec.erb +16 -16
  122. data/rubocop/jekyll/assert_equal_literal_actual.rb +149 -149
  123. data/rubocop/jekyll/no_p_allowed.rb +23 -23
  124. data/rubocop/jekyll/no_puts_allowed.rb +23 -23
  125. data/rubocop/jekyll.rb +5 -5
  126. metadata +64 -18
data/lib/jekyll/url.rb CHANGED
@@ -1,167 +1,167 @@
1
- # frozen_string_literal: true
2
-
3
- # Public: Methods that generate a URL for a resource such as a Post or a Page.
4
- #
5
- # Examples
6
- #
7
- # URL.new({
8
- # :template => /:categories/:title.html",
9
- # :placeholders => {:categories => "ruby", :title => "something"}
10
- # }).to_s
11
- #
12
- module Jekyll
13
- class URL
14
- # options - One of :permalink or :template must be supplied.
15
- # :template - The String used as template for URL generation,
16
- # for example "/:path/:basename:output_ext", where
17
- # a placeholder is prefixed with a colon.
18
- # :placeholders - A hash containing the placeholders which will be
19
- # replaced when used inside the template. E.g.
20
- # { "year" => Time.now.strftime("%Y") } would replace
21
- # the placeholder ":year" with the current year.
22
- # :permalink - If supplied, no URL will be generated from the
23
- # template. Instead, the given permalink will be
24
- # used as URL.
25
- def initialize(options)
26
- @template = options[:template]
27
- @placeholders = options[:placeholders] || {}
28
- @permalink = options[:permalink]
29
-
30
- if (@template || @permalink).nil?
31
- raise ArgumentError, "One of :template or :permalink must be supplied."
32
- end
33
- end
34
-
35
- # The generated relative URL of the resource
36
- #
37
- # Returns the String URL
38
- def to_s
39
- sanitize_url(generated_permalink || generated_url)
40
- end
41
-
42
- # Generates a URL from the permalink
43
- #
44
- # Returns the _unsanitized String URL
45
- def generated_permalink
46
- (@generated_permalink ||= generate_url(@permalink)) if @permalink
47
- end
48
-
49
- # Generates a URL from the template
50
- #
51
- # Returns the unsanitized String URL
52
- def generated_url
53
- @generated_url ||= generate_url(@template)
54
- end
55
-
56
- # Internal: Generate the URL by replacing all placeholders with their
57
- # respective values in the given template
58
- #
59
- # Returns the unsanitized String URL
60
- def generate_url(template)
61
- if @placeholders.is_a? Drops::UrlDrop
62
- generate_url_from_drop(template)
63
- else
64
- generate_url_from_hash(template)
65
- end
66
- end
67
-
68
- def generate_url_from_hash(template)
69
- @placeholders.inject(template) do |result, token|
70
- break result if result.index(":").nil?
71
-
72
- if token.last.nil?
73
- # Remove leading "/" to avoid generating urls with `//`
74
- result.gsub("/:#{token.first}", "")
75
- else
76
- result.gsub(":#{token.first}", self.class.escape_path(token.last))
77
- end
78
- end
79
- end
80
-
81
- # We include underscores in keys to allow for 'i_month' and so forth.
82
- # This poses a problem for keys which are followed by an underscore
83
- # but the underscore is not part of the key, e.g. '/:month_:day'.
84
- # That should be :month and :day, but our key extraction regexp isn't
85
- # smart enough to know that so we have to make it an explicit
86
- # possibility.
87
- def possible_keys(key)
88
- if key.end_with?("_")
89
- [key, key.chomp("_")]
90
- else
91
- [key]
92
- end
93
- end
94
-
95
- def generate_url_from_drop(template)
96
- template.gsub(%r!:([a-z_]+)!) do |match|
97
- name = Regexp.last_match(1)
98
- pool = name.end_with?("_") ? [name, name.chomp!("_")] : [name]
99
-
100
- winner = pool.find { |key| @placeholders.key?(key) }
101
- if winner.nil?
102
- raise NoMethodError,
103
- "The URL template doesn't have #{pool.join(" or ")} keys. "\
104
- "Check your permalink template!"
105
- end
106
-
107
- value = @placeholders[winner]
108
- value = "" if value.nil?
109
- replacement = self.class.escape_path(value)
110
-
111
- match.sub!(":#{winner}", replacement)
112
- end
113
- end
114
-
115
- # Returns a sanitized String URL, stripping "../../" and multiples of "/",
116
- # as well as the beginning "/" so we can enforce and ensure it.
117
- def sanitize_url(str)
118
- "/#{str}".gsub("..", "/").tap do |result|
119
- result.gsub!("./", "")
120
- result.squeeze!("/")
121
- end
122
- end
123
-
124
- # Escapes a path to be a valid URL path segment
125
- #
126
- # path - The path to be escaped.
127
- #
128
- # Examples:
129
- #
130
- # URL.escape_path("/a b")
131
- # # => "/a%20b"
132
- #
133
- # Returns the escaped path.
134
- def self.escape_path(path)
135
- return path if path.empty? || %r!^[a-zA-Z0-9./-]+$!.match?(path)
136
-
137
- # Because URI.escape doesn't escape "?", "[" and "]" by default,
138
- # specify unsafe string (except unreserved, sub-delims, ":", "@" and "/").
139
- #
140
- # URI path segment is defined in RFC 3986 as follows:
141
- # segment = *pchar
142
- # pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
143
- # unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
144
- # pct-encoded = "%" HEXDIG HEXDIG
145
- # sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
146
- # / "*" / "+" / "," / ";" / "="
147
- Addressable::URI.encode(path).encode("utf-8").sub("#", "%23")
148
- end
149
-
150
- # Unescapes a URL path segment
151
- #
152
- # path - The path to be unescaped.
153
- #
154
- # Examples:
155
- #
156
- # URL.unescape_path("/a%20b")
157
- # # => "/a b"
158
- #
159
- # Returns the unescaped path.
160
- def self.unescape_path(path)
161
- path = path.encode("utf-8")
162
- return path unless path.include?("%")
163
-
164
- Addressable::URI.unencode(path)
165
- end
166
- end
167
- end
1
+ # frozen_string_literal: true
2
+
3
+ # Public: Methods that generate a URL for a resource such as a Post or a Page.
4
+ #
5
+ # Examples
6
+ #
7
+ # URL.new({
8
+ # :template => /:categories/:title.html",
9
+ # :placeholders => {:categories => "ruby", :title => "something"}
10
+ # }).to_s
11
+ #
12
+ module Jekyll
13
+ class URL
14
+ # options - One of :permalink or :template must be supplied.
15
+ # :template - The String used as template for URL generation,
16
+ # for example "/:path/:basename:output_ext", where
17
+ # a placeholder is prefixed with a colon.
18
+ # :placeholders - A hash containing the placeholders which will be
19
+ # replaced when used inside the template. E.g.
20
+ # { "year" => Time.now.strftime("%Y") } would replace
21
+ # the placeholder ":year" with the current year.
22
+ # :permalink - If supplied, no URL will be generated from the
23
+ # template. Instead, the given permalink will be
24
+ # used as URL.
25
+ def initialize(options)
26
+ @template = options[:template]
27
+ @placeholders = options[:placeholders] || {}
28
+ @permalink = options[:permalink]
29
+
30
+ if (@template || @permalink).nil?
31
+ raise ArgumentError, "One of :template or :permalink must be supplied."
32
+ end
33
+ end
34
+
35
+ # The generated relative URL of the resource
36
+ #
37
+ # Returns the String URL
38
+ def to_s
39
+ sanitize_url(generated_permalink || generated_url)
40
+ end
41
+
42
+ # Generates a URL from the permalink
43
+ #
44
+ # Returns the _unsanitized String URL
45
+ def generated_permalink
46
+ (@generated_permalink ||= generate_url(@permalink)) if @permalink
47
+ end
48
+
49
+ # Generates a URL from the template
50
+ #
51
+ # Returns the unsanitized String URL
52
+ def generated_url
53
+ @generated_url ||= generate_url(@template)
54
+ end
55
+
56
+ # Internal: Generate the URL by replacing all placeholders with their
57
+ # respective values in the given template
58
+ #
59
+ # Returns the unsanitized String URL
60
+ def generate_url(template)
61
+ if @placeholders.is_a? Drops::UrlDrop
62
+ generate_url_from_drop(template)
63
+ else
64
+ generate_url_from_hash(template)
65
+ end
66
+ end
67
+
68
+ def generate_url_from_hash(template)
69
+ @placeholders.inject(template) do |result, token|
70
+ break result if result.index(":").nil?
71
+
72
+ if token.last.nil?
73
+ # Remove leading "/" to avoid generating urls with `//`
74
+ result.gsub("/:#{token.first}", "")
75
+ else
76
+ result.gsub(":#{token.first}", self.class.escape_path(token.last))
77
+ end
78
+ end
79
+ end
80
+
81
+ # We include underscores in keys to allow for 'i_month' and so forth.
82
+ # This poses a problem for keys which are followed by an underscore
83
+ # but the underscore is not part of the key, e.g. '/:month_:day'.
84
+ # That should be :month and :day, but our key extraction regexp isn't
85
+ # smart enough to know that so we have to make it an explicit
86
+ # possibility.
87
+ def possible_keys(key)
88
+ if key.end_with?("_")
89
+ [key, key.chomp("_")]
90
+ else
91
+ [key]
92
+ end
93
+ end
94
+
95
+ def generate_url_from_drop(template)
96
+ template.gsub(%r!:([a-z_]+)!) do |match|
97
+ name = Regexp.last_match(1)
98
+ pool = name.end_with?("_") ? [name, name.chomp!("_")] : [name]
99
+
100
+ winner = pool.find { |key| @placeholders.key?(key) }
101
+ if winner.nil?
102
+ raise NoMethodError,
103
+ "The URL template doesn't have #{pool.join(" or ")} keys. " \
104
+ "Check your permalink template!"
105
+ end
106
+
107
+ value = @placeholders[winner]
108
+ value = "" if value.nil?
109
+ replacement = self.class.escape_path(value)
110
+
111
+ match.sub!(":#{winner}", replacement)
112
+ end
113
+ end
114
+
115
+ # Returns a sanitized String URL, stripping "../../" and multiples of "/",
116
+ # as well as the beginning "/" so we can enforce and ensure it.
117
+ def sanitize_url(str)
118
+ "/#{str}".gsub("..", "/").tap do |result|
119
+ result.gsub!("./", "")
120
+ result.squeeze!("/")
121
+ end
122
+ end
123
+
124
+ # Escapes a path to be a valid URL path segment
125
+ #
126
+ # path - The path to be escaped.
127
+ #
128
+ # Examples:
129
+ #
130
+ # URL.escape_path("/a b")
131
+ # # => "/a%20b"
132
+ #
133
+ # Returns the escaped path.
134
+ def self.escape_path(path)
135
+ return path if path.empty? || %r!^[a-zA-Z0-9./-]+$!.match?(path)
136
+
137
+ # Because URI.escape doesn't escape "?", "[" and "]" by default,
138
+ # specify unsafe string (except unreserved, sub-delims, ":", "@" and "/").
139
+ #
140
+ # URI path segment is defined in RFC 3986 as follows:
141
+ # segment = *pchar
142
+ # pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
143
+ # unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
144
+ # pct-encoded = "%" HEXDIG HEXDIG
145
+ # sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
146
+ # / "*" / "+" / "," / ";" / "="
147
+ Addressable::URI.encode(path).encode("utf-8").sub("#", "%23")
148
+ end
149
+
150
+ # Unescapes a URL path segment
151
+ #
152
+ # path - The path to be unescaped.
153
+ #
154
+ # Examples:
155
+ #
156
+ # URL.unescape_path("/a%20b")
157
+ # # => "/a b"
158
+ #
159
+ # Returns the unescaped path.
160
+ def self.unescape_path(path)
161
+ path = path.encode("utf-8")
162
+ return path unless path.include?("%")
163
+
164
+ Addressable::URI.unencode(path)
165
+ end
166
+ end
167
+ end
@@ -1,57 +1,57 @@
1
- # Frozen-string-literal: true
2
-
3
- module Jekyll
4
- module Utils
5
- module Ansi
6
- extend self
7
-
8
- ESCAPE = format("%c", 27)
9
- MATCH = %r!#{ESCAPE}\[(?:\d+)(?:;\d+)*(j|k|m|s|u|A|B|G)|\e\(B\e\[m!ix.freeze
10
- COLORS = {
11
- :red => 31,
12
- :green => 32,
13
- :black => 30,
14
- :magenta => 35,
15
- :yellow => 33,
16
- :white => 37,
17
- :blue => 34,
18
- :cyan => 36,
19
- }.freeze
20
-
21
- # Strip ANSI from the current string. It also strips cursor stuff,
22
- # well some of it, and it also strips some other stuff that a lot of
23
- # the other ANSI strippers don't.
24
-
25
- def strip(str)
26
- str.gsub MATCH, ""
27
- end
28
-
29
- #
30
-
31
- def has?(str)
32
- !!(str =~ MATCH)
33
- end
34
-
35
- # Reset the color back to the default color so that you do not leak any
36
- # colors when you move onto the next line. This is probably normally
37
- # used as part of a wrapper so that we don't leak colors.
38
-
39
- def reset(str = "")
40
- @ansi_reset ||= format("%c[0m", 27)
41
- "#{@ansi_reset}#{str}"
42
- end
43
-
44
- # SEE: `self::COLORS` for a list of methods. They are mostly
45
- # standard base colors supported by pretty much any xterm-color, we do
46
- # not need more than the base colors so we do not include them.
47
- # Actually... if I'm honest we don't even need most of the
48
- # base colors.
49
-
50
- COLORS.each do |color, num|
51
- define_method color do |str|
52
- "#{format("%c", 27)}[#{num}m#{str}#{reset}"
53
- end
54
- end
55
- end
56
- end
57
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Jekyll
4
+ module Utils
5
+ module Ansi
6
+ extend self
7
+
8
+ ESCAPE = format("%c", 27)
9
+ MATCH = %r!#{ESCAPE}\[(?:\d+)(?:;\d+)*(j|k|m|s|u|A|B|G)|\e\(B\e\[m!ix.freeze
10
+ COLORS = {
11
+ :red => 31,
12
+ :green => 32,
13
+ :black => 30,
14
+ :magenta => 35,
15
+ :yellow => 33,
16
+ :white => 37,
17
+ :blue => 34,
18
+ :cyan => 36,
19
+ }.freeze
20
+
21
+ # Strip ANSI from the current string. It also strips cursor stuff,
22
+ # well some of it, and it also strips some other stuff that a lot of
23
+ # the other ANSI strippers don't.
24
+
25
+ def strip(str)
26
+ str.gsub MATCH, ""
27
+ end
28
+
29
+ #
30
+
31
+ def has?(str)
32
+ !!(str =~ MATCH)
33
+ end
34
+
35
+ # Reset the color back to the default color so that you do not leak any
36
+ # colors when you move onto the next line. This is probably normally
37
+ # used as part of a wrapper so that we don't leak colors.
38
+
39
+ def reset(str = "")
40
+ @ansi_reset ||= format("%c[0m", 27)
41
+ "#{@ansi_reset}#{str}"
42
+ end
43
+
44
+ # SEE: `self::COLORS` for a list of methods. They are mostly
45
+ # standard base colors supported by pretty much any xterm-color, we do
46
+ # not need more than the base colors so we do not include them.
47
+ # Actually... if I'm honest we don't even need most of the
48
+ # base colors.
49
+
50
+ COLORS.each do |color, num|
51
+ define_method color do |str|
52
+ "#{format("%c", 27)}[#{num}m#{str}#{reset}"
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -1,26 +1,26 @@
1
- # frozen_string_literal: true
2
-
3
- require "open3"
4
-
5
- module Jekyll
6
- module Utils
7
- module Exec
8
- extend self
9
-
10
- # Runs a program in a sub-shell.
11
- #
12
- # *args - a list of strings containing the program name and arguments
13
- #
14
- # Returns a Process::Status and a String of output in an array in
15
- # that order.
16
- def run(*args)
17
- stdin, stdout, stderr, process = Open3.popen3(*args)
18
- out = stdout.read.strip
19
- err = stderr.read.strip
20
-
21
- [stdin, stdout, stderr].each(&:close)
22
- [process.value, out + err]
23
- end
24
- end
25
- end
26
- end
1
+ # frozen_string_literal: true
2
+
3
+ require "open3"
4
+
5
+ module Jekyll
6
+ module Utils
7
+ module Exec
8
+ extend self
9
+
10
+ # Runs a program in a sub-shell.
11
+ #
12
+ # *args - a list of strings containing the program name and arguments
13
+ #
14
+ # Returns a Process::Status and a String of output in an array in
15
+ # that order.
16
+ def run(*args)
17
+ stdin, stdout, stderr, process = Open3.popen3(*args)
18
+ out = stdout.read.strip
19
+ err = stderr.read.strip
20
+
21
+ [stdin, stdout, stderr].each(&:close)
22
+ [process.value, out + err]
23
+ end
24
+ end
25
+ end
26
+ end
@@ -1,37 +1,37 @@
1
- # frozen_string_literal: true
2
-
3
- module Jekyll
4
- module Utils
5
- module Internet
6
- # Public: Determine whether the present device has a connection to
7
- # the Internet. This allows plugin writers which require the outside
8
- # world to have a neat fallback mechanism for offline building.
9
- #
10
- # Example:
11
- # if Internet.connected?
12
- # Typhoeus.get("https://pages.github.com/versions.json")
13
- # else
14
- # Jekyll.logger.warn "Warning:", "Version check has been disabled."
15
- # Jekyll.logger.warn "", "Connect to the Internet to enable it."
16
- # nil
17
- # end
18
- #
19
- # Returns true if a DNS call can successfully be made, or false if not.
20
-
21
- module_function
22
-
23
- def connected?
24
- !dns("example.com").nil?
25
- end
26
-
27
- def dns(domain)
28
- require "resolv"
29
- Resolv::DNS.open do |resolver|
30
- resolver.getaddress(domain)
31
- end
32
- rescue Resolv::ResolvError, Resolv::ResolvTimeout
33
- nil
34
- end
35
- end
36
- end
37
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Jekyll
4
+ module Utils
5
+ module Internet
6
+ # Public: Determine whether the present device has a connection to
7
+ # the Internet. This allows plugin writers which require the outside
8
+ # world to have a neat fallback mechanism for offline building.
9
+ #
10
+ # Example:
11
+ # if Internet.connected?
12
+ # Typhoeus.get("https://pages.github.com/versions.json")
13
+ # else
14
+ # Jekyll.logger.warn "Warning:", "Version check has been disabled."
15
+ # Jekyll.logger.warn "", "Connect to the Internet to enable it."
16
+ # nil
17
+ # end
18
+ #
19
+ # Returns true if a DNS call can successfully be made, or false if not.
20
+
21
+ module_function
22
+
23
+ def connected?
24
+ !dns("example.com").nil?
25
+ end
26
+
27
+ def dns(domain)
28
+ require "resolv"
29
+ Resolv::DNS.open do |resolver|
30
+ resolver.getaddress(domain)
31
+ end
32
+ rescue Resolv::ResolvError, Resolv::ResolvTimeout
33
+ nil
34
+ end
35
+ end
36
+ end
37
+ end