schema-model 0.7.4 → 0.9.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +23 -0
- data/README.md +185 -10
- data/lib/schema/active_model_parsing_errors.rb +31 -0
- data/lib/schema/active_model_validations.rb +13 -16
- data/lib/schema/attribute_values.rb +41 -0
- data/lib/schema/deep_copy.rb +33 -0
- data/lib/schema/errors.rb +4 -0
- data/lib/schema/model.rb +19 -0
- data/lib/schema/parsers/american.rb +4 -12
- data/lib/schema/parsers/array.rb +1 -0
- data/lib/schema/parsers/common.rb +17 -26
- data/lib/schema/parsers/string_value.rb +23 -0
- data/lib/schema/parsing_status.rb +20 -0
- data/lib/schema/utils.rb +27 -0
- data/lib/schema/version.rb +1 -1
- data/lib/schema-model.rb +8 -0
- data/lib/schema_validator.rb +9 -8
- metadata +9 -17
- data/.github/dependabot.yml +0 -18
- data/.github/workflows/ci.yml +0 -93
- data/.github/workflows/release.yml +0 -93
- data/.gitignore +0 -51
- data/.release-please-manifest.json +0 -3
- data/.rubocop.yml +0 -68
- data/.ruby-gemset +0 -1
- data/.ruby-version +0 -1
- data/ARCHITECTURE.md +0 -161
- data/CLAUDE.md +0 -87
- data/Gemfile +0 -16
- data/Gemfile.lock +0 -134
- data/release-please-config.json +0 -12
- data/schema-model.gemspec +0 -24
- data/script/console +0 -7
- data/script/coverage_badge.rb +0 -49
data/ARCHITECTURE.md
DELETED
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
# Architecture
|
|
2
|
-
|
|
3
|
-
This document describes the internal architecture of the `schema-model` gem.
|
|
4
|
-
|
|
5
|
-
## Overview
|
|
6
|
-
|
|
7
|
-
The gem transforms hash data into strongly-typed Ruby objects with parsing, validation, and nested associations. The core flow is:
|
|
8
|
-
|
|
9
|
-
```
|
|
10
|
-
Hash Data → from_hash() → Parser Methods → Schema Instance
|
|
11
|
-
↓
|
|
12
|
-
parsing_errors (if invalid)
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
## Module Hierarchy
|
|
16
|
-
|
|
17
|
-
```
|
|
18
|
-
Schema::All (convenience bundle)
|
|
19
|
-
├── Schema::Model (core attribute system)
|
|
20
|
-
│ └── Schema::Parsers::Common
|
|
21
|
-
├── Schema::Associations::HasOne
|
|
22
|
-
├── Schema::Associations::HasMany
|
|
23
|
-
├── Schema::Parsers::American
|
|
24
|
-
├── Schema::Parsers::Array
|
|
25
|
-
├── Schema::Parsers::Hash
|
|
26
|
-
├── Schema::Parsers::Json
|
|
27
|
-
└── Schema::ActiveModelValidations
|
|
28
|
-
|
|
29
|
-
Opt-in (via schema_include):
|
|
30
|
-
├── Schema::ArrayHeaders (map CSV headers to attributes)
|
|
31
|
-
└── Schema::Arrays (models to/from flat arrays)
|
|
32
|
-
|
|
33
|
-
Standalone:
|
|
34
|
-
├── Schema::CSVParser (class; reads CSV rows into models)
|
|
35
|
-
└── SchemaValidator (ActiveModel validator for `schema: true`)
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
`schema_include` both includes a module and records it in `schema_config[:schema_includes]`, so it is also included in every nested association class, including ones defined later.
|
|
39
|
-
|
|
40
|
-
## Core Components
|
|
41
|
-
|
|
42
|
-
### Schema::Model (`lib/schema/model.rb`)
|
|
43
|
-
|
|
44
|
-
The foundation module providing:
|
|
45
|
-
|
|
46
|
-
- **`attribute(name, type, options)`**: Defines schema fields. Each call:
|
|
47
|
-
1. Adds field metadata to the class's `schema` hash via `add_value_to_class_method`
|
|
48
|
-
2. Generates getter, setter, and `<name>_was_set?` methods
|
|
49
|
-
3. Setter invokes `parse_<type>` method automatically
|
|
50
|
-
|
|
51
|
-
- **`from_hash(data, skip_fields)`**: Class method that creates instance and calls `update_attributes`
|
|
52
|
-
|
|
53
|
-
- **`update_attributes(data, skip_fields)`**: Iterates the data's key/value pairs, matches them against the schema, and invokes setters. Plain attributes are set before associations, so an association's `external_type_field` can read a sibling attribute. Each key is looked up on its own: symbol keys in `schema`, anything else in `schema_with_string_keys` (rebuilt whenever `schema` changes). `skip_fields` entries match a field by name or alias, as a symbol or string; a `{ association: [...] }` entry passes a nested list down.
|
|
54
|
-
|
|
55
|
-
- **Aliases**: each alias adds a second schema entry with `alias_of:` pointing at the real attribute, plus aliased getter/setter methods. Serialization and array conversion skip entries with `alias_of`.
|
|
56
|
-
|
|
57
|
-
- **`as_json` / `to_hash`**: Serialization back to hash format
|
|
58
|
-
|
|
59
|
-
### Schema::Parsers::Common (`lib/schema/parsers/common.rb`)
|
|
60
|
-
|
|
61
|
-
Base parser methods for fundamental types:
|
|
62
|
-
- `parse_integer`, `parse_float`, `parse_string`, `parse_string_or_nil`
|
|
63
|
-
- `parse_boolean`, `parse_time`, `parse_date`
|
|
64
|
-
|
|
65
|
-
Each parser:
|
|
66
|
-
1. Accepts `(field_name, parsing_errors, value)`
|
|
67
|
-
2. Returns converted value or nil
|
|
68
|
-
3. Adds to `parsing_errors` on failure (never raises)
|
|
69
|
-
|
|
70
|
-
Additional parsers extend these: `Parsers::American` (date formats), `Parsers::Array`, `Parsers::Hash`, `Parsers::Json`.
|
|
71
|
-
|
|
72
|
-
### Schema::Associations (`lib/schema/associations/`)
|
|
73
|
-
|
|
74
|
-
**HasOne** and **HasMany** define nested relationships:
|
|
75
|
-
|
|
76
|
-
```ruby
|
|
77
|
-
has_one(:profile) { attribute :bio, :string }
|
|
78
|
-
has_many(:posts) { attribute :title, :string }
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
Each association gets a generated class (`SchemaHasOne<Name>` / `SchemaHasMany<Name>` by default, or `class_name:`), defined as a constant inside the parent class. `base_class:` subclasses an existing schema instead of creating a fresh model class.
|
|
82
|
-
|
|
83
|
-
Both use **SchemaCreator** (`schema_creator.rb`) to:
|
|
84
|
-
1. Determine which class to instantiate (static or dynamic)
|
|
85
|
-
2. Call `from_hash` on the nested class
|
|
86
|
-
3. Propagate parsing errors to parent: `invalid` when the nested model has parsing errors, `incompatible` when the value isn't a hash (or, for has-many, an array), and `unknown` when no dynamic type matches
|
|
87
|
-
|
|
88
|
-
`has_many ..., from: :hash` accepts a hash keyed by id instead of an array; each key is written to `hash_key_field` (default `:id`) on the nested model.
|
|
89
|
-
|
|
90
|
-
**DynamicTypes** enables polymorphic associations:
|
|
91
|
-
|
|
92
|
-
```ruby
|
|
93
|
-
has_many(:items, type_field: :kind) do
|
|
94
|
-
add_type('widget') { attribute :size, :integer }
|
|
95
|
-
add_type('gadget') { attribute :power, :float }
|
|
96
|
-
default_type { } # fallback
|
|
97
|
-
end
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
The `type_field` option tells SchemaCreator which key in the nested data determines the subclass (the type field attribute's aliases are checked too); `external_type_field` reads the type from an attribute on the parent instead. `type_ignorecase: true` compares type names case-insensitively. Each `add_type` creates a subclass of the association class, defined on the parent class as `<Name>AssociationType<Type>`.
|
|
101
|
-
|
|
102
|
-
`Associations::Base` stores the parent class by name and resolves it with `Object.const_get` (so reloaded constants are picked up); a parent that was anonymous when the association was declared is kept by reference instead.
|
|
103
|
-
|
|
104
|
-
### Schema::Utils (`lib/schema/utils.rb`)
|
|
105
|
-
|
|
106
|
-
Utility methods for:
|
|
107
|
-
- `classify_name`: String → ClassName conversion
|
|
108
|
-
- `create_schema_class`: Dynamically creates nested schema classes
|
|
109
|
-
- `add_association_class`: Wires up association with proper modules
|
|
110
|
-
- `add_attribute_default_methods` / `add_association_default_methods`: Default value handling (`copy_default` hands each read a deep copy of the default)
|
|
111
|
-
|
|
112
|
-
### Error Handling
|
|
113
|
-
|
|
114
|
-
Two error storage mechanisms:
|
|
115
|
-
|
|
116
|
-
1. **Schema::Errors** (`lib/schema/errors.rb`): Simple hash-based storage, used standalone
|
|
117
|
-
|
|
118
|
-
2. **ActiveModel::Errors**: When `Schema::ActiveModelValidations` is included, `parsing_errors` returns `ActiveModel::Errors` instance
|
|
119
|
-
|
|
120
|
-
Parsing errors are distinct from validation errors:
|
|
121
|
-
- **Parsing errors**: Type conversion failures (string "abc" → integer)
|
|
122
|
-
- **Validation errors**: Business rule failures (via `validates` DSL)
|
|
123
|
-
|
|
124
|
-
`parsed!` raises `ParsingException` when there are parsing errors and `valid_model!` raises `ValidationException` when validations fail; `valid!` calls both. `valid?` runs validations only and does not look at parsing errors.
|
|
125
|
-
|
|
126
|
-
Parsing errors use these codes from `Schema::ParsingErrors`: `invalid`, `incompatible`, `unknown`, `unknown_attribute`, `unhandled_type`.
|
|
127
|
-
|
|
128
|
-
### CSV and Arrays
|
|
129
|
-
|
|
130
|
-
- **`Schema::ArrayHeaders`** (`lib/schema/array_headers.rb`): `map_headers_to_attributes(headers)` returns a nested hash of `{ field: { index: n } }` entries. Has-many fields are matched as `<prefix><n><key>` (prefix is the association name or an alias, `n` counts from 1) and map to `{ indexes: [...] }`. Has-one fields are matched by their own key or alias; a column already claimed by the parent or an earlier has-one isn't reused. Associations never map to a column of their own.
|
|
131
|
-
- **`Schema::Arrays`** (`lib/schema/arrays.rb`): `to_headers`, `to_empty_array`, `to_a` and `from_array(array, mapped_headers)`. Has-many associations need a `size:` option for the fixed-width methods.
|
|
132
|
-
- **`Schema::CSVParser`** (`lib/schema/csv_parser.rb`): wraps a `CSV` object, maps its header row once, and yields a model per row (`each`, `shift`, `missing_fields`).
|
|
133
|
-
|
|
134
|
-
### Inheritance Helper Integration
|
|
135
|
-
|
|
136
|
-
The gem uses `inheritance-helper` for schema inheritance. Key method:
|
|
137
|
-
- `add_value_to_class_method(:schema, name => options)`: Accumulates schema definitions across class hierarchy
|
|
138
|
-
|
|
139
|
-
This allows schema classes to inherit attributes from parent classes.
|
|
140
|
-
|
|
141
|
-
## Data Flow Example
|
|
142
|
-
|
|
143
|
-
```ruby
|
|
144
|
-
class OrderSchema
|
|
145
|
-
include Schema::All
|
|
146
|
-
attribute :total, :float
|
|
147
|
-
has_one(:customer) { attribute :name, :string }
|
|
148
|
-
end
|
|
149
|
-
|
|
150
|
-
order = OrderSchema.from_hash({
|
|
151
|
-
total: "99.50",
|
|
152
|
-
customer: { name: "Alice" }
|
|
153
|
-
})
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
1. `from_hash` calls `new.update_attributes(data)`
|
|
157
|
-
2. `update_attributes` iterates keys, finds `:total` in schema
|
|
158
|
-
3. Calls `self.total = "99.50"` → invokes `parse_float`
|
|
159
|
-
4. For `:customer`, recognizes association, delegates to SchemaCreator
|
|
160
|
-
5. SchemaCreator calls `OrderSchema::SchemaHasOneCustomer.from_hash({name: "Alice"})`
|
|
161
|
-
6. Returns populated `OrderSchema` instance
|
data/CLAUDE.md
DELETED
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
# CLAUDE.md
|
|
2
|
-
|
|
3
|
-
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
-
|
|
5
|
-
## Build and Test Commands
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
# Install dependencies
|
|
9
|
-
bundle install
|
|
10
|
-
|
|
11
|
-
# Run all tests
|
|
12
|
-
bundle exec rspec
|
|
13
|
-
|
|
14
|
-
# Run a single test file
|
|
15
|
-
bundle exec rspec spec/schema/model_spec.rb
|
|
16
|
-
|
|
17
|
-
# Run a specific test by line number
|
|
18
|
-
bundle exec rspec spec/schema/model_spec.rb:42
|
|
19
|
-
|
|
20
|
-
# Run linter
|
|
21
|
-
bundle exec rubocop
|
|
22
|
-
|
|
23
|
-
# Auto-fix linter issues
|
|
24
|
-
bundle exec rubocop -A
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
## Architecture
|
|
28
|
-
|
|
29
|
-
This is a Ruby gem (`schema-model`) for data transformation, validation, and type safety. It transforms hash data into strongly-typed model objects.
|
|
30
|
-
|
|
31
|
-
### Core Module Structure
|
|
32
|
-
|
|
33
|
-
- **Schema::Model** (`lib/schema/model.rb`) - Foundation module providing `attribute` definitions, `from_hash` class method, and attribute accessors.
|
|
34
|
-
|
|
35
|
-
- **Schema::All** (`lib/schema/all.rb`) - Convenience module bundling Model + Associations + Parsers + ActiveModel validations. This is the typical include.
|
|
36
|
-
|
|
37
|
-
- **Schema::Parsers** - Type parsers in `lib/schema/parsers/`:
|
|
38
|
-
- `Common` - integer, string, string_or_nil, float, time, date, boolean (included by `Schema::Model`)
|
|
39
|
-
- `American` - american_date, american_time (MM/DD/YYYY format)
|
|
40
|
-
- `Array` - array with optional separator and data_type
|
|
41
|
-
- `Hash` - hash/dictionary values
|
|
42
|
-
- `Json` - JSON string parsing
|
|
43
|
-
|
|
44
|
-
- **Schema::Associations** - `HasOne` and `HasMany` for nested relationships. `DynamicTypes` enables polymorphic associations via `type_field`/`add_type`.
|
|
45
|
-
|
|
46
|
-
- **Schema::Arrays** (`lib/schema/arrays.rb`) - Convert models to/from flat arrays for CSV support.
|
|
47
|
-
|
|
48
|
-
- **Schema::ArrayHeaders** (`lib/schema/array_headers.rb`) - Map CSV headers to schema attributes.
|
|
49
|
-
|
|
50
|
-
- **Schema::CSVParser** (`lib/schema/csv_parser.rb`) - Class that reads `CSV` rows into models (needs ArrayHeaders + Arrays on the model).
|
|
51
|
-
|
|
52
|
-
- **SchemaValidator** (`lib/schema_validator.rb`) - ActiveModel validator behind `validates :assoc, schema: true`.
|
|
53
|
-
|
|
54
|
-
### Key Patterns
|
|
55
|
-
|
|
56
|
-
**Attribute Definition**: Each `attribute` call generates getter, setter, and `<name>_was_set?` predicate. Setter invokes type-specific parser.
|
|
57
|
-
|
|
58
|
-
**Parsing Errors**: Stored in `parsing_errors`. Parsers add errors for invalid values rather than raising exceptions. With ActiveModelValidations, use `parsed?`/`parsed!`; `valid?` does not check parsing errors.
|
|
59
|
-
|
|
60
|
-
**Schema Inheritance**: Uses `inheritance-helper` gem. Schema definitions accumulate via `add_value_to_class_method(:schema, ...)`.
|
|
61
|
-
|
|
62
|
-
**Dynamic Types**: For polymorphic associations, use `type_field` option with `add_type` blocks. Supports `external_type_field`, `type_ignorecase`, and `default_type`.
|
|
63
|
-
|
|
64
|
-
## CI
|
|
65
|
-
|
|
66
|
-
`.github/workflows/ci.yml` runs RuboCop and the specs on the `.ruby-version` Ruby. On pushes to `master`, it publishes `coverage.svg` (line) and `branches.svg` (branch) from `script/coverage_badge.rb` to the orphan `badges` branch for the README badges.
|
|
67
|
-
|
|
68
|
-
## Releases
|
|
69
|
-
|
|
70
|
-
Releases are automated by release-please (`.github/workflows/release.yml`). Conventional commits on `master` (`fix:` → patch, `feat:` → minor, `!`/`BREAKING CHANGE` → major) update an open release PR that bumps `lib/schema/version.rb` (`Schema::VERSION`, read by the gemspec) and `CHANGELOG.md`. Merging that PR tags `vX.Y.Z`, creates the GitHub release, and publishes the gem to RubyGems. Don't bump the version by hand.
|
|
71
|
-
|
|
72
|
-
## Code Commits
|
|
73
|
-
|
|
74
|
-
Format using angular formatting:
|
|
75
|
-
```
|
|
76
|
-
<type>(<scope>): <short summary>
|
|
77
|
-
```
|
|
78
|
-
- **type**: build|ci|docs|feat|fix|perf|refactor|test
|
|
79
|
-
- **scope**: The feature or component of the service we're working on
|
|
80
|
-
- **summary**: Summary in present tense. Not capitalized. No period at the end.
|
|
81
|
-
|
|
82
|
-
## Documentation Maintenance
|
|
83
|
-
|
|
84
|
-
When modifying the codebase, keep documentation in sync:
|
|
85
|
-
- **ARCHITECTURE.md** - Update when adding/removing classes, changing component relationships, or altering data flow patterns
|
|
86
|
-
- **README.md** - Update when adding new features, changing public APIs, or modifying usage examples
|
|
87
|
-
- **CHANGELOG.md** - Generated by release-please from commit messages; don't edit by hand except to fix release notes
|
data/Gemfile
DELETED
data/Gemfile.lock
DELETED
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
GEM
|
|
2
|
-
remote: https://rubygems.org/
|
|
3
|
-
specs:
|
|
4
|
-
activemodel (8.1.4)
|
|
5
|
-
activesupport (= 8.1.4)
|
|
6
|
-
activesupport (8.1.4)
|
|
7
|
-
base64
|
|
8
|
-
bigdecimal
|
|
9
|
-
concurrent-ruby (~> 1.0, >= 1.3.1)
|
|
10
|
-
connection_pool (>= 2.2.5)
|
|
11
|
-
drb
|
|
12
|
-
i18n (>= 1.6, < 2)
|
|
13
|
-
json
|
|
14
|
-
logger (>= 1.4.2)
|
|
15
|
-
minitest (>= 5.1)
|
|
16
|
-
securerandom (>= 0.3)
|
|
17
|
-
tzinfo (~> 2.0, >= 2.0.5)
|
|
18
|
-
uri (>= 0.13.1)
|
|
19
|
-
ast (2.4.3)
|
|
20
|
-
base64 (0.3.0)
|
|
21
|
-
bigdecimal (4.1.3)
|
|
22
|
-
concurrent-ruby (1.3.8)
|
|
23
|
-
connection_pool (3.0.2)
|
|
24
|
-
csv (3.3.6)
|
|
25
|
-
diff-lcs (1.6.2)
|
|
26
|
-
drb (2.2.3)
|
|
27
|
-
i18n (1.15.2)
|
|
28
|
-
concurrent-ruby (~> 1.0)
|
|
29
|
-
inheritance-helper (0.2.5)
|
|
30
|
-
json (3.0.2)
|
|
31
|
-
language_server-protocol (3.17.0.6)
|
|
32
|
-
lint_roller (1.1.0)
|
|
33
|
-
logger (1.7.0)
|
|
34
|
-
minitest (6.0.6)
|
|
35
|
-
drb (~> 2.0)
|
|
36
|
-
prism (~> 1.5)
|
|
37
|
-
parallel (2.3.0)
|
|
38
|
-
parser (3.3.12.0)
|
|
39
|
-
ast (~> 2.4.1)
|
|
40
|
-
racc
|
|
41
|
-
prism (1.9.0)
|
|
42
|
-
racc (1.8.1)
|
|
43
|
-
rainbow (3.1.1)
|
|
44
|
-
regexp_parser (2.13.1)
|
|
45
|
-
rspec (3.13.2)
|
|
46
|
-
rspec-core (~> 3.13.0)
|
|
47
|
-
rspec-expectations (~> 3.13.0)
|
|
48
|
-
rspec-mocks (~> 3.13.0)
|
|
49
|
-
rspec-core (3.13.6)
|
|
50
|
-
rspec-support (~> 3.13.0)
|
|
51
|
-
rspec-expectations (3.13.5)
|
|
52
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
|
53
|
-
rspec-support (~> 3.13.0)
|
|
54
|
-
rspec-mocks (3.13.8)
|
|
55
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
|
56
|
-
rspec-support (~> 3.13.0)
|
|
57
|
-
rspec-support (3.13.7)
|
|
58
|
-
rubocop (1.91.0)
|
|
59
|
-
json (>= 2.3)
|
|
60
|
-
language_server-protocol (~> 3.17.0.2)
|
|
61
|
-
lint_roller (~> 1.1.0)
|
|
62
|
-
parallel (>= 1.10)
|
|
63
|
-
parser (>= 3.3.0.2)
|
|
64
|
-
rainbow (>= 2.2.2, < 4.0)
|
|
65
|
-
regexp_parser (>= 2.9.3, < 3.0)
|
|
66
|
-
rubocop-ast (>= 1.49.0, < 2.0)
|
|
67
|
-
ruby-progressbar (~> 1.7)
|
|
68
|
-
unicode-display_width (>= 2.4.0, < 4.0)
|
|
69
|
-
rubocop-ast (1.50.0)
|
|
70
|
-
parser (>= 3.3.7.2)
|
|
71
|
-
prism (~> 1.7)
|
|
72
|
-
ruby-progressbar (1.13.0)
|
|
73
|
-
securerandom (0.4.1)
|
|
74
|
-
simplecov (1.3.2)
|
|
75
|
-
tzinfo (2.0.6)
|
|
76
|
-
concurrent-ruby (~> 1.0)
|
|
77
|
-
unicode-display_width (3.3.0)
|
|
78
|
-
unicode-emoji (~> 4.3)
|
|
79
|
-
unicode-emoji (4.3.0)
|
|
80
|
-
uri (1.1.1)
|
|
81
|
-
|
|
82
|
-
PLATFORMS
|
|
83
|
-
ruby
|
|
84
|
-
x86_64-darwin-24
|
|
85
|
-
|
|
86
|
-
DEPENDENCIES
|
|
87
|
-
activemodel
|
|
88
|
-
csv
|
|
89
|
-
inheritance-helper
|
|
90
|
-
rspec
|
|
91
|
-
rubocop
|
|
92
|
-
simplecov
|
|
93
|
-
|
|
94
|
-
CHECKSUMS
|
|
95
|
-
activemodel (8.1.4) sha256=9a0906c127bd118aa5f06157db12b8f750da83dccee72db2f658547a0ae7a0e8
|
|
96
|
-
activesupport (8.1.4) sha256=891dd3fe43c4fc8391934b237b1189bb1f661c932a84a840043db9d46a4e80df
|
|
97
|
-
ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383
|
|
98
|
-
base64 (0.3.0) sha256=27337aeabad6ffae05c265c450490628ef3ebd4b67be58257393227588f5a97b
|
|
99
|
-
bigdecimal (4.1.3) sha256=61ebe1e5e559bdc3cc6f2c0ee7f427321fc838f59611c294356eb04d6e21cf66
|
|
100
|
-
concurrent-ruby (1.3.8) sha256=b2f1be836e968ccc78ccfce277ea79c72a88633f22306782c16ff23fb415d1e1
|
|
101
|
-
connection_pool (3.0.2) sha256=33fff5ba71a12d2aa26cb72b1db8bba2a1a01823559fb01d29eb74c286e62e0a
|
|
102
|
-
csv (3.3.6) sha256=aba61e7e507a66f03d45cb1f3c4b6359861c3504038b422962875dce099e4456
|
|
103
|
-
diff-lcs (1.6.2) sha256=9ae0d2cba7d4df3075fe8cd8602a8604993efc0dfa934cff568969efb1909962
|
|
104
|
-
drb (2.2.3) sha256=0b00d6fdb50995fe4a45dea13663493c841112e4068656854646f418fda13373
|
|
105
|
-
i18n (1.15.2) sha256=00f9eb62412fe593b2a65a97daa75300d37abb8f7202ec748e94b6d46a9dd1b5
|
|
106
|
-
inheritance-helper (0.2.5) sha256=e318d548d2e201910ab484b2139a11e61f3dfac012c4aba090bcfaa5f9687b85
|
|
107
|
-
json (3.0.2) sha256=8e6d7e7b11384c21230430cef90b71f14849a34a1f4452796670f7c981bd19df
|
|
108
|
-
language_server-protocol (3.17.0.6) sha256=5ef2c0c138f8267e1bc631d3328347d354f96724b0af22f2c79516120443b7f0
|
|
109
|
-
lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87
|
|
110
|
-
logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203
|
|
111
|
-
minitest (6.0.6) sha256=153ea36d1d987a62942382b61075745042a2b3123b1cd48f4c3675af9cc7d6f1
|
|
112
|
-
parallel (2.3.0) sha256=f75a3e904101ce6a1ccb6b8dc800cbafd42166d83330192438dcf29395167a6f
|
|
113
|
-
parser (3.3.12.0) sha256=21a6d7f755d5a24dfbdc6e6b772e4e879a52e7631a88bc5a3a134606052c9828
|
|
114
|
-
prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85
|
|
115
|
-
racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f
|
|
116
|
-
rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a
|
|
117
|
-
regexp_parser (2.13.1) sha256=5aedb6b7c35688f51e86eef17a15374dfd287c83f4ca644b2c5f3ec50a33b44b
|
|
118
|
-
rspec (3.13.2) sha256=206284a08ad798e61f86d7ca3e376718d52c0bc944626b2349266f239f820587
|
|
119
|
-
rspec-core (3.13.6) sha256=a8823c6411667b60a8bca135364351dda34cd55e44ff94c4be4633b37d828b2d
|
|
120
|
-
rspec-expectations (3.13.5) sha256=33a4d3a1d95060aea4c94e9f237030a8f9eae5615e9bd85718fe3a09e4b58836
|
|
121
|
-
rspec-mocks (3.13.8) sha256=086ad3d3d17533f4237643de0b5c42f04b66348c28bf6b9c2d3f4a3b01af1d47
|
|
122
|
-
rspec-support (3.13.7) sha256=0640e5570872aafefd79867901deeeeb40b0c9875a36b983d85f54fb7381c47c
|
|
123
|
-
rubocop (1.91.0) sha256=9c82b7bf391c5d7e3798c5b9996e22a1fe3bd7468e351dfdeb96140c058296d0
|
|
124
|
-
rubocop-ast (1.50.0) sha256=b9ca88300da0803ee222ad20cdb30494c0a784eed06fdc35d254b06d662788db
|
|
125
|
-
ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33
|
|
126
|
-
securerandom (0.4.1) sha256=cc5193d414a4341b6e225f0cb4446aceca8e50d5e1888743fac16987638ea0b1
|
|
127
|
-
simplecov (1.3.2) sha256=2a22ec1759f1b8db60881a2e038758956fc69ef93ed669be0bde0678de6d0e85
|
|
128
|
-
tzinfo (2.0.6) sha256=8daf828cc77bcf7d63b0e3bdb6caa47e2272dcfaf4fbfe46f8c3a9df087a829b
|
|
129
|
-
unicode-display_width (3.3.0) sha256=4b7aa66a4b11db50f6f7e98411215cd0dd10eaecb665d36eec5bcacb3fa0b613
|
|
130
|
-
unicode-emoji (4.3.0) sha256=11c02fa73290378c066bb0562cd4c87d8e1b706fbbe0059ca12746a4244de8ce
|
|
131
|
-
uri (1.1.1) sha256=379fa58d27ffb1387eaada68c749d1426738bd0f654d812fcc07e7568f5c57c6
|
|
132
|
-
|
|
133
|
-
BUNDLED WITH
|
|
134
|
-
4.0.20
|
data/release-please-config.json
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json",
|
|
3
|
-
"bootstrap-sha": "de8a6c418c6b662696e48b7af3b2d8ad55fb3b4e",
|
|
4
|
-
"packages": {
|
|
5
|
-
".": {
|
|
6
|
-
"release-type": "ruby",
|
|
7
|
-
"package-name": "schema-model",
|
|
8
|
-
"version-file": "lib/schema/version.rb",
|
|
9
|
-
"include-component-in-tag": false
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
}
|
data/schema-model.gemspec
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative 'lib/schema/version'
|
|
4
|
-
|
|
5
|
-
Gem::Specification.new do |s|
|
|
6
|
-
s.name = 'schema-model'
|
|
7
|
-
s.version = Schema::VERSION
|
|
8
|
-
s.licenses = ['MIT']
|
|
9
|
-
s.summary = 'Typed Ruby models built from hashes, JSON and CSV rows'
|
|
10
|
-
s.description = 'Declare typed attributes and Schema turns incoming hashes, JSON and CSV rows into Ruby objects. ' \
|
|
11
|
-
'Values are coerced to integers, floats, booleans, dates, times, arrays and hashes, and bad input ' \
|
|
12
|
-
'is recorded as parsing errors instead of raised. Supports nested has_one/has_many associations, ' \
|
|
13
|
-
'polymorphic types chosen by a type field, CSV header mapping, and ActiveModel validations.'
|
|
14
|
-
s.authors = ['Doug Youch']
|
|
15
|
-
s.email = 'dougyouch@gmail.com'
|
|
16
|
-
s.homepage = 'https://github.com/dougyouch/schema'
|
|
17
|
-
s.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
|
18
|
-
s.required_ruby_version = '>= 3.2'
|
|
19
|
-
s.bindir = 'bin'
|
|
20
|
-
s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
|
21
|
-
|
|
22
|
-
s.add_dependency 'inheritance-helper'
|
|
23
|
-
s.metadata['rubygems_mfa_required'] = 'true'
|
|
24
|
-
end
|
data/script/console
DELETED
data/script/coverage_badge.rb
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
# frozen_string_literal: true
|
|
3
|
-
|
|
4
|
-
# Renders a shields-style SVG badge from SimpleCov's .last_run.json.
|
|
5
|
-
# script/coverage_badge.rb coverage/.last_run.json coverage.svg # line coverage
|
|
6
|
-
# script/coverage_badge.rb coverage/.last_run.json branches.svg branch # branch coverage
|
|
7
|
-
|
|
8
|
-
require 'json'
|
|
9
|
-
|
|
10
|
-
input, output, metric = ARGV
|
|
11
|
-
abort "usage: #{$PROGRAM_NAME} <.last_run.json> <out.svg> [line|branch]" unless input && output
|
|
12
|
-
|
|
13
|
-
result = JSON.parse(File.read(input)).fetch('result')
|
|
14
|
-
title = metric == 'branch' ? 'branches' : 'coverage'
|
|
15
|
-
percent = (metric == 'branch' ? result.fetch('branch') : result['line'] || result.fetch('covered_percent')).to_f
|
|
16
|
-
label = "#{percent.floor(1)}%"
|
|
17
|
-
|
|
18
|
-
color =
|
|
19
|
-
if percent >= 95 then '#4c1'
|
|
20
|
-
elsif percent >= 90 then '#97ca00'
|
|
21
|
-
elsif percent >= 80 then '#dfb317'
|
|
22
|
-
elsif percent >= 70 then '#fe7d37'
|
|
23
|
-
else '#e05d44'
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
# ~7px per character at 11px Verdana, plus padding
|
|
27
|
-
left_width = 63
|
|
28
|
-
right_width = (label.length * 7) + 10
|
|
29
|
-
width = left_width + right_width
|
|
30
|
-
|
|
31
|
-
File.write(output, <<~SVG)
|
|
32
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="#{width}" height="20" role="img" aria-label="#{title}: #{label}">
|
|
33
|
-
<title>#{title}: #{label}</title>
|
|
34
|
-
<linearGradient id="s" x2="0" y2="100%">
|
|
35
|
-
<stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
|
|
36
|
-
<stop offset="1" stop-opacity=".1"/>
|
|
37
|
-
</linearGradient>
|
|
38
|
-
<clipPath id="r"><rect width="#{width}" height="20" rx="3" fill="#fff"/></clipPath>
|
|
39
|
-
<g clip-path="url(#r)">
|
|
40
|
-
<rect width="#{left_width}" height="20" fill="#555"/>
|
|
41
|
-
<rect x="#{left_width}" width="#{right_width}" height="20" fill="#{color}"/>
|
|
42
|
-
<rect width="#{width}" height="20" fill="url(#s)"/>
|
|
43
|
-
</g>
|
|
44
|
-
<g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" font-size="11">
|
|
45
|
-
<text x="#{left_width / 2}" y="14">#{title}</text>
|
|
46
|
-
<text x="#{left_width + (right_width / 2)}" y="14">#{label}</text>
|
|
47
|
-
</g>
|
|
48
|
-
</svg>
|
|
49
|
-
SVG
|