familia 2.0.0.pre15 → 2.0.0.pre17
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 +4 -4
- data/.github/workflows/ci.yml +2 -2
- data/.github/workflows/code-quality.yml +138 -0
- data/.github/workflows/code-smells.yml +85 -0
- data/.github/workflows/docs.yml +31 -8
- data/.gitignore +3 -1
- data/.pre-commit-config.yaml +7 -1
- data/.reek.yml +98 -0
- data/.rubocop.yml +54 -10
- data/.talismanrc +9 -0
- data/.yardopts +18 -13
- data/CHANGELOG.rst +86 -4
- data/CLAUDE.md +39 -1
- data/Gemfile +6 -5
- data/Gemfile.lock +99 -23
- data/LICENSE.txt +1 -1
- data/README.md +285 -85
- data/changelog.d/README.md +2 -2
- data/docs/archive/FAMILIA_RELATIONSHIPS.md +22 -22
- data/docs/archive/FAMILIA_TECHNICAL.md +42 -42
- data/docs/archive/FAMILIA_UPDATE.md +3 -3
- data/docs/archive/README.md +3 -2
- data/docs/{guides/API-Reference.md → archive/api-reference.md} +87 -101
- data/docs/conf.py +29 -0
- data/docs/guides/{Field-System-Guide.md → core-field-system.md} +9 -9
- data/docs/guides/feature-encrypted-fields.md +785 -0
- data/docs/guides/{Expiration-Feature-Guide.md → feature-expiration.md} +11 -2
- data/docs/guides/feature-external-identifiers.md +637 -0
- data/docs/guides/feature-object-identifiers.md +435 -0
- data/docs/guides/{Quantization-Feature-Guide.md → feature-quantization.md} +94 -29
- data/docs/guides/feature-relationships-methods.md +684 -0
- data/docs/guides/feature-relationships.md +200 -0
- data/docs/guides/{Features-System-Developer-Guide.md → feature-system-devs.md} +4 -4
- data/docs/guides/{Feature-System-Guide.md → feature-system.md} +5 -5
- data/docs/guides/{Transient-Fields-Guide.md → feature-transient-fields.md} +2 -2
- data/docs/guides/{Implementation-Guide.md → implementation.md} +3 -3
- data/docs/guides/index.md +176 -0
- data/docs/guides/{Security-Model.md → security-model.md} +1 -1
- data/docs/migrating/v2.0.0-pre.md +1 -1
- data/docs/migrating/v2.0.0-pre11.md +2 -2
- data/docs/migrating/v2.0.0-pre12.md +2 -2
- data/docs/migrating/v2.0.0-pre5.md +33 -12
- data/docs/migrating/v2.0.0-pre6.md +2 -2
- data/docs/migrating/v2.0.0-pre7.md +8 -8
- data/docs/overview.md +624 -20
- data/docs/reference/api-technical.md +1365 -0
- data/examples/autoloader/mega_customer/features/deprecated_fields.rb +7 -0
- data/examples/autoloader/mega_customer/safe_dump_fields.rb +1 -1
- data/examples/autoloader/mega_customer.rb +3 -1
- data/examples/encrypted_fields.rb +378 -0
- data/examples/json_usage_patterns.rb +144 -0
- data/examples/relationships.rb +13 -13
- data/examples/safe_dump.rb +7 -7
- data/examples/single_connection_transaction_confusions.rb +379 -0
- data/lib/familia/base.rb +51 -10
- data/lib/familia/connection/handlers.rb +223 -0
- data/lib/familia/connection/individual_command_proxy.rb +64 -0
- data/lib/familia/connection/middleware.rb +75 -0
- data/lib/familia/connection/operation_core.rb +93 -0
- data/lib/familia/connection/operations.rb +277 -0
- data/lib/familia/connection/pipeline_core.rb +87 -0
- data/lib/familia/connection/transaction_core.rb +100 -0
- data/lib/familia/connection.rb +60 -186
- data/lib/familia/data_type/class_methods.rb +63 -0
- data/lib/familia/data_type/commands.rb +53 -51
- data/lib/familia/data_type/connection.rb +83 -0
- data/lib/familia/data_type/serialization.rb +108 -107
- data/lib/familia/data_type/settings.rb +96 -0
- data/lib/familia/data_type/types/counter.rb +1 -1
- data/lib/familia/data_type/types/hashkey.rb +15 -11
- data/lib/familia/data_type/types/{list.rb → listkey.rb} +13 -5
- data/lib/familia/data_type/types/lock.rb +3 -2
- data/lib/familia/data_type/types/sorted_set.rb +128 -14
- data/lib/familia/data_type/types/{string.rb → stringkey.rb} +7 -9
- data/lib/familia/data_type/types/unsorted_set.rb +20 -27
- data/lib/familia/data_type.rb +12 -171
- data/lib/familia/distinguisher.rb +85 -0
- data/lib/familia/encryption/encrypted_data.rb +15 -24
- data/lib/familia/encryption/manager.rb +6 -4
- data/lib/familia/encryption/providers/aes_gcm_provider.rb +1 -1
- data/lib/familia/encryption/providers/secure_xchacha20_poly1305_provider.rb +7 -9
- data/lib/familia/encryption/providers/xchacha20_poly1305_provider.rb +4 -5
- data/lib/familia/encryption/request_cache.rb +7 -7
- data/lib/familia/encryption.rb +2 -3
- data/lib/familia/errors.rb +9 -3
- data/lib/familia/features/autoloader.rb +30 -12
- data/lib/familia/features/encrypted_fields/concealed_string.rb +3 -4
- data/lib/familia/features/encrypted_fields/encrypted_field_type.rb +13 -14
- data/lib/familia/features/encrypted_fields.rb +71 -66
- data/lib/familia/features/expiration/extensions.rb +1 -1
- data/lib/familia/features/expiration.rb +31 -26
- data/lib/familia/features/external_identifier.rb +57 -19
- data/lib/familia/features/object_identifier.rb +134 -25
- data/lib/familia/features/quantization.rb +16 -21
- data/lib/familia/features/relationships/README.md +97 -0
- data/lib/familia/features/relationships/collection_operations.rb +104 -0
- data/lib/familia/features/relationships/indexing/multi_index_generators.rb +202 -0
- data/lib/familia/features/relationships/indexing/unique_index_generators.rb +306 -0
- data/lib/familia/features/relationships/indexing.rb +182 -256
- data/lib/familia/features/relationships/indexing_relationship.rb +35 -0
- data/lib/familia/features/relationships/participation/participant_methods.rb +164 -0
- data/lib/familia/features/relationships/participation/target_methods.rb +225 -0
- data/lib/familia/features/relationships/participation.rb +656 -0
- data/lib/familia/features/relationships/participation_relationship.rb +31 -0
- data/lib/familia/features/relationships/score_encoding.rb +20 -20
- data/lib/familia/features/relationships.rb +65 -266
- data/lib/familia/features/safe_dump.rb +127 -130
- data/lib/familia/features/transient_fields/redacted_string.rb +6 -6
- data/lib/familia/features/transient_fields/transient_field_type.rb +5 -5
- data/lib/familia/features/transient_fields.rb +10 -7
- data/lib/familia/features.rb +10 -14
- data/lib/familia/field_type.rb +6 -4
- data/lib/familia/horreum/connection.rb +297 -0
- data/lib/familia/horreum/{core/database_commands.rb → database_commands.rb} +27 -17
- data/lib/familia/horreum/{subclass/definition.rb → definition.rb} +139 -74
- data/lib/familia/horreum/{subclass/management.rb → management.rb} +73 -27
- data/lib/familia/horreum/{core/serialization.rb → persistence.rb} +108 -185
- data/lib/familia/horreum/{subclass/related_fields_management.rb → related_fields.rb} +104 -23
- data/lib/familia/horreum/serialization.rb +172 -0
- data/lib/familia/horreum/{shared/settings.rb → settings.rb} +2 -1
- data/lib/familia/horreum/{core/utils.rb → utils.rb} +2 -1
- data/lib/familia/horreum.rb +222 -119
- data/lib/familia/json_serializer.rb +0 -1
- data/lib/familia/logging.rb +11 -114
- data/lib/familia/refinements/dear_json.rb +122 -0
- data/lib/familia/refinements/logger_trace.rb +20 -17
- data/lib/familia/refinements/stylize_words.rb +65 -0
- data/lib/familia/refinements/time_literals.rb +60 -52
- data/lib/familia/refinements.rb +2 -1
- data/lib/familia/secure_identifier.rb +60 -28
- data/lib/familia/settings.rb +83 -7
- data/lib/familia/utils.rb +5 -87
- data/lib/familia/verifiable_identifier.rb +4 -4
- data/lib/familia/version.rb +1 -1
- data/lib/familia.rb +72 -14
- data/lib/middleware/database_middleware.rb +56 -14
- data/lib/{familia/multi_result.rb → multi_result.rb} +23 -16
- data/try/configuration/scenarios_try.rb +2 -2
- data/try/connection/fiber_context_preservation_try.rb +250 -0
- data/try/connection/handler_constraints_try.rb +59 -0
- data/try/connection/operation_mode_guards_try.rb +208 -0
- data/try/connection/pipeline_fallback_integration_try.rb +128 -0
- data/try/connection/responsibility_chain_tracking_try.rb +72 -0
- data/try/connection/transaction_fallback_integration_try.rb +288 -0
- data/try/connection/transaction_mode_permissive_try.rb +153 -0
- data/try/connection/transaction_mode_strict_try.rb +98 -0
- data/try/connection/transaction_mode_warn_try.rb +131 -0
- data/try/connection/transaction_modes_try.rb +249 -0
- data/try/core/autoloader_try.rb +120 -2
- data/try/core/connection_try.rb +10 -10
- data/try/core/conventional_inheritance_try.rb +130 -0
- data/try/core/create_method_try.rb +15 -23
- data/try/core/database_consistency_try.rb +11 -10
- data/try/core/errors_try.rb +11 -14
- data/try/core/familia_extended_try.rb +2 -2
- data/try/core/familia_members_methods_try.rb +76 -0
- data/try/core/familia_try.rb +1 -1
- data/try/core/isolated_dbclient_try.rb +165 -0
- data/try/core/middleware_try.rb +16 -16
- data/try/core/persistence_operations_try.rb +4 -4
- data/try/core/pools_try.rb +42 -26
- data/try/core/secure_identifier_try.rb +28 -24
- data/try/core/time_utils_try.rb +10 -10
- data/try/core/tools_try.rb +3 -3
- data/try/core/utils_try.rb +2 -2
- data/try/data_types/boolean_try.rb +4 -4
- data/try/data_types/datatype_base_try.rb +0 -2
- data/try/data_types/list_try.rb +10 -10
- data/try/data_types/sorted_set_try.rb +5 -5
- data/try/data_types/sorted_set_zadd_options_try.rb +625 -0
- data/try/data_types/string_try.rb +12 -12
- data/try/data_types/unsortedset_try.rb +33 -0
- data/try/debugging/cache_behavior_tracer.rb +7 -7
- data/try/debugging/debug_aad_process.rb +1 -1
- data/try/debugging/debug_concealed_internal.rb +1 -1
- data/try/debugging/debug_cross_context.rb +1 -1
- data/try/debugging/debug_fresh_cross_context.rb +1 -1
- data/try/debugging/encryption_method_tracer.rb +10 -10
- data/try/edge_cases/hash_symbolization_try.rb +1 -1
- data/try/edge_cases/ttl_side_effects_try.rb +1 -1
- data/try/encryption/config_persistence_try.rb +2 -2
- data/try/encryption/encryption_core_try.rb +19 -19
- data/try/encryption/instance_variable_scope_try.rb +1 -1
- data/try/encryption/module_loading_try.rb +2 -2
- data/try/encryption/providers/aes_gcm_provider_try.rb +1 -1
- data/try/encryption/providers/xchacha20_poly1305_provider_try.rb +1 -1
- data/try/encryption/secure_memory_handling_try.rb +1 -1
- data/try/features/encrypted_fields/concealed_string_core_try.rb +11 -7
- data/try/features/encrypted_fields/encrypted_fields_core_try.rb +1 -1
- data/try/features/encrypted_fields/encrypted_fields_integration_try.rb +3 -3
- data/try/features/encrypted_fields/encrypted_fields_no_cache_security_try.rb +10 -10
- data/try/features/encrypted_fields/encrypted_fields_security_try.rb +14 -14
- data/try/features/encrypted_fields/error_conditions_try.rb +7 -7
- data/try/features/encrypted_fields/fresh_key_try.rb +1 -1
- data/try/features/encrypted_fields/nonce_uniqueness_try.rb +1 -1
- data/try/features/encrypted_fields/secure_by_default_behavior_try.rb +7 -7
- data/try/features/encrypted_fields/universal_serialization_safety_try.rb +13 -20
- data/try/features/external_identifier/external_identifier_try.rb +1 -1
- data/try/features/feature_dependencies_try.rb +3 -3
- data/try/features/field_groups_try.rb +244 -0
- data/try/features/object_identifier/object_identifier_integration_try.rb +28 -34
- data/try/features/object_identifier/object_identifier_try.rb +10 -0
- data/try/features/quantization/quantization_try.rb +1 -1
- data/try/features/relationships/indexing_commands_verification_try.rb +136 -0
- data/try/features/relationships/indexing_try.rb +443 -0
- data/try/features/relationships/participation_commands_verification_spec.rb +102 -0
- data/try/features/relationships/participation_commands_verification_try.rb +105 -0
- data/try/features/relationships/participation_performance_improvements_try.rb +124 -0
- data/try/features/relationships/participation_reverse_index_try.rb +196 -0
- data/try/features/relationships/relationships_api_changes_try.rb +72 -71
- data/try/features/relationships/relationships_edge_cases_try.rb +15 -18
- data/try/features/relationships/relationships_performance_minimal_try.rb +2 -2
- data/try/features/relationships/relationships_performance_simple_try.rb +8 -8
- data/try/features/relationships/relationships_performance_try.rb +20 -20
- data/try/features/relationships/relationships_try.rb +27 -38
- data/try/features/safe_dump/safe_dump_advanced_try.rb +2 -2
- data/try/features/transient_fields/refresh_reset_try.rb +3 -1
- data/try/features/transient_fields/simple_refresh_test.rb +1 -1
- data/try/helpers/test_cleanup.rb +86 -0
- data/try/helpers/test_helpers.rb +6 -7
- data/try/horreum/auto_indexing_on_save_try.rb +212 -0
- data/try/horreum/base_try.rb +3 -2
- data/try/horreum/commands_try.rb +3 -1
- data/try/horreum/defensive_initialization_try.rb +86 -0
- data/try/horreum/destroy_related_fields_cleanup_try.rb +332 -0
- data/try/horreum/initialization_try.rb +11 -7
- data/try/horreum/relations_try.rb +21 -13
- data/try/horreum/serialization_try.rb +12 -11
- data/try/horreum/settings_try.rb +2 -0
- data/try/integration/cross_component_try.rb +3 -3
- data/try/memory/memory_basic_test.rb +1 -1
- data/try/memory/memory_docker_ruby_dump.sh +2 -2
- data/try/models/customer_safe_dump_try.rb +1 -1
- data/try/models/customer_try.rb +13 -15
- data/try/models/datatype_base_try.rb +3 -3
- data/try/models/familia_object_try.rb +9 -8
- data/try/performance/benchmarks_try.rb +2 -2
- data/try/prototypes/atomic_saves_v1_context_proxy.rb +2 -2
- data/try/prototypes/atomic_saves_v3_connection_pool.rb +3 -3
- data/try/prototypes/atomic_saves_v4.rb +1 -1
- data/try/prototypes/lib/atomic_saves_v2_connection_switching_helpers.rb +4 -4
- data/try/prototypes/lib/atomic_saves_v3_connection_pool_helpers.rb +4 -4
- data/try/prototypes/pooling/lib/atomic_saves_v3_connection_pool_helpers.rb +4 -4
- data/try/prototypes/pooling/lib/connection_pool_metrics.rb +5 -5
- data/try/prototypes/pooling/lib/connection_pool_stress_test.rb +26 -26
- data/try/prototypes/pooling/lib/connection_pool_threading_models.rb +7 -7
- data/try/prototypes/pooling/lib/visualize_stress_results.rb +1 -1
- data/try/prototypes/pooling/pool_siege.rb +11 -11
- data/try/prototypes/pooling/run_stress_tests.rb +7 -7
- data/try/refinements/dear_json_array_methods_try.rb +53 -0
- data/try/refinements/dear_json_hash_methods_try.rb +54 -0
- data/try/refinements/logger_trace_methods_try.rb +44 -0
- data/try/refinements/time_literals_numeric_methods_try.rb +141 -0
- data/try/refinements/time_literals_string_methods_try.rb +80 -0
- data/try/valkey.conf +26 -0
- metadata +92 -52
- data/.rubocop_todo.yml +0 -208
- data/docs/connection_pooling.md +0 -192
- data/docs/guides/Connection-Pooling-Guide.md +0 -437
- data/docs/guides/Encrypted-Fields-Overview.md +0 -101
- data/docs/guides/Feature-System-Autoloading.md +0 -198
- data/docs/guides/Home.md +0 -116
- data/docs/guides/Relationships-Guide.md +0 -737
- data/docs/guides/relationships-methods.md +0 -266
- data/docs/reference/auditing_database_commands.rb +0 -228
- data/examples/permissions.rb +0 -240
- data/lib/familia/features/relationships/cascading.rb +0 -437
- data/lib/familia/features/relationships/membership.rb +0 -497
- data/lib/familia/features/relationships/permission_management.rb +0 -264
- data/lib/familia/features/relationships/querying.rb +0 -615
- data/lib/familia/features/relationships/redis_operations.rb +0 -274
- data/lib/familia/features/relationships/tracking.rb +0 -418
- data/lib/familia/horreum/core/connection.rb +0 -73
- data/lib/familia/horreum/core.rb +0 -21
- data/lib/familia/refinements/snake_case.rb +0 -40
- data/lib/familia/validation/command_recorder.rb +0 -336
- data/lib/familia/validation/expectations.rb +0 -519
- data/lib/familia/validation/validation_helpers.rb +0 -443
- data/lib/familia/validation/validator.rb +0 -412
- data/lib/familia/validation.rb +0 -140
- data/try/data_types/set_try.rb +0 -33
- data/try/features/relationships/categorical_permissions_try.rb +0 -515
- data/try/features/safe_dump/module_based_extensions_try.rb +0 -100
- data/try/features/safe_dump/safe_dump_autoloading_try.rb +0 -107
- data/try/validation/atomic_operations_try.rb.disabled +0 -320
- data/try/validation/command_validation_try.rb.disabled +0 -207
- data/try/validation/performance_validation_try.rb.disabled +0 -324
- 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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e760a3ff094446126c56a0c2b76fd5bed0f6ff64d8eed89580e19d98a5a9ba66
|
4
|
+
data.tar.gz: 74545b0bbb8c89b06ffd385c1448a95a7808b168686a955155a004b91160dafa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cd9cd6c374f24859279125ef05199b0dfdac51f7cccdf2bcdf0489c7cca5126ac03d7cab1d54aa8021ce38b286203212514b2b412322ea151b8957fa16c9b445
|
7
|
+
data.tar.gz: 3e44e06249e6daf715ce09b02643b8faf153c85fc2d8451d4cf56d77c5115e5e5fdb1b752acef3f1fdd46f7b7eb7f019213f22850ffe728ec51a05d98ecc5528
|
data/.github/workflows/ci.yml
CHANGED
@@ -35,8 +35,8 @@ jobs:
|
|
35
35
|
--health-retries 5
|
36
36
|
ports:
|
37
37
|
# https://docs.github.com/en/actions/using-containerized-services/creating-redis-service-containers#running-jobs-in-containers
|
38
|
-
# Maps port 6379 on service container to the host
|
39
|
-
-
|
38
|
+
# Maps port 6379 on service container to 2525 on the host
|
39
|
+
- 2525:6379
|
40
40
|
|
41
41
|
steps:
|
42
42
|
- uses: actions/checkout@v4
|
@@ -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,85 @@
|
|
1
|
+
# ..github/workflows/code-smells.yml
|
2
|
+
---
|
3
|
+
name: Code Smells
|
4
|
+
|
5
|
+
on:
|
6
|
+
pull_request:
|
7
|
+
branches: [main]
|
8
|
+
push:
|
9
|
+
branches: [main]
|
10
|
+
workflow_dispatch:
|
11
|
+
|
12
|
+
permissions:
|
13
|
+
contents: read
|
14
|
+
pull-requests: write # Needed to post comments on PRs
|
15
|
+
|
16
|
+
jobs:
|
17
|
+
reek:
|
18
|
+
name: Reek Code Analysis
|
19
|
+
runs-on: ubuntu-24.04
|
20
|
+
timeout-minutes: 5
|
21
|
+
|
22
|
+
steps:
|
23
|
+
- name: Checkout code
|
24
|
+
uses: actions/checkout@v4
|
25
|
+
|
26
|
+
- name: Set up Ruby
|
27
|
+
uses: ruby/setup-ruby@v1
|
28
|
+
with:
|
29
|
+
ruby-version: 3.4
|
30
|
+
bundler-cache: true
|
31
|
+
|
32
|
+
- name: Configure Bundler for secure gem installation
|
33
|
+
run: |
|
34
|
+
bundle config set --local path 'vendor/bundle'
|
35
|
+
bundle config set --local deployment 'false'
|
36
|
+
|
37
|
+
- name: Install dependencies
|
38
|
+
run: bundle install --jobs 4 --retry 3
|
39
|
+
|
40
|
+
- name: Run Reek analysis
|
41
|
+
run: |
|
42
|
+
echo "=== Running Reek code analysis ==="
|
43
|
+
echo "This analysis identifies code smells and potential improvements."
|
44
|
+
echo "Results are informational and won't fail the build."
|
45
|
+
echo ""
|
46
|
+
|
47
|
+
# Run reek and capture output (don't fail on warnings)
|
48
|
+
# Use success-exit-code to prevent failures from stopping the analysis
|
49
|
+
bundle exec reek --format=text --success-exit-code 0 --failure-exit-code 0 || true
|
50
|
+
|
51
|
+
echo ""
|
52
|
+
echo "=== Reek analysis complete ==="
|
53
|
+
continue-on-error: true # Don't fail the build on code smells
|
54
|
+
|
55
|
+
- name: Generate Reek report (if analysis available)
|
56
|
+
run: |
|
57
|
+
echo "=== Generating detailed Reek report ==="
|
58
|
+
|
59
|
+
# Generate JSON report for potential future processing
|
60
|
+
bundle exec reek --format=json --success-exit-code 0 --failure-exit-code 0 > reek-report.json || true
|
61
|
+
|
62
|
+
# If no JSON was generated, create an empty valid JSON array
|
63
|
+
if [ ! -s reek-report.json ]; then
|
64
|
+
echo "[]" > reek-report.json
|
65
|
+
echo "No code smells detected - created empty report"
|
66
|
+
else
|
67
|
+
echo "Reek JSON report generated: $(wc -l < reek-report.json) lines"
|
68
|
+
echo "Top code smell types found:"
|
69
|
+
jq -r '.[].smells[].smell_type' reek-report.json 2>/dev/null | sort | uniq -c | sort -rn | head -10 || echo "Unable to parse JSON report"
|
70
|
+
fi
|
71
|
+
|
72
|
+
# Also generate a human-readable HTML report for easier viewing
|
73
|
+
bundle exec reek --format=html --success-exit-code 0 --failure-exit-code 0 > reek-report.html || echo "<!-- No code smells detected -->" > reek-report.html
|
74
|
+
continue-on-error: true
|
75
|
+
|
76
|
+
- name: Upload Reek report as artifact
|
77
|
+
uses: actions/upload-artifact@v4
|
78
|
+
if: always()
|
79
|
+
with:
|
80
|
+
name: reek-report
|
81
|
+
path: |
|
82
|
+
reek-report.json
|
83
|
+
reek-report.html
|
84
|
+
if-no-files-found: ignore
|
85
|
+
retention-days: 30
|
data/.github/workflows/docs.yml
CHANGED
@@ -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:
|
12
|
+
description: "Reason for manual documentation build"
|
11
13
|
required: false
|
12
|
-
default:
|
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:
|
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
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
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: ./
|
75
|
+
path: ./public
|
53
76
|
|
54
77
|
deploy:
|
55
78
|
environment:
|
data/.gitignore
CHANGED
data/.pre-commit-config.yaml
CHANGED
@@ -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
|
-
- "
|
32
|
-
- "
|
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:
|
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:
|
104
|
+
Max: 50
|
82
105
|
CountAsOne: ["method_call"]
|
83
106
|
|
84
107
|
Metrics/ModuleLength:
|
85
108
|
Enabled: true
|
86
|
-
Max:
|
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,25 @@ Style/NegatedIfElseCondition:
|
|
97
124
|
Naming/AsciiIdentifiers:
|
98
125
|
Enabled: false
|
99
126
|
|
100
|
-
|
127
|
+
Naming/PredicateMethod:
|
101
128
|
Enabled: false
|
102
129
|
|
130
|
+
Style/StringLiterals:
|
131
|
+
Enabled: true
|
132
|
+
EnforcedStyle: single_quotes
|
133
|
+
|
134
|
+
Style/FrozenStringLiteralComment:
|
135
|
+
Enabled: true
|
136
|
+
EnforcedStyle: never
|
137
|
+
|
103
138
|
Naming/MemoizedInstanceVariableName:
|
104
139
|
Enabled: false
|
140
|
+
|
141
|
+
ThreadSafety/ClassAndModuleAttributes:
|
142
|
+
Enabled: false
|
143
|
+
|
144
|
+
ThreadSafety/ClassInstanceVariable:
|
145
|
+
Enabled: false
|
146
|
+
|
147
|
+
ThreadSafety/MutableClassInstanceVariable:
|
148
|
+
Enabled: false
|
data/.talismanrc
ADDED
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
|
-
|
28
|
+
README.md
|
29
|
+
CHANGELOG.rst
|
20
30
|
LICENSE.txt
|
21
|
-
docs/guides
|
22
|
-
docs/
|
23
|
-
docs/
|
24
|
-
docs/
|
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
|