bridgetown-core 2.0.0.beta1 → 2.0.0.beta3

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 (63) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +3 -0
  3. data/Rakefile +2 -1
  4. data/bridgetown-core.gemspec +2 -2
  5. data/lib/bridgetown-core/cache.rb +3 -19
  6. data/lib/bridgetown-core/cleaner.rb +17 -19
  7. data/lib/bridgetown-core/collection.rb +9 -2
  8. data/lib/bridgetown-core/commands/build.rb +6 -17
  9. data/lib/bridgetown-core/commands/concerns/actions.rb +4 -0
  10. data/lib/bridgetown-core/commands/esbuild/esbuild.config.js +7 -6
  11. data/lib/bridgetown-core/commands/esbuild/esbuild.defaults.js.erb +14 -13
  12. data/lib/bridgetown-core/commands/esbuild/migrate-from-webpack.rb +1 -1
  13. data/lib/bridgetown-core/commands/esbuild/update.rb +17 -3
  14. data/lib/bridgetown-core/commands/esbuild.rb +1 -1
  15. data/lib/bridgetown-core/component.rb +1 -1
  16. data/lib/bridgetown-core/concerns/layout_placeable.rb +1 -1
  17. data/lib/bridgetown-core/concerns/publishable.rb +2 -0
  18. data/lib/bridgetown-core/concerns/site/content.rb +4 -1
  19. data/lib/bridgetown-core/concerns/site/extensible.rb +6 -1
  20. data/lib/bridgetown-core/concerns/site/fast_refreshable.rb +20 -13
  21. data/lib/bridgetown-core/concerns/site/localizable.rb +2 -0
  22. data/lib/bridgetown-core/concerns/site/processable.rb +2 -0
  23. data/lib/bridgetown-core/concerns/site/renderable.rb +3 -0
  24. data/lib/bridgetown-core/concerns/site/ssr.rb +0 -1
  25. data/lib/bridgetown-core/configuration.rb +8 -14
  26. data/lib/bridgetown-core/converter.rb +2 -7
  27. data/lib/bridgetown-core/converters/identity.rb +3 -11
  28. data/lib/bridgetown-core/converters/liquid_templates.rb +3 -5
  29. data/lib/bridgetown-core/converters/markdown/kramdown_parser.rb +1 -1
  30. data/lib/bridgetown-core/converters/markdown.rb +11 -14
  31. data/lib/bridgetown-core/converters/serbea_templates.rb +3 -4
  32. data/lib/bridgetown-core/drops/drop.rb +29 -42
  33. data/lib/bridgetown-core/drops/resource_drop.rb +3 -12
  34. data/lib/bridgetown-core/errors.rb +2 -8
  35. data/lib/bridgetown-core/filters/condition_helpers.rb +6 -9
  36. data/lib/bridgetown-core/filters/date_filters.rb +22 -35
  37. data/lib/bridgetown-core/filters/grouping_filters.rb +11 -11
  38. data/lib/bridgetown-core/filters.rb +53 -72
  39. data/lib/bridgetown-core/front_matter/defaults.rb +8 -13
  40. data/lib/bridgetown-core/generated_page.rb +6 -6
  41. data/lib/bridgetown-core/generators/prototype_generator.rb +0 -2
  42. data/lib/bridgetown-core/hooks.rb +0 -1
  43. data/lib/bridgetown-core/layout.rb +3 -4
  44. data/lib/bridgetown-core/liquid_extensions.rb +3 -5
  45. data/lib/bridgetown-core/log_adapter.rb +37 -56
  46. data/lib/bridgetown-core/plugin_manager.rb +18 -3
  47. data/lib/bridgetown-core/rack/logger.rb +0 -2
  48. data/lib/bridgetown-core/resource/base.rb +8 -8
  49. data/lib/bridgetown-core/resource/permalink_processor.rb +1 -1
  50. data/lib/bridgetown-core/ruby_template_view.rb +0 -1
  51. data/lib/bridgetown-core/static_file.rb +15 -20
  52. data/lib/bridgetown-core/tags/class_map.rb +1 -1
  53. data/lib/bridgetown-core/tags/post_url.rb +2 -32
  54. data/lib/bridgetown-core/utils/require_gems.rb +1 -3
  55. data/lib/bridgetown-core/utils.rb +41 -44
  56. data/lib/bridgetown-core/watcher.rb +2 -3
  57. data/lib/bridgetown-core.rb +1 -2
  58. data/lib/roda/plugins/bridgetown_server.rb +2 -3
  59. data/lib/site_template/package.json.erb +1 -0
  60. data/lib/site_template/postcss.config.js.erb +1 -1
  61. data/lib/site_template/src/posts.md.erb +8 -8
  62. metadata +6 -7
  63. data/lib/bridgetown-core/version.rb +0 -6
@@ -3,14 +3,15 @@
3
3
  module Bridgetown
4
4
  module Filters
5
5
  module GroupingFilters
6
- # Group an array of items by a property
6
+ # Group an array of items by a property, returning an array of hashes
7
7
  #
8
- # input - the inputted Enumerable
9
- # property - the property
8
+ # @example
9
+ # {"name" => "larry"
10
+ # "items" => [...] } # all the items where `property` == "larry"
10
11
  #
11
- # Returns an array of Hashes, each looking something like this:
12
- # {"name" => "larry"
13
- # "items" => [...] } # all the items where `property` == "larry"
12
+ # @param input [Enumerable]
13
+ # @param property [String]
14
+ # @return [Array<Hash>]
14
15
  def group_by(input, property)
15
16
  if groupable?(input)
16
17
  groups = input.group_by { |item| item_property(item, property).to_s }
@@ -22,11 +23,10 @@ module Bridgetown
22
23
 
23
24
  # Group an array of items by an expression
24
25
  #
25
- # input - the object array
26
- # variable - the variable to assign each item to in the expression
27
- # expression -a Liquid comparison expression passed in as a string
28
- #
29
- # Returns the filtered array of objects
26
+ # @param input [Enumerable]
27
+ # @param variable [String] variable to assign each item to in the expression
28
+ # @param expression [String] Liquid comparison expression
29
+ # @return [Array<Hash>]
30
30
  def group_by_exp(input, variable, expression)
31
31
  return input unless groupable?(input)
32
32
 
@@ -11,33 +11,30 @@ module Bridgetown
11
11
  include TranslationFilters
12
12
  include ConditionHelpers
13
13
 
14
- # Convert a Markdown string into HTML output.
14
+ # Convert a Markdown string into HTML output
15
15
  #
16
- # input - The Markdown String to convert.
17
- #
18
- # Returns the HTML formatted String.
16
+ # @param input [String]
17
+ # @return [String] HTML formatted text
19
18
  def markdownify(input)
20
19
  @context.registers[:site].find_converter_instance(
21
20
  Bridgetown::Converters::Markdown
22
21
  ).convert(input.to_s)
23
22
  end
24
23
 
25
- # Convert quotes into smart quotes.
26
- #
27
- # input - The String to convert.
24
+ # Convert quotes into smart quotes
28
25
  #
29
- # Returns the smart-quotified String.
26
+ # @param input [String]
27
+ # @return [String] smart-quotified text
30
28
  def smartify(input)
31
29
  Utils::SmartyPantsConverter.new(@context.registers[:site].config).convert(input.to_s)
32
30
  end
33
31
 
34
- # Slugify a filename or title.
35
- #
36
- # input - The filename or title to slugify.
37
- # mode - how string is slugified
32
+ # Slugify a filename or title
38
33
  #
39
- # Returns the given filename or title as a lowercase URL String.
40
- # See Utils.slugify for more detail.
34
+ # @param input [String] the filename or title to slugify
35
+ # @param mode [String] how string is slugified
36
+ # @see Utils.slugify
37
+ # @return [String] lowercase URL
41
38
  def slugify(input, mode = nil)
42
39
  mode = @context.registers[:site].config.slugify_mode if mode.nil?
43
40
  Utils.slugify(input, mode:)
@@ -45,10 +42,9 @@ module Bridgetown
45
42
 
46
43
  # Titleize a slug or identifier string.
47
44
  #
48
- # input - The string to titleize.
49
- #
50
- # Returns a transformed string with spaces and capitalized words.
51
- # See Utils.titleize_slug for more detail.
45
+ # @param input [String]
46
+ # @see Utils.titleize_slug for more detail
47
+ # @return [String] transformed string with spaces and capitalized words
52
48
  def titleize(input)
53
49
  Utils.titleize_slug(input)
54
50
  end
@@ -56,13 +52,12 @@ module Bridgetown
56
52
  # XML escape a string for use. Replaces any special characters with
57
53
  # appropriate HTML entity replacements.
58
54
  #
59
- # Examples
60
- #
55
+ # @example
61
56
  # xml_escape('foo "bar" <baz>')
62
57
  # # => "foo &quot;bar&quot; &lt;baz&gt;"
63
58
  #
64
- # @param input [String] The String to escape.
65
- # @return [String] the escaped String.
59
+ # @param input [String]
60
+ # @return [String]
66
61
  def xml_escape(input)
67
62
  Utils.xml_escape(input)
68
63
  end
@@ -70,28 +65,24 @@ module Bridgetown
70
65
  # CGI escape a string for use in a URL. Replaces any special characters
71
66
  # with appropriate %XX replacements.
72
67
  #
73
- # input - The String to escape.
74
- #
75
- # Examples
76
- #
68
+ # @example
77
69
  # cgi_escape('foo,bar;baz?')
78
70
  # # => "foo%2Cbar%3Bbaz%3F"
79
71
  #
80
- # Returns the escaped String.
72
+ # @param input [String]
73
+ # @return [String]
81
74
  def cgi_escape(input)
82
75
  CGI.escape(input.to_s)
83
76
  end
84
77
 
85
78
  # URI escape a string.
86
79
  #
87
- # input - The String to escape.
88
- #
89
- # Examples
90
- #
80
+ # @example
91
81
  # uri_escape('foo, bar \\baz?')
92
82
  # # => "foo,%20bar%20%5Cbaz?"
93
83
  #
94
- # Returns the escaped String.
84
+ # @param input [String]
85
+ # @return [String]
95
86
  def uri_escape(input)
96
87
  Addressable::URI.normalize_component(input)
97
88
  end
@@ -113,23 +104,22 @@ module Bridgetown
113
104
 
114
105
  # Replace any whitespace in the input string with a single space
115
106
  #
116
- # input - The String on which to operate.
117
- #
118
- # Returns the formatted String
107
+ # @param input [String]
108
+ # @return [String]
119
109
  def normalize_whitespace(input)
120
110
  input.to_s.gsub(%r!\s+!, " ").strip
121
111
  end
122
112
 
123
113
  # Count the number of words in the input string.
124
114
  #
125
- # input - The String on which to operate.
126
- #
127
- # Returns the Integer word count.
115
+ # @param input [String]
116
+ # @return [Integer] word count
128
117
  def number_of_words(input)
129
118
  input.split.length
130
119
  end
131
120
 
132
- # Calculates the average reading time of the supplied content.
121
+ # Calculates the average reading time of the supplied content
122
+ #
133
123
  # @param input [String] the String of content to analyze.
134
124
  # @return [Float] the number of minutes required to read the content.
135
125
  def reading_time(input, round_to = 0)
@@ -138,17 +128,15 @@ module Bridgetown
138
128
  end
139
129
 
140
130
  # Join an array of things into a string by separating with commas and the
141
- # word "and" for the last one.
142
- #
143
- # array - The Array of Strings to join.
144
- # connector - Word used to connect the last 2 items in the array
145
- #
146
- # Examples
131
+ # word "and" for the last one
147
132
  #
133
+ # @example
148
134
  # array_to_sentence_string(["apples", "oranges", "grapes"])
149
135
  # # => "apples, oranges, and grapes"
150
136
  #
151
- # Returns the formatted String.
137
+ # @param array [Array<String>]
138
+ # @param connector [String] word used to connect the last 2 items in the array
139
+ # @return [String]
152
140
  def array_to_sentence_string(array, connector = "and")
153
141
  case array.length
154
142
  when 0
@@ -162,24 +150,20 @@ module Bridgetown
162
150
  end
163
151
  end
164
152
 
165
- # Convert the input into json string
166
- #
167
- # input - The Array or Hash to be converted
153
+ # Convert the input into JSON string
168
154
  #
169
- # Returns the converted json string
155
+ # @param input [Array, Hash, String, Integer]
156
+ # @return [String] JSON string
170
157
  def jsonify(input)
171
158
  as_liquid(input).to_json
172
159
  end
173
160
 
174
- # Filter an array of objects
161
+ # Filter an array of objects or a hash (will use values)
175
162
  #
176
- # input - the object array.
177
- # property - the property within each object to filter by.
178
- # value - the desired value.
179
- # Cannot be an instance of Array nor Hash since calling #to_s on them returns
180
- # their `#inspect` string object.
181
- #
182
- # Returns the filtered array of objects
163
+ # @param input [Array, Hash]
164
+ # @param property [String] the property within each object to filter by
165
+ # @param value [String] value for the search
166
+ # @return [Array] filtered array of objects
183
167
  def where(input, property, value) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
184
168
  return input if !property || value.is_a?(Array) || value.is_a?(Hash)
185
169
  return input unless input.respond_to?(:select)
@@ -201,15 +185,14 @@ module Bridgetown
201
185
 
202
186
  # Filters an array of objects against an expression
203
187
  #
204
- # input - the object array
205
- # variable - the variable to assign each item to in the expression
206
- # expression - a Liquid comparison expression passed in as a string
207
- #
208
- # Returns the filtered array of objects
188
+ # @param input [Array, Hash]
189
+ # @param variable [String] the variable to assign each item to in the expression
190
+ # @param expression [String] a Liquid comparison expression passed in as a string
191
+ # @return [Array] filtered array of objects
209
192
  def where_exp(input, variable, expression)
210
193
  return input unless input.respond_to?(:select)
211
194
 
212
- input = input.values if input.is_a?(Hash) # FIXME
195
+ input = input.values if input.is_a?(Hash)
213
196
 
214
197
  condition = parse_condition(expression)
215
198
  @context.stack do
@@ -222,9 +205,8 @@ module Bridgetown
222
205
 
223
206
  # Convert the input into integer
224
207
  #
225
- # input - the object string
226
- #
227
- # Returns the integer value
208
+ # @param input [String, Boolean] if boolean, 1 for true and 0 for false
209
+ # @return [Integer]
228
210
  def to_integer(input)
229
211
  return 1 if input == true
230
212
  return 0 if input == false
@@ -234,11 +216,10 @@ module Bridgetown
234
216
 
235
217
  # Sort an array of objects
236
218
  #
237
- # input - the object array
238
- # property - property within each object to filter by
239
- # nils ('first' | 'last') - nils appear before or after non-nil values
240
- #
241
- # Returns the filtered array of objects
219
+ # @param input [Array]
220
+ # @param property [String] the property within each object to filter by
221
+ # @param nils [String] `first` | `last` (nils appear before or after non-nil values)
222
+ # @return [Array] sorted array of objects
242
223
  def sort(input, property = nil, nils = "first")
243
224
  raise ArgumentError, "Cannot sort a null object." if input.nil?
244
225
 
@@ -33,7 +33,6 @@ module Bridgetown
33
33
  #
34
34
  # @param path [String] the relative path of the resource
35
35
  # @param collection_name [Symbol] :posts, :pages, etc.
36
- #
37
36
  # @return [Hash] all default values (an empty hash if there are none)
38
37
  def all(path, collection_name)
39
38
  if @defaults_cache.key?([path, collection_name])
@@ -70,11 +69,10 @@ module Bridgetown
70
69
 
71
70
  # Checks if a given default setting scope matches the given path and collection
72
71
  #
73
- # scope - the hash indicating the scope, as defined in bridgetown.config.yml
74
- # path - the path to check for
75
- # collection - the collection (:posts or :pages) to check for
76
- #
77
- # Returns true if the scope applies to the given collection and path
72
+ # @param scope [Hash] the scope as defined in site configuration
73
+ # @param path [String] the path to check for
74
+ # @param collection [Symbol] the collection (:posts, :pages, etc.) to check for
75
+ # @return [Boolean] true if the scope applies to the given collection and path
78
76
  def applies?(scope, path, collection)
79
77
  applies_collection?(scope, collection) && applies_path?(scope, path)
80
78
  end
@@ -129,7 +127,6 @@ module Bridgetown
129
127
  #
130
128
  # @param scope [Hash] the defaults set being asked about
131
129
  # @param collection [Symbol] the collection of the resource being processed
132
- #
133
130
  # @return [Boolean] whether either of the above conditions are satisfied
134
131
  def applies_collection?(scope, collection)
135
132
  !scope.key?("collection") || scope["collection"].eql?(collection.to_s)
@@ -137,8 +134,7 @@ module Bridgetown
137
134
 
138
135
  # Checks if a given set of default values is valid
139
136
  #
140
- # @param set [Hash] the default value hash as defined in bridgetown.config.yml
141
- #
137
+ # @param set [Hash] the default value hash as defined in site configuration
142
138
  # @return [Boolean] if the set is valid and can be used
143
139
  def valid?(set)
144
140
  set.is_a?(Hash) && set["values"].is_a?(Hash)
@@ -146,10 +142,9 @@ module Bridgetown
146
142
 
147
143
  # Determines if a new scope has precedence over an old one
148
144
  #
149
- # old_scope - the old scope hash, or nil if there's none
150
- # new_scope - the new scope hash
151
- #
152
- # Returns true if the new scope has precedence over the older
145
+ # @param old_scope [Hash] old scope hash, or nil if there's none
146
+ # @param new_scope [Hash] new scope hash
147
+ # @return [Boolean] true if the new scope has precedence over the older
153
148
  # rubocop: disable Naming/PredicateName
154
149
  def has_precedence?(old_scope, new_scope)
155
150
  return true if old_scope.nil?
@@ -25,13 +25,13 @@ module Bridgetown
25
25
  .htm
26
26
  ).freeze
27
27
 
28
- # Initialize a new GeneratedPage.
28
+ # Initialize a new GeneratedPage
29
29
  #
30
- # site - The Site object.
31
- # base - The String path to the source.
32
- # dir - The String path between the source and the file.
33
- # name - The String filename of the file.
34
- # from_plugin - true if the Page file is located in a Gem-based plugin folder
30
+ # @param site [Bridgetown::Site]
31
+ # @param base [String] path to the source
32
+ # @param dir [String] path between the source and the file
33
+ # @param name [String] filename of the file.
34
+ # @param from_plugin [Boolean] true if the Page file is located in a Gem-based plugin folder
35
35
  # rubocop:disable Metrics/ParameterLists
36
36
  def initialize(site, base, dir, name, from_plugin: false)
37
37
  @site = site
@@ -76,7 +76,6 @@ module Bridgetown
76
76
  # Check incoming prototype configuration and normalize options.
77
77
  #
78
78
  # @param prototype_page [Bridgetown::GeneratedPage, Bridgetown::Resource::Base]
79
- #
80
79
  # @return [String, nil]
81
80
  def validate_search_term(prototype_page)
82
81
  # @type [String]
@@ -108,7 +107,6 @@ module Bridgetown
108
107
  # Provide a list of all relevent indexed values for the given term.
109
108
  #
110
109
  # @param search_term [String]
111
- #
112
110
  # @return [Array<String>]
113
111
  def terms_matching_pages(search_term)
114
112
  pages_list = site.collections[@configured_collection].resources
@@ -25,7 +25,6 @@ module Bridgetown
25
25
 
26
26
  @registry = {}
27
27
 
28
- NotAvailable = Class.new(RuntimeError)
29
28
  Uncallable = Class.new(RuntimeError)
30
29
 
31
30
  def self.priority_value(priority)
@@ -95,11 +95,10 @@ module Bridgetown
95
95
  content || ""
96
96
  end
97
97
 
98
- # Accessor for data properties by Liquid.
98
+ # Accessor for data properties by Liquid
99
99
  #
100
- # property - The String name of the property to retrieve.
101
- #
102
- # Returns the String value or nil if the property isn't included.
100
+ # @param property [String] name of the property to retrieve
101
+ # @return [String, nil] value or nil if the property isn't included
103
102
  def [](property)
104
103
  data[property]
105
104
  end
@@ -4,11 +4,9 @@ module Bridgetown
4
4
  module LiquidExtensions
5
5
  # Lookup a Liquid variable in the given context.
6
6
  #
7
- # context - the Liquid context in question.
8
- # variable - the variable name, as a string.
9
- #
10
- # Returns the value of the variable in the context
11
- # or the variable name if not found.
7
+ # @param context [Liquid::Context]
8
+ # @param variable [String] the variable name
9
+ # @return [Object] value of the variable in the context or the variable name if not found
12
10
  def lookup_variable(context, variable)
13
11
  lookup = context
14
12
 
@@ -11,23 +11,19 @@ module Bridgetown
11
11
  error: ::Logger::ERROR,
12
12
  }.freeze
13
13
 
14
- # Public: Create a new instance of a log writer
14
+ # Create a new instance of a log writer
15
15
  #
16
- # writer - Logger compatible instance
17
- # log_level - (optional, symbol) the log level
18
- #
19
- # Returns nothing
16
+ # @param writer [Logger] compatible instance
17
+ # @param log_level [Symbol] the log level (`debug` | `info` | `warn` | `error`)
20
18
  def initialize(writer, level = :info)
21
19
  @messages = []
22
20
  @writer = writer
23
21
  self.log_level = level
24
22
  end
25
23
 
26
- # Public: Set the log level on the writer
27
- #
28
- # level - (symbol) the log level
24
+ # Set the log level on the writer
29
25
  #
30
- # Returns nothing
26
+ # @param log_level [Symbol] the log level (`debug` | `info` | `warn` | `error`)
31
27
  def log_level=(level)
32
28
  writer.level = level if level.is_a?(Integer) && level.between?(0, 3)
33
29
  writer.level = LOG_LEVELS[level] ||
@@ -45,63 +41,52 @@ module Bridgetown
45
41
  debug "Logging at level:", LOG_LEVELS.key(writer.level).to_s
46
42
  end
47
43
 
48
- # Public: Print a debug message
49
- #
50
- # topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
51
- # message - the message detail
44
+ # Print a debug message
52
45
  #
53
- # Returns nothing
46
+ # @param topic [String] e.g. "Configuration file", "Deprecation", etc.
47
+ # @param message [String] the message detail
54
48
  def debug(topic, message = nil, &)
55
49
  write(:debug, topic, message, &)
56
50
  end
57
51
 
58
- # Public: Print a message
52
+ # Print an informational message
59
53
  #
60
- # topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
61
- # message - the message detail
62
- #
63
- # Returns nothing
54
+ # @param topic [String] e.g. "Configuration file", "Deprecation", etc.
55
+ # @param message [String] the message detail
64
56
  def info(topic, message = nil, &)
65
57
  write(:info, topic, message, &)
66
58
  end
67
59
 
68
- # Public: Print a message
69
- #
70
- # topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
71
- # message - the message detail
60
+ # Print a warning message
72
61
  #
73
- # Returns nothing
62
+ # @param topic [String] e.g. "Configuration file", "Deprecation", etc.
63
+ # @param message [String] the message detail
74
64
  def warn(topic, message = nil, &)
75
65
  write(:warn, topic, message, &)
76
66
  end
77
67
 
78
- # Public: Print an error message
79
- #
80
- # topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
81
- # message - the message detail
68
+ # Print an error message
82
69
  #
83
- # Returns nothing
70
+ # @param topic [String] e.g. "Configuration file", "Deprecation", etc.
71
+ # @param message [String] the message detail
84
72
  def error(topic, message = nil, &)
85
73
  write(:error, topic, message, &)
86
74
  end
87
75
 
88
- # Public: Print an error message and immediately abort the process
76
+ # Print an error message and immediately abort the process
89
77
  #
90
- # topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
91
- # message - the message detail (can be omitted)
92
- #
93
- # Returns nothing
78
+ # @param topic [String] e.g. "Configuration file", "Deprecation", etc.
79
+ # @param message [String] the message detail
94
80
  def abort_with(topic, message = nil, &)
95
81
  error(topic, message, &)
96
82
  abort
97
83
  end
98
84
 
99
- # Internal: Build a topic method
100
- #
101
- # topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
102
- # message - the message detail
85
+ # Build a topic method
103
86
  #
104
- # Returns the formatted message
87
+ # @param topic [String] e.g. "Configuration file", "Deprecation", etc.
88
+ # @param message [String] the message detail
89
+ # @return [String] the formatted message
105
90
  def message(topic, message = nil)
106
91
  raise ArgumentError, "block or message, not both" if block_given? && message
107
92
 
@@ -113,34 +98,30 @@ module Bridgetown
113
98
  out
114
99
  end
115
100
 
116
- # Internal: Format the topic
117
- #
118
- # topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
119
- # colon -
101
+ # Format the topic
120
102
  #
121
- # Returns the formatted topic statement
103
+ # @param topic [String] e.g. "Configuration file", "Deprecation", etc.
104
+ # @param colon [Boolean]
105
+ # @return [String] formatted topic statement
122
106
  def formatted_topic(topic, colon = false) # rubocop:disable Style/OptionalBooleanParameter
123
107
  "#{topic}#{colon ? ": " : " "}".rjust(20)
124
108
  end
125
109
 
126
- # Internal: Check if the message should be written given the log level.
110
+ # Check if the message should be written given the log level
127
111
  #
128
- # level_of_message - the Symbol level of message, one of :debug, :info, :warn, :error
129
- #
130
- # Returns whether the message should be written.
112
+ # @param level_of_message [Symbol] the message level (`debug` | `info` | `warn` | `error`)
113
+ # @return [Boolean] whether the message should be written to the log
131
114
  def write_message?(level_of_message)
132
115
  LOG_LEVELS.fetch(level) <= LOG_LEVELS.fetch(level_of_message)
133
116
  end
134
117
 
135
- # Internal: Log a message.
136
- #
137
- # level_of_message - the Symbol level of message, one of :debug, :info, :warn, :error
138
- # topic - the String topic or full message
139
- # message - the String message (optional)
140
- # block - a block containing the message (optional)
118
+ # Log a message. If a block is provided containing the message, use that instead.
141
119
  #
142
- # Returns false if the message was not written, otherwise returns the value of calling
143
- # the appropriate writer method, e.g. writer.info.
120
+ # @param level_of_message [Symbol] the message level (`debug` | `info` | `warn` | `error`)
121
+ # @param topic [String] e.g. "Configuration file", "Deprecation", etc.
122
+ # @param message [String] the message detail
123
+ # @return [BasicObject] false if the message was not written, otherwise returns the value of
124
+ # calling the appropriate writer method, e.g. writer.info.
144
125
  def write(level_of_message, topic, message = nil, &)
145
126
  return false unless write_message?(level_of_message)
146
127
 
@@ -27,6 +27,7 @@ module Bridgetown
27
27
 
28
28
  require_relative "utils/initializers"
29
29
  load_determined_bundler_environment
30
+ require_plugin_features
30
31
 
31
32
  ENV["BRIDGETOWN_NO_BUNDLER_REQUIRE"] = "true"
32
33
  true
@@ -52,6 +53,16 @@ module Bridgetown
52
53
  end
53
54
  end
54
55
 
56
+ def self.require_plugin_features
57
+ bundler_specs.select do |loaded_gem|
58
+ loaded_gem.to_spec.metadata["bridgetown_features"] == "true"
59
+ end.each do |plugin_gem|
60
+ Bridgetown::Utils::RequireGems.require_with_graceful_fail(
61
+ "bridgetown/features/#{plugin_gem.name}"
62
+ )
63
+ end
64
+ end
65
+
55
66
  def self.require_gem(name)
56
67
  Bridgetown::Utils::RequireGems.require_with_graceful_fail(name)
57
68
  plugins = Bridgetown::PluginManager.install_npm_dependencies(name:)
@@ -70,12 +81,12 @@ module Bridgetown
70
81
  end
71
82
 
72
83
  def self.package_manager
73
- @package_manager ||= if File.exist?("package-lock.json")
74
- "npm"
75
- elsif File.exist?("yarn.lock")
84
+ @package_manager ||= if File.exist?("yarn.lock")
76
85
  "yarn"
77
86
  elsif File.exist?("pnpm-lock.yaml")
78
87
  "pnpm"
88
+ elsif File.exist?("package.json")
89
+ "npm"
79
90
  else
80
91
  ""
81
92
  end
@@ -85,6 +96,10 @@ module Bridgetown
85
96
  package_manager == "npm" ? "install" : "add"
86
97
  end
87
98
 
99
+ def self.package_manager_uninstall_command
100
+ package_manager == "npm" ? "uninstall" : "remove"
101
+ end
102
+
88
103
  # rubocop:disable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
89
104
 
90
105
  # Iterates through loaded gems and finds npm-add gemspec metadata.
@@ -7,8 +7,6 @@ module Bridgetown
7
7
  module Rack
8
8
  class Logger < Bridgetown::LogWriter
9
9
  def self.message_with_prefix(msg)
10
- # return if msg.include?("/_bridgetown/live_reload")
11
-
12
10
  "\e[35m[Server]\e[0m #{msg}"
13
11
  end
14
12