cocina-models 0.86.0 → 0.87.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 (54) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +1 -1
  3. data/.rubocop.yml +52 -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 +36 -16
  11. data/lib/cocina/generator/schema_value.rb +2 -2
  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: 272a5d8e2b026dc773452921e549241338c6c8cda4f21b3ae6da3b7511f7cec6
4
+ data.tar.gz: f3471e9e52d279444b8ef4bac802d116c71b23d5d937363c084f322204b9ce1f
5
5
  SHA512:
6
- metadata.gz: 7dafbf718bf85eecf60c896342e88b94381055b8b39f729eecfc3117d5e632c70763e4630d358e09e7477b235f3bc007321884fa0ac7930f663b9dbcc25ac112
7
- data.tar.gz: b1c7a624ecdb052f1273b0aa1bc9267c046bab1b25b32e79ad4a9c7dc18da60b426cc334a1f2d36c64c9b45682589929343b9b6b872b02ba4b1538937bafd5b1
6
+ metadata.gz: a44093101a258a2d88b83f82955dc81c81624419baf0cf55892eb976e04ac770ddf34d8c60e5649522c1c4b14687aed0715b14b92ede2a8858af839ff2bb6b8e
7
+ data.tar.gz: a95e82570f152ac1498d072c0ee7320c0da738a45b80949cb098c722838d9495cd4e6c6e74aa78cf40ba6f3b88ea846779cc2adbddd42d161929ae8bd79a7856
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,51 @@ 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
344
394
  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.0)
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
@@ -60,33 +61,52 @@ module Cocina
60
61
  end
61
62
 
62
63
  def dry_datatype(doc)
64
+ return doc.name if doc.name.present? && schemas.include?(doc.name)
65
+
66
+ datatype_from_doc_names(doc) ||
67
+ datatype_from_doc_type(doc) ||
68
+ raise("#{doc.type} not supported")
69
+ end
70
+
71
+ def datatype_from_doc_type(doc)
63
72
  case doc.type
64
73
  when 'integer'
65
- 'Strict::Integer'
74
+ 'Types::Strict::Integer'
66
75
  when 'string'
67
76
  string_dry_datatype(doc)
68
77
  when 'boolean'
69
- 'Strict::Bool'
78
+ 'Types::Strict::Bool'
70
79
  else
71
- if any_datatype?(doc)
72
- 'Nominal::Any'
73
- else
74
- raise "#{schema_doc.type} not supported"
75
- end
80
+ return 'Types::Nominal::Any' if any_datatype?(doc)
81
+
82
+ raise "#{schema_doc.type} not supported"
76
83
  end
77
84
  end
78
85
 
86
+ def datatype_from_doc_names(doc)
87
+ return unless defined_datatypes?(doc)
88
+
89
+ doc.one_of.map(&:name).join(' | ')
90
+ end
91
+
92
+ def defined_datatypes?(doc)
93
+ doc.one_of&.map(&:name)&.all? { |name| name.present? && schemas.include?(name) }
94
+ end
95
+
79
96
  def any_datatype?(doc)
80
- relaxed || doc.one_of&.map(&:type).all? { |o| %w[integer string].include?(o) }
97
+ relaxed || doc.one_of&.map(&:type)&.all? { |o| %w[integer string].include?(o) }
81
98
  end
82
99
 
83
100
  def string_dry_datatype(doc)
84
- case doc.format
85
- when 'date-time'
86
- 'Params::DateTime'
87
- else
88
- 'Strict::String'
89
- end
101
+ format = case doc.format
102
+ when 'date-time'
103
+ 'Types::Params::DateTime'
104
+ else
105
+ 'Types::Strict::String'
106
+ end
107
+ return format unless doc.pattern
108
+
109
+ "Types::Strict::String.constrained(format: /#{doc.pattern}/)"
90
110
  end
91
111
 
92
112
  def preamble
@@ -16,7 +16,7 @@ module Cocina
16
16
  private
17
17
 
18
18
  def type
19
- "Types::#{dry_datatype(schema_doc)}#{optional}#{default}#{enum}"
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
@@ -11,10 +11,10 @@ module Cocina
11
11
 
12
12
  # The version of Cocina with which this object conforms.
13
13
  # example: 1.2.3
14
- attribute :cocinaVersion, Types::Strict::String.default(Cocina::Models::VERSION)
14
+ attribute :cocinaVersion, CocinaVersion.default(VERSION)
15
15
  attribute :type, Types::Strict::String.enum(*AdminPolicy::TYPES)
16
16
  # example: druid:bc123df4567
17
- attribute :externalIdentifier, Types::Strict::String
17
+ attribute :externalIdentifier, Druid
18
18
  attribute :label, Types::Strict::String
19
19
  attribute :version, Types::Strict::Integer
20
20
  attribute(:administrative, AdminPolicyAdministrative.default { AdminPolicyAdministrative.new })
@@ -11,9 +11,9 @@ module Cocina
11
11
  attribute? :disseminationWorkflow, Types::Strict::String
12
12
  attribute :collectionsForRegistration, Types::Strict::Array.of(Types::Strict::String).default([].freeze)
13
13
  # example: druid:bc123df4567
14
- attribute :hasAdminPolicy, Types::Strict::String
14
+ attribute :hasAdminPolicy, Druid
15
15
  # example: druid:bc123df4567
16
- attribute :hasAgreement, Types::Strict::String
16
+ attribute :hasAgreement, Druid
17
17
  attribute :roles, Types::Strict::Array.of(AccessRole).default([].freeze)
18
18
  end
19
19
  end