familia 2.0.0.pre15 → 2.0.0.pre16

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 (274) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/code-quality.yml +138 -0
  3. data/.github/workflows/code-smellage.yml +145 -0
  4. data/.github/workflows/docs.yml +31 -8
  5. data/.gitignore +1 -1
  6. data/.pre-commit-config.yaml +7 -1
  7. data/.reek.yml +98 -0
  8. data/.rubocop.yml +48 -10
  9. data/.talismanrc +9 -0
  10. data/.yardopts +18 -13
  11. data/CHANGELOG.rst +64 -4
  12. data/CLAUDE.md +1 -1
  13. data/Gemfile +6 -5
  14. data/Gemfile.lock +99 -23
  15. data/LICENSE.txt +1 -1
  16. data/README.md +285 -85
  17. data/changelog.d/README.md +2 -2
  18. data/docs/archive/FAMILIA_RELATIONSHIPS.md +22 -22
  19. data/docs/archive/FAMILIA_TECHNICAL.md +41 -41
  20. data/docs/archive/FAMILIA_UPDATE.md +3 -3
  21. data/docs/archive/README.md +3 -2
  22. data/docs/{guides/API-Reference.md → archive/api-reference.md} +87 -101
  23. data/docs/conf.py +29 -0
  24. data/docs/guides/{Field-System-Guide.md → core-field-system.md} +9 -9
  25. data/docs/guides/feature-encrypted-fields.md +785 -0
  26. data/docs/guides/{Expiration-Feature-Guide.md → feature-expiration.md} +11 -2
  27. data/docs/guides/feature-external-identifiers.md +637 -0
  28. data/docs/guides/feature-object-identifiers.md +435 -0
  29. data/docs/guides/{Quantization-Feature-Guide.md → feature-quantization.md} +94 -29
  30. data/docs/guides/feature-relationships-methods.md +684 -0
  31. data/docs/guides/feature-relationships.md +200 -0
  32. data/docs/guides/{Features-System-Developer-Guide.md → feature-system-devs.md} +4 -4
  33. data/docs/guides/{Feature-System-Guide.md → feature-system.md} +5 -5
  34. data/docs/guides/{Transient-Fields-Guide.md → feature-transient-fields.md} +2 -2
  35. data/docs/guides/{Implementation-Guide.md → implementation.md} +3 -3
  36. data/docs/guides/index.md +176 -0
  37. data/docs/guides/{Security-Model.md → security-model.md} +1 -1
  38. data/docs/migrating/v2.0.0-pre.md +1 -1
  39. data/docs/migrating/v2.0.0-pre11.md +2 -2
  40. data/docs/migrating/v2.0.0-pre12.md +2 -2
  41. data/docs/migrating/v2.0.0-pre5.md +33 -12
  42. data/docs/migrating/v2.0.0-pre6.md +2 -2
  43. data/docs/migrating/v2.0.0-pre7.md +8 -8
  44. data/docs/overview.md +623 -19
  45. data/docs/reference/api-technical.md +1365 -0
  46. data/examples/autoloader/mega_customer/features/deprecated_fields.rb +7 -0
  47. data/examples/autoloader/mega_customer/safe_dump_fields.rb +1 -1
  48. data/examples/autoloader/mega_customer.rb +3 -1
  49. data/examples/encrypted_fields.rb +378 -0
  50. data/examples/json_usage_patterns.rb +144 -0
  51. data/examples/relationships.rb +13 -13
  52. data/examples/safe_dump.rb +6 -6
  53. data/examples/single_connection_transaction_confusions.rb +379 -0
  54. data/lib/familia/base.rb +49 -10
  55. data/lib/familia/connection/handlers.rb +223 -0
  56. data/lib/familia/connection/individual_command_proxy.rb +64 -0
  57. data/lib/familia/connection/middleware.rb +75 -0
  58. data/lib/familia/connection/operation_core.rb +93 -0
  59. data/lib/familia/connection/operations.rb +277 -0
  60. data/lib/familia/connection/pipeline_core.rb +87 -0
  61. data/lib/familia/connection/transaction_core.rb +100 -0
  62. data/lib/familia/connection.rb +60 -186
  63. data/lib/familia/data_type/commands.rb +53 -51
  64. data/lib/familia/data_type/serialization.rb +108 -107
  65. data/lib/familia/data_type/types/counter.rb +1 -1
  66. data/lib/familia/data_type/types/hashkey.rb +13 -10
  67. data/lib/familia/data_type/types/{list.rb → listkey.rb} +13 -5
  68. data/lib/familia/data_type/types/lock.rb +3 -2
  69. data/lib/familia/data_type/types/sorted_set.rb +26 -15
  70. data/lib/familia/data_type/types/{string.rb → stringkey.rb} +7 -5
  71. data/lib/familia/data_type/types/unsorted_set.rb +20 -27
  72. data/lib/familia/data_type.rb +75 -47
  73. data/lib/familia/distinguisher.rb +85 -0
  74. data/lib/familia/encryption/encrypted_data.rb +15 -24
  75. data/lib/familia/encryption/manager.rb +6 -4
  76. data/lib/familia/encryption/providers/aes_gcm_provider.rb +1 -1
  77. data/lib/familia/encryption/providers/secure_xchacha20_poly1305_provider.rb +7 -9
  78. data/lib/familia/encryption/providers/xchacha20_poly1305_provider.rb +4 -5
  79. data/lib/familia/encryption/request_cache.rb +7 -7
  80. data/lib/familia/encryption.rb +2 -3
  81. data/lib/familia/errors.rb +9 -3
  82. data/lib/familia/features/autoloader.rb +30 -12
  83. data/lib/familia/features/encrypted_fields/concealed_string.rb +3 -4
  84. data/lib/familia/features/encrypted_fields/encrypted_field_type.rb +13 -14
  85. data/lib/familia/features/encrypted_fields.rb +66 -64
  86. data/lib/familia/features/expiration/extensions.rb +1 -1
  87. data/lib/familia/features/expiration.rb +31 -26
  88. data/lib/familia/features/external_identifier.rb +9 -12
  89. data/lib/familia/features/object_identifier.rb +56 -19
  90. data/lib/familia/features/quantization.rb +16 -21
  91. data/lib/familia/features/relationships/README.md +97 -0
  92. data/lib/familia/features/relationships/collection_operations.rb +104 -0
  93. data/lib/familia/features/relationships/indexing/multi_index_generators.rb +202 -0
  94. data/lib/familia/features/relationships/indexing/unique_index_generators.rb +301 -0
  95. data/lib/familia/features/relationships/indexing.rb +176 -256
  96. data/lib/familia/features/relationships/indexing_relationship.rb +35 -0
  97. data/lib/familia/features/relationships/participation/participant_methods.rb +160 -0
  98. data/lib/familia/features/relationships/participation/target_methods.rb +225 -0
  99. data/lib/familia/features/relationships/participation.rb +656 -0
  100. data/lib/familia/features/relationships/participation_relationship.rb +31 -0
  101. data/lib/familia/features/relationships/score_encoding.rb +20 -20
  102. data/lib/familia/features/relationships.rb +65 -266
  103. data/lib/familia/features/safe_dump.rb +127 -130
  104. data/lib/familia/features/transient_fields/redacted_string.rb +6 -6
  105. data/lib/familia/features/transient_fields/transient_field_type.rb +5 -5
  106. data/lib/familia/features/transient_fields.rb +3 -5
  107. data/lib/familia/features.rb +4 -13
  108. data/lib/familia/field_type.rb +24 -4
  109. data/lib/familia/horreum/core/connection.rb +229 -26
  110. data/lib/familia/horreum/core/database_commands.rb +27 -17
  111. data/lib/familia/horreum/core/serialization.rb +40 -20
  112. data/lib/familia/horreum/core/utils.rb +2 -1
  113. data/lib/familia/horreum/shared/settings.rb +2 -1
  114. data/lib/familia/horreum/subclass/definition.rb +33 -45
  115. data/lib/familia/horreum/subclass/management.rb +72 -24
  116. data/lib/familia/horreum/subclass/related_fields_management.rb +82 -21
  117. data/lib/familia/horreum.rb +196 -114
  118. data/lib/familia/json_serializer.rb +0 -1
  119. data/lib/familia/logging.rb +11 -114
  120. data/lib/familia/refinements/dear_json.rb +122 -0
  121. data/lib/familia/refinements/logger_trace.rb +20 -17
  122. data/lib/familia/refinements/stylize_words.rb +65 -0
  123. data/lib/familia/refinements/time_literals.rb +60 -52
  124. data/lib/familia/refinements.rb +2 -1
  125. data/lib/familia/secure_identifier.rb +60 -28
  126. data/lib/familia/settings.rb +83 -7
  127. data/lib/familia/utils.rb +5 -87
  128. data/lib/familia/verifiable_identifier.rb +4 -4
  129. data/lib/familia/version.rb +1 -1
  130. data/lib/familia.rb +72 -14
  131. data/lib/middleware/database_middleware.rb +56 -14
  132. data/lib/{familia/multi_result.rb → multi_result.rb} +23 -16
  133. data/try/configuration/scenarios_try.rb +1 -1
  134. data/try/connection/fiber_context_preservation_try.rb +250 -0
  135. data/try/connection/handler_constraints_try.rb +59 -0
  136. data/try/connection/operation_mode_guards_try.rb +208 -0
  137. data/try/connection/pipeline_fallback_integration_try.rb +128 -0
  138. data/try/connection/responsibility_chain_tracking_try.rb +72 -0
  139. data/try/connection/transaction_fallback_integration_try.rb +288 -0
  140. data/try/connection/transaction_mode_permissive_try.rb +153 -0
  141. data/try/connection/transaction_mode_strict_try.rb +98 -0
  142. data/try/connection/transaction_mode_warn_try.rb +131 -0
  143. data/try/connection/transaction_modes_try.rb +249 -0
  144. data/try/core/autoloader_try.rb +120 -2
  145. data/try/core/connection_try.rb +7 -7
  146. data/try/core/conventional_inheritance_try.rb +130 -0
  147. data/try/core/create_method_try.rb +15 -23
  148. data/try/core/database_consistency_try.rb +10 -10
  149. data/try/core/errors_try.rb +8 -11
  150. data/try/core/familia_extended_try.rb +2 -2
  151. data/try/core/familia_members_methods_try.rb +76 -0
  152. data/try/core/isolated_dbclient_try.rb +165 -0
  153. data/try/core/middleware_try.rb +16 -16
  154. data/try/core/persistence_operations_try.rb +4 -4
  155. data/try/core/pools_try.rb +42 -26
  156. data/try/core/secure_identifier_try.rb +28 -24
  157. data/try/core/time_utils_try.rb +10 -10
  158. data/try/core/tools_try.rb +1 -1
  159. data/try/core/utils_try.rb +2 -2
  160. data/try/data_types/boolean_try.rb +4 -4
  161. data/try/data_types/datatype_base_try.rb +0 -2
  162. data/try/data_types/list_try.rb +10 -10
  163. data/try/data_types/sorted_set_try.rb +5 -5
  164. data/try/data_types/string_try.rb +12 -12
  165. data/try/data_types/unsortedset_try.rb +33 -0
  166. data/try/debugging/cache_behavior_tracer.rb +7 -7
  167. data/try/debugging/debug_aad_process.rb +1 -1
  168. data/try/debugging/debug_concealed_internal.rb +1 -1
  169. data/try/debugging/debug_cross_context.rb +1 -1
  170. data/try/debugging/debug_fresh_cross_context.rb +1 -1
  171. data/try/debugging/encryption_method_tracer.rb +10 -10
  172. data/try/edge_cases/hash_symbolization_try.rb +1 -1
  173. data/try/edge_cases/ttl_side_effects_try.rb +1 -1
  174. data/try/encryption/config_persistence_try.rb +2 -2
  175. data/try/encryption/encryption_core_try.rb +19 -19
  176. data/try/encryption/instance_variable_scope_try.rb +1 -1
  177. data/try/encryption/module_loading_try.rb +2 -2
  178. data/try/encryption/providers/aes_gcm_provider_try.rb +1 -1
  179. data/try/encryption/providers/xchacha20_poly1305_provider_try.rb +1 -1
  180. data/try/encryption/secure_memory_handling_try.rb +1 -1
  181. data/try/features/encrypted_fields/concealed_string_core_try.rb +11 -7
  182. data/try/features/encrypted_fields/encrypted_fields_core_try.rb +1 -1
  183. data/try/features/encrypted_fields/encrypted_fields_integration_try.rb +3 -3
  184. data/try/features/encrypted_fields/encrypted_fields_no_cache_security_try.rb +10 -10
  185. data/try/features/encrypted_fields/encrypted_fields_security_try.rb +14 -14
  186. data/try/features/encrypted_fields/error_conditions_try.rb +7 -7
  187. data/try/features/encrypted_fields/fresh_key_try.rb +1 -1
  188. data/try/features/encrypted_fields/nonce_uniqueness_try.rb +1 -1
  189. data/try/features/encrypted_fields/secure_by_default_behavior_try.rb +7 -7
  190. data/try/features/encrypted_fields/universal_serialization_safety_try.rb +13 -20
  191. data/try/features/external_identifier/external_identifier_try.rb +1 -1
  192. data/try/features/feature_dependencies_try.rb +3 -3
  193. data/try/features/object_identifier/object_identifier_integration_try.rb +28 -34
  194. data/try/features/object_identifier/object_identifier_try.rb +10 -0
  195. data/try/features/quantization/quantization_try.rb +1 -1
  196. data/try/features/relationships/indexing_commands_verification_try.rb +136 -0
  197. data/try/features/relationships/indexing_try.rb +433 -0
  198. data/try/features/relationships/participation_commands_verification_spec.rb +102 -0
  199. data/try/features/relationships/participation_commands_verification_try.rb +105 -0
  200. data/try/features/relationships/participation_performance_improvements_try.rb +124 -0
  201. data/try/features/relationships/participation_reverse_index_try.rb +196 -0
  202. data/try/features/relationships/relationships_api_changes_try.rb +72 -71
  203. data/try/features/relationships/relationships_edge_cases_try.rb +15 -18
  204. data/try/features/relationships/relationships_performance_minimal_try.rb +2 -2
  205. data/try/features/relationships/relationships_performance_simple_try.rb +8 -8
  206. data/try/features/relationships/relationships_performance_try.rb +20 -20
  207. data/try/features/relationships/relationships_try.rb +27 -38
  208. data/try/features/safe_dump/safe_dump_advanced_try.rb +2 -2
  209. data/try/features/transient_fields/refresh_reset_try.rb +1 -1
  210. data/try/features/transient_fields/simple_refresh_test.rb +1 -1
  211. data/try/helpers/test_cleanup.rb +86 -0
  212. data/try/helpers/test_helpers.rb +3 -3
  213. data/try/horreum/base_try.rb +3 -2
  214. data/try/horreum/commands_try.rb +1 -1
  215. data/try/horreum/destroy_related_fields_cleanup_try.rb +330 -0
  216. data/try/horreum/initialization_try.rb +11 -7
  217. data/try/horreum/relations_try.rb +21 -13
  218. data/try/horreum/serialization_try.rb +12 -11
  219. data/try/integration/cross_component_try.rb +3 -3
  220. data/try/memory/memory_basic_test.rb +1 -1
  221. data/try/memory/memory_docker_ruby_dump.sh +1 -1
  222. data/try/models/customer_safe_dump_try.rb +1 -1
  223. data/try/models/customer_try.rb +8 -10
  224. data/try/models/datatype_base_try.rb +3 -3
  225. data/try/models/familia_object_try.rb +9 -8
  226. data/try/performance/benchmarks_try.rb +2 -2
  227. data/try/prototypes/atomic_saves_v1_context_proxy.rb +2 -2
  228. data/try/prototypes/atomic_saves_v3_connection_pool.rb +3 -3
  229. data/try/prototypes/atomic_saves_v4.rb +1 -1
  230. data/try/prototypes/lib/atomic_saves_v2_connection_switching_helpers.rb +4 -4
  231. data/try/prototypes/lib/atomic_saves_v3_connection_pool_helpers.rb +4 -4
  232. data/try/prototypes/pooling/lib/atomic_saves_v3_connection_pool_helpers.rb +4 -4
  233. data/try/prototypes/pooling/lib/connection_pool_metrics.rb +5 -5
  234. data/try/prototypes/pooling/lib/connection_pool_stress_test.rb +26 -26
  235. data/try/prototypes/pooling/lib/connection_pool_threading_models.rb +7 -7
  236. data/try/prototypes/pooling/lib/visualize_stress_results.rb +1 -1
  237. data/try/prototypes/pooling/pool_siege.rb +11 -11
  238. data/try/prototypes/pooling/run_stress_tests.rb +7 -7
  239. data/try/refinements/dear_json_array_methods_try.rb +53 -0
  240. data/try/refinements/dear_json_hash_methods_try.rb +54 -0
  241. data/try/refinements/logger_trace_methods_try.rb +44 -0
  242. data/try/refinements/time_literals_numeric_methods_try.rb +141 -0
  243. data/try/refinements/time_literals_string_methods_try.rb +80 -0
  244. metadata +75 -43
  245. data/.rubocop_todo.yml +0 -208
  246. data/docs/connection_pooling.md +0 -192
  247. data/docs/guides/Connection-Pooling-Guide.md +0 -437
  248. data/docs/guides/Encrypted-Fields-Overview.md +0 -101
  249. data/docs/guides/Feature-System-Autoloading.md +0 -198
  250. data/docs/guides/Home.md +0 -116
  251. data/docs/guides/Relationships-Guide.md +0 -737
  252. data/docs/guides/relationships-methods.md +0 -266
  253. data/docs/reference/auditing_database_commands.rb +0 -228
  254. data/examples/permissions.rb +0 -240
  255. data/lib/familia/features/relationships/cascading.rb +0 -437
  256. data/lib/familia/features/relationships/membership.rb +0 -497
  257. data/lib/familia/features/relationships/permission_management.rb +0 -264
  258. data/lib/familia/features/relationships/querying.rb +0 -615
  259. data/lib/familia/features/relationships/redis_operations.rb +0 -274
  260. data/lib/familia/features/relationships/tracking.rb +0 -418
  261. data/lib/familia/refinements/snake_case.rb +0 -40
  262. data/lib/familia/validation/command_recorder.rb +0 -336
  263. data/lib/familia/validation/expectations.rb +0 -519
  264. data/lib/familia/validation/validation_helpers.rb +0 -443
  265. data/lib/familia/validation/validator.rb +0 -412
  266. data/lib/familia/validation.rb +0 -140
  267. data/try/data_types/set_try.rb +0 -33
  268. data/try/features/relationships/categorical_permissions_try.rb +0 -515
  269. data/try/features/safe_dump/module_based_extensions_try.rb +0 -100
  270. data/try/features/safe_dump/safe_dump_autoloading_try.rb +0 -107
  271. data/try/validation/atomic_operations_try.rb.disabled +0 -320
  272. data/try/validation/command_validation_try.rb.disabled +0 -207
  273. data/try/validation/performance_validation_try.rb.disabled +0 -324
  274. data/try/validation/real_world_scenarios_try.rb.disabled +0 -390
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 00416beac08786c1fffd75a0c2578669c6a0d18169824ca1a23e9122018a386b
4
- data.tar.gz: c38f7bfe985a7d6151abf2ce4b6d7ca32ddb97adf8d069880f7e919662937851
3
+ metadata.gz: ebaf394ebbccf9d096e87da84c693040c71d963860002a9d970d9b04edc11b6c
4
+ data.tar.gz: 4862991d1b2a1538876089030657986eb1b56f5551c7e5e9978a1009c77e86f9
5
5
  SHA512:
6
- metadata.gz: a3d6a60c86460578567fbd6f33e96c8ae0ee2dbfc80f3ffc6f123dc6fb84c6020efd359601122e63543c0128401d235587e9770df8acbbfa1f55cb908a012e07
7
- data.tar.gz: 5062f93d7494df05a6d62dade395a0522ca8ab02afd4fdc5a00ee21db08b05ace8c3227d07739ef7cdd727fa72888ea4ec415491eb60028b25166d107d574e8e
6
+ metadata.gz: 533af9a33a115e8a59c87ae35e5b82401e1d72edbe43fd4a2963a3ca25a2c1ac259e5aaf02e68945d9d2f576393c6f77e9843ec87c4ed92696ca41d0b06e4d4c
7
+ data.tar.gz: b74dca7e415cbd0d6933beb77185e7738d33b3c10a704569120892fa9062fe92874fe2b879439f8d9508b8d02ba0e8154c79cb1546b029ac9e6bbdde442fd5e1
@@ -0,0 +1,138 @@
1
+ name: Code Quality
2
+
3
+ on:
4
+ pull_request:
5
+ branches: [ main ]
6
+ push:
7
+ branches: [ main ]
8
+ workflow_dispatch:
9
+
10
+ permissions:
11
+ contents: read
12
+ pull-requests: write # Needed to post comments on PRs
13
+
14
+ jobs:
15
+ reek:
16
+ name: Reek Code Analysis
17
+ runs-on: ubuntu-24.04
18
+ timeout-minutes: 5
19
+
20
+ steps:
21
+ - name: Checkout code
22
+ uses: actions/checkout@v4
23
+
24
+ - name: Set up Ruby
25
+ uses: ruby/setup-ruby@v1
26
+ with:
27
+ ruby-version: 3.4
28
+ bundler-cache: true
29
+
30
+ - name: Configure Bundler for secure gem installation
31
+ run: |
32
+ bundle config set --local path 'vendor/bundle'
33
+ bundle config set --local deployment 'false'
34
+
35
+ - name: Install dependencies
36
+ run: bundle install
37
+
38
+ - name: Run Reek analysis
39
+ run: |
40
+ echo "=== Running Reek code analysis ==="
41
+ echo "This analysis identifies code smells and potential improvements."
42
+ echo "Results are informational and won't fail the build."
43
+ echo ""
44
+
45
+ # Run reek and capture output (don't fail on warnings)
46
+ # Use success-exit-code to prevent failures from stopping the analysis
47
+ bundle exec reek --format=text --success-exit-code 0 --failure-exit-code 0 || true
48
+
49
+ echo ""
50
+ echo "=== Reek analysis complete ==="
51
+ continue-on-error: true # Don't fail the build on code smells
52
+
53
+ - name: Generate Reek report (if analysis available)
54
+ run: |
55
+ echo "=== Generating detailed Reek report ==="
56
+
57
+ # Generate JSON report for potential future processing
58
+ bundle exec reek --format=json --success-exit-code 0 --failure-exit-code 0 > reek-report.json || true
59
+
60
+ # Display summary
61
+ if [ -s reek-report.json ]; then
62
+ echo "Reek JSON report generated: $(wc -l < reek-report.json) lines"
63
+ echo "Top code smell types found:"
64
+ jq -r '.[].smells[].smell_type' reek-report.json 2>/dev/null | sort | uniq -c | sort -rn | head -10 || echo "Unable to parse JSON report"
65
+ else
66
+ echo "No code smells detected or analysis failed"
67
+ fi
68
+ continue-on-error: true
69
+
70
+ - name: Upload Reek report as artifact
71
+ uses: actions/upload-artifact@v4
72
+ if: always()
73
+ with:
74
+ name: reek-report
75
+ path: reek-report.json
76
+ retention-days: 30
77
+
78
+ # Add other code quality checks here
79
+ additional-quality-checks:
80
+ name: Additional Quality Checks
81
+ runs-on: ubuntu-24.04
82
+ timeout-minutes: 5
83
+
84
+ steps:
85
+ - name: Checkout code
86
+ uses: actions/checkout@v4
87
+
88
+ - name: Set up Ruby
89
+ uses: ruby/setup-ruby@v1
90
+ with:
91
+ ruby-version: 3.4
92
+ bundler-cache: true
93
+
94
+ - name: Configure Bundler for secure gem installation
95
+ run: |
96
+ bundle config set --local path 'vendor/bundle'
97
+ bundle config set --local deployment 'false'
98
+
99
+ - name: Install dependencies
100
+ run: bundle install
101
+
102
+ - name: Check for TODO/FIXME comments
103
+ run: |
104
+ echo "=== Scanning for TODO/FIXME comments ==="
105
+ echo "This helps track technical debt and action items."
106
+ echo ""
107
+
108
+ # Find TODO/FIXME comments (excluding this workflow file)
109
+ find . -name "*.rb" -not -path "./vendor/*" -not -path "./tmp/*" | \
110
+ xargs grep -Hn -i -E "(TODO|FIXME|HACK|XXX|NOTE):" 2>/dev/null | \
111
+ head -20 || echo "No TODO/FIXME comments found"
112
+ continue-on-error: true
113
+
114
+ - name: Check Ruby file syntax
115
+ run: |
116
+ echo "=== Checking Ruby syntax ==="
117
+ echo "Validates that all Ruby files have correct syntax."
118
+ echo ""
119
+
120
+ find . -name "*.rb" -not -path "./vendor/*" -not -path "./tmp/*" | \
121
+ while read -r file; do
122
+ if ! ruby -c "$file" > /dev/null 2>&1; then
123
+ echo "Syntax error in: $file"
124
+ ruby -c "$file"
125
+ fi
126
+ done
127
+ continue-on-error: true
128
+
129
+ - name: Check for long lines
130
+ run: |
131
+ echo "=== Checking for long lines (>120 characters) ==="
132
+ echo "Identifies potentially hard-to-read code lines."
133
+ echo ""
134
+
135
+ find . -name "*.rb" -not -path "./vendor/*" -not -path "./tmp/*" | \
136
+ xargs grep -Hn "^.\{121,\}$" | \
137
+ head -10 || echo "No overly long lines found"
138
+ continue-on-error: true
@@ -0,0 +1,145 @@
1
+ name: Any Code Smellage?
2
+
3
+ on:
4
+ pull_request:
5
+ branches: [main]
6
+ push:
7
+ branches: [main]
8
+ workflow_dispatch:
9
+
10
+ permissions:
11
+ contents: read
12
+ pull-requests: write # Needed to post comments on PRs
13
+
14
+ jobs:
15
+ reek:
16
+ name: Reek Code Analysis
17
+ runs-on: ubuntu-24.04
18
+ timeout-minutes: 5
19
+
20
+ steps:
21
+ - name: Checkout code
22
+ uses: actions/checkout@v4
23
+
24
+ - name: Set up Ruby
25
+ uses: ruby/setup-ruby@v1
26
+ with:
27
+ ruby-version: 3.4
28
+ bundler-cache: true
29
+
30
+ - name: Configure Bundler for secure gem installation
31
+ run: |
32
+ bundle config set --local path 'vendor/bundle'
33
+ bundle config set --local deployment 'false'
34
+
35
+ - name: Install dependencies
36
+ run: bundle install --jobs 4 --retry 3
37
+
38
+ - name: Run Reek analysis
39
+ run: |
40
+ echo "=== Running Reek code analysis ==="
41
+ echo "This analysis identifies code smells and potential improvements."
42
+ echo "Results are informational and won't fail the build."
43
+ echo ""
44
+
45
+ # Run reek and capture output (don't fail on warnings)
46
+ # Use success-exit-code to prevent failures from stopping the analysis
47
+ bundle exec reek --format=text --success-exit-code 0 --failure-exit-code 0 || true
48
+
49
+ echo ""
50
+ echo "=== Reek analysis complete ==="
51
+ continue-on-error: true # Don't fail the build on code smells
52
+
53
+ - name: Generate Reek report (if analysis available)
54
+ run: |
55
+ echo "=== Generating detailed Reek report ==="
56
+
57
+ # Generate JSON report for potential future processing
58
+ bundle exec reek --format=json --success-exit-code 0 --failure-exit-code 0 > reek-report.json || true
59
+
60
+ # If no JSON was generated, create an empty valid JSON array
61
+ if [ ! -s reek-report.json ]; then
62
+ echo "[]" > reek-report.json
63
+ echo "No code smells detected - created empty report"
64
+ else
65
+ echo "Reek JSON report generated: $(wc -l < reek-report.json) lines"
66
+ echo "Top code smell types found:"
67
+ jq -r '.[].smells[].smell_type' reek-report.json 2>/dev/null | sort | uniq -c | sort -rn | head -10 || echo "Unable to parse JSON report"
68
+ fi
69
+
70
+ # Also generate a human-readable HTML report for easier viewing
71
+ bundle exec reek --format=html --success-exit-code 0 --failure-exit-code 0 > reek-report.html || echo "<!-- No code smells detected -->" > reek-report.html
72
+ continue-on-error: true
73
+
74
+ - name: Upload Reek report as artifact
75
+ uses: actions/upload-artifact@v4
76
+ if: always()
77
+ with:
78
+ name: reek-report
79
+ path: |
80
+ reek-report.json
81
+ reek-report.html
82
+ if-no-files-found: ignore
83
+ retention-days: 30
84
+
85
+ # Add other code quality checks here
86
+ additional-quality-checks:
87
+ name: Additional Quality Checks
88
+ runs-on: ubuntu-24.04
89
+ timeout-minutes: 5
90
+
91
+ steps:
92
+ - name: Checkout code
93
+ uses: actions/checkout@v4
94
+
95
+ - name: Set up Ruby
96
+ uses: ruby/setup-ruby@v1
97
+ with:
98
+ ruby-version: 3.4
99
+ bundler-cache: true
100
+
101
+ - name: Configure Bundler for secure gem installation
102
+ run: |
103
+ bundle config set --local path 'vendor/bundle'
104
+ bundle config set --local deployment 'false'
105
+
106
+ - name: Install dependencies
107
+ run: bundle install --jobs 4 --retry 3
108
+
109
+ - name: Check for TODO/FIXME comments
110
+ run: |
111
+ echo "=== Scanning for TODO/FIXME comments ==="
112
+ echo "This helps track technical debt and action items."
113
+ echo ""
114
+
115
+ # Find TODO/FIXME comments (excluding this workflow file)
116
+ find . -name "*.rb" -not -path "./vendor/*" -not -path "./tmp/*" | \
117
+ xargs grep -Hn -i -E "(TODO|FIXME|HACK|XXX|NOTE):" 2>/dev/null | \
118
+ head -20 || echo "No TODO/FIXME comments found"
119
+ continue-on-error: true
120
+
121
+ - name: Check Ruby file syntax
122
+ run: |
123
+ echo "=== Checking Ruby syntax ==="
124
+ echo "Validates that all Ruby files have correct syntax."
125
+ echo ""
126
+
127
+ find . -name "*.rb" -not -path "./vendor/*" -not -path "./tmp/*" | \
128
+ while read -r file; do
129
+ if ! ruby -c "$file" > /dev/null 2>&1; then
130
+ echo "Syntax error in: $file"
131
+ ruby -c "$file"
132
+ fi
133
+ done
134
+ continue-on-error: true
135
+
136
+ - name: Check for long lines
137
+ run: |
138
+ echo "=== Checking for long lines (>120 characters) ==="
139
+ echo "Identifies potentially hard-to-read code lines."
140
+ echo ""
141
+
142
+ find . -name "*.rb" -not -path "./vendor/*" -not -path "./tmp/*" | \
143
+ xargs grep -Hn "^.\{121,\}$" | \
144
+ head -10 || echo "No overly long lines found"
145
+ continue-on-error: true
@@ -1,3 +1,5 @@
1
+ # .github/workflows/docs.yml
2
+ ---
1
3
  name: Build and Publish YARD Documentation
2
4
 
3
5
  on:
@@ -7,9 +9,14 @@ on:
7
9
  workflow_dispatch:
8
10
  inputs:
9
11
  reason:
10
- description: 'Reason for manual documentation build'
12
+ description: "Reason for manual documentation build"
11
13
  required: false
12
- default: 'Manual documentation update'
14
+ default: "Manual documentation update"
15
+ debug_enabled:
16
+ type: boolean
17
+ description: "Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)"
18
+ required: false
19
+ default: false
13
20
 
14
21
  permissions:
15
22
  contents: read
@@ -33,23 +40,39 @@ jobs:
33
40
  - name: Set up Ruby
34
41
  uses: ruby/setup-ruby@v1
35
42
  with:
36
- ruby-version: '3.4'
43
+ ruby-version: "3.4"
37
44
  bundler-cache: true
38
45
 
39
46
  - name: Install dependencies
40
47
  run: bundle install
41
48
 
49
+ - name: Setup tmate session
50
+ uses: mxschmitt/action-tmate@7b6a61a73bbb9793cb80ad69b8dd8ac19261834c # v3
51
+ if: ${{ github.event_name == 'workflow_dispatch' && inputs.debug_enabled }}
52
+ with:
53
+ detached: true
54
+
42
55
  - name: Build YARD documentation
43
56
  run: |
44
- bundle exec yard doc --output-dir ./doc
45
- # Ensure doc directory exists and create .nojekyll file to prevent GitHub Pages Jekyll processing
46
- mkdir -p ./doc
47
- touch ./doc/.nojekyll
57
+ # Generate docs with maximum volume
58
+ bundle exec yard doc --debug --backtrace 2>&1 | tee yard_debug.log
59
+
60
+ # Display the last 10 lines of the log file
61
+ tail -n 10 yard_debug.log
62
+
63
+ # Search for specific error messages in the log file
64
+ grep -A 5 -B 5 "Exception occurred" yard_debug.log || echo "No exceptions found (good!)"
65
+ grep -A 5 -B 5 "Cannot resolve link" yard_debug.log || echo "No unresolved links found (good!)"
66
+
67
+ # Ensure public directory exists and create .nojekyll file to
68
+ # prevent GitHub Pages Jekyll processing
69
+ mkdir -p ./public
70
+ touch ./public/.nojekyll
48
71
 
49
72
  - name: Upload documentation artifacts
50
73
  uses: actions/upload-pages-artifact@v3
51
74
  with:
52
- path: ./doc
75
+ path: ./public
53
76
 
54
77
  deploy:
55
78
  environment:
data/.gitignore CHANGED
@@ -19,7 +19,7 @@ log
19
19
  tmp
20
20
  vendor
21
21
  *.gem
22
- doc/
22
+ public/
23
23
 
24
24
  # Ignore WIP or temp dev files with uppercase names
25
25
  [A-Z]*.md
@@ -50,7 +50,6 @@ repos:
50
50
  - id: trailing-whitespace
51
51
  - id: end-of-file-fixer
52
52
  - id: check-yaml
53
- - id: detect-private-key
54
53
  - id: mixed-line-ending
55
54
  - id: check-added-large-files
56
55
  args: ["--maxkb=1000"]
@@ -59,6 +58,13 @@ repos:
59
58
  - id: check-merge-conflict
60
59
  - id: forbid-submodules
61
60
 
61
+ - repo: https://github.com/thoughtworks/talisman
62
+ rev: v1.32.2
63
+ hooks:
64
+ - id: talisman-commit
65
+ env:
66
+ TALISMAN_SCAN_MODE: CI
67
+
62
68
  - repo: https://github.com/avilaton/add-msg-issue-prefix-hook
63
69
  rev: v0.0.11
64
70
  hooks:
data/.reek.yml ADDED
@@ -0,0 +1,98 @@
1
+ # .reek.yml
2
+ # Reek configuration for Familia
3
+ #
4
+ # Basic commands:
5
+ # bundle exec reek # Analyze all Ruby files
6
+ # bundle exec reek lib/ # Analyze specific directory
7
+ # bundle exec reek lib/familia/horreum.rb # Analyze specific file
8
+ # bundle exec reek --help # Show all options
9
+ # bundle exec reek --docs # Open documentation
10
+ #
11
+ # Advanced usage:
12
+ # bundle exec reek --format=html > report.html # Generate HTML report
13
+ # bundle exec reek --format=json # JSON output for CI
14
+ # bundle exec reek --config .reek.yml # Use specific config
15
+ # bundle exec reek --show-docs IrresponsibleModule # Explain specific smell
16
+ # bundle exec reek --failure-exit-code 1 # Exit with error on smells (for CI)
17
+
18
+ ---
19
+ detectors:
20
+ # Disable some detectors for initial adoption
21
+ # You can gradually enable these as you clean up the codebase
22
+
23
+ # Class/Module Structure
24
+ IrresponsibleModule:
25
+ enabled: false # Modules without documentation - start with this disabled
26
+
27
+ # Method Complexity
28
+ TooManyStatements:
29
+ enabled: true
30
+ max_statements: 15 # Default is 5, relaxed for initial adoption
31
+
32
+ TooManyMethods:
33
+ enabled: true
34
+ max_methods: 25 # Default is 15, relaxed for ORMs which often have many methods
35
+
36
+ LongParameterList:
37
+ enabled: true
38
+ max_params: 4 # Default is 3, slightly relaxed
39
+
40
+ # Data Classes and Feature Envy
41
+ DataClump:
42
+ enabled: true
43
+
44
+ FeatureEnvy:
45
+ enabled: true
46
+
47
+ # Control Structure
48
+ NestedIterators:
49
+ enabled: true
50
+ max_allowed_nesting: 2 # Default is 1, relaxed for data processing
51
+
52
+ # Variable and Constant Usage
53
+ UnusedParameters:
54
+ enabled: true
55
+
56
+ InstanceVariableAssumption:
57
+ enabled: true
58
+
59
+ # Naming
60
+ UncommunicativeParameterName:
61
+ enabled: true
62
+ reject:
63
+ - '/^.$/' # Single letter names
64
+ - '/[0-9]$/' # Names ending in numbers
65
+ - '/^_/' # Names starting with underscore (common Ruby pattern)
66
+ accept: []
67
+
68
+ UncommunicativeVariableName:
69
+ enabled: true
70
+ reject:
71
+ - '/^.$/' # Single letter names
72
+ - '/[0-9]$/' # Names ending in numbers
73
+ accept:
74
+ - e # Exception variable
75
+ - id # Common identifier
76
+ - db # Database connection
77
+ - op # Operation
78
+ - io # Input/output
79
+
80
+ UncommunicativeMethodName:
81
+ enabled: true
82
+ reject:
83
+ - '/^.$/' # Single letter method names
84
+ - '/[0-9]$/' # Methods ending in numbers
85
+ accept:
86
+ - "<<" # Common Ruby operator overload
87
+
88
+ # Directory and file exclusions
89
+ exclude_paths:
90
+ - "vendor/**/*.rb"
91
+ - "tmp/**/*.rb"
92
+ - "try/**/*.rb" # Test files using tryouts framework
93
+ - "examples/**/*.rb" # Example code files
94
+ - "bin/*" # Executable scripts
95
+ - "*.gemspec" # Gem specification files
96
+
97
+ # Note: For limiting warnings output, use CLI: bundle exec reek | head -50
98
+ # Note: For failure exit codes, use CLI: bundle exec reek --failure-exit-code 1
data/.rubocop.yml CHANGED
@@ -16,7 +16,6 @@
16
16
  # How to resolve "RuboCop version incompatibility found":
17
17
  # `rubocop --stop-server`
18
18
  #
19
- inherit_from: .rubocop_todo.yml
20
19
 
21
20
  plugins:
22
21
  - rubocop-performance
@@ -28,11 +27,9 @@ AllCops:
28
27
  MaxFilesInCache: 100
29
28
  TargetRubyVersion: 3.4
30
29
  Exclude:
31
- - "migrate/**/*.rb"
32
- - "migrate/*.rb"
33
- - "try/**/*"
34
- - "try/*.rb"
35
- - "vendor/**/*"
30
+ - "rspec/**/*.rb"
31
+ - "tmp/**/*.rb"
32
+ - "try/**/*.rb"
36
33
 
37
34
  #
38
35
  # Trailing commas
@@ -46,6 +43,7 @@ Style/TrailingCommaInArrayLiteral:
46
43
 
47
44
  Style/TrailingCommaInArguments:
48
45
  Enabled: true
46
+ EnforcedStyleForMultiline: comma
49
47
 
50
48
  Style/TrailingCommaInBlockArgs:
51
49
  Enabled: true
@@ -62,30 +60,59 @@ Gemspec/DevelopmentDependencies:
62
60
  Layout/HashAlignment:
63
61
  Enabled: false
64
62
 
63
+ # Format with consistent indentation levels rather than vertical dot alignment.
64
+ Layout/MultilineMethodCallIndentation:
65
+ Enabled: false
66
+ EnforcedStyle: indented
67
+ IndentationWidth: 2
68
+
69
+ Layout/IndentationWidth:
70
+ Width: 2
71
+
72
+ Layout/ArgumentAlignment:
73
+ Enabled: false
74
+
75
+ Layout/DotPosition:
76
+ EnforcedStyle: leading # or 'trailing'
77
+
65
78
  Lint/Void:
66
79
  Enabled: false
67
80
 
81
+ Layout/MultilineAssignmentLayout:
82
+ Enabled: true
83
+ EnforcedStyle: same_line
84
+
85
+ Layout/EndAlignment:
86
+ EnforcedStyleAlignWith: start_of_line
87
+
88
+ Layout/FirstArgumentIndentation:
89
+ EnforcedStyle: consistent
90
+
68
91
  Metrics/AbcSize:
69
92
  Enabled: false
70
93
  Max: 20
71
94
 
72
95
  Metrics/ClassLength:
73
96
  Enabled: true
74
- Max: 200
97
+ Max: 350
75
98
 
76
99
  Metrics/CyclomaticComplexity:
77
100
  Enabled: false
78
101
 
79
102
  Metrics/MethodLength:
80
103
  Enabled: true
81
- Max: 40
104
+ Max: 50
82
105
  CountAsOne: ["method_call"]
83
106
 
84
107
  Metrics/ModuleLength:
85
108
  Enabled: true
86
- Max: 250
109
+ Max: 350
87
110
  CountAsOne: ["method_call"]
88
111
 
112
+ Metrics/ParameterLists:
113
+ Enabled: true
114
+ Max: 6
115
+
89
116
  Performance/Size:
90
117
  Enabled: true
91
118
  Exclude:
@@ -97,8 +124,19 @@ Style/NegatedIfElseCondition:
97
124
  Naming/AsciiIdentifiers:
98
125
  Enabled: false
99
126
 
127
+ Style/StringLiterals:
128
+ Enabled: true
129
+ EnforcedStyle: single_quotes
130
+
100
131
  Style/FrozenStringLiteralComment:
101
- Enabled: false
132
+ Enabled: true
133
+ EnforcedStyle: never
102
134
 
103
135
  Naming/MemoizedInstanceVariableName:
104
136
  Enabled: false
137
+
138
+ ThreadSafety/ClassInstanceVariable:
139
+ Enabled: false
140
+
141
+ ThreadSafety/MutableClassInstanceVariable:
142
+ Enabled: false
data/.talismanrc ADDED
@@ -0,0 +1,9 @@
1
+ # .talismanrc
2
+ #
3
+ # @see:
4
+ # https://thoughtworks.github.io/talisman/docs/configuring-talisman/ignoring/
5
+ # https://thoughtworks.github.io/talisman/docs/configuring-talisman/severity-threshold/
6
+ #
7
+ threshold: medium
8
+ fileignoreconfig: []
9
+ version: ""
data/.yardopts CHANGED
@@ -1,30 +1,35 @@
1
1
  --readme README.md
2
2
  --title "Familia Ruby Library Documentation"
3
- --markup markdown
4
- --markup-provider kramdown
5
3
  --protected
6
4
  --no-private
5
+ --verbose
6
+ --charset utf-8
7
+ --markup markdown
8
+ --markup-provider redcarpet
9
+ --output-dir public
7
10
  --embed-mixin ClassMethods
11
+ --embed-mixin InstanceMethods
8
12
  --embed-mixin Features
9
13
  --tag feature:"Feature"
10
14
  --tag since:"Since Version"
11
- --tag example:"Example Usage"
12
15
  --tag note:"Note"
13
16
  --tag warning:"Warning"
14
17
  --tag deprecated:"Deprecated"
18
+ --tag abstract:"Abstract"
19
+ --tag security:"Security"
15
20
  --hide-tag nodoc
16
21
  --exclude lib/familia/version.rb
22
+ --readme README.md
23
+ --no-stats
24
+ --no-save
25
+ --no-cache
17
26
  lib/**/*.rb
18
27
  -
19
- CHANGELOG.md
28
+ README.md
29
+ CHANGELOG.rst
20
30
  LICENSE.txt
21
- docs/guides/Home.md
22
- docs/guides/Getting-Started.md
23
- docs/guides/Feature-System-Guide.md
24
- docs/guides/Relationships-Guide.md
25
- docs/guides/relationships-methods.md
26
- docs/guides/Encrypted-Fields-Overview.md
27
- docs/guides/Connection-Pooling-Guide.md
28
- docs/reference/api-technical.md
29
- docs/migration/*.md
31
+ docs/guides/*
32
+ docs/reference/*
33
+ docs/migrating/*.md
34
+ docs/overview.md
30
35
  examples/*.rb