andromeda_cms 0.6.2 → 0.6.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 64670cf71e6544d5427eeb01b7fbd90eda3a717dbb28379dd836df5662d24563
4
- data.tar.gz: 7966c38ad14347e3161f3a8f7018daa5438dddb00aacfee099e9d2c014e500d9
3
+ metadata.gz: 1d92fa60e3244d13f120342265e2f29a752dc6062dabd92a1c51b1a6f8c1f22a
4
+ data.tar.gz: 91a101ffae9034aa33c1eadc84c9d9d5cc0a8f08dea30f3e075a754917c053cf
5
5
  SHA512:
6
- metadata.gz: b6fe4b7a80ca8828ef6ecfeb77ec1ceb8ec5717df836bd6f68e328adc5e9fdb162e1607d26b92167d7420639874c5a203ea25bcf7325d5952a4acbb1f76b76c3
7
- data.tar.gz: 5db3fa88aab475e40522a9024d8d22f8887ec106fad290fbfec7b18addb13ab68dba3db3e48e080d43603c3c50a6439e14c6b0fec912ba40a8dba270fae82799
6
+ metadata.gz: d8f6e1c4f538a237870c99b5f2ac1bef995c4d0373320a86598b00a2eb889d9a8b2741f77bc2a109d20ec0891838d86db54d87294269a3ebdbe424dc5f0f9bd1
7
+ data.tar.gz: 64f980afb528c86e323a153b5d2932272ecad9e6df9b737255d4aa5062aaa102b8c139e2783e71fcaa9de990a14712f75157d9c7a9fda37809508cb5c6824d6f
data/CHANGELOG.md CHANGED
@@ -5,6 +5,25 @@ All notable changes to this project are documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.6.3] - 2026-10-16
9
+
10
+ ### Fixed
11
+
12
+ - `andromeda:import_astro` no longer silently mishandles a `glob()` `pattern`
13
+ it cannot carry over. An array pattern is reduced to its first
14
+ non-exclusion element (it used to take the first string, even a `!`
15
+ exclusion), and a note in the report's "Needs a human" section plus a
16
+ `# TODO` above the generated `collection` line name what was lost:
17
+ exclusions that are not applied (those files are still copied and
18
+ loaded) and extra patterns that were dropped (those files are copied but
19
+ not loaded). An extglob pattern such as `!(drafts)/**/*.md`, which Ruby's
20
+ glob cannot match, is flagged the same way instead of leaving the
21
+ collection empty.
22
+ - The gem now requires `tomlrb ~> 2.0`. tomlrb 3.0 removed
23
+ `Tomlrb::Scanner`, which TOML frontmatter parsing uses to report the line
24
+ of a syntax error, so on Ruby 3.3 and later a fresh install picked up 3.0
25
+ and every TOML frontmatter raised `NameError`.
26
+
8
27
  ## [0.6.2] - 2026-10-09
9
28
 
10
29
  ### Fixed
@@ -189,6 +208,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
189
208
  - Generators: `andromeda:install`, `andromeda:collection`,
190
209
  `andromeda:component` and `andromeda:import_astro`.
191
210
 
211
+ [0.6.3]: https://github.com/AndromedaCMS/andromeda_cms/releases/tag/v0.6.3
192
212
  [0.6.2]: https://github.com/AndromedaCMS/andromeda_cms/releases/tag/v0.6.2
193
213
  [0.6.1]: https://github.com/AndromedaCMS/andromeda_cms/releases/tag/v0.6.1
194
214
  [0.6.0]: https://github.com/AndromedaCMS/andromeda_cms/releases/tag/v0.6.0
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Andromeda
4
- VERSION = "0.6.2"
4
+ VERSION = "0.6.3"
5
5
  end
@@ -18,7 +18,19 @@ module Andromeda
18
18
  # already makes for MDX import statements. Anything shaped differently
19
19
  # falls through to `Attribute#unsupported?` rather than guessing.
20
20
  module ContentConfigConverter
21
- Collection = Struct.new(:name, :base, :pattern, :attributes, keyword_init: true)
21
+ # `notes` are things about the collection itself (not one field)
22
+ # that still need a human -- e.g. a `pattern` this importer cannot
23
+ # carry over as written. Defaults to empty so existing
24
+ # `Collection.new` calls stay valid.
25
+ Collection = Struct.new(:name, :base, :pattern, :attributes, :notes, keyword_init: true) do
26
+ def initialize(notes: [], **rest) = super(notes: notes, **rest)
27
+ end
28
+
29
+ DEFAULT_PATTERN = "**/*.{md,mdx}"
30
+
31
+ # Bash-style extglob openers (`!(drafts)`, `@(a|b)`, ...), which
32
+ # Astro's glob loader accepts but Ruby's `Dir.glob` does not.
33
+ EXTGLOB_RE = /[!@+*?]\(/.freeze
22
34
 
23
35
  # One frontmatter field. `ruby_type` is nil when the Zod expression
24
36
  # could not be recognized at all -- `source` (the original
@@ -65,16 +77,64 @@ module Andromeda
65
77
  def build_collection(name, body, astro_root:)
66
78
  body = BalancedScanner.strip_comments(body)
67
79
  base = extract_string(body, /base\s*:/) || "./src/content/#{name}"
68
- pattern = extract_string(body, /pattern\s*:/) || "**/*.{md,mdx}"
80
+ pattern, notes = extract_pattern(body)
69
81
 
70
82
  Collection.new(
71
83
  name: name,
72
84
  base: File.expand_path(base, astro_root),
73
85
  pattern: pattern,
74
- attributes: extract_attributes(body)
86
+ attributes: extract_attributes(body),
87
+ notes: notes
75
88
  )
76
89
  end
77
90
 
91
+ # Astro's `glob({ pattern: ... })` also takes an array (with `!`
92
+ # exclusions) and extglob syntax -- neither of which `Dir.glob`
93
+ # understands. Rather than silently dropping them, the closest
94
+ # usable pattern is kept and a note says what was lost.
95
+ #
96
+ # @return [Array(String, Array<String>)] the pattern and any notes.
97
+ def extract_pattern(body)
98
+ match = /pattern\s*:\s*\[/.match(body)
99
+ return extract_array_pattern(body, match.end(0) - 1) if match
100
+
101
+ pattern = extract_string(body, /pattern\s*:/) || DEFAULT_PATTERN
102
+ return [pattern, []] unless pattern.match?(EXTGLOB_RE)
103
+
104
+ [pattern, ["pattern `#{pattern}` uses extglob syntax, which Ruby's glob does not support -- " \
105
+ "no files will match this pattern"]]
106
+ end
107
+
108
+ # Only what was actually lost gets a note: `!` exclusions (still
109
+ # copied and loaded) and any further non-exclusion patterns (copied
110
+ # but not loaded). A one-element or empty array loses nothing.
111
+ def extract_array_pattern(body, open_index)
112
+ close = BalancedScanner.matching_close(body, open_index)
113
+ # Squished onto one line: the note also becomes a `# TODO` comment.
114
+ source = body[open_index..close].gsub(/\s+/, " ")
115
+ elements = BalancedScanner.split_top_level(body[(open_index + 1)...close]).map do |literal|
116
+ literal.gsub(/\A(['"`])(.*)\1\z/, '\2')
117
+ end.reject(&:empty?)
118
+ exclusions, includes = elements.partition { |element| element.start_with?("!") }
119
+ pattern = includes.first || DEFAULT_PATTERN
120
+ dropped = includes.drop(1)
121
+
122
+ notes = []
123
+ unless exclusions.empty?
124
+ notes << "exclusions #{backticked(exclusions)} from pattern array #{source} are not applied, " \
125
+ "so the files they exclude are still copied and loaded"
126
+ end
127
+ unless dropped.empty?
128
+ notes << "patterns #{backticked(dropped)} from pattern array #{source} were dropped " \
129
+ "(only `#{pattern}` was kept), so files matching only them are copied but not loaded"
130
+ end
131
+ [pattern, notes]
132
+ end
133
+
134
+ def backticked(elements)
135
+ elements.map { |element| "`#{element}`" }.join(", ")
136
+ end
137
+
78
138
  # @return [String, nil] the quoted value right after `label_re`, e.g.
79
139
  # `base: './src/content/blog'` -> `"./src/content/blog"`.
80
140
  def extract_string(body, label_re)
@@ -80,7 +80,10 @@ module Andromeda
80
80
  fallback_collections
81
81
  end
82
82
 
83
- @collections.each { |collection| refine_with_json_schema!(collection) }
83
+ @collections.each do |collection|
84
+ refine_with_json_schema!(collection)
85
+ collection.notes.each { |note| @report[:notes] << "#{collection.name}: #{note}" }
86
+ end
84
87
  end
85
88
 
86
89
  # The fallback clause: every top-level directory under
@@ -231,6 +234,9 @@ module Andromeda
231
234
  lines = ["# frozen_string_literal: true", ""]
232
235
  namespace_modules.each_with_index { |mod, i| lines << "#{" " * i}module #{mod}" }
233
236
  lines << "#{indent}class #{collection.name.to_s.singularize.camelize} < Andromeda::Entry"
237
+ collection.notes.each do |note|
238
+ lines << "#{indent} # TODO: #{note} (content.config.ts) -- fix `pattern` by hand."
239
+ end
234
240
  lines << "#{indent} collection :#{collection.name}, base: \"app/content/#{collection.name}\", " \
235
241
  "pattern: \"#{collection.pattern}\""
236
242
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: andromeda_cms
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.2
4
+ version: 0.6.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - LIMHAUS Inc.
@@ -55,14 +55,14 @@ dependencies:
55
55
  name: tomlrb
56
56
  requirement: !ruby/object:Gem::Requirement
57
57
  requirements:
58
- - - ">="
58
+ - - "~>"
59
59
  - !ruby/object:Gem::Version
60
60
  version: '2.0'
61
61
  type: :runtime
62
62
  prerelease: false
63
63
  version_requirements: !ruby/object:Gem::Requirement
64
64
  requirements:
65
- - - ">="
65
+ - - "~>"
66
66
  - !ruby/object:Gem::Version
67
67
  version: '2.0'
68
68
  - !ruby/object:Gem::Dependency