cocina-models 0.118.1 → 0.120.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +1 -1
  3. data/.rubocop.yml +22 -15
  4. data/.rubocop_todo.yml +33 -35
  5. data/Gemfile.lock +21 -30
  6. data/bin/validate-data +2 -0
  7. data/bin/validate-schema +6 -1
  8. data/cocina-models.gemspec +1 -2
  9. data/lib/cocina/models/builders/title_builder.rb +0 -4
  10. data/lib/cocina/models/california_historical_society_barcode.rb +1 -1
  11. data/lib/cocina/models/mapping/from_mods/event.rb +12 -3
  12. data/lib/cocina/models/mapping/from_mods/form.rb +4 -2
  13. data/lib/cocina/models/mapping/from_mods/name_builder.rb +4 -2
  14. data/lib/cocina/models/mapping/from_mods/note.rb +12 -5
  15. data/lib/cocina/models/mapping/from_mods/related_resource.rb +37 -4
  16. data/lib/cocina/models/mapping/from_mods/subject.rb +0 -4
  17. data/lib/cocina/models/related_resource.rb +1 -1
  18. data/lib/cocina/models/validators/base_description_visitor_validator.rb +33 -0
  19. data/lib/cocina/models/validators/base_structural_visitor_validator.rb +23 -0
  20. data/lib/cocina/models/validators/catalog_links_validator.rb +3 -1
  21. data/lib/cocina/models/validators/composite_description_validator.rb +62 -0
  22. data/lib/cocina/models/validators/composite_structural_validator.rb +48 -0
  23. data/lib/cocina/models/validators/dark_visitor_validator.rb +46 -0
  24. data/lib/cocina/models/validators/description_date_time_visitor_validator.rb +132 -0
  25. data/lib/cocina/models/validators/{description_types_validator.rb → description_types_visitor_validator.rb} +8 -54
  26. data/lib/cocina/models/validators/description_values_visitor_validator.rb +81 -0
  27. data/lib/cocina/models/validators/json_schema_validator.rb +56 -99
  28. data/lib/cocina/models/validators/language_tag_visitor_validator.rb +32 -0
  29. data/lib/cocina/models/validators/reserved_filename_visitor_validator.rb +40 -0
  30. data/lib/cocina/models/validators/validator.rb +5 -9
  31. data/lib/cocina/models/version.rb +1 -1
  32. data/lib/cocina/models.rb +1 -1
  33. data/lib/cocina/rspec/factories.rb +6 -2
  34. data/schema.json +169 -2
  35. metadata +13 -50
  36. data/lib/cocina/models/mapping/escape_html.rb +0 -23
  37. data/lib/cocina/models/mapping/normalizers/base.rb +0 -16
  38. data/lib/cocina/models/mapping/normalizers/mods/geo_extension_normalizer.rb +0 -69
  39. data/lib/cocina/models/mapping/normalizers/mods/name_normalizer.rb +0 -216
  40. data/lib/cocina/models/mapping/normalizers/mods/origin_info_normalizer.rb +0 -158
  41. data/lib/cocina/models/mapping/normalizers/mods/subject_normalizer.rb +0 -292
  42. data/lib/cocina/models/mapping/normalizers/mods/title_normalizer.rb +0 -91
  43. data/lib/cocina/models/mapping/normalizers/mods_normalizer.rb +0 -410
  44. data/lib/cocina/models/mapping/to_mods/access.rb +0 -155
  45. data/lib/cocina/models/mapping/to_mods/admin_metadata.rb +0 -129
  46. data/lib/cocina/models/mapping/to_mods/contributor.rb +0 -49
  47. data/lib/cocina/models/mapping/to_mods/description.rb +0 -65
  48. data/lib/cocina/models/mapping/to_mods/event.rb +0 -206
  49. data/lib/cocina/models/mapping/to_mods/form.rb +0 -296
  50. data/lib/cocina/models/mapping/to_mods/geographic.rb +0 -149
  51. data/lib/cocina/models/mapping/to_mods/id_generator.rb +0 -25
  52. data/lib/cocina/models/mapping/to_mods/identifier.rb +0 -57
  53. data/lib/cocina/models/mapping/to_mods/language.rb +0 -82
  54. data/lib/cocina/models/mapping/to_mods/mods_writer.rb +0 -40
  55. data/lib/cocina/models/mapping/to_mods/name_title_group.rb +0 -29
  56. data/lib/cocina/models/mapping/to_mods/name_writer.rb +0 -299
  57. data/lib/cocina/models/mapping/to_mods/note.rb +0 -102
  58. data/lib/cocina/models/mapping/to_mods/part_writer.rb +0 -115
  59. data/lib/cocina/models/mapping/to_mods/related_resource.rb +0 -123
  60. data/lib/cocina/models/mapping/to_mods/role_writer.rb +0 -50
  61. data/lib/cocina/models/mapping/to_mods/subject.rb +0 -496
  62. data/lib/cocina/models/mapping/to_mods/title.rb +0 -274
  63. data/lib/cocina/models/validators/dark_validator.rb +0 -76
  64. data/lib/cocina/models/validators/date_time_validator.rb +0 -100
  65. data/lib/cocina/models/validators/description_values_validator.rb +0 -107
  66. data/lib/cocina/models/validators/language_tag_validator.rb +0 -74
  67. data/lib/cocina/models/validators/reserved_filename_validator.rb +0 -60
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 980d1887539c11b65c897fc0f48a6d5529b8bb9e23821f9f87ac677623c7a05a
4
- data.tar.gz: 58b30197236ad99946ec8598fd84b03e8e8ea804a9625483ef4d678d93972dd9
3
+ metadata.gz: 36dff333c23753eed79b03fd9f4442339d677ba28baaf396408049bedd4ffc69
4
+ data.tar.gz: 3235a1280a037df4570e19de4f98f86577f6e048c7bb5b00d3c7f6a69dc2b377
5
5
  SHA512:
6
- metadata.gz: 8e599c4ce9337e1ef65ece3c33522f3efa88ee986b048d628889e329aaee752616208eb4e048193f2a5173fa506b9c8170b9032129418d9434f32e60f7c625d4
7
- data.tar.gz: 07ab88971c0c7a3d2810d9db68c3423755c421d96d7d778339350a64348a2d39a7c021719639fad4a05fdb14b08e4a5313953c3b62865521b7249b2b0a63059b
6
+ metadata.gz: 79466fddfa3fe42db002704a4d8f1e62e282e85dfe593aa7a6e58aea0449a247304d7b96596b15809f5a7f5ced5d0308160afee3efc95f3ec9051354e02e8eb2
7
+ data.tar.gz: b22313bbb8cea20829173cbf8569b5402472a7e01354a5e2790290771ecbb59e20eca361a94307b15fd2674f04ecfe62d7b57304eda8fb514bc0af7b35d9e832
data/.circleci/config.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  version: 2.1
2
2
  orbs:
3
- ruby-rails: sul-dlss/ruby-rails@4.8.0
3
+ ruby-rails: sul-dlss/ruby-rails@4.10.0
4
4
  workflows:
5
5
  build:
6
6
  jobs:
data/.rubocop.yml CHANGED
@@ -14,11 +14,12 @@ Layout/BeginEndAlignment: # (new in 0.91)
14
14
  Enabled: true
15
15
  Layout/EmptyLinesAroundAttributeAccessor:
16
16
  Enabled: true
17
+ Layout/SpaceAroundMethodCallOperator:
18
+ Enabled: true
17
19
  Layout/LineLength:
18
20
  Exclude:
19
21
  - lib/cocina/models/*
20
- Layout/SpaceAroundMethodCallOperator:
21
- Enabled: true
22
+ - spec/**/*
22
23
 
23
24
  # This cop throws an error in 1.37.1
24
25
  Layout/SpaceInsideHashLiteralBraces:
@@ -80,35 +81,35 @@ Metrics/BlockLength:
80
81
  - cocina-models.gemspec
81
82
  - spec/cocina/**/*
82
83
  - lib/cocina/rspec/matchers.rb
83
- - 'spec/support/mods_mapping_spec_helper.rb'
84
+ - "spec/support/mods_mapping_spec_helper.rb"
84
85
 
85
86
  # Offense count: 16
86
87
  # Configuration parameters: CountComments, CountAsOne.
87
88
  Metrics/ClassLength:
88
89
  Max: 100
89
90
  Exclude:
90
- - 'lib/cocina/rspec/factories.rb'
91
+ - "lib/cocina/rspec/factories.rb"
91
92
 
92
93
  Metrics/MethodLength:
93
94
  Max: 14
94
95
  Exclude:
95
- - 'spec/cocina/models/file_access_spec.rb'
96
- - 'spec/cocina/models/dro_access_spec.rb'
97
- - 'lib/cocina/rspec/factories.rb'
98
- - 'lib/cocina/models/mapping/to_mods/*'
99
- - 'lib/cocina/models/mapping/from_mods/*'
100
- - 'lib/cocina/models/mapping/normalizers/mods/origin_info_normalizer.rb'
101
- - 'lib/cocina/models/mapping/normalizers/mods/subject_normalizer.rb'
102
- - 'lib/cocina/models/mapping/normalizers/mods_normalizer.rb'
96
+ - "spec/cocina/models/file_access_spec.rb"
97
+ - "spec/cocina/models/dro_access_spec.rb"
98
+ - "lib/cocina/rspec/factories.rb"
99
+ - "lib/cocina/models/mapping/to_mods/*"
100
+ - "lib/cocina/models/mapping/from_mods/*"
101
+ - "lib/cocina/models/mapping/normalizers/mods/origin_info_normalizer.rb"
102
+ - "lib/cocina/models/mapping/normalizers/mods/subject_normalizer.rb"
103
+ - "lib/cocina/models/mapping/normalizers/mods_normalizer.rb"
103
104
 
104
105
  # Offense count: 37
105
106
  # Configuration parameters: IgnoredMethods.
106
107
  Metrics/PerceivedComplexity:
107
108
  # Max: 20
108
109
  Exclude:
109
- - 'lib/cocina/models/mapping/from_mods/*'
110
- - 'lib/cocina/models/mapping/to_mods/*'
111
- - 'lib/cocina/models/mapping/normalizers/**/*'
110
+ - "lib/cocina/models/mapping/from_mods/*"
111
+ - "lib/cocina/models/mapping/to_mods/*"
112
+ - "lib/cocina/models/mapping/normalizers/**/*"
112
113
 
113
114
  Naming/PredicatePrefix:
114
115
  ForbiddenPrefixes:
@@ -125,6 +126,12 @@ RSpec/BeEq: # new in 2.9.0
125
126
  RSpec/BeNil: # new in 2.9.0
126
127
  Enabled: true
127
128
 
129
+ RSpec/DiscardedMatcher: # new in 3.10
130
+ Enabled: true
131
+
132
+ RSpec/MatchWithSimpleRegex: # new in 3.10
133
+ Enabled: true
134
+
128
135
  RSpec/MultipleExpectations:
129
136
  Enabled: false
130
137
 
data/.rubocop_todo.yml CHANGED
@@ -1,27 +1,29 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config --auto-gen-only-exclude`
3
- # on 2023-11-01 19:51:40 UTC using RuboCop version 1.57.2.
3
+ # on 2026-06-02 13:55:43 UTC using RuboCop version 1.87.0.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
7
7
  # versions of RuboCop, may require this file to be generated again.
8
8
 
9
- # Offense count: 8
10
- # Configuration parameters: EnforcedStyle, AllowedGems, Include.
9
+ # Offense count: 7
10
+ # Configuration parameters: EnforcedStyle, AllowedGems.
11
11
  # SupportedStyles: Gemfile, gems.rb, gemspec
12
- # Include: **/*.gemspec, **/Gemfile, **/gems.rb
13
12
  Gemspec/DevelopmentDependencies:
14
13
  Exclude:
15
14
  - 'cocina-models.gemspec'
16
15
 
17
- # Offense count: 1
18
- Lint/NoReturnInBeginEndBlocks:
19
- Exclude:
20
- - 'lib/cocina/models/mapping/to_mods/description.rb'
16
+ # Offense count: 55
17
+ # This cop supports safe autocorrection (--autocorrect).
18
+ # Configuration parameters: AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, AllowRBSInlineAnnotation, AllowCopDirectives, AllowedPatterns, SplitStrings.
19
+ # URISchemes: http, https
20
+ Layout/LineLength:
21
+ Max: 159
21
22
 
22
- # Offense count: 13
23
+ # Offense count: 12
23
24
  # This cop supports safe autocorrection (--autocorrect).
24
- # Configuration parameters: AllowUnusedKeywordArguments, IgnoreEmptyMethods, IgnoreNotImplementedMethods.
25
+ # Configuration parameters: AllowUnusedKeywordArguments, IgnoreEmptyMethods, IgnoreNotImplementedMethods, NotImplementedExceptions.
26
+ # NotImplementedExceptions: NotImplementedError
25
27
  Lint/UnusedMethodArgument:
26
28
  Exclude:
27
29
  - 'lib/cocina/models/mapping/from_mods/admin_metadata.rb'
@@ -34,17 +36,27 @@ Lint/UnusedMethodArgument:
34
36
  - 'lib/cocina/models/mapping/from_mods/language.rb'
35
37
  - 'lib/cocina/models/mapping/from_mods/note.rb'
36
38
  - 'lib/cocina/models/mapping/from_mods/subject.rb'
37
- - 'lib/cocina/models/mapping/to_mods/event.rb'
38
39
 
39
- # Offense count: 98
40
+ # Offense count: 62
40
41
  # Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes.
41
42
  Metrics/AbcSize:
42
- Max: 40
43
+ Max: 48
43
44
 
44
- # Offense count: 43
45
- # Configuration parameters: AllowedMethods, AllowedPatterns.
45
+ # Offense count: 27
46
+ # Configuration parameters: AllowedMethods, AllowedPatterns, Max.
46
47
  Metrics/CyclomaticComplexity:
47
- Max: 12
48
+ Exclude:
49
+ - 'lib/cocina/generator/generator.rb'
50
+ - 'lib/cocina/models/builders/title_builder.rb'
51
+ - 'lib/cocina/models/mapping/from_mods/event.rb'
52
+ - 'lib/cocina/models/mapping/from_mods/form.rb'
53
+ - 'lib/cocina/models/mapping/from_mods/identifier_type.rb'
54
+ - 'lib/cocina/models/mapping/from_mods/language_term.rb'
55
+ - 'lib/cocina/models/mapping/from_mods/name_builder.rb'
56
+ - 'lib/cocina/models/mapping/from_mods/subject.rb'
57
+ - 'lib/cocina/models/mapping/from_mods/title.rb'
58
+ - 'lib/cocina/models/mapping/from_mods/title_builder.rb'
59
+ - 'lib/cocina/models/mapping/normalizers/mods_normalizer.rb'
48
60
 
49
61
  # Offense count: 1
50
62
  # Configuration parameters: Max, CountKeywordArgs, MaxOptionalParameters.
@@ -52,12 +64,12 @@ Metrics/ParameterLists:
52
64
  Exclude:
53
65
  - 'lib/cocina/generator/schema_base.rb'
54
66
 
55
- # Offense count: 41
67
+ # Offense count: 32
56
68
  # Configuration parameters: IgnoredMetadata.
57
69
  RSpec/DescribeClass:
58
70
  Enabled: false
59
71
 
60
- # Offense count: 224
72
+ # Offense count: 95
61
73
  # Configuration parameters: CountAsOne.
62
74
  RSpec/ExampleLength:
63
75
  Max: 103
@@ -78,23 +90,9 @@ RSpec/PendingWithoutReason:
78
90
  - 'spec/cocina/models/mapping/descriptive/mods/title_info_spec.rb'
79
91
  - 'spec/cocina/models/mapping/descriptive/mods/type_of_resource_spec.rb'
80
92
 
81
- # Offense count: 1
93
+ # Offense count: 3
82
94
  # This cop supports safe autocorrection (--autocorrect).
83
95
  Style/IfUnlessModifier:
84
96
  Exclude:
85
- - 'lib/cocina/models/validators/open_api_validator.rb'
86
-
87
- # Offense count: 9
88
- Style/MultilineBlockChain:
89
- Exclude:
90
- - 'lib/cocina/models/mapping/to_mods/access.rb'
91
- - 'lib/cocina/models/mapping/to_mods/contributor.rb'
92
- - 'lib/cocina/models/mapping/to_mods/form.rb'
93
- - 'lib/cocina/models/mapping/to_mods/subject.rb'
94
-
95
- # Offense count: 249
96
- # This cop supports safe autocorrection (--autocorrect).
97
- # Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns.
98
- # URISchemes: http, https
99
- Layout/LineLength:
100
- Max: 267
97
+ - 'lib/cocina/models/mapping/from_mods/name_builder.rb'
98
+ - 'lib/cocina/models/mapping/normalizers/mods_normalizer.rb'
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- cocina-models (0.118.1)
4
+ cocina-models (0.120.0)
5
5
  activesupport
6
6
  deprecation
7
7
  dry-struct (~> 1.0)
@@ -9,8 +9,7 @@ PATH
9
9
  edtf
10
10
  equivalent-xml
11
11
  i18n
12
- json_schemer (~> 2.0)
13
- jsonpath
12
+ jsonschema_rs
14
13
  nokogiri
15
14
  super_diff
16
15
  thor
@@ -74,7 +73,6 @@ GEM
74
73
  equivalent-xml (0.6.0)
75
74
  nokogiri (>= 1.4.3)
76
75
  erb (6.0.4)
77
- hana (1.3.7)
78
76
  i18n (1.14.8)
79
77
  concurrent-ruby (~> 1.0)
80
78
  ice_nine (0.11.2)
@@ -84,21 +82,17 @@ GEM
84
82
  prism (>= 1.3.0)
85
83
  rdoc (>= 4.0.0)
86
84
  reline (>= 0.4.2)
87
- json (2.19.5)
88
- json_schemer (2.5.0)
89
- bigdecimal
90
- hana (~> 1.3)
91
- regexp_parser (~> 2.0)
92
- simpleidn (~> 0.2)
93
- jsonpath (1.1.5)
94
- multi_json
85
+ json (2.19.8)
86
+ jsonschema_rs (0.46.5-arm64-darwin)
87
+ bigdecimal (>= 3.1, < 5)
88
+ jsonschema_rs (0.46.5-x86_64-linux)
89
+ bigdecimal (>= 3.1, < 5)
95
90
  language_server-protocol (3.17.0.5)
96
91
  lint_roller (1.1.0)
97
92
  logger (1.7.0)
98
93
  minitest (6.0.6)
99
94
  drb (~> 2.0)
100
95
  prism (~> 1.5)
101
- multi_json (1.21.1)
102
96
  nokogiri (1.19.3-arm64-darwin)
103
97
  racc (~> 1.4)
104
98
  nokogiri (1.19.3-x86_64-linux-gnu)
@@ -114,7 +108,7 @@ GEM
114
108
  prettyprint
115
109
  prettyprint (0.2.0)
116
110
  prism (1.9.0)
117
- psych (5.3.1)
111
+ psych (5.4.0)
118
112
  date
119
113
  stringio
120
114
  racc (1.8.1)
@@ -142,7 +136,7 @@ GEM
142
136
  rspec-support (3.13.7)
143
137
  rspec_junit_formatter (0.6.0)
144
138
  rspec-core (>= 2, < 4, != 2.12.0)
145
- rubocop (1.86.2)
139
+ rubocop (1.87.0)
146
140
  json (~> 2.3)
147
141
  language_server-protocol (~> 3.17.0.2)
148
142
  lint_roller (~> 1.1.0)
@@ -159,9 +153,10 @@ GEM
159
153
  rubocop-rake (0.7.1)
160
154
  lint_roller (~> 1.1)
161
155
  rubocop (>= 1.72.1)
162
- rubocop-rspec (3.9.0)
156
+ rubocop-rspec (3.10.2)
163
157
  lint_roller (~> 1.1)
164
- rubocop (~> 1.81)
158
+ regexp_parser (>= 2.0)
159
+ rubocop (~> 1.86, >= 1.86.2)
165
160
  ruby-progressbar (1.13.0)
166
161
  securerandom (0.4.1)
167
162
  simplecov (0.22.0)
@@ -170,7 +165,6 @@ GEM
170
165
  simplecov_json_formatter (~> 0.1)
171
166
  simplecov-html (0.13.2)
172
167
  simplecov_json_formatter (0.1.4)
173
- simpleidn (0.2.3)
174
168
  stringio (3.2.0)
175
169
  super_diff (0.19.0)
176
170
  attr_extras (>= 6.2.4, < 8)
@@ -209,8 +203,8 @@ CHECKSUMS
209
203
  attr_extras (7.1.0) sha256=d96fc9a9dd5d85ba2d37762440a816f840093959ae26bb90da994c2d9f1fc827
210
204
  base64 (0.3.0) sha256=27337aeabad6ffae05c265c450490628ef3ebd4b67be58257393227588f5a97b
211
205
  bigdecimal (4.1.2) sha256=53d217666027eab4280346fba98e7d5b66baaae1b9c3c1c0ffe89d48188a3fbd
212
- bundler (4.0.12) sha256=7f8b757d28dfb636e7b24fba2344ac6dd13b5b24f4b46d62573d483f211825ac
213
- cocina-models (0.118.1)
206
+ bundler (4.0.13) sha256=19f08be7f27022cf0b89f27da0b044ae075e8270a9ef44ad248a932614e1ca3b
207
+ cocina-models (0.120.0)
214
208
  concurrent-ruby (1.3.6) sha256=6b56837e1e7e5292f9864f34b69c5a2cbc75c0cf5338f1ce9903d10fa762d5ab
215
209
  connection_pool (3.0.2) sha256=33fff5ba71a12d2aa26cb72b1db8bba2a1a01823559fb01d29eb74c286e62e0a
216
210
  date (3.5.1) sha256=750d06384d7b9c15d562c76291407d89e368dda4d4fff957eb94962d325a0dc0
@@ -227,19 +221,17 @@ CHECKSUMS
227
221
  edtf (3.2.0) sha256=a15a0ee274e49c8047a3ebb5d61d793ba44f7f8ffbf0595392c467e3ea8d2447
228
222
  equivalent-xml (0.6.0) sha256=8919761efa848ad0846369ff8be1f646b17e5061698c4867b09829000cc3f487
229
223
  erb (6.0.4) sha256=38e3803694be357fe2bfe312487c74beaf9fb4e5beb3e22498952fe1645b95d9
230
- hana (1.3.7) sha256=5425db42d651fea08859811c29d20446f16af196308162894db208cac5ce9b0d
231
224
  i18n (1.14.8) sha256=285778639134865c5e0f6269e0b818256017e8cde89993fdfcbfb64d088824a5
232
225
  ice_nine (0.11.2) sha256=5d506a7d2723d5592dc121b9928e4931742730131f22a1a37649df1c1e2e63db
233
226
  io-console (0.8.2) sha256=d6e3ae7a7cc7574f4b8893b4fca2162e57a825b223a177b7afa236c5ef9814cc
234
227
  irb (1.18.0) sha256=de9454a0703a54704b9811a5ef31a60c86949fbf4013fcf244fabc7c775248e3
235
- json (2.19.5) sha256=218a18553e4801d579ca7e0f5bc72bafd776d7397238a1fb4e74db5b0a812c59
236
- json_schemer (2.5.0) sha256=2f01fb4cce721a4e08dd068fc2030cffd0702a7f333f1ea2be6e8991f00ae396
237
- jsonpath (1.1.5) sha256=29f70467193a2dc93ab864ec3d3326d54267961acc623f487340eb9c34931dbe
228
+ json (2.19.8) sha256=6354310fd76ef69b87d5bd1f38b40d730613baf90b6803d2d0a48f618d32dfaa
229
+ jsonschema_rs (0.46.5-arm64-darwin) sha256=e80414ed67f0956d3e06474a2fa076fc4a7b722f00e5d7142b70289c016ac6f1
230
+ jsonschema_rs (0.46.5-x86_64-linux) sha256=345c65ec7a5abf8879b9c9356752f0fdf4c9926f6480458fc32803a871b5cbb3
238
231
  language_server-protocol (3.17.0.5) sha256=fd1e39a51a28bf3eec959379985a72e296e9f9acfce46f6a79d31ca8760803cc
239
232
  lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87
240
233
  logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203
241
234
  minitest (6.0.6) sha256=153ea36d1d987a62942382b61075745042a2b3123b1cd48f4c3675af9cc7d6f1
242
- multi_json (1.21.1) sha256=e6126a31808e3b4d19f483c775ceac34df190dffa62adfb63a165ee14ba68080
243
235
  nokogiri (1.19.3-arm64-darwin) sha256=71b9bd424b1b7abc18b05052a1a3cfd3627abdca62be280854cc411791357e42
244
236
  nokogiri (1.19.3-x86_64-linux-gnu) sha256=2f5078620fe12e83669b5b17311b32532a8153d02eee7ad06948b926d6080976
245
237
  optimist (3.2.1) sha256=8cf8a0fd69f3aa24ab48885d3a666717c27bc3d9edd6e976e18b9d771e72e34e
@@ -249,7 +241,7 @@ CHECKSUMS
249
241
  pp (0.6.3) sha256=2951d514450b93ccfeb1df7d021cae0da16e0a7f95ee1e2273719669d0ab9df6
250
242
  prettyprint (0.2.0) sha256=2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193
251
243
  prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85
252
- psych (5.3.1) sha256=eb7a57cef10c9d70173ff74e739d843ac3b2c019a003de48447b2963d81b1974
244
+ psych (5.4.0) sha256=14f72d69a611af663d7d70e4a7b67d9eb1f3ae9f8d916b478961d5a0075ba5b7
253
245
  racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f
254
246
  rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a
255
247
  rake (13.4.2) sha256=cb825b2bd5f1f8e91ca37bddb4b9aaf345551b4731da62949be002fa89283701
@@ -262,16 +254,15 @@ CHECKSUMS
262
254
  rspec-mocks (3.13.8) sha256=086ad3d3d17533f4237643de0b5c42f04b66348c28bf6b9c2d3f4a3b01af1d47
263
255
  rspec-support (3.13.7) sha256=0640e5570872aafefd79867901deeeeb40b0c9875a36b983d85f54fb7381c47c
264
256
  rspec_junit_formatter (0.6.0) sha256=40dde674e6ae4e6cc0ff560da25497677e34fefd2338cc467a8972f602b62b15
265
- rubocop (1.86.2) sha256=bb2e97f635eda42c448f2588f4a6ff78f221b8bdfdf65b1e9b07fbd57521b45d
257
+ rubocop (1.87.0) sha256=b9d9ddf55116a513f8ef2c7ae660662d8b49301f118d3f0df61865b33a5c188d
266
258
  rubocop-ast (1.49.1) sha256=4412f3ee70f6fe4546cc489548e0f6fcf76cafcfa80fa03af67098ffed755035
267
259
  rubocop-rake (0.7.1) sha256=3797f2b6810c3e9df7376c26d5f44f3475eda59eb1adc38e6f62ecf027cbae4d
268
- rubocop-rspec (3.9.0) sha256=8fa70a3619408237d789aeecfb9beef40576acc855173e60939d63332fdb55e2
260
+ rubocop-rspec (3.10.2) sha256=0b3e2ecc592cd10ecbf0095bb58d1e357905276e069643523cc19eb7495f65e2
269
261
  ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33
270
262
  securerandom (0.4.1) sha256=cc5193d414a4341b6e225f0cb4446aceca8e50d5e1888743fac16987638ea0b1
271
263
  simplecov (0.22.0) sha256=fe2622c7834ff23b98066bb0a854284b2729a569ac659f82621fc22ef36213a5
272
264
  simplecov-html (0.13.2) sha256=bd0b8e54e7c2d7685927e8d6286466359b6f16b18cb0df47b508e8d73c777246
273
265
  simplecov_json_formatter (0.1.4) sha256=529418fbe8de1713ac2b2d612aa3daa56d316975d307244399fa4838c601b428
274
- simpleidn (0.2.3) sha256=08ce96f03fa1605286be22651ba0fc9c0b2d6272c9b27a260bc88be05b0d2c29
275
266
  stringio (3.2.0) sha256=c37cb2e58b4ffbd33fe5cd948c05934af997b36e0b6ca6fdf43afa234cf222e1
276
267
  super_diff (0.19.0) sha256=c35fc1c0daa223d67b203fe3fb49a6cfd67850a53920319565c3c654e03ec902
277
268
  thor (1.5.0) sha256=e3a9e55fe857e44859ce104a84675ab6e8cd59c650a49106a05f55f136425e73
@@ -283,4 +274,4 @@ CHECKSUMS
283
274
  zeitwerk (2.8.2) sha256=7212a61311083c604184b1ea2574b9aa05cd14f855a0841c06985cabe9181d12
284
275
 
285
276
  BUNDLED WITH
286
- 4.0.12
277
+ 4.0.13
data/bin/validate-data CHANGED
@@ -191,6 +191,8 @@ def distribute_work(filename, workers, batch_size, total_lines) # rubocop:disabl
191
191
 
192
192
  # Update progress bar
193
193
  progressbar.increment
194
+
195
+ break if line_number >= total_lines
194
196
  end
195
197
  end
196
198
 
data/bin/validate-schema CHANGED
@@ -5,4 +5,9 @@ require 'bundler/setup'
5
5
  require 'cocina/models'
6
6
 
7
7
  filepath = ARGV[0]
8
- exit(1) unless JSONSchemer.valid_schema?(Pathname.new(filepath))
8
+ begin
9
+ JSONSchema.validator_for(JSON.parse(File.read(filepath)))
10
+ rescue StandardError => e
11
+ warn e.message
12
+ exit(1)
13
+ end
@@ -31,8 +31,7 @@ Gem::Specification.new do |spec|
31
31
  spec.add_dependency 'edtf' # used for date/time validation
32
32
  spec.add_dependency 'equivalent-xml' # for diffing MODS
33
33
  spec.add_dependency 'i18n' # for validating BCP 47 language tags, according to RFC 4646
34
- spec.add_dependency 'jsonpath' # used for date/time validation
35
- spec.add_dependency 'json_schemer', '~> 2.0'
34
+ spec.add_dependency 'jsonschema_rs'
36
35
  spec.add_dependency 'nokogiri'
37
36
  spec.add_dependency 'super_diff'
38
37
  spec.add_dependency 'thor'
@@ -227,8 +227,6 @@ module Cocina
227
227
  #
228
228
  # for punctuaion funky town, thank MARC and catalog cards
229
229
  #
230
- # rubocop:disable Metrics/AbcSize
231
- # rubocop:disable Metrics/CyclomaticComplexity
232
230
  # rubocop:disable Metrics/MethodLength
233
231
  # rubocop:disable Metrics/PerceivedComplexity
234
232
  def rebuild_structured_value(cocina_title)
@@ -283,8 +281,6 @@ module Cocina
283
281
 
284
282
  result
285
283
  end
286
- # rubocop:enable Metrics/AbcSize
287
- # rubocop:enable Metrics/CyclomaticComplexity
288
284
  # rubocop:enable Metrics/MethodLength
289
285
  # rubocop:enable Metrics/PerceivedComplexity
290
286
 
@@ -4,6 +4,6 @@ module Cocina
4
4
  module Models
5
5
  # The barcode associated with a CHS DRO, prefixed with 405
6
6
  # example: 405000111956
7
- CaliforniaHistoricalSocietyBarcode = Types::String.constrained(format: /^405[0-9]+$/)
7
+ CaliforniaHistoricalSocietyBarcode = Types::String.constrained(format: /^405[0-9]{9}$/)
8
8
  end
9
9
  end
@@ -435,7 +435,7 @@ module Cocina
435
435
  new_node = node.deep_dup
436
436
  new_node.remove_attribute('encoding') if common_attribs[:encoding].present? || node[:encoding]&.empty?
437
437
  new_node.remove_attribute('qualifier') if common_attribs[:qualifier].present? || node[:qualifier]&.empty?
438
- build_date(new_node)
438
+ build_date(new_node, encoding: common_attribs.dig(:encoding, :code))
439
439
  end
440
440
  { structuredValue: dates }.merge(common_attribs).compact
441
441
  end
@@ -462,9 +462,11 @@ module Cocina
462
462
  attribs.compact
463
463
  end
464
464
 
465
- def build_date(date_node)
465
+ def build_date(date_node, encoding: nil)
466
+ effective_encoding = date_node['encoding'] || encoding
466
467
  {}.tap do |date|
467
- date[:value] = clean_date(date_node.text) if date_node.text.present?
468
+ raw_value = clean_date(date_node.text)
469
+ date[:value] = effective_encoding == 'edtf' ? pad_edtf_year(raw_value) : raw_value if date_node.text.present?
468
470
  date[:encoding] = { code: date_node['encoding'] } if date_node['encoding']
469
471
  date[:status] = 'primary' if date_node['keyDate']
470
472
  date[:note] = build_date_note(date_node)
@@ -489,6 +491,13 @@ module Cocina
489
491
  date.delete_suffix('.')
490
492
  end
491
493
 
494
+ # Pads a 1-3 digit year to 4 digits, handling modifiers like ~,-.
495
+ def pad_edtf_year(value)
496
+ value.sub(%r{\A(-?)(\d{1,3})(?=[~?%/-]|\z)}) do
497
+ "#{::Regexp.last_match(1)}#{::Regexp.last_match(2).rjust(4, '0')}"
498
+ end
499
+ end
500
+
492
501
  # NOTE: Do any eventType/displayLabel transformations before determining role (i.e. with LEGACY_EVENT_TYPES_2_TYPE)
493
502
  def role_for(event)
494
503
  case event[:type]
@@ -9,6 +9,7 @@ module Cocina
9
9
  class Form
10
10
  # NOTE: H2 is the first case of structured form (genre/typeOfResource) values we're implementing
11
11
  H2_GENRE_TYPE_PREFIX = 'H2 '
12
+ H2_SOURCE_LABEL = 'Stanford self-deposit resource types'
12
13
 
13
14
  # @param [Nokogiri::XML::Element] resource_element mods or relatedItem element
14
15
  # @param [Cocina::Models::Mapping::FromMods::DescriptionBuilder] description_builder
@@ -58,7 +59,8 @@ module Cocina
58
59
 
59
60
  def build_cartographics(subject_node)
60
61
  carto_forms = []
61
- subject_node.xpath('mods:cartographics[mods:scale]', mods: Description::DESC_METADATA_NS).each do |carto_node|
62
+ subject_node.xpath('mods:cartographics[mods:scale]',
63
+ mods: Description::DESC_METADATA_NS).each do |carto_node|
62
64
  scale_nodes = carto_node.xpath('mods:scale', mods: Description::DESC_METADATA_NS).reject do |scale_node|
63
65
  scale_node.text.blank?
64
66
  end
@@ -142,7 +144,7 @@ module Cocina
142
144
  forms << {
143
145
  type: 'resource type',
144
146
  source: {
145
- value: Cocina::Models::Mapping::ToMods::Form::H2_SOURCE_LABEL
147
+ value: H2_SOURCE_LABEL
146
148
  },
147
149
  structuredValue: structured_genre.map do |genre|
148
150
  {
@@ -7,7 +7,7 @@ module Cocina
7
7
  module FromMods
8
8
  # Maps a name
9
9
  class NameBuilder
10
- UNCITED_DESCRIPTION = Cocina::Models::Mapping::ToMods::NameWriter::UNCITED_DESCRIPTION
10
+ UNCITED_DESCRIPTION = 'not included in citation'
11
11
  TYPE_FOR_ROLES = Cocina::Models::Mapping::FromMods::Contributor::ROLES.merge('event' => 'event').freeze
12
12
 
13
13
  # @param [Array<Nokogiri::XML::Element>] name_elements (multiple if parallel)
@@ -154,7 +154,9 @@ module Cocina
154
154
  end
155
155
 
156
156
  def build_structured_value_name(name_node, name_part_nodes)
157
- vals = name_part_nodes.filter_map { |name_part_node| build_name_part(name_node, name_part_node, default_type: name_node['type'] != 'corporate').presence }
157
+ vals = name_part_nodes.filter_map do |name_part_node|
158
+ build_name_part(name_node, name_part_node, default_type: name_node['type'] != 'corporate').presence
159
+ end
158
160
  display_form_node = name_node.xpath('mods:displayForm', mods: Description::DESC_METADATA_NS).first
159
161
  if display_form_node.present?
160
162
  cocina_contrib_name =
@@ -6,6 +6,11 @@ module Cocina
6
6
  module FromMods
7
7
  # Maps notes
8
8
  class Note # rubocop:disable Metrics/ClassLength
9
+ # notes with these types will produce an `abstract` XML node
10
+ NOTE_TYPE_TO_ABSTRACT_TYPE = ['summary', 'abstract', 'scope and content'].freeze
11
+ DISPLAY_LABEL_TO_ABSTRACT_TYPE = ['Content advice', 'Subject', 'Abstract', 'Review', 'Summary', 'Scope and content',
12
+ 'Scope and Content', 'Content Advice'].freeze
13
+
9
14
  # @param [Nokogiri::XML::Element] resource_element mods or relatedItem element
10
15
  # @param [Cocina::Models::Mapping::FromMods::DescriptionBuilder] description_builder (not used, but passed in by DescriptionBuilder)
11
16
  # @param [String] purl (not used, but passed in by DescriptionBuilder)
@@ -28,7 +33,8 @@ module Cocina
28
33
  attr_reader :resource_element
29
34
 
30
35
  def abstracts
31
- all_abstract_nodes = resource_element.xpath('mods:abstract', mods: Description::DESC_METADATA_NS).select do |node|
36
+ all_abstract_nodes = resource_element.xpath('mods:abstract',
37
+ mods: Description::DESC_METADATA_NS).select do |node|
32
38
  note_present?(node)
33
39
  end
34
40
  altrepgroup_abstract_nodes, other_abstract_nodes = AltRepGroup.split(nodes: all_abstract_nodes)
@@ -58,13 +64,13 @@ module Cocina
58
64
  end
59
65
 
60
66
  def note_type(node)
61
- return node['type'].downcase if Cocina::Models::Mapping::ToMods::Note.note_type_to_abstract_type.include?(node['type']&.downcase)
67
+ return node['type'].downcase if NOTE_TYPE_TO_ABSTRACT_TYPE.include?(node['type']&.downcase)
62
68
 
63
69
  node['type']
64
70
  end
65
71
 
66
72
  def display_label(node)
67
- return node[:displayLabel].capitalize if Cocina::Models::Mapping::ToMods::Note.display_label_to_abstract_type.include? node[:displayLabel]
73
+ return node[:displayLabel].capitalize if DISPLAY_LABEL_TO_ABSTRACT_TYPE.include? node[:displayLabel]
68
74
 
69
75
  node[:displayLabel].presence
70
76
  end
@@ -72,7 +78,7 @@ module Cocina
72
78
  def abstract_type(node, parallel: false)
73
79
  if node['type'].present?
74
80
  { type: node['type'].downcase }
75
- elsif Cocina::Models::Mapping::ToMods::Note.display_label_to_abstract_type.exclude?(node['displayLabel']) && !parallel
81
+ elsif DISPLAY_LABEL_TO_ABSTRACT_TYPE.exclude?(node['displayLabel']) && !parallel
76
82
  { type: 'abstract' }
77
83
  else
78
84
  {}
@@ -111,7 +117,8 @@ module Cocina
111
117
  end
112
118
 
113
119
  def table_of_contents
114
- all_toc_nodes = resource_element.xpath('mods:tableOfContents', mods: Description::DESC_METADATA_NS).select do |node|
120
+ all_toc_nodes = resource_element.xpath('mods:tableOfContents',
121
+ mods: Description::DESC_METADATA_NS).select do |node|
115
122
  note_present?(node)
116
123
  end
117
124
  altrepgroup_toc_nodes, other_toc_nodes = AltRepGroup.split(nodes: all_toc_nodes)
@@ -5,9 +5,42 @@ module Cocina
5
5
  module Mapping
6
6
  module FromMods
7
7
  # Maps MODS relatedItem to cocina relatedResource
8
- class RelatedResource
9
- TYPES = Cocina::Models::Mapping::ToMods::RelatedResource::TYPES.invert.freeze
10
- DETAIL_TYPES = Cocina::Models::Mapping::ToMods::RelatedResource::DETAIL_TYPES.invert.freeze
8
+ class RelatedResource # rubocop:disable Metrics/ClassLength
9
+ # see https://docs.google.com/spreadsheets/d/1d5PokzgXqNykvQeckG2ND43B6i9_CsjfIVwS_IsphS8/edit#gid=0
10
+ TYPES = {
11
+ 'has original version' => 'original',
12
+ 'has other format' => 'otherFormat',
13
+ 'has part' => 'constituent',
14
+ 'has version' => 'otherVersion',
15
+ 'in series' => 'series',
16
+ 'part of' => 'host',
17
+ 'preceded by' => 'preceding',
18
+ 'related to' => nil, # 'related to' is a null type by design
19
+ 'reviewed by' => 'reviewOf',
20
+ 'referenced by' => 'isReferencedBy',
21
+ 'references' => 'references',
22
+ 'succeeded by' => 'succeeding'
23
+ }.invert.freeze
24
+
25
+ DETAIL_TYPES = {
26
+ 'location within source' => 'part',
27
+ 'volume' => 'volume',
28
+ 'issue' => 'issue',
29
+ 'chapter' => 'chapter',
30
+ 'section' => 'section',
31
+ 'paragraph' => 'paragraph',
32
+ 'track' => 'track',
33
+ 'marker' => 'marker'
34
+ }.invert.freeze
35
+
36
+ OTHER_TYPES = [
37
+ 'supplement to',
38
+ 'supplemented by',
39
+ 'derived from',
40
+ 'source of',
41
+ 'version of record',
42
+ 'identical to'
43
+ ].freeze
11
44
 
12
45
  # @param [Nokogiri::XML::Element] resource_element mods or relatedItem element
13
46
  # @param [Cocina::Models::Mapping::FromMods::DescriptionBuilder] description_builder
@@ -52,7 +85,7 @@ module Cocina
52
85
  if related_item['type']
53
86
  item[:type] = normalized_type_for(related_item['type'])
54
87
  elsif (other_type = related_item['otherType'])
55
- if Cocina::Models::Mapping::ToMods::RelatedResource::OTHER_TYPES.include?(other_type)
88
+ if OTHER_TYPES.include?(other_type)
56
89
  item[:type] = other_type
57
90
  else
58
91
  item[:type] = 'related to'
@@ -55,8 +55,6 @@ module Cocina
55
55
  }.compact.presence
56
56
  end
57
57
 
58
- # rubocop:disable Metrics/CyclomaticComplexity
59
- # rubocop:disable Metrics/AbcSize
60
58
  def build_subject(subject_node)
61
59
  if subject_node['xlink:href']
62
60
  return { valueAt: subject_node['xlink:href'] } if subject_node.elements.empty?
@@ -96,8 +94,6 @@ module Cocina
96
94
  simple_item(first_child_node, attrs)
97
95
  end
98
96
  end
99
- # rubocop:enable Metrics/CyclomaticComplexity
100
- # rubocop:enable Metrics/AbcSize
101
97
 
102
98
  def temporal_range?(children_nodes)
103
99
  children_nodes.all? { |node| node.name == 'temporal' && node['point'] }