ro 4.2.0 → 5.0.0

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 (252) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +57 -10
  3. data/LICENSE +1 -1
  4. data/MIGRATION.md +320 -0
  5. data/README.md +286 -111
  6. data/Rakefile +2 -2
  7. data/a.yml +60 -0
  8. data/bin/ro +10 -0
  9. data/lib/ro/_lib.rb +18 -6
  10. data/lib/ro/asset.rb +67 -16
  11. data/lib/ro/collection.rb +91 -10
  12. data/lib/ro/config.rb +4 -0
  13. data/lib/ro/error.rb +5 -2
  14. data/lib/ro/html.rb +23 -0
  15. data/lib/ro/html_safe.rb +143 -0
  16. data/lib/ro/methods.rb +95 -38
  17. data/lib/ro/migrator.rb +285 -0
  18. data/lib/ro/node.rb +128 -45
  19. data/lib/ro/path.rb +4 -0
  20. data/lib/ro/root.rb +75 -1
  21. data/lib/ro/script/migrate.rb +204 -0
  22. data/lib/ro/script/server.rb +1 -1
  23. data/lib/ro/template.rb +62 -22
  24. data/lib/ro/text.rb +120 -0
  25. data/lib/ro.rb +5 -0
  26. data/public/api/ro/index-1.json +997 -79
  27. data/public/api/ro/index.json +997 -79
  28. data/public/api/ro/nerd/fastest-possible-embeddings/index.json +90 -0
  29. data/public/api/ro/nerd/ima/index.json +49 -0
  30. data/public/api/ro/nerd/index/index.json +74 -0
  31. data/public/api/ro/nerd/index-1.json +204 -0
  32. data/public/api/ro/nerd/index.json +194 -0
  33. data/public/api/ro/pages/about/index.json +60 -0
  34. data/public/api/ro/pages/contact/index.json +50 -0
  35. data/public/api/ro/pages/cv/index.json +49 -0
  36. data/public/api/ro/pages/disco/index.json +117 -0
  37. data/public/api/ro/pages/index/index.json +30 -0
  38. data/public/api/ro/pages/index-1.json +366 -0
  39. data/public/api/ro/pages/index.json +356 -0
  40. data/public/api/ro/pages/jess/index.json +62 -0
  41. data/public/api/ro/pages/now/index.json +43 -0
  42. data/public/api/ro/posts/almost-died-in-an-ice-cave/index.json +265 -0
  43. data/public/api/ro/posts/facebook-and-global-extremism/index.json +90 -0
  44. data/public/api/ro/posts/index-1.json +461 -79
  45. data/public/api/ro/posts/index.json +461 -79
  46. data/public/api/ro/posts/lemmings-considered-harmful/index.json +49 -0
  47. data/public/api/ro/posts/lost-in-the-desert/index.json +49 -0
  48. data/public/api/ro/posts/mission/index.json +49 -0
  49. data/public/api/ro/posts/return-your-laptop/index.json +61 -0
  50. data/public/ro/nerd/fastest-possible-embeddings/assets/giraffe.jpeg +0 -0
  51. data/public/ro/nerd/fastest-possible-embeddings/assets/let-me-in.jpg +0 -0
  52. data/public/ro/nerd/fastest-possible-embeddings/assets/src/fastembed.js +70 -0
  53. data/public/ro/nerd/fastest-possible-embeddings/assets/src/fastembed.rs +68 -0
  54. data/public/ro/nerd/fastest-possible-embeddings/assets/terminal.jpg +0 -0
  55. data/public/ro/nerd/fastest-possible-embeddings/body.md +266 -0
  56. data/public/ro/nerd/fastest-possible-embeddings.yml +7 -0
  57. data/public/ro/nerd/ima/assets/og.jpeg +0 -0
  58. data/public/ro/nerd/ima/body.md +22 -0
  59. data/public/ro/nerd/ima.yml +8 -0
  60. data/public/ro/nerd/index/assets/giraffe.jpeg +0 -0
  61. data/public/ro/nerd/index/assets/let-me-in.jpg +0 -0
  62. data/public/ro/nerd/index/assets/terminal.jpg +0 -0
  63. data/public/ro/nerd/index/body.md +130 -0
  64. data/public/ro/nerd/index.yml +7 -0
  65. data/public/ro/pages/about/assets/og.jpeg +0 -0
  66. data/public/ro/pages/about/assets/speak-english-pulp-fiction.gif +0 -0
  67. data/public/ro/pages/about/body.md +40 -0
  68. data/public/ro/pages/contact/assets/giraffe.jpeg +0 -0
  69. data/public/ro/pages/contact/body.md +9 -0
  70. data/public/ro/pages/contact.yml +7 -0
  71. data/public/ro/pages/cv/assets/ara.jpg +0 -0
  72. data/public/ro/pages/cv/body.md +122 -0
  73. data/public/ro/pages/cv.yml +6 -0
  74. data/public/ro/pages/disco/assets/disco.jpg +0 -0
  75. data/public/ro/pages/disco/assets/disco.png +0 -0
  76. data/public/ro/pages/disco/assets/speak-english-pulp-fiction.gif +0 -0
  77. data/public/ro/pages/disco/assets/src/environment.md +2354 -0
  78. data/public/ro/pages/disco/assets/src/fortune-500.md +2518 -0
  79. data/public/ro/pages/disco/assets/src/greed.md +2703 -0
  80. data/public/ro/pages/disco/assets/src/up-at-night.md +2337 -0
  81. data/public/ro/pages/disco/body.md +99 -0
  82. data/public/ro/pages/disco/samples/environment.md +2354 -0
  83. data/public/ro/pages/disco/samples/fortune-500.md +2518 -0
  84. data/public/ro/pages/disco/samples/greed.md +2703 -0
  85. data/public/ro/pages/disco/samples/up-at-night.md +2337 -0
  86. data/public/ro/pages/disco.yml +9 -0
  87. data/public/ro/pages/index/body.md +15 -0
  88. data/public/ro/pages/index.yml +1 -0
  89. data/public/ro/pages/jess/assets/og.jpg +0 -0
  90. data/public/ro/pages/jess/assets/speak-english-pulp-fiction.gif +0 -0
  91. data/public/ro/pages/jess/body.md +3 -0
  92. data/public/ro/pages/jess.yml +7 -0
  93. data/public/ro/pages/now/assets/speak-english-pulp-fiction.gif +0 -0
  94. data/public/ro/pages/now/body.md +24 -0
  95. data/public/ro/pages/now.yml +1 -0
  96. data/public/ro/posts/almost-died-in-an-ice-cave/assets/image1.png +0 -0
  97. data/public/ro/posts/almost-died-in-an-ice-cave/assets/image10.png +0 -0
  98. data/public/ro/posts/almost-died-in-an-ice-cave/assets/image11.png +0 -0
  99. data/public/ro/posts/almost-died-in-an-ice-cave/assets/image12.png +0 -0
  100. data/public/ro/posts/almost-died-in-an-ice-cave/assets/image13.png +0 -0
  101. data/public/ro/posts/almost-died-in-an-ice-cave/assets/image14.png +0 -0
  102. data/public/ro/posts/almost-died-in-an-ice-cave/assets/image15.png +0 -0
  103. data/public/ro/posts/almost-died-in-an-ice-cave/assets/image2.png +0 -0
  104. data/public/ro/posts/almost-died-in-an-ice-cave/assets/image3.png +0 -0
  105. data/public/ro/posts/almost-died-in-an-ice-cave/assets/image4.png +0 -0
  106. data/public/ro/posts/almost-died-in-an-ice-cave/assets/image5.png +0 -0
  107. data/public/ro/posts/almost-died-in-an-ice-cave/assets/image6.png +0 -0
  108. data/public/ro/posts/almost-died-in-an-ice-cave/assets/image7.png +0 -0
  109. data/public/ro/posts/almost-died-in-an-ice-cave/assets/image8.png +0 -0
  110. data/public/ro/posts/almost-died-in-an-ice-cave/assets/image9.png +0 -0
  111. data/public/ro/posts/almost-died-in-an-ice-cave/assets/josh-pointing.jpg +0 -0
  112. data/public/ro/posts/almost-died-in-an-ice-cave/assets/levi-rawr.png +0 -0
  113. data/public/ro/posts/almost-died-in-an-ice-cave/assets/og.jpg +0 -0
  114. data/public/ro/posts/almost-died-in-an-ice-cave/assets/purple-heart.jpg +0 -0
  115. data/public/ro/posts/almost-died-in-an-ice-cave/body.md +419 -0
  116. data/public/ro/posts/almost-died-in-an-ice-cave.yml +6 -0
  117. data/public/ro/posts/facebook-and-global-extremism/assets/background.html +125 -0
  118. data/public/ro/posts/facebook-and-global-extremism/assets/background.md +95 -0
  119. data/public/ro/posts/facebook-and-global-extremism/assets/og.jpg +0 -0
  120. data/public/ro/posts/facebook-and-global-extremism/assets/prompt.txt +122 -0
  121. data/public/ro/posts/facebook-and-global-extremism/assets/results.md +183 -0
  122. data/public/ro/posts/facebook-and-global-extremism/assets/survey.txt +190 -0
  123. data/public/ro/posts/facebook-and-global-extremism/body.md +393 -0
  124. data/public/ro/posts/facebook-and-global-extremism.yml +7 -0
  125. data/public/ro/posts/lemmings-considered-harmful/assets/lemming.jpeg +0 -0
  126. data/public/ro/posts/lemmings-considered-harmful/body.md +43 -0
  127. data/public/ro/posts/lemmings-considered-harmful.yml +6 -0
  128. data/public/ro/posts/lost-in-the-desert/assets/og.jpg +0 -0
  129. data/public/ro/posts/lost-in-the-desert/body.md +7 -0
  130. data/public/ro/posts/lost-in-the-desert.yml +6 -0
  131. data/public/ro/posts/mission/assets/og.jpg +0 -0
  132. data/public/ro/posts/mission/body.md +4 -0
  133. data/public/ro/posts/mission.yml +6 -0
  134. data/public/ro/posts/return-your-laptop/assets/og.jpg +0 -0
  135. data/public/ro/posts/return-your-laptop/assets/return-your-laptop.png +0 -0
  136. data/public/ro/posts/return-your-laptop/body.md +58 -0
  137. data/public/ro/posts/return-your-laptop.yml +6 -0
  138. data/ro.gemspec +369 -49
  139. data/scripts/speedtest.rb +324 -0
  140. data/specs/001-simplify-asset-structure/IMPLEMENTATION_SUMMARY.md +212 -0
  141. data/specs/001-simplify-asset-structure/checklists/requirements.md +36 -0
  142. data/specs/001-simplify-asset-structure/contracts/collection_api.md +407 -0
  143. data/specs/001-simplify-asset-structure/contracts/migrator_api.md +461 -0
  144. data/specs/001-simplify-asset-structure/contracts/node_api.md +294 -0
  145. data/specs/001-simplify-asset-structure/data-model.md +381 -0
  146. data/specs/001-simplify-asset-structure/plan.md +90 -0
  147. data/specs/001-simplify-asset-structure/quickstart.md +575 -0
  148. data/specs/001-simplify-asset-structure/research.md +333 -0
  149. data/specs/001-simplify-asset-structure/spec.md +127 -0
  150. data/specs/001-simplify-asset-structure/tasks.md +349 -0
  151. data/test/fixtures/new_structure/mixed/test-json.json +5 -0
  152. data/test/fixtures/new_structure/mixed/test-yaml.yml +3 -0
  153. data/test/fixtures/new_structure/posts/metadata-only.yml +7 -0
  154. data/test/fixtures/new_structure/posts/nested-test/assets/subdirectory/image.png +2 -0
  155. data/test/fixtures/new_structure/posts/nested-test.yml +7 -0
  156. data/test/fixtures/new_structure/posts/sample-post/assets/body.md +5 -0
  157. data/test/fixtures/new_structure/posts/sample-post/assets/image.jpg +2 -0
  158. data/test/fixtures/new_structure/posts/sample-post.yml +7 -0
  159. data/test/fixtures/old_structure/posts/assets-only/assets/test.txt +1 -0
  160. data/test/fixtures/old_structure/posts/sample-post/assets/body.md +5 -0
  161. data/test/fixtures/old_structure/posts/sample-post/assets/image.jpg +2 -0
  162. data/test/fixtures/old_structure/posts/sample-post/attributes.yml +2 -0
  163. data/test/integration/ro_integration_test.rb +165 -0
  164. data/test/test_helper.rb +149 -0
  165. data/test/tmp/migration_test_1760746513.backup.20251018001513/migration_test_1760746513/posts/sample-post/assets/image.jpg +2 -0
  166. data/test/tmp/migration_test_1760746513.backup.20251018001513/migration_test_1760746513/posts/sample-post/attributes.yml +7 -0
  167. data/test/tmp/migration_test_1760746513.backup.20251018001513/migration_test_1760746513/posts/sample-post/body.md +5 -0
  168. data/test/tmp/migration_test_1760746513.backup.20251018001513/posts/sample-post/assets/image.jpg +2 -0
  169. data/test/tmp/migration_test_1760746513.backup.20251018001513/posts/sample-post/attributes.yml +7 -0
  170. data/test/tmp/migration_test_1760746513.backup.20251018001513/posts/sample-post/body.md +5 -0
  171. data/test/tmp/migration_test_1760746556.backup.20251018001556/migration_test_1760746556/posts/sample-post/assets/image.jpg +2 -0
  172. data/test/tmp/migration_test_1760746556.backup.20251018001556/migration_test_1760746556/posts/sample-post/attributes.yml +7 -0
  173. data/test/tmp/migration_test_1760746556.backup.20251018001556/migration_test_1760746556/posts/sample-post/body.md +5 -0
  174. data/test/tmp/migration_test_1760746556.backup.20251018001556/posts/sample-post/assets/image.jpg +2 -0
  175. data/test/tmp/migration_test_1760746556.backup.20251018001556/posts/sample-post/attributes.yml +7 -0
  176. data/test/tmp/migration_test_1760746556.backup.20251018001556/posts/sample-post/body.md +5 -0
  177. data/test/tmp/migration_test_1760755248.backup.20251018024048/migration_test_1760755248/posts/sample-post/assets/image.jpg +2 -0
  178. data/test/tmp/migration_test_1760755248.backup.20251018024048/migration_test_1760755248/posts/sample-post/attributes.yml +7 -0
  179. data/test/tmp/migration_test_1760755248.backup.20251018024048/migration_test_1760755248/posts/sample-post/body.md +5 -0
  180. data/test/tmp/migration_test_1760755248.backup.20251018024048/posts/sample-post/assets/image.jpg +2 -0
  181. data/test/tmp/migration_test_1760755248.backup.20251018024048/posts/sample-post/attributes.yml +7 -0
  182. data/test/tmp/migration_test_1760755248.backup.20251018024048/posts/sample-post/body.md +5 -0
  183. data/test/tmp/migration_test_1760758803.backup.20251018034003/migration_test_1760758803/posts/sample-post/body.md +5 -0
  184. data/test/tmp/migration_test_1760758803.backup.20251018034003/migration_test_1760758803/posts/sample-post/image.jpg +2 -0
  185. data/test/tmp/migration_test_1760758803.backup.20251018034003/migration_test_1760758803/posts/sample-post.yml +7 -0
  186. data/test/tmp/migration_test_1760758803.backup.20251018034003/posts/sample-post/body.md +5 -0
  187. data/test/tmp/migration_test_1760758803.backup.20251018034003/posts/sample-post/image.jpg +2 -0
  188. data/test/tmp/migration_test_1760758803.backup.20251018034003/posts/sample-post.yml +7 -0
  189. data/test/tmp/migration_test_1760758869.backup.20251018034109/migration_test_1760758869/posts/sample-post/assets/body.md +5 -0
  190. data/test/tmp/migration_test_1760758869.backup.20251018034109/migration_test_1760758869/posts/sample-post/assets/image.jpg +2 -0
  191. data/test/tmp/migration_test_1760758869.backup.20251018034109/migration_test_1760758869/posts/sample-post/attributes.yml +2 -0
  192. data/test/tmp/migration_test_1760758869.backup.20251018034109/posts/sample-post/assets/body.md +5 -0
  193. data/test/tmp/migration_test_1760758869.backup.20251018034109/posts/sample-post/assets/image.jpg +2 -0
  194. data/test/tmp/migration_test_1760758869.backup.20251018034109/posts/sample-post/attributes.yml +2 -0
  195. data/test/tmp/migration_test_1760758920.backup.20251018034200/migration_test_1760758920/posts/sample-post/assets/body.md +5 -0
  196. data/test/tmp/migration_test_1760758920.backup.20251018034200/migration_test_1760758920/posts/sample-post/assets/image.jpg +2 -0
  197. data/test/tmp/migration_test_1760758920.backup.20251018034200/migration_test_1760758920/posts/sample-post/attributes.yml +2 -0
  198. data/test/tmp/migration_test_1760758920.backup.20251018034200/posts/sample-post/assets/body.md +5 -0
  199. data/test/tmp/migration_test_1760758920.backup.20251018034200/posts/sample-post/assets/image.jpg +2 -0
  200. data/test/tmp/migration_test_1760758920.backup.20251018034200/posts/sample-post/attributes.yml +2 -0
  201. data/test/tmp/migration_test_1760824728.backup.20251018215848/migration_test_1760824728/posts/assets-only/assets/test.txt +1 -0
  202. data/test/tmp/migration_test_1760824728.backup.20251018215848/migration_test_1760824728/posts/sample-post/assets/body.md +5 -0
  203. data/test/tmp/migration_test_1760824728.backup.20251018215848/migration_test_1760824728/posts/sample-post/assets/image.jpg +2 -0
  204. data/test/tmp/migration_test_1760824728.backup.20251018215848/migration_test_1760824728/posts/sample-post/attributes.yml +2 -0
  205. data/test/tmp/migration_test_1760824728.backup.20251018215848/posts/assets-only/assets/test.txt +1 -0
  206. data/test/tmp/migration_test_1760824728.backup.20251018215848/posts/sample-post/assets/body.md +5 -0
  207. data/test/tmp/migration_test_1760824728.backup.20251018215848/posts/sample-post/assets/image.jpg +2 -0
  208. data/test/tmp/migration_test_1760824728.backup.20251018215848/posts/sample-post/attributes.yml +2 -0
  209. data/test/tmp/migration_test_1760844153.backup.20251019032233/migration_test_1760844153/posts/assets-only/assets/test.txt +1 -0
  210. data/test/tmp/migration_test_1760844153.backup.20251019032233/migration_test_1760844153/posts/sample-post/assets/body.md +5 -0
  211. data/test/tmp/migration_test_1760844153.backup.20251019032233/migration_test_1760844153/posts/sample-post/assets/image.jpg +2 -0
  212. data/test/tmp/migration_test_1760844153.backup.20251019032233/migration_test_1760844153/posts/sample-post/attributes.yml +2 -0
  213. data/test/tmp/migration_test_1760844153.backup.20251019032233/posts/assets-only/assets/test.txt +1 -0
  214. data/test/tmp/migration_test_1760844153.backup.20251019032233/posts/sample-post/assets/body.md +5 -0
  215. data/test/tmp/migration_test_1760844153.backup.20251019032233/posts/sample-post/assets/image.jpg +2 -0
  216. data/test/tmp/migration_test_1760844153.backup.20251019032233/posts/sample-post/attributes.yml +2 -0
  217. data/test/tmp/new_structure_test_1760746452/mixed/test-json.json +5 -0
  218. data/test/tmp/new_structure_test_1760746452/mixed/test-yaml.yml +3 -0
  219. data/test/tmp/new_structure_test_1760746452/posts/metadata-only.yml +7 -0
  220. data/test/tmp/new_structure_test_1760746452/posts/nested-test/subdirectory/image.png +2 -0
  221. data/test/tmp/new_structure_test_1760746452/posts/nested-test.yml +7 -0
  222. data/test/tmp/new_structure_test_1760746452/posts/sample-post/body.md +5 -0
  223. data/test/tmp/new_structure_test_1760746452/posts/sample-post/image.jpg +2 -0
  224. data/test/tmp/new_structure_test_1760746452/posts/sample-post.yml +7 -0
  225. data/test/unit/asset_test.rb +90 -0
  226. data/test/unit/collection_test.rb +127 -0
  227. data/test/unit/migrator_test.rb +209 -0
  228. data/test/unit/node_test.rb +138 -0
  229. data/tmp/gem-details.oe +0 -0
  230. metadata +250 -33
  231. data/public/api/ro/posts/first_post/index.json +0 -52
  232. data/public/api/ro/posts/second_post/index.json +0 -51
  233. data/public/api/ro/posts/third_post/index.json +0 -51
  234. data/public/ro/posts/first_post/assets/foo/bar/baz.jpg +0 -0
  235. data/public/ro/posts/first_post/assets/foo.jpg +0 -0
  236. data/public/ro/posts/first_post/assets/src/foo/bar.rb +0 -3
  237. data/public/ro/posts/first_post/attributes.yml +0 -2
  238. data/public/ro/posts/first_post/blurb.erb.md +0 -7
  239. data/public/ro/posts/first_post/body.md +0 -16
  240. data/public/ro/posts/first_post/testing.txt +0 -3
  241. data/public/ro/posts/second_post/assets/foo/bar/baz.jpg +0 -0
  242. data/public/ro/posts/second_post/assets/foo.jpg +0 -0
  243. data/public/ro/posts/second_post/assets/src/foo/bar.rb +0 -3
  244. data/public/ro/posts/second_post/attributes.yml +0 -2
  245. data/public/ro/posts/second_post/blurb.erb.md +0 -5
  246. data/public/ro/posts/second_post/body.md +0 -16
  247. data/public/ro/posts/third_post/assets/foo/bar/baz.jpg +0 -0
  248. data/public/ro/posts/third_post/assets/foo.jpg +0 -0
  249. data/public/ro/posts/third_post/assets/src/foo/bar.rb +0 -3
  250. data/public/ro/posts/third_post/attributes.yml +0 -2
  251. data/public/ro/posts/third_post/blurb.erb.md +0 -5
  252. data/public/ro/posts/third_post/body.md +0 -16
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 50e5d272b2bdbfe25f9ae109ed44568e71637820c4768ea772e757c7436c38cc
4
- data.tar.gz: 84372b1f2cc28f316ed1eff63c0ce6ec4333f18a886a0cc38f4c86617baa0c0a
3
+ metadata.gz: f467beebd987ebb866a7f57a04810ca0c9c4f55396ca07607788c9c614919531
4
+ data.tar.gz: 73ccfea5d2a5d0d8eac25c1a508c3d16de2d52d44dc6b6d250f2e6e1b5616a2e
5
5
  SHA512:
6
- metadata.gz: e92b12b8067606b5b5ee11a3db65c926e492298aa3bed178459550d578a6b493762acbc3424fc0e2ac259d84d45cab1a69bc5e07e3550e58cbbdd14b18078c11
7
- data.tar.gz: 7a587649abd8cb3a79e667d4767b33005a47a860983725546acdae8f97dfadaafe140f49fda93a12000097171ed4aba7fea5507467bd480b9b83496115aa3352
6
+ metadata.gz: 4f625e44529a3e41f0d9e1f7ddd324ab439be33e364487bf48a8c9d01611694143f80d5747b0432fea673a2a598692bdbb760306a7a6370f5abb006c3ef23a1b
7
+ data.tar.gz: be8bf1fdb7ea9e0ba6b66095c767c6ce4d68c3680cab4fbe8c01cf1e5f85aad011542c94c8478bbf35dab2ec431befd0e7c343a06ff53b54386049e7f42fb013
data/Gemfile.lock CHANGED
@@ -1,13 +1,17 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ro (2.0.0)
5
- ak47 (~> 0.2)
4
+ ro (4.4.1)
5
+ ak47 (~> 0.2.5)
6
+ front_matter_parser (~> 1.0)
7
+ image_size (~> 3.4)
6
8
  kramdown (~> 2.4, >= 2.4.0)
7
9
  kramdown-parser-gfm (~> 1.1, >= 1.1.0)
8
10
  map (~> 6.6, >= 6.6.0)
11
+ nokogiri (~> 1)
12
+ rinku (~> 2.0)
9
13
  rouge (~> 4.1, >= 4.1.1)
10
- webrick (~> 1.8.1)
14
+ webrick (~> 1.9, >= 1.9.1)
11
15
 
12
16
  GEM
13
17
  remote: https://rubygems.org/
@@ -16,28 +20,71 @@ GEM
16
20
  guard (~> 0.10.0)
17
21
  shell_tools (~> 0.1.0)
18
22
  smart_colored
19
- ffi (1.16.3)
23
+ ffi (1.17.2)
24
+ ffi (1.17.2-aarch64-linux-gnu)
25
+ ffi (1.17.2-aarch64-linux-musl)
26
+ ffi (1.17.2-arm-linux-gnu)
27
+ ffi (1.17.2-arm-linux-musl)
28
+ ffi (1.17.2-arm64-darwin)
29
+ ffi (1.17.2-x86-linux-gnu)
30
+ ffi (1.17.2-x86-linux-musl)
31
+ ffi (1.17.2-x86_64-darwin)
32
+ ffi (1.17.2-x86_64-linux-gnu)
33
+ ffi (1.17.2-x86_64-linux-musl)
34
+ front_matter_parser (1.0.1)
20
35
  guard (0.10.0)
21
36
  ffi (>= 0.5.0)
22
37
  thor (~> 0.14.6)
38
+ image_size (3.4.0)
23
39
  kramdown (2.4.0)
24
40
  rexml
25
41
  kramdown-parser-gfm (1.1.0)
26
42
  kramdown (~> 2.0)
27
43
  map (6.6.0)
28
- rexml (3.2.6)
29
- rouge (4.1.1)
44
+ mini_portile2 (2.8.8)
45
+ nokogiri (1.18.8)
46
+ mini_portile2 (~> 2.8.2)
47
+ racc (~> 1.4)
48
+ nokogiri (1.18.8-aarch64-linux-gnu)
49
+ racc (~> 1.4)
50
+ nokogiri (1.18.8-aarch64-linux-musl)
51
+ racc (~> 1.4)
52
+ nokogiri (1.18.8-arm-linux-gnu)
53
+ racc (~> 1.4)
54
+ nokogiri (1.18.8-arm-linux-musl)
55
+ racc (~> 1.4)
56
+ nokogiri (1.18.8-arm64-darwin)
57
+ racc (~> 1.4)
58
+ nokogiri (1.18.8-x86_64-darwin)
59
+ racc (~> 1.4)
60
+ nokogiri (1.18.8-x86_64-linux-gnu)
61
+ racc (~> 1.4)
62
+ nokogiri (1.18.8-x86_64-linux-musl)
63
+ racc (~> 1.4)
64
+ racc (1.8.1)
65
+ rexml (3.3.9)
66
+ rinku (2.0.6)
67
+ rouge (4.4.0)
30
68
  shell_tools (0.1.2)
31
69
  smart_colored (1.1.1)
32
70
  thor (0.14.6)
33
- webrick (1.8.1)
71
+ webrick (1.9.1)
34
72
 
35
73
  PLATFORMS
36
- arm64-darwin-21
37
- x86_64-linux
74
+ aarch64-linux-gnu
75
+ aarch64-linux-musl
76
+ arm-linux-gnu
77
+ arm-linux-musl
78
+ arm64-darwin
79
+ ruby
80
+ x86-linux-gnu
81
+ x86-linux-musl
82
+ x86_64-darwin
83
+ x86_64-linux-gnu
84
+ x86_64-linux-musl
38
85
 
39
86
  DEPENDENCIES
40
87
  ro!
41
88
 
42
89
  BUNDLED WITH
43
- 2.4.22
90
+ 2.5.22
data/LICENSE CHANGED
@@ -1 +1 @@
1
- Ruby
1
+ Nonstandard
data/MIGRATION.md ADDED
@@ -0,0 +1,320 @@
1
+ # Ro v5.0 Asset Structure Migration Guide
2
+
3
+ ## Overview
4
+
5
+ Ro v5.0 introduces a simplified asset directory structure that reduces nesting depth and makes assets easier to understand and manage.
6
+
7
+ ### Automatic Warning System
8
+
9
+ Ro v5.0 automatically detects when you're using old structure data and warns you on stderr:
10
+
11
+ ```
12
+ ⚠️ WARNING: Old Ro asset structure detected!
13
+
14
+ This Ro root contains assets in the OLD structure format:
15
+ • identifier/attributes.yml
16
+ • identifier/assets/
17
+
18
+ Ro v5.0 uses a simplified NEW structure:
19
+ • identifier.yml
20
+ • identifier/
21
+
22
+ Collections will NOT automatically discover old-structure nodes.
23
+
24
+ To migrate your data, run:
25
+ ro migrate /path/to/your/data
26
+ ```
27
+
28
+ **This warning does NOT stop your program** - it's informational to help you know you need to migrate. The warning appears once per root directory when `Ro::Root.new` is called.
29
+
30
+ ### Old Structure (v4.x)
31
+ ```
32
+ posts/
33
+ sample-post/
34
+ attributes.yml # Metadata file INSIDE node directory
35
+ assets/ # Assets subdirectory
36
+ image.jpg
37
+ document.pdf
38
+ ```
39
+
40
+ ### New Structure (v5.0)
41
+ ```
42
+ posts/
43
+ sample-post.yml # Metadata file at COLLECTION level (moved out)
44
+ sample-post/ # Node directory (same location)
45
+ assets/ # Assets subdirectory (SAME location as before!)
46
+ image.jpg
47
+ document.pdf
48
+ ```
49
+
50
+ ## Benefits
51
+
52
+ - **Simpler**: One less level of nesting
53
+ - **Clearer**: Metadata file and assets directory are siblings, not parent/child
54
+ - **Faster**: Easier to locate assets by identifier
55
+ - **More Intuitive**: Structure is self-documenting
56
+
57
+ ## Migration Tool
58
+
59
+ Ro v5.0 includes a migration tool to automate the conversion from old to new structure.
60
+
61
+ ### Basic Usage
62
+
63
+ ```bash
64
+ # Preview migration (dry run)
65
+ ./bin/ro migrate --dry-run /path/to/your/ro/root
66
+
67
+ # Run migration with backup (recommended)
68
+ ./bin/ro migrate /path/to/your/ro/root
69
+
70
+ # Run migration without backup (not recommended)
71
+ ./bin/ro migrate --no-backup /path/to/your/ro/root
72
+ ```
73
+
74
+ ### Options
75
+
76
+ - `--dry-run`, `-d`: Preview changes without making them
77
+ - `--backup`, `--no-backup`, `-b`: Create backup before migrating (default: true)
78
+ - `--verbose`, `-v`: Show detailed progress
79
+ - `--force`, `-f`: Force migration even if new structure detected
80
+ - `--help`, `-h`: Show help message
81
+
82
+ ### Migration Process
83
+
84
+ The migration tool:
85
+
86
+ 1. **Validates** the structure to detect old/new/mixed formats
87
+ 2. **Creates a backup** (unless `--no-backup` is specified)
88
+ 3. **For each old-structure node directory**:
89
+ - **If node has attributes file**: Moves `identifier/attributes.yml` → `identifier.yml` (at collection level)
90
+ - **If node has NO attributes**: Creates empty `identifier.yml` with `{}` content
91
+ - Assets remain in `identifier/assets/` (no change needed!)
92
+
93
+ **Important**: The migrator processes ALL node directories, even those without an attributes file. This ensures every node is discoverable in the new structure.
94
+
95
+ ### Safety Features
96
+
97
+ - **Automatic backups**: Creates timestamped backup before migration
98
+ - **Dry run mode**: Preview changes before applying
99
+ - **Validation**: Detects mixed structures and warns
100
+ - **Rollback support**: Can restore from backup if needed
101
+
102
+ ## Manual Migration
103
+
104
+ If you prefer to migrate manually:
105
+
106
+ 1. **For each node WITH attributes**:
107
+ ```bash
108
+ cd posts
109
+
110
+ # Move metadata file out to collection level
111
+ mv sample-post/attributes.yml sample-post.yml
112
+
113
+ # Assets stay in sample-post/assets/
114
+ ```
115
+
116
+ 2. **For each node WITHOUT attributes** (assets-only):
117
+ ```bash
118
+ cd posts
119
+
120
+ # Create empty metadata file at collection level
121
+ echo '{}' > orphan-assets.yml
122
+
123
+ # Assets stay in orphan-assets/assets/
124
+ ```
125
+
126
+ 3. **Update your code** to use Ro v5.0
127
+
128
+ ## Rollback
129
+
130
+ If you need to rollback after migration:
131
+
132
+ ```ruby
133
+ # Using the Migrator class
134
+ migrator = Ro::Migrator.new('/path/to/ro/root')
135
+ migrator.rollback
136
+ ```
137
+
138
+ This will restore from the most recent backup.
139
+
140
+ ## Migration Checklist
141
+
142
+ - [ ] Review migration plan with `--dry-run`
143
+ - [ ] Backup your data (migration creates backup automatically)
144
+ - [ ] Run migration: `./bin/ro migrate /path/to/ro/root`
145
+ - [ ] Verify migrated data loads correctly
146
+ - [ ] Test your application with new structure
147
+ - [ ] Update code to Ro v5.0 if needed
148
+ - [ ] Remove old backups once confident
149
+
150
+ ## Breaking Changes
151
+
152
+ ### API Changes
153
+
154
+ **Node initialization**:
155
+ ```ruby
156
+ # Old (v4.x) - still works for backward compatibility
157
+ node = Ro::Node.new(node_directory_path)
158
+
159
+ # New (v5.0) - preferred for new structure
160
+ node = Ro::Node.new(collection, metadata_file)
161
+ ```
162
+
163
+ **Asset paths**:
164
+ ```ruby
165
+ # Both old and new structure
166
+ node.asset_dir # => identifier/assets/
167
+
168
+ # The assets/ subdirectory stays the same!
169
+ # Only the metadata file location changes
170
+ ```
171
+
172
+ ### What Stays the Same
173
+
174
+ - **Metadata format**: YAML/JSON/TOML structure unchanged
175
+ - **Asset access**: `node.assets`, `node.asset_paths` work the same
176
+ - **Collection access**: `root['collection']['node']` unchanged
177
+ - **Attribute access**: `node[:title]`, `node.attributes` unchanged
178
+
179
+ ## Testing
180
+
181
+ Run tests to verify migration:
182
+
183
+ ```bash
184
+ # Unit tests
185
+ ruby test/unit/collection_test.rb
186
+ ruby test/unit/node_test.rb
187
+ ruby test/unit/asset_test.rb
188
+ ruby test/unit/migrator_test.rb
189
+
190
+ # Integration tests
191
+ ruby test/integration/ro_integration_test.rb
192
+ ```
193
+
194
+ ## Troubleshooting
195
+
196
+ ### "Both old and new structures detected"
197
+
198
+ This indicates a partial migration. Options:
199
+ 1. Use `--force` to continue migration
200
+ 2. Manually inspect and resolve conflicts
201
+ 3. Restore from backup and retry
202
+
203
+ ### "Node directory not found"
204
+
205
+ Ensure you're running the migration from the correct root directory.
206
+
207
+ ### Assets not loading after migration
208
+
209
+ Check that:
210
+ 1. Metadata files are at collection level (e.g., `posts/sample-post.yml`)
211
+ 2. Node directories exist at collection level (e.g., `posts/sample-post/`)
212
+ 3. Assets are in the `assets/` subdirectory (e.g., `posts/sample-post/assets/image.jpg`)
213
+
214
+ ## Examples
215
+
216
+ ### Example 1: Single Collection
217
+
218
+ Before:
219
+ ```
220
+ ro_data/
221
+ posts/
222
+ welcome/
223
+ attributes.yml
224
+ assets/
225
+ banner.jpg
226
+ ```
227
+
228
+ After:
229
+ ```
230
+ ro_data/
231
+ posts/
232
+ welcome.yml ← Metadata moved out
233
+ welcome/
234
+ assets/
235
+ banner.jpg ← Assets stay in same location
236
+ ```
237
+
238
+ ### Example 2: Multiple Collections
239
+
240
+ Before:
241
+ ```
242
+ ro_data/
243
+ posts/
244
+ post-1/
245
+ attributes.yml
246
+ assets/
247
+ image.jpg
248
+ pages/
249
+ about/
250
+ attributes.yml
251
+ assets/
252
+ photo.png
253
+ ```
254
+
255
+ After:
256
+ ```
257
+ ro_data/
258
+ posts/
259
+ post-1.yml
260
+ post-1/
261
+ assets/
262
+ image.jpg
263
+ pages/
264
+ about.yml
265
+ about/
266
+ assets/
267
+ photo.png
268
+ ```
269
+
270
+ ### Example 3: Metadata-Only Node
271
+
272
+ Before:
273
+ ```
274
+ ro_data/
275
+ posts/
276
+ text-only/
277
+ attributes.yml
278
+ ```
279
+
280
+ After:
281
+ ```
282
+ ro_data/
283
+ posts/
284
+ text-only.yml
285
+ ```
286
+
287
+ ### Example 4: Assets-Only Node (No Attributes)
288
+
289
+ Before:
290
+ ```
291
+ ro_data/
292
+ posts/
293
+ orphan-assets/ ← Directory with no attributes.yml
294
+ assets/
295
+ image.jpg
296
+ ```
297
+
298
+ After:
299
+ ```
300
+ ro_data/
301
+ posts/
302
+ orphan-assets.yml ← Empty metadata file created: {}
303
+ orphan-assets/
304
+ assets/
305
+ image.jpg
306
+ ```
307
+
308
+ ## Support
309
+
310
+ For issues or questions:
311
+ - GitHub Issues: https://github.com/ahoward/ro/issues
312
+ - Documentation: See README.md and code comments
313
+
314
+ ## Version Compatibility
315
+
316
+ - **Ro v4.x**: Old structure only
317
+ - **Ro v5.0**: Both structures (with backward compatibility)
318
+ - **Ro v6.0+**: New structure only (planned)
319
+
320
+ **Recommendation**: Migrate to new structure before Ro v6.0 release.