bridgetown-core 0.7.0 → 0.7.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +42 -0
  3. data/bridgetown-core.gemspec +46 -0
  4. data/lib/bridgetown-core.rb +202 -0
  5. data/lib/bridgetown-core/cache.rb +190 -0
  6. data/lib/bridgetown-core/cleaner.rb +111 -0
  7. data/lib/bridgetown-core/collection.rb +279 -0
  8. data/lib/bridgetown-core/command.rb +106 -0
  9. data/lib/bridgetown-core/commands/build.rb +96 -0
  10. data/lib/bridgetown-core/commands/clean.rb +43 -0
  11. data/lib/bridgetown-core/commands/console.rb +56 -0
  12. data/lib/bridgetown-core/commands/doctor.rb +172 -0
  13. data/lib/bridgetown-core/commands/help.rb +34 -0
  14. data/lib/bridgetown-core/commands/new.rb +148 -0
  15. data/lib/bridgetown-core/commands/serve.rb +273 -0
  16. data/lib/bridgetown-core/commands/serve/servlet.rb +68 -0
  17. data/lib/bridgetown-core/configuration.rb +323 -0
  18. data/lib/bridgetown-core/converter.rb +54 -0
  19. data/lib/bridgetown-core/converters/identity.rb +39 -0
  20. data/lib/bridgetown-core/converters/markdown.rb +108 -0
  21. data/lib/bridgetown-core/converters/markdown/kramdown_parser.rb +132 -0
  22. data/lib/bridgetown-core/converters/smartypants.rb +69 -0
  23. data/lib/bridgetown-core/convertible.rb +237 -0
  24. data/lib/bridgetown-core/deprecator.rb +50 -0
  25. data/lib/bridgetown-core/document.rb +475 -0
  26. data/lib/bridgetown-core/drops/bridgetown_drop.rb +32 -0
  27. data/lib/bridgetown-core/drops/collection_drop.rb +20 -0
  28. data/lib/bridgetown-core/drops/document_drop.rb +69 -0
  29. data/lib/bridgetown-core/drops/drop.rb +215 -0
  30. data/lib/bridgetown-core/drops/excerpt_drop.rb +19 -0
  31. data/lib/bridgetown-core/drops/page_drop.rb +14 -0
  32. data/lib/bridgetown-core/drops/site_drop.rb +62 -0
  33. data/lib/bridgetown-core/drops/static_file_drop.rb +14 -0
  34. data/lib/bridgetown-core/drops/unified_payload_drop.rb +26 -0
  35. data/lib/bridgetown-core/drops/url_drop.rb +132 -0
  36. data/lib/bridgetown-core/entry_filter.rb +108 -0
  37. data/lib/bridgetown-core/errors.rb +20 -0
  38. data/lib/bridgetown-core/excerpt.rb +202 -0
  39. data/lib/bridgetown-core/external.rb +62 -0
  40. data/lib/bridgetown-core/filters.rb +467 -0
  41. data/lib/bridgetown-core/filters/date_filters.rb +110 -0
  42. data/lib/bridgetown-core/filters/grouping_filters.rb +64 -0
  43. data/lib/bridgetown-core/filters/url_filters.rb +79 -0
  44. data/lib/bridgetown-core/frontmatter_defaults.rb +238 -0
  45. data/lib/bridgetown-core/generator.rb +5 -0
  46. data/lib/bridgetown-core/hooks.rb +103 -0
  47. data/lib/bridgetown-core/layout.rb +57 -0
  48. data/lib/bridgetown-core/liquid_extensions.rb +22 -0
  49. data/lib/bridgetown-core/liquid_renderer.rb +71 -0
  50. data/lib/bridgetown-core/liquid_renderer/file.rb +67 -0
  51. data/lib/bridgetown-core/liquid_renderer/table.rb +75 -0
  52. data/lib/bridgetown-core/log_adapter.rb +151 -0
  53. data/lib/bridgetown-core/log_writer.rb +60 -0
  54. data/lib/bridgetown-core/mime.types +867 -0
  55. data/lib/bridgetown-core/page.rb +214 -0
  56. data/lib/bridgetown-core/page_without_a_file.rb +14 -0
  57. data/lib/bridgetown-core/path_manager.rb +31 -0
  58. data/lib/bridgetown-core/plugin.rb +80 -0
  59. data/lib/bridgetown-core/plugin_manager.rb +60 -0
  60. data/lib/bridgetown-core/publisher.rb +23 -0
  61. data/lib/bridgetown-core/reader.rb +185 -0
  62. data/lib/bridgetown-core/readers/collection_reader.rb +22 -0
  63. data/lib/bridgetown-core/readers/data_reader.rb +75 -0
  64. data/lib/bridgetown-core/readers/layout_reader.rb +48 -0
  65. data/lib/bridgetown-core/readers/page_reader.rb +24 -0
  66. data/lib/bridgetown-core/readers/post_reader.rb +74 -0
  67. data/lib/bridgetown-core/readers/static_file_reader.rb +24 -0
  68. data/lib/bridgetown-core/regenerator.rb +195 -0
  69. data/lib/bridgetown-core/related_posts.rb +52 -0
  70. data/lib/bridgetown-core/renderer.rb +261 -0
  71. data/lib/bridgetown-core/site.rb +469 -0
  72. data/lib/bridgetown-core/static_file.rb +205 -0
  73. data/lib/bridgetown-core/tags/component.rb +34 -0
  74. data/lib/bridgetown-core/tags/highlight.rb +111 -0
  75. data/lib/bridgetown-core/tags/include.rb +220 -0
  76. data/lib/bridgetown-core/tags/link.rb +41 -0
  77. data/lib/bridgetown-core/tags/post_url.rb +107 -0
  78. data/lib/bridgetown-core/url.rb +164 -0
  79. data/lib/bridgetown-core/utils.rb +367 -0
  80. data/lib/bridgetown-core/utils/ansi.rb +57 -0
  81. data/lib/bridgetown-core/utils/exec.rb +26 -0
  82. data/lib/bridgetown-core/utils/internet.rb +37 -0
  83. data/lib/bridgetown-core/utils/platforms.rb +80 -0
  84. data/lib/bridgetown-core/utils/thread_event.rb +31 -0
  85. data/lib/bridgetown-core/utils/win_tz.rb +75 -0
  86. data/lib/bridgetown-core/version.rb +5 -0
  87. data/lib/bridgetown-core/watcher.rb +139 -0
  88. data/lib/site_template/.gitignore +6 -0
  89. data/lib/site_template/bridgetown.config.yml +21 -0
  90. data/lib/site_template/frontend/javascript/index.js +3 -0
  91. data/lib/site_template/frontend/styles/index.scss +17 -0
  92. data/lib/site_template/package.json +23 -0
  93. data/lib/site_template/src/404.html +9 -0
  94. data/lib/site_template/src/_data/site_metadata.yml +11 -0
  95. data/lib/site_template/src/_includes/footer.html +3 -0
  96. data/lib/site_template/src/_includes/head.html +9 -0
  97. data/lib/site_template/src/_includes/navbar.html +4 -0
  98. data/lib/site_template/src/_layouts/default.html +15 -0
  99. data/lib/site_template/src/_layouts/home.html +7 -0
  100. data/lib/site_template/src/_layouts/page.html +7 -0
  101. data/lib/site_template/src/_layouts/post.html +7 -0
  102. data/lib/site_template/src/_posts/0000-00-00-welcome-to-bridgetown.md.erb +26 -0
  103. data/lib/site_template/src/about.md +11 -0
  104. data/lib/site_template/src/index.md +7 -0
  105. data/lib/site_template/webpack.config.js +60 -0
  106. data/rake/release.rake +30 -0
  107. metadata +106 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1bdc825b903ba9de033edc8fcce7b94f871cd6c98b4c267856316a5f842f0c6d
4
- data.tar.gz: d8aa948572f48e2450059cd47ac3d6766d6cc43494ebe771f9859a01bcb9bb9c
3
+ metadata.gz: 01abda216c9aa5c096d73906bd6b76e516f42286a37039a99d8894497b1896b4
4
+ data.tar.gz: 5dabe33f2ec5614a3637b2880c471e460699ed1f65399abf0b17ab6d92889ceb
5
5
  SHA512:
6
- metadata.gz: 3d2fd4b262ca60a39b3b3799caddb655c48808c336e5c266c55a06886a3e64e2bc54dbd54cc5f338b08bb089d10bfa9a7fec0c95bddbaded541d60b56615461e
7
- data.tar.gz: 2c5b6899c86c1a48662b0d7229ac65bfacf487a88444f6b2b0bc3481ad668e3ccf11fcb7bef14b37ec375c07d92dcc1e1120067104b575fda9945349e811e6c0
6
+ metadata.gz: 637885282a2398b8715aa05fbed070999a05a0256507a73110591f68eafa0d854acc9831078263e59213dd8b3e4eed11b9838b69620f71653af4d45b4f06555b
7
+ data.tar.gz: da314910ec05c60a3a70b960a5b4a27d45adb68ef019e54366d0c35304023545d4b4d046602b8dcdbdc9055ac00dcd94c96aa665c41bd4c555a08d9639c9875b
@@ -0,0 +1,42 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ $LOAD_PATH.unshift File.expand_path("lib", __dir__)
4
+ require "bridgetown-core/version"
5
+
6
+ Dir.glob("rake/**.rake").each { |f| import f }
7
+
8
+ #############################################################################
9
+ #
10
+ # Helper functions
11
+ #
12
+ #############################################################################
13
+
14
+ def name
15
+ "bridgetown-core"
16
+ end
17
+
18
+ def version
19
+ Bridgetown::VERSION
20
+ end
21
+
22
+ def gemspec_file
23
+ "#{name}.gemspec"
24
+ end
25
+
26
+ def gem_file
27
+ "#{name}-#{Gem::Version.new(version)}.gem"
28
+ end
29
+
30
+ #############################################################################
31
+ #
32
+ # Standard tasks
33
+ #
34
+ #############################################################################
35
+
36
+ task :spec => :test
37
+ require "rake/testtask"
38
+ Rake::TestTask.new(:test) do |test|
39
+ test.libs << "lib" << "test"
40
+ test.pattern = "test/**/test_*.rb"
41
+ test.verbose = true
42
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/bridgetown-core/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "bridgetown-core"
7
+ s.version = Bridgetown::VERSION
8
+ s.license = "MIT"
9
+ s.author = "Bridgetown Team"
10
+ s.email = "maintainers@bridgetownrb.com"
11
+ s.homepage = "https://bridgetownrb.com"
12
+ s.summary = "A Webpack-aware, Ruby-based static site generator for the modern Jamstack era"
13
+ s.description = "Bridgetown is a Webpack-aware, Ruby-powered static site generator for the modern Jamstack era"
14
+
15
+ s.files = `git ls-files -z`.split("\x0").reject do |f|
16
+ f.match(%r{^(benchmark|features|script|test)/})
17
+ end
18
+ s.executables = ["bridgetown"]
19
+ s.bindir = "bin"
20
+ s.require_paths = ["lib"]
21
+
22
+ s.metadata = {
23
+ "source_code_uri" => "https://github.com/bridgetownrb/bridgetown",
24
+ "bug_tracker_uri" => "https://github.com/bridgetownrb/bridgetown/issues",
25
+ "changelog_uri" => "https://github.com/bridgetownrb/bridgetown/releases",
26
+ "homepage_uri" => s.homepage,
27
+ }
28
+
29
+ s.rdoc_options = ["--charset=UTF-8"]
30
+
31
+ s.required_ruby_version = ">= 2.4.0"
32
+ s.required_rubygems_version = ">= 2.7.0"
33
+
34
+ s.add_runtime_dependency("addressable", "~> 2.4")
35
+ s.add_runtime_dependency("colorator", "~> 1.0")
36
+ s.add_runtime_dependency("i18n", "~> 1.0")
37
+ s.add_runtime_dependency("kramdown", "~> 2.1")
38
+ s.add_runtime_dependency("kramdown-parser-gfm", "~> 1.0")
39
+ s.add_runtime_dependency("liquid", "~> 4.0")
40
+ s.add_runtime_dependency("listen", "~> 3.0")
41
+ s.add_runtime_dependency("mercenary", "~> 0.4.0")
42
+ s.add_runtime_dependency("pathutil", "~> 0.9")
43
+ s.add_runtime_dependency("rouge", "~> 3.0")
44
+ s.add_runtime_dependency("safe_yaml", "~> 1.0")
45
+ s.add_runtime_dependency("terminal-table", "~> 1.8")
46
+ end
@@ -0,0 +1,202 @@
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH.unshift __dir__ # For use/testing when no gem is installed
4
+
5
+ # Require all of the Ruby files in the given directory.
6
+ #
7
+ # path - The String relative path from here to the directory.
8
+ #
9
+ # Returns nothing.
10
+ def require_all(path)
11
+ glob = File.join(__dir__, path, "*.rb")
12
+ Dir[glob].sort.each do |f|
13
+ require f
14
+ end
15
+ end
16
+
17
+ # rubygems
18
+ require "rubygems"
19
+
20
+ # stdlib
21
+ require "forwardable"
22
+ require "fileutils"
23
+ require "time"
24
+ require "English"
25
+ require "pathname"
26
+ require "logger"
27
+ require "set"
28
+ require "csv"
29
+ require "json"
30
+
31
+ # 3rd party
32
+ require "pathutil"
33
+ require "addressable/uri"
34
+ require "safe_yaml/load"
35
+ require "liquid"
36
+ require "kramdown"
37
+ require "colorator"
38
+ require "i18n"
39
+
40
+ SafeYAML::OPTIONS[:suppress_warnings] = true
41
+
42
+ module Bridgetown
43
+ # internal requires
44
+ autoload :Cleaner, "bridgetown-core/cleaner"
45
+ autoload :Collection, "bridgetown-core/collection"
46
+ autoload :Configuration, "bridgetown-core/configuration"
47
+ autoload :Convertible, "bridgetown-core/convertible"
48
+ autoload :Deprecator, "bridgetown-core/deprecator"
49
+ autoload :Document, "bridgetown-core/document"
50
+ autoload :EntryFilter, "bridgetown-core/entry_filter"
51
+ autoload :Errors, "bridgetown-core/errors"
52
+ autoload :Excerpt, "bridgetown-core/excerpt"
53
+ autoload :External, "bridgetown-core/external"
54
+ autoload :FrontmatterDefaults, "bridgetown-core/frontmatter_defaults"
55
+ autoload :Hooks, "bridgetown-core/hooks"
56
+ autoload :Layout, "bridgetown-core/layout"
57
+ autoload :Cache, "bridgetown-core/cache"
58
+ autoload :CollectionReader, "bridgetown-core/readers/collection_reader"
59
+ autoload :DataReader, "bridgetown-core/readers/data_reader"
60
+ autoload :LayoutReader, "bridgetown-core/readers/layout_reader"
61
+ autoload :PostReader, "bridgetown-core/readers/post_reader"
62
+ autoload :PageReader, "bridgetown-core/readers/page_reader"
63
+ autoload :StaticFileReader, "bridgetown-core/readers/static_file_reader"
64
+ autoload :LogAdapter, "bridgetown-core/log_adapter"
65
+ autoload :Page, "bridgetown-core/page"
66
+ autoload :PageWithoutAFile, "bridgetown-core/page_without_a_file"
67
+ autoload :PathManager, "bridgetown-core/path_manager"
68
+ autoload :PluginManager, "bridgetown-core/plugin_manager"
69
+ autoload :Publisher, "bridgetown-core/publisher"
70
+ autoload :Reader, "bridgetown-core/reader"
71
+ autoload :Regenerator, "bridgetown-core/regenerator"
72
+ autoload :RelatedPosts, "bridgetown-core/related_posts"
73
+ autoload :Renderer, "bridgetown-core/renderer"
74
+ autoload :LiquidRenderer, "bridgetown-core/liquid_renderer"
75
+ autoload :LogWriter, "bridgetown-core/log_writer"
76
+ autoload :Site, "bridgetown-core/site"
77
+ autoload :StaticFile, "bridgetown-core/static_file"
78
+ autoload :URL, "bridgetown-core/url"
79
+ autoload :Utils, "bridgetown-core/utils"
80
+ autoload :VERSION, "bridgetown-core/version"
81
+ autoload :Watcher, "bridgetown-core/watcher"
82
+
83
+ # extensions
84
+ require "bridgetown-core/plugin"
85
+ require "bridgetown-core/converter"
86
+ require "bridgetown-core/generator"
87
+ require "bridgetown-core/command"
88
+ require "bridgetown-core/liquid_extensions"
89
+ require "bridgetown-core/filters"
90
+
91
+ require "bridgetown-core/drops/drop"
92
+ require "bridgetown-core/drops/document_drop"
93
+ require_all "bridgetown-core/commands"
94
+ require_all "bridgetown-core/converters"
95
+ require_all "bridgetown-core/converters/markdown"
96
+ require_all "bridgetown-core/drops"
97
+ require_all "bridgetown-core/generators"
98
+ require_all "bridgetown-core/tags"
99
+
100
+ class << self
101
+ # Public: Tells you which Bridgetown environment you are building in so
102
+ # you can skip tasks if you need to.
103
+
104
+ def env
105
+ ENV["BRIDGETOWN_ENV"] || "development"
106
+ end
107
+
108
+ # Public: Generate a Bridgetown configuration Hash by merging the default
109
+ # options with anything in bridgetown.config.yml, and adding the given
110
+ # options on top.
111
+ #
112
+ # override - A Hash of config directives that override any options in both
113
+ # the defaults and the config file.
114
+ # See Bridgetown::Configuration::DEFAULTS for a
115
+ # list of option names and their defaults.
116
+ #
117
+ # Returns the final configuration Hash.
118
+ def configuration(override = {})
119
+ config = Configuration.new
120
+ override = Configuration[override].stringify_keys
121
+ unless override.delete("skip_config_files")
122
+ config = config.read_config_files(config.config_files(override))
123
+ end
124
+
125
+ # Merge DEFAULTS < bridgetown.config.yml < override
126
+ Configuration.from(Utils.deep_merge_hashes(config, override)).tap do |obj|
127
+ set_timezone(obj["timezone"]) if obj["timezone"]
128
+ end
129
+ end
130
+
131
+ # Public: Set the TZ environment variable to use the timezone specified
132
+ #
133
+ # timezone - the IANA Time Zone
134
+ #
135
+ # Returns nothing
136
+ # rubocop:disable Naming/AccessorMethodName
137
+ def set_timezone(timezone)
138
+ ENV["TZ"] = if Utils::Platforms.really_windows?
139
+ Utils::WinTZ.calculate(timezone)
140
+ else
141
+ timezone
142
+ end
143
+ end
144
+ # rubocop:enable Naming/AccessorMethodName
145
+
146
+ # Public: Fetch the logger instance for this Bridgetown process.
147
+ #
148
+ # Returns the LogAdapter instance.
149
+ def logger
150
+ @logger ||= LogAdapter.new(LogWriter.new, (ENV["BRIDGETOWN_LOG_LEVEL"] || :info).to_sym)
151
+ end
152
+
153
+ # Public: Set the log writer.
154
+ # New log writer must respond to the same methods
155
+ # as Ruby's interal Logger.
156
+ #
157
+ # writer - the new Logger-compatible log transport
158
+ #
159
+ # Returns the new logger.
160
+ def logger=(writer)
161
+ @logger = LogAdapter.new(writer, (ENV["BRIDGETOWN_LOG_LEVEL"] || :info).to_sym)
162
+ end
163
+
164
+ # Public: An array of sites
165
+ #
166
+ # Returns the Bridgetown sites created.
167
+ def sites
168
+ @sites ||= []
169
+ end
170
+
171
+ # Public: Ensures the questionable path is prefixed with the base directory
172
+ # and prepends the questionable path with the base directory if false.
173
+ #
174
+ # base_directory - the directory with which to prefix the questionable path
175
+ # questionable_path - the path we're unsure about, and want prefixed
176
+ #
177
+ # Returns the sanitized path.
178
+ def sanitized_path(base_directory, questionable_path)
179
+ return base_directory if base_directory.eql?(questionable_path)
180
+
181
+ clean_path = questionable_path.dup
182
+ clean_path.insert(0, "/") if clean_path.start_with?("~")
183
+ clean_path = File.expand_path(clean_path, "/")
184
+
185
+ return clean_path if clean_path.eql?(base_directory)
186
+
187
+ # remove any remaining extra leading slashes not stripped away by calling
188
+ # `File.expand_path` above.
189
+ clean_path.squeeze!("/")
190
+
191
+ if clean_path.start_with?(base_directory.sub(%r!\z!, "/"))
192
+ clean_path
193
+ else
194
+ clean_path.sub!(%r!\A\w:/!, "/")
195
+ File.join(base_directory, clean_path)
196
+ end
197
+ end
198
+
199
+ # Conditional optimizations
200
+ Bridgetown::External.require_if_present("liquid/c")
201
+ end
202
+ end
@@ -0,0 +1,190 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "digest"
4
+
5
+ module Bridgetown
6
+ class Cache
7
+ # class-wide base cache
8
+ @base_cache = {}
9
+
10
+ # class-wide directive to write cache to disk is enabled by default
11
+ @disk_cache_enabled = true
12
+
13
+ class << self
14
+ # class-wide cache location
15
+ attr_accessor :cache_dir
16
+
17
+ # class-wide directive to write cache to disk
18
+ attr_reader :disk_cache_enabled
19
+
20
+ # class-wide base cache reader
21
+ attr_reader :base_cache
22
+
23
+ # Disable Marshaling cached items to disk
24
+ def disable_disk_cache!
25
+ @disk_cache_enabled = false
26
+ end
27
+
28
+ # Clear all caches
29
+ def clear
30
+ delete_cache_files
31
+ base_cache.each_value(&:clear)
32
+ end
33
+
34
+ # Compare the current config to the cached config
35
+ # If they are different, clear all caches
36
+ #
37
+ # Returns nothing.
38
+ def clear_if_config_changed(config)
39
+ config = config.inspect
40
+ cache = Bridgetown::Cache.new "Bridgetown::Cache"
41
+ return if cache.key?("config") && cache["config"] == config
42
+
43
+ clear
44
+ cache = Bridgetown::Cache.new "Bridgetown::Cache"
45
+ cache["config"] = config
46
+ nil
47
+ end
48
+
49
+ private
50
+
51
+ # Delete all cached items from all caches
52
+ #
53
+ # Returns nothing.
54
+ def delete_cache_files
55
+ FileUtils.rm_rf(@cache_dir) if disk_cache_enabled
56
+ end
57
+ end
58
+
59
+ #
60
+
61
+ # Get an existing named cache, or create a new one if none exists
62
+ #
63
+ # name - name of the cache
64
+ #
65
+ # Returns nothing.
66
+ def initialize(name)
67
+ @cache = Bridgetown::Cache.base_cache[name] ||= {}
68
+ @name = name.gsub(%r![^\w\s-]!, "-")
69
+ end
70
+
71
+ # Clear this particular cache
72
+ def clear
73
+ delete_cache_files
74
+ @cache.clear
75
+ end
76
+
77
+ # Retrieve a cached item
78
+ # Raises if key does not exist in cache
79
+ #
80
+ # Returns cached value
81
+ def [](key)
82
+ return @cache[key] if @cache.key?(key)
83
+
84
+ path = path_to(hash(key))
85
+ if disk_cache_enabled? && File.file?(path) && File.readable?(path)
86
+ @cache[key] = load(path)
87
+ else
88
+ raise
89
+ end
90
+ end
91
+
92
+ # Add an item to cache
93
+ #
94
+ # Returns nothing.
95
+ def []=(key, value)
96
+ @cache[key] = value
97
+ return unless disk_cache_enabled?
98
+
99
+ path = path_to(hash(key))
100
+ value = new Hash(value) if value.is_a?(Hash) && !value.default.nil?
101
+ dump(path, value)
102
+ rescue TypeError
103
+ Bridgetown.logger.debug "Cache:", "Cannot dump object #{key}"
104
+ end
105
+
106
+ # If an item already exists in the cache, retrieve it.
107
+ # Else execute code block, and add the result to the cache, and return that result.
108
+ def getset(key)
109
+ self[key]
110
+ rescue StandardError
111
+ value = yield
112
+ self[key] = value
113
+ value
114
+ end
115
+
116
+ # Remove one particular item from the cache
117
+ #
118
+ # Returns nothing.
119
+ def delete(key)
120
+ @cache.delete(key)
121
+ File.delete(path_to(hash(key))) if disk_cache_enabled?
122
+ end
123
+
124
+ # Check if `key` already exists in this cache
125
+ #
126
+ # Returns true if key exists in the cache, false otherwise
127
+ def key?(key)
128
+ # First, check if item is already cached in memory
129
+ return true if @cache.key?(key)
130
+ # Otherwise, it might be cached on disk
131
+ # but we should not consider the disk cache if it is disabled
132
+ return false unless disk_cache_enabled?
133
+
134
+ path = path_to(hash(key))
135
+ File.file?(path) && File.readable?(path)
136
+ end
137
+
138
+ def disk_cache_enabled?
139
+ !!Bridgetown::Cache.disk_cache_enabled
140
+ end
141
+
142
+ private
143
+
144
+ # Given a hashed key, return the path to where this item would be saved on disk.
145
+ def path_to(hash = nil)
146
+ @base_dir ||= File.join(Bridgetown::Cache.cache_dir, @name)
147
+ return @base_dir if hash.nil?
148
+
149
+ File.join(@base_dir, hash[0..1], hash[2..-1]).freeze
150
+ end
151
+
152
+ # Given a key, return a SHA2 hash that can be used for caching this item to disk.
153
+ def hash(key)
154
+ Digest::SHA2.hexdigest(key).freeze
155
+ end
156
+
157
+ # Remove all this caches items from disk
158
+ #
159
+ # Returns nothing.
160
+ def delete_cache_files
161
+ FileUtils.rm_rf(path_to) if disk_cache_enabled?
162
+ end
163
+
164
+ # Load `path` from disk and return the result.
165
+ # This MUST NEVER be called in Safe Mode
166
+ # rubocop:disable Security/MarshalLoad
167
+ def load(path)
168
+ raise unless disk_cache_enabled?
169
+
170
+ cached_file = File.open(path, "rb")
171
+ value = Marshal.load(cached_file)
172
+ cached_file.close
173
+ value
174
+ end
175
+ # rubocop:enable Security/MarshalLoad
176
+
177
+ # Given a path and a value, save value to disk at path.
178
+ # This should NEVER be called in Safe Mode
179
+ #
180
+ # Returns nothing.
181
+ def dump(path, value)
182
+ return unless disk_cache_enabled?
183
+
184
+ FileUtils.mkdir_p(File.dirname(path))
185
+ File.open(path, "wb") do |cached_file|
186
+ Marshal.dump(value, cached_file)
187
+ end
188
+ end
189
+ end
190
+ end