cocina-models 0.86.0 → 0.87.1

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 (54) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +1 -1
  3. data/.rubocop.yml +54 -2
  4. data/.rubocop_todo.yml +49 -15
  5. data/Gemfile.lock +56 -52
  6. data/lib/cocina/generator/datatype.rb +1 -1
  7. data/lib/cocina/generator/generator.rb +19 -12
  8. data/lib/cocina/generator/schema.rb +4 -2
  9. data/lib/cocina/generator/schema_array.rb +1 -1
  10. data/lib/cocina/generator/schema_base.rb +50 -19
  11. data/lib/cocina/generator/schema_value.rb +3 -3
  12. data/lib/cocina/generator/union_type.rb +24 -0
  13. data/lib/cocina/models/admin_policy.rb +2 -2
  14. data/lib/cocina/models/admin_policy_administrative.rb +2 -2
  15. data/lib/cocina/models/admin_policy_with_metadata.rb +2 -2
  16. data/lib/cocina/models/administrative.rb +1 -1
  17. data/lib/cocina/models/barcode.rb +7 -0
  18. data/lib/cocina/models/business_barcode.rb +1 -1
  19. data/lib/cocina/models/catalog_link.rb +1 -10
  20. data/lib/cocina/models/catkey_barcode.rb +1 -1
  21. data/lib/cocina/models/cocina_version.rb +1 -1
  22. data/lib/cocina/models/collection.rb +2 -2
  23. data/lib/cocina/models/collection_identification.rb +1 -1
  24. data/lib/cocina/models/collection_with_metadata.rb +2 -2
  25. data/lib/cocina/models/created_in_folio_identifier.rb +9 -0
  26. data/lib/cocina/models/description.rb +2 -2
  27. data/lib/cocina/models/doi.rb +7 -0
  28. data/lib/cocina/models/doi_exceptions.rb +1 -1
  29. data/lib/cocina/models/doi_pattern.rb +1 -1
  30. data/lib/cocina/models/dro.rb +2 -2
  31. data/lib/cocina/models/dro_with_metadata.rb +2 -2
  32. data/lib/cocina/models/druid.rb +1 -1
  33. data/lib/cocina/models/folio_catalog_link.rb +16 -0
  34. data/lib/cocina/models/identification.rb +3 -3
  35. data/lib/cocina/models/lane_medical_barcode.rb +1 -1
  36. data/lib/cocina/models/mapping/from_mods/identifier.rb +1 -1
  37. data/lib/cocina/models/mapping/from_mods/identifier_builder.rb +1 -1
  38. data/lib/cocina/models/mapping/normalizers/mods_normalizer.rb +2 -2
  39. data/lib/cocina/models/migrated_from_symphony_identifier.rb +9 -0
  40. data/lib/cocina/models/migrated_from_voyager_identifier.rb +9 -0
  41. data/lib/cocina/models/purl.rb +1 -1
  42. data/lib/cocina/models/related_resource.rb +2 -2
  43. data/lib/cocina/models/request_admin_policy.rb +1 -1
  44. data/lib/cocina/models/request_administrative.rb +1 -1
  45. data/lib/cocina/models/request_collection.rb +1 -1
  46. data/lib/cocina/models/request_dro.rb +1 -1
  47. data/lib/cocina/models/request_identification.rb +2 -2
  48. data/lib/cocina/models/source_id.rb +1 -1
  49. data/lib/cocina/models/standard_barcode.rb +1 -1
  50. data/lib/cocina/models/symphony_catalog_link.rb +17 -0
  51. data/lib/cocina/models/version.rb +1 -1
  52. data/lib/cocina/models.rb +7 -3
  53. data/openapi.yml +366 -317
  54. metadata +14 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 15d31900b286fa2945fbbb10a957cdb71aadc1b7f3f4a0463a9ab04ac5d181d5
4
- data.tar.gz: d1ee89eec766056327f8999bff0ae9c15d908b4d75338d98c6ab427c5a8c5ef8
3
+ metadata.gz: 90ae20c8c80e4bbcf51179f0c6cba44c76f3f1551962f4da938d297c152ed77d
4
+ data.tar.gz: b71a9f5c05e153ebdf93f623164a7a77c12aeae2de32b96757096a7d2f747cfa
5
5
  SHA512:
6
- metadata.gz: 7dafbf718bf85eecf60c896342e88b94381055b8b39f729eecfc3117d5e632c70763e4630d358e09e7477b235f3bc007321884fa0ac7930f663b9dbcc25ac112
7
- data.tar.gz: b1c7a624ecdb052f1273b0aa1bc9267c046bab1b25b32e79ad4a9c7dc18da60b426cc334a1f2d36c64c9b45682589929343b9b6b872b02ba4b1538937bafd5b1
6
+ metadata.gz: 26f2fe285a9249a70015b31b7fb30983d3f4fff6befe671508f56ac57d6bbcb901f5740290fcd3bcfb6a5e7ccc9697ccf8032b0d3aa07d6a743485ce34cb9c1d
7
+ data.tar.gz: cf8992389b7097a416f5050d196758145dd958abeef155a672fa21ffdef382f5e025e6b101dd2f26baf427aef2b195b43b93431b9faaae569d1386efe9cafb1d
data/.circleci/config.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  version: 2.1
2
2
  orbs:
3
- ruby-rails: sul-dlss/ruby-rails@3.1.2
3
+ ruby-rails: sul-dlss/ruby-rails@3.2.0
4
4
  workflows:
5
5
  build:
6
6
  jobs:
data/.rubocop.yml CHANGED
@@ -20,6 +20,10 @@ Layout/LineLength:
20
20
  Layout/SpaceAroundMethodCallOperator:
21
21
  Enabled: true
22
22
 
23
+ # This cop throws an error in 1.37.1
24
+ Layout/SpaceInsideHashLiteralBraces:
25
+ Enabled: false
26
+
23
27
  # ----- Lint ------
24
28
 
25
29
  Lint/BinaryOperatorWithIdenticalOperands:
@@ -331,7 +335,7 @@ Style/MapCompactWithConditionalBlock: # new in 1.30
331
335
  Enabled: true
332
336
  RSpec/ChangeByZero: # new in 2.11.0
333
337
  Enabled: true
334
- RSpec/Capybara/SpecificMatcher: # new in 2.12
338
+ Capybara/SpecificMatcher: # new in 2.12
335
339
  Enabled: false
336
340
  RSpec/Rails/HaveHttpStatus: # new in 2.12
337
341
  Enabled: false
@@ -340,5 +344,53 @@ RSpec/ClassCheck: # new in 2.13
340
344
  Enabled: true
341
345
  RSpec/NoExpectationExample: # new in 2.13
342
346
  Enabled: true
343
- RSpec/Capybara/SpecificFinders: # new in 2.13
347
+ Capybara/SpecificFinders: # new in 2.13
348
+ Enabled: true
349
+ Gemspec/DevelopmentDependencies: # new in 1.44
350
+ Enabled: true
351
+ Lint/DuplicateMagicComment: # new in 1.37
352
+ Enabled: true
353
+ Lint/UselessRescue: # new in 1.43
354
+ Enabled: true
355
+ Style/ArrayIntersect: # new in 1.40
356
+ Enabled: true
357
+ Style/ComparableClamp: # new in 1.44
358
+ Enabled: true
359
+ Style/ConcatArrayLiterals: # new in 1.41
360
+ Enabled: true
361
+ Style/MapToSet: # new in 1.42
362
+ Enabled: true
363
+ Style/MinMaxComparison: # new in 1.42
364
+ Enabled: true
365
+ Style/OperatorMethodCall: # new in 1.37
366
+ Enabled: true
367
+ Style/RedundantConstantBase: # new in 1.40
368
+ Enabled: true
369
+ Style/RedundantDoubleSplatHashBraces: # new in 1.41
370
+ Enabled: true
371
+ Style/RedundantEach: # new in 1.38
372
+ Enabled: true
373
+ Style/RedundantStringEscape: # new in 1.37
374
+ Enabled: true
375
+ Capybara/MatchStyle: # new in <<next>>
376
+ Enabled: true
377
+ Capybara/NegationMatcher: # new in 2.14
378
+ Enabled: true
379
+ Capybara/SpecificActions: # new in 2.14
380
+ Enabled: true
381
+ RSpec/DuplicatedMetadata: # new in 2.16
382
+ Enabled: true
383
+ RSpec/PendingWithoutReason: # new in 2.16
384
+ Enabled: true
385
+ RSpec/SortMetadata: # new in 2.14
386
+ Enabled: true
387
+ RSpec/FactoryBot/ConsistentParenthesesStyle: # new in 2.14
388
+ Enabled: true
389
+ RSpec/FactoryBot/FactoryNameStyle: # new in 2.16
390
+ Enabled: true
391
+ RSpec/Rails/InferredSpecType: # new in 2.14
392
+ Enabled: true
393
+ RSpec/Rails/MinitestAssertions: # new in 2.17
394
+ Enabled: true
395
+ Style/RedundantHeredocDelimiterQuotes: # new in 1.45
344
396
  Enabled: true
data/.rubocop_todo.yml CHANGED
@@ -1,17 +1,27 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config --auto-gen-only-exclude`
3
- # on 2022-06-08 23:20:02 UTC using RuboCop version 1.28.2.
3
+ # on 2023-02-07 01:43:53 UTC using RuboCop version 1.44.1.
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: 3
10
+ # Configuration parameters: EnforcedStyle, AllowedGems, Include.
11
+ # SupportedStyles: Gemfile, gems.rb, gemspec
12
+ # AllowedGems: bundler
13
+ # Include: **/*.gemspec, **/Gemfile, **/gems.rb
14
+ Gemspec/DevelopmentDependencies:
15
+ Exclude:
16
+ - 'cocina-models.gemspec'
17
+
9
18
  # Offense count: 1
10
19
  Lint/NoReturnInBeginEndBlocks:
11
20
  Exclude:
12
21
  - 'lib/cocina/models/mapping/to_mods/description.rb'
13
22
 
14
- # Offense count: 1
23
+ # Offense count: 2
24
+ # This cop supports safe autocorrection (--autocorrect).
15
25
  # Configuration parameters: AllowedMethods.
16
26
  # AllowedMethods: present?, blank?, presence, try, try!, in?
17
27
  Lint/SafeNavigationChain:
@@ -19,7 +29,7 @@ Lint/SafeNavigationChain:
19
29
  - 'lib/cocina/generator/schema_base.rb'
20
30
 
21
31
  # Offense count: 13
22
- # This cop supports safe auto-correction (--auto-correct).
32
+ # This cop supports safe autocorrection (--autocorrect).
23
33
  # Configuration parameters: AllowUnusedKeywordArguments, IgnoreEmptyMethods, IgnoreNotImplementedMethods.
24
34
  Lint/UnusedMethodArgument:
25
35
  Exclude:
@@ -35,16 +45,30 @@ Lint/UnusedMethodArgument:
35
45
  - 'lib/cocina/models/mapping/from_mods/subject.rb'
36
46
  - 'lib/cocina/models/mapping/to_mods/event.rb'
37
47
 
38
- # Offense count: 96
39
- # Configuration parameters: IgnoredMethods, CountRepeatedAttributes.
48
+ # Offense count: 95
49
+ # Configuration parameters: AllowedMethods, AllowedPatterns, IgnoredMethods, CountRepeatedAttributes.
40
50
  Metrics/AbcSize:
41
51
  Max: 40
42
52
 
43
- # Offense count: 42
44
- # Configuration parameters: IgnoredMethods.
53
+ # Offense count: 43
54
+ # Configuration parameters: AllowedMethods, AllowedPatterns, IgnoredMethods.
45
55
  Metrics/CyclomaticComplexity:
46
56
  Max: 12
47
57
 
58
+ # Offense count: 1
59
+ # Configuration parameters: CountComments, Max, CountAsOne, ExcludedMethods, AllowedMethods, AllowedPatterns, IgnoredMethods.
60
+ Metrics/MethodLength:
61
+ Exclude:
62
+ - 'spec/cocina/models/file_access_spec.rb'
63
+ - 'spec/cocina/models/dro_access_spec.rb'
64
+ - 'lib/cocina/rspec/factories.rb'
65
+ - 'lib/cocina/models/mapping/to_mods/*'
66
+ - 'lib/cocina/models/mapping/from_mods/*'
67
+ - 'lib/cocina/models/mapping/normalizers/mods/origin_info_normalizer.rb'
68
+ - 'lib/cocina/models/mapping/normalizers/mods/subject_normalizer.rb'
69
+ - 'lib/cocina/models/mapping/normalizers/mods_normalizer.rb'
70
+ - 'lib/cocina/generator/schema_base.rb'
71
+
48
72
  # Offense count: 1
49
73
  # Configuration parameters: Max, CountKeywordArgs, MaxOptionalParameters.
50
74
  Metrics/ParameterLists:
@@ -62,20 +86,30 @@ RSpec/ExampleLength:
62
86
  Max: 128
63
87
 
64
88
  # Offense count: 10
65
- # Configuration parameters: Max.
89
+ # Configuration parameters: Max, AllowedGroups.
66
90
  RSpec/NestedGroups:
67
91
  Exclude:
68
92
  - 'spec/cocina/models/mapping/normalizers/mods/origin_info_normalizer_spec.rb'
69
93
  - 'spec/cocina/models/validators/date_time_validator_spec.rb'
70
94
 
71
- # Offense count: 1
72
- # Configuration parameters: MinBodyLength, AllowConsecutiveConditionals.
73
- Style/GuardClause:
95
+ # Offense count: 19
96
+ RSpec/PendingWithoutReason:
74
97
  Exclude:
75
- - 'lib/cocina/generator/schema_base.rb'
98
+ - 'spec/cocina/models/mapping/descriptive/mods/name_spec.rb'
99
+ - 'spec/cocina/models/mapping/descriptive/mods/origin_info_place_spec.rb'
100
+ - 'spec/cocina/models/mapping/descriptive/mods/physical_description_spec.rb'
101
+ - 'spec/cocina/models/mapping/descriptive/mods/record_info_spec.rb'
102
+ - 'spec/cocina/models/mapping/descriptive/mods/subject_classification_spec.rb'
103
+ - 'spec/cocina/models/mapping/descriptive/mods/subject_genre_spec.rb'
104
+ - 'spec/cocina/models/mapping/descriptive/mods/subject_geographic_spec.rb'
105
+ - 'spec/cocina/models/mapping/descriptive/mods/subject_name_spec.rb'
106
+ - 'spec/cocina/models/mapping/descriptive/mods/subject_spec.rb'
107
+ - 'spec/cocina/models/mapping/descriptive/mods/subject_title_spec.rb'
108
+ - 'spec/cocina/models/mapping/descriptive/mods/title_info_spec.rb'
109
+ - 'spec/cocina/models/mapping/descriptive/mods/type_of_resource_spec.rb'
76
110
 
77
111
  # Offense count: 1
78
- # This cop supports safe auto-correction (--auto-correct).
112
+ # This cop supports safe autocorrection (--autocorrect).
79
113
  Style/IfUnlessModifier:
80
114
  Exclude:
81
115
  - 'lib/cocina/models/validators/open_api_validator.rb'
@@ -88,8 +122,8 @@ Style/MultilineBlockChain:
88
122
  - 'lib/cocina/models/mapping/to_mods/form.rb'
89
123
  - 'lib/cocina/models/mapping/to_mods/subject.rb'
90
124
 
91
- # Offense count: 223
92
- # This cop supports safe auto-correction (--auto-correct).
125
+ # Offense count: 225
126
+ # This cop supports safe autocorrection (--autocorrect).
93
127
  # Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns, IgnoredPatterns.
94
128
  # URISchemes: http, https
95
129
  Layout/LineLength:
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- cocina-models (0.86.0)
4
+ cocina-models (0.87.1)
5
5
  activesupport
6
6
  deprecation
7
7
  dry-struct (~> 1.0)
@@ -20,57 +20,58 @@ PATH
20
20
  GEM
21
21
  remote: https://rubygems.org/
22
22
  specs:
23
- activesupport (7.0.4)
23
+ activesupport (7.0.4.2)
24
24
  concurrent-ruby (~> 1.0, >= 1.0.2)
25
25
  i18n (>= 1.6, < 2)
26
26
  minitest (>= 5.1)
27
27
  tzinfo (~> 2.0)
28
28
  ast (2.4.2)
29
- attr_extras (6.2.5)
29
+ attr_extras (7.1.0)
30
30
  byebug (11.1.3)
31
- committee (4.4.0)
31
+ committee (4.99.1)
32
32
  json_schema (~> 0.14, >= 0.14.3)
33
33
  openapi_parser (>= 0.11.1, < 1.0)
34
34
  rack (>= 1.5)
35
- commonmarker (0.23.6)
36
- concurrent-ruby (1.1.10)
35
+ commonmarker (0.23.8)
36
+ concurrent-ruby (1.2.0)
37
37
  deprecation (1.1.0)
38
38
  activesupport
39
39
  diff-lcs (1.5.0)
40
40
  docile (1.4.0)
41
- dry-container (0.11.0)
41
+ dry-core (1.0.0)
42
42
  concurrent-ruby (~> 1.0)
43
- dry-core (0.8.1)
43
+ zeitwerk (~> 2.6)
44
+ dry-inflector (1.0.0)
45
+ dry-logic (1.5.0)
44
46
  concurrent-ruby (~> 1.0)
45
- dry-inflector (0.3.0)
46
- dry-logic (1.2.0)
47
- concurrent-ruby (~> 1.0)
48
- dry-core (~> 0.5, >= 0.5)
49
- dry-struct (1.4.0)
50
- dry-core (~> 0.5, >= 0.5)
51
- dry-types (~> 1.5)
47
+ dry-core (~> 1.0, < 2)
48
+ zeitwerk (~> 2.6)
49
+ dry-struct (1.6.0)
50
+ dry-core (~> 1.0, < 2)
51
+ dry-types (>= 1.7, < 2)
52
52
  ice_nine (~> 0.11)
53
- dry-types (1.5.1)
53
+ zeitwerk (~> 2.6)
54
+ dry-types (1.7.0)
54
55
  concurrent-ruby (~> 1.0)
55
- dry-container (~> 0.3)
56
- dry-core (~> 0.5, >= 0.5)
57
- dry-inflector (~> 0.1, >= 0.1.2)
58
- dry-logic (~> 1.0, >= 1.0.2)
59
- edtf (3.1.0)
56
+ dry-core (~> 1.0, < 2)
57
+ dry-inflector (~> 1.0, < 2)
58
+ dry-logic (>= 1.4, < 2)
59
+ zeitwerk (~> 2.6)
60
+ edtf (3.1.1)
60
61
  activesupport (>= 3.0, < 8.0)
61
62
  equivalent-xml (0.6.0)
62
63
  nokogiri (>= 1.4.3)
63
64
  i18n (1.12.0)
64
65
  concurrent-ruby (~> 1.0)
65
66
  ice_nine (0.11.2)
66
- json (2.6.2)
67
+ json (2.6.3)
67
68
  json_schema (0.21.0)
68
69
  jsonpath (1.1.2)
69
70
  multi_json
70
- mini_portile2 (2.8.0)
71
- minitest (5.16.3)
71
+ mini_portile2 (2.8.1)
72
+ minitest (5.17.0)
72
73
  multi_json (1.15.0)
73
- nokogiri (1.13.8)
74
+ nokogiri (1.14.2)
74
75
  mini_portile2 (~> 2.8.0)
75
76
  racc (~> 1.4)
76
77
  openapi3_parser (0.9.2)
@@ -78,51 +79,54 @@ GEM
78
79
  openapi_parser (0.15.0)
79
80
  optimist (3.0.1)
80
81
  parallel (1.22.1)
81
- parser (3.1.2.1)
82
+ parser (3.2.1.0)
82
83
  ast (~> 2.4.1)
83
84
  patience_diff (1.2.0)
84
85
  optimist (~> 3.0)
85
- racc (1.6.0)
86
- rack (3.0.0)
86
+ racc (1.6.2)
87
+ rack (3.0.4.1)
87
88
  rainbow (3.1.1)
88
89
  rake (13.0.6)
89
- regexp_parser (2.5.0)
90
+ regexp_parser (2.7.0)
90
91
  rexml (3.2.5)
91
- rspec (3.11.0)
92
- rspec-core (~> 3.11.0)
93
- rspec-expectations (~> 3.11.0)
94
- rspec-mocks (~> 3.11.0)
95
- rspec-core (3.11.0)
96
- rspec-support (~> 3.11.0)
97
- rspec-expectations (3.11.1)
92
+ rspec (3.12.0)
93
+ rspec-core (~> 3.12.0)
94
+ rspec-expectations (~> 3.12.0)
95
+ rspec-mocks (~> 3.12.0)
96
+ rspec-core (3.12.1)
97
+ rspec-support (~> 3.12.0)
98
+ rspec-expectations (3.12.2)
98
99
  diff-lcs (>= 1.2.0, < 2.0)
99
- rspec-support (~> 3.11.0)
100
- rspec-mocks (3.11.1)
100
+ rspec-support (~> 3.12.0)
101
+ rspec-mocks (3.12.3)
101
102
  diff-lcs (>= 1.2.0, < 2.0)
102
- rspec-support (~> 3.11.0)
103
- rspec-support (3.11.1)
104
- rspec_junit_formatter (0.5.1)
103
+ rspec-support (~> 3.12.0)
104
+ rspec-support (3.12.0)
105
+ rspec_junit_formatter (0.6.0)
105
106
  rspec-core (>= 2, < 4, != 2.12.0)
106
107
  rss (0.2.9)
107
108
  rexml
108
- rubocop (1.36.0)
109
+ rubocop (1.45.1)
109
110
  json (~> 2.3)
110
111
  parallel (~> 1.10)
111
- parser (>= 3.1.2.1)
112
+ parser (>= 3.2.0.0)
112
113
  rainbow (>= 2.2.2, < 4.0)
113
114
  regexp_parser (>= 1.8, < 3.0)
114
115
  rexml (>= 3.2.5, < 4.0)
115
- rubocop-ast (>= 1.20.1, < 2.0)
116
+ rubocop-ast (>= 1.24.1, < 2.0)
116
117
  ruby-progressbar (~> 1.7)
117
- unicode-display_width (>= 1.4.0, < 3.0)
118
- rubocop-ast (1.21.0)
119
- parser (>= 3.1.1.0)
118
+ unicode-display_width (>= 2.4.0, < 3.0)
119
+ rubocop-ast (1.26.0)
120
+ parser (>= 3.2.1.0)
121
+ rubocop-capybara (2.17.0)
122
+ rubocop (~> 1.41)
120
123
  rubocop-rake (0.6.0)
121
124
  rubocop (~> 1.0)
122
- rubocop-rspec (2.13.2)
125
+ rubocop-rspec (2.18.1)
123
126
  rubocop (~> 1.33)
127
+ rubocop-capybara (~> 2.17)
124
128
  ruby-progressbar (1.11.0)
125
- simplecov (0.21.2)
129
+ simplecov (0.22.0)
126
130
  docile (~> 1.1)
127
131
  simplecov-html (~> 0.11)
128
132
  simplecov_json_formatter (~> 0.1)
@@ -133,10 +137,10 @@ GEM
133
137
  diff-lcs
134
138
  patience_diff
135
139
  thor (1.2.1)
136
- tzinfo (2.0.5)
140
+ tzinfo (2.0.6)
137
141
  concurrent-ruby (~> 1.0)
138
- unicode-display_width (2.3.0)
139
- zeitwerk (2.6.0)
142
+ unicode-display_width (2.4.2)
143
+ zeitwerk (2.6.7)
140
144
 
141
145
  PLATFORMS
142
146
  ruby
@@ -11,7 +11,7 @@ module Cocina
11
11
  module Cocina
12
12
  module Models
13
13
  #{name} = Types::String.constrained(
14
- format: /#{schema_doc.pattern}/i
14
+ format: /#{schema_doc.pattern}/
15
15
  )
16
16
  end
17
17
  end
@@ -5,7 +5,7 @@ require 'fileutils'
5
5
  module Cocina
6
6
  module Generator
7
7
  # Class for generating Cocina models from openapi.
8
- class Generator < Thor
8
+ class Generator < Thor # rubocop:disable Metrics/ClassLength
9
9
  include Thor::Actions
10
10
 
11
11
  class_option :openapi, desc: 'Path of openapi.yml', default: 'openapi.yml'
@@ -19,14 +19,12 @@ module Cocina
19
19
  def generate
20
20
  clean_output
21
21
 
22
- # rubocop:disable Style/HashEachMethods
23
- # This is not a Hash
24
- schemas.keys.each do |schema_name|
22
+ filepaths = schemas.keys.filter_map do |schema_name|
25
23
  schema = schema_for(schema_name)
26
24
  generate_for(schema) if schema
27
25
  end
28
- # rubocop:enable Style/HashEachMethods
29
26
 
27
+ auto_format(filepaths)
30
28
  generate_vocab
31
29
  generate_descriptive_docs
32
30
  end
@@ -38,7 +36,8 @@ module Cocina
38
36
 
39
37
  FileUtils.mkdir_p(options[:output])
40
38
 
41
- generate_for(schema)
39
+ filepath = generate_for(schema)
40
+ auto_format(filepath)
42
41
  end
43
42
 
44
43
  desc 'generate_vocab', 'generate vocab'
@@ -101,18 +100,26 @@ module Cocina
101
100
 
102
101
  case schema_doc.type
103
102
  when 'object'
104
- Schema.new(schema_doc)
103
+ Schema.new(schema_doc, schemas: schemas.keys)
105
104
  when 'string'
106
- Datatype.new(schema_doc)
105
+ Datatype.new(schema_doc, schemas: schemas.keys)
106
+ when NilClass
107
+ return unless schema_doc.one_of.map(&:name).all? { |ref_schema_name| schemas.keys.include?(ref_schema_name) }
108
+
109
+ UnionType.new(schema_doc)
107
110
  end
108
111
  end
109
112
 
110
113
  def generate_for(schema)
111
- filepath = "#{options[:output]}/#{schema.filename}"
112
- FileUtils.rm_f(filepath)
114
+ "#{options[:output]}/#{schema.filename}".tap do |filepath|
115
+ FileUtils.rm_f(filepath)
116
+
117
+ create_file filepath, schema.generate
118
+ end
119
+ end
113
120
 
114
- create_file filepath, schema.generate
115
- run("rubocop -a #{filepath} > /dev/null")
121
+ def auto_format(*filepaths)
122
+ run("rubocop -a #{filepaths.join(' ')} > /dev/null")
116
123
  end
117
124
 
118
125
  NO_CLEAN = [
@@ -111,7 +111,8 @@ module Cocina
111
111
  # different oneOf schemas. Validation is still performed
112
112
  # by openAPI.
113
113
  relaxed: true,
114
- parent: self)
114
+ parent: self,
115
+ schemas: schemas)
115
116
  end
116
117
  end
117
118
  end
@@ -122,7 +123,8 @@ module Cocina
122
123
  key: key,
123
124
  required: doc.requires?(key),
124
125
  nullable: properties_doc.nullable?,
125
- parent: self)
126
+ parent: self,
127
+ schemas: schemas)
126
128
  end
127
129
  end
128
130
  end
@@ -9,7 +9,7 @@ module Cocina
9
9
  end
10
10
 
11
11
  def array_of_type
12
- schema_doc.items.name || "Types::#{dry_datatype(schema_doc.items)}"
12
+ schema_doc.items.name || dry_datatype(schema_doc.items)
13
13
  end
14
14
  end
15
15
  end
@@ -4,15 +4,16 @@ module Cocina
4
4
  module Generator
5
5
  # Base class for generating from openapi
6
6
  class SchemaBase
7
- attr_reader :schema_doc, :key, :required, :nullable, :parent, :relaxed
7
+ attr_reader :schema_doc, :key, :required, :nullable, :parent, :relaxed, :schemas
8
8
 
9
- def initialize(schema_doc, key: nil, required: false, nullable: false, parent: nil, relaxed: false)
9
+ def initialize(schema_doc, key: nil, required: false, nullable: false, parent: nil, relaxed: false, schemas: [])
10
10
  @schema_doc = schema_doc
11
11
  @key = key
12
12
  @required = required
13
13
  @nullable = nullable
14
14
  @parent = parent
15
15
  @relaxed = relaxed
16
+ @schemas = schemas
16
17
  end
17
18
 
18
19
  def filename
@@ -23,10 +24,16 @@ module Cocina
23
24
  key || schema_doc.name
24
25
  end
25
26
 
26
- # Allows nillable values to be set to nil. This is useful when doing
27
- # an update and you want to clear out a value.
27
+ # Allows nullable values to be set to nil. This is useful when doing an
28
+ # update and you want to clear out a value. The logic also permits custom
29
+ # types (e.g., `Barcode`, `SourceId`) to be nullable if they are not
30
+ # required.
28
31
  def optional
29
- nullable || relaxed ? '.optional' : ''
32
+ return '.optional' if nullable ||
33
+ relaxed ||
34
+ (custom_type? && !required)
35
+
36
+ ''
30
37
  end
31
38
 
32
39
  def quote(item)
@@ -59,34 +66,58 @@ module Cocina
59
66
  "# Validation of this property is relaxed. See the openapi for full validation.\n"
60
67
  end
61
68
 
69
+ # dry-types-based types contain the word `Types` (e.g., `Types::String`), and custom types (e.g., `SourceId`) do not
70
+ def custom_type?
71
+ !dry_datatype(schema_doc).match?('Types')
72
+ end
73
+
62
74
  def dry_datatype(doc)
75
+ return doc.name if doc.name.present? && schemas.include?(doc.name)
76
+
77
+ datatype_from_doc_names(doc) ||
78
+ datatype_from_doc_type(doc) ||
79
+ raise("#{doc.type} not supported")
80
+ end
81
+
82
+ def datatype_from_doc_type(doc)
63
83
  case doc.type
64
84
  when 'integer'
65
- 'Strict::Integer'
85
+ 'Types::Strict::Integer'
66
86
  when 'string'
67
87
  string_dry_datatype(doc)
68
88
  when 'boolean'
69
- 'Strict::Bool'
89
+ 'Types::Strict::Bool'
70
90
  else
71
- if any_datatype?(doc)
72
- 'Nominal::Any'
73
- else
74
- raise "#{schema_doc.type} not supported"
75
- end
91
+ return 'Types::Nominal::Any' if any_datatype?(doc)
92
+
93
+ raise "#{schema_doc.type} not supported"
76
94
  end
77
95
  end
78
96
 
97
+ def datatype_from_doc_names(doc)
98
+ return unless defined_datatypes?(doc)
99
+
100
+ doc.one_of.map(&:name).join(' | ')
101
+ end
102
+
103
+ def defined_datatypes?(doc)
104
+ doc.one_of&.map(&:name)&.all? { |name| name.present? && schemas.include?(name) }
105
+ end
106
+
79
107
  def any_datatype?(doc)
80
- relaxed || doc.one_of&.map(&:type).all? { |o| %w[integer string].include?(o) }
108
+ relaxed || doc.one_of&.map(&:type)&.all? { |o| %w[integer string].include?(o) }
81
109
  end
82
110
 
83
111
  def string_dry_datatype(doc)
84
- case doc.format
85
- when 'date-time'
86
- 'Params::DateTime'
87
- else
88
- 'Strict::String'
89
- end
112
+ format = case doc.format
113
+ when 'date-time'
114
+ 'Types::Params::DateTime'
115
+ else
116
+ 'Types::Strict::String'
117
+ end
118
+ return format unless doc.pattern
119
+
120
+ "Types::Strict::String.constrained(format: /#{doc.pattern}/)"
90
121
  end
91
122
 
92
123
  def preamble
@@ -5,7 +5,6 @@ module Cocina
5
5
  # Class for generating from an openapi value
6
6
  class SchemaValue < SchemaBase
7
7
  def generate
8
- # optional has to come before default or the default value that gets set will be nil.
9
8
  if required && !relaxed
10
9
  "#{preamble}attribute :#{name.camelize(:lower)}, #{type}"
11
10
  else
@@ -16,7 +15,8 @@ module Cocina
16
15
  private
17
16
 
18
17
  def type
19
- "Types::#{dry_datatype(schema_doc)}#{optional}#{default}#{enum}"
18
+ # optional has to come before default or the default value that gets set will be nil.
19
+ "#{dry_datatype(schema_doc)}#{optional}#{default}#{enum}"
20
20
  end
21
21
 
22
22
  def enum
@@ -33,7 +33,7 @@ module Cocina
33
33
 
34
34
  def default
35
35
  # Provide version as default for cocinaVersion
36
- return '.default(Cocina::Models::VERSION)' if name == 'cocinaVersion'
36
+ return '.default(VERSION)' if name == 'cocinaVersion'
37
37
 
38
38
  # If type is boolean and default is false, erroneously getting a nil.
39
39
  # Assuming that if required, then default is false.
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cocina
4
+ module Generator
5
+ # Class for generating a union type
6
+ class UnionType < SchemaBase
7
+ def generate
8
+ <<~RUBY
9
+ # frozen_string_literal: true
10
+
11
+ module Cocina
12
+ module Models
13
+ #{name} = #{type_names}
14
+ end
15
+ end
16
+ RUBY
17
+ end
18
+
19
+ def type_names
20
+ schema_doc.one_of.map(&:name).join(' | ')
21
+ end
22
+ end
23
+ end
24
+ end