cocina-models 0.106.0 → 0.107.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e344b96eb11f904d0730963727606fed5046857f72901761c7e75a1101992086
4
- data.tar.gz: 1d446ff09f267b94684b57afeada1be9f393fd99874ed360c5c67f6e2d35051c
3
+ metadata.gz: 3e982057b0f0017c03ce8809fa93494bd179b28a90e6ad3f32ad6859c4a8249c
4
+ data.tar.gz: 4777322f4d9b18fa6d814b36974dbbbd9e79857a4ce5149a756ae737e82ca49c
5
5
  SHA512:
6
- metadata.gz: 3941a79c6c26af81128ed0face784ce398c5b343970c5511d5da8cf8aad9dde10d1ea6fe19dad6122e6d460b2a53c3f1bcd9ca800dfbb2885e98d9d37a4e588f
7
- data.tar.gz: 4df7a5daf531751de3e26bb168f498a0b07042e039ea6797ee0f42e18893b74a464f72fc7ced0e6625818964f2e67d159bfa133878aa83f4c1410b6e67b0a076
6
+ metadata.gz: c0c1136149b28c85dfa4c7a5e1aab4ee6829beecb2a04367db82a85f31a4a84aca774a3243fdbbfac34db1dca4d6f7624eaf399548db69a281c0e7059136d67a
7
+ data.tar.gz: 0ba5d2b587e122a0ab1cd363fcc5c32e0fc3a3a26ae35621967bcb8e0eead73bc87d86f263520be8b6d831ca528f2e7e0a85138f545e31ff8381d90bd826971c
data/.rubocop.yml CHANGED
@@ -6,7 +6,7 @@ plugins:
6
6
  - rubocop-rspec
7
7
 
8
8
  AllCops:
9
- TargetRubyVersion: 3.0
9
+ TargetRubyVersion: 3.4
10
10
 
11
11
  # ----- Layout ------
12
12
 
@@ -110,7 +110,7 @@ Metrics/PerceivedComplexity:
110
110
  - 'lib/cocina/models/mapping/to_mods/*'
111
111
  - 'lib/cocina/models/mapping/normalizers/**/*'
112
112
 
113
- Naming/PredicateName:
113
+ Naming/PredicatePrefix:
114
114
  ForbiddenPrefixes:
115
115
  - is_
116
116
 
@@ -521,3 +521,20 @@ Style/ItBlockParameter: # new in 1.75
521
521
  Enabled: true
522
522
  RSpec/IncludeExamples: # new in 3.6
523
523
  Enabled: true
524
+
525
+ Gemspec/AttributeAssignment: # new in 1.77
526
+ Enabled: true
527
+ Layout/EmptyLinesAfterModuleInclusion: # new in 1.79
528
+ Enabled: true
529
+ Lint/UselessDefaultValueArgument: # new in 1.76
530
+ Enabled: true
531
+ Lint/UselessOr: # new in 1.76
532
+ Enabled: true
533
+ Naming/PredicateMethod: # new in 1.76
534
+ Enabled: true
535
+ Style/CollectionQuerying: # new in 1.77
536
+ Enabled: true
537
+ Style/EmptyStringInsideInterpolation: # new in 1.76
538
+ Enabled: true
539
+ Style/RedundantArrayFlatten: # new in 1.76
540
+ Enabled: true
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- cocina-models (0.106.0)
4
+ cocina-models (0.107.1)
5
5
  activesupport
6
6
  deprecation
7
7
  dry-struct (~> 1.0)
@@ -19,7 +19,7 @@ PATH
19
19
  GEM
20
20
  remote: https://rubygems.org/
21
21
  specs:
22
- activesupport (8.0.2.1)
22
+ activesupport (8.0.3)
23
23
  base64
24
24
  benchmark (>= 0.3)
25
25
  bigdecimal
@@ -36,7 +36,7 @@ GEM
36
36
  attr_extras (7.1.0)
37
37
  base64 (0.3.0)
38
38
  benchmark (0.4.1)
39
- bigdecimal (3.2.3)
39
+ bigdecimal (3.3.1)
40
40
  byebug (12.0.0)
41
41
  committee (5.0.0)
42
42
  json_schema (~> 0.14, >= 0.14.3)
@@ -78,7 +78,7 @@ GEM
78
78
  i18n (1.14.7)
79
79
  concurrent-ruby (~> 1.0)
80
80
  ice_nine (0.11.2)
81
- json (2.13.2)
81
+ json (2.15.1)
82
82
  json_schema (0.21.0)
83
83
  jsonpath (1.1.5)
84
84
  multi_json
@@ -86,7 +86,7 @@ GEM
86
86
  lint_roller (1.1.0)
87
87
  logger (1.7.0)
88
88
  mini_portile2 (2.8.9)
89
- minitest (5.25.5)
89
+ minitest (5.26.0)
90
90
  multi_json (1.17.0)
91
91
  nokogiri (1.18.10)
92
92
  mini_portile2 (~> 2.8.2)
@@ -99,9 +99,9 @@ GEM
99
99
  racc
100
100
  patience_diff (1.2.0)
101
101
  optimist (~> 3.0)
102
- prism (1.5.1)
102
+ prism (1.6.0)
103
103
  racc (1.8.1)
104
- rack (3.2.1)
104
+ rack (3.2.3)
105
105
  rainbow (3.1.1)
106
106
  rake (13.3.0)
107
107
  regexp_parser (2.11.3)
@@ -109,18 +109,18 @@ GEM
109
109
  rspec-core (~> 3.13.0)
110
110
  rspec-expectations (~> 3.13.0)
111
111
  rspec-mocks (~> 3.13.0)
112
- rspec-core (3.13.5)
112
+ rspec-core (3.13.6)
113
113
  rspec-support (~> 3.13.0)
114
114
  rspec-expectations (3.13.5)
115
115
  diff-lcs (>= 1.2.0, < 2.0)
116
116
  rspec-support (~> 3.13.0)
117
- rspec-mocks (3.13.5)
117
+ rspec-mocks (3.13.6)
118
118
  diff-lcs (>= 1.2.0, < 2.0)
119
119
  rspec-support (~> 3.13.0)
120
- rspec-support (3.13.5)
120
+ rspec-support (3.13.6)
121
121
  rspec_junit_formatter (0.6.0)
122
122
  rspec-core (>= 2, < 4, != 2.12.0)
123
- rubocop (1.80.2)
123
+ rubocop (1.81.1)
124
124
  json (~> 2.3)
125
125
  language_server-protocol (~> 3.17.0.2)
126
126
  lint_roller (~> 1.1.0)
@@ -128,10 +128,10 @@ GEM
128
128
  parser (>= 3.3.0.2)
129
129
  rainbow (>= 2.2.2, < 4.0)
130
130
  regexp_parser (>= 2.9.3, < 3.0)
131
- rubocop-ast (>= 1.46.0, < 2.0)
131
+ rubocop-ast (>= 1.47.1, < 2.0)
132
132
  ruby-progressbar (~> 1.7)
133
133
  unicode-display_width (>= 2.4.0, < 4.0)
134
- rubocop-ast (1.46.0)
134
+ rubocop-ast (1.47.1)
135
135
  parser (>= 3.3.7.2)
136
136
  prism (~> 1.4)
137
137
  rubocop-rake (0.7.1)
@@ -158,7 +158,7 @@ GEM
158
158
  unicode-display_width (3.2.0)
159
159
  unicode-emoji (~> 4.1)
160
160
  unicode-emoji (4.1.0)
161
- uri (1.0.3)
161
+ uri (1.0.4)
162
162
  zeitwerk (2.7.3)
163
163
 
164
164
  PLATFORMS
data/README.md CHANGED
@@ -91,32 +91,8 @@ RAILS_ENV=production bin/validate-cocina -p 8
91
91
 
92
92
  ## Running Reports in DSA
93
93
 
94
- Custom reports stored in dor-services-app can be run similarly to validation testing described above.
95
-
96
- 1. Connect to the `sdr-infra` box:
97
- ```shell
98
- ssh sdr-infra
99
- ```
100
- 1. Start a shell as the `deploy` user:
101
- ```shell
102
- # you may or may not need to supply the `-n SUNETID` argument
103
- ksu deploy
104
- ```
105
- 1. Go to the `~/dor-services-app` directory and reset to main if needed (verify nobody else is using this first though):
106
- ```shell
107
- cd ~/dor-services-app
108
- git status # see if there are any unsaved changes, if so, you may need to git stash them
109
- git pull # OR git reset --hard main to just ditch any local unsaved changes
110
- ```
111
- 1. Connect to the desired database by setting the environment variables as described in the section above. This must be done each time you SSH back into the box to run a new report.
112
- 1. Run the report (good idea to do it in a screen or via background process in case you get disconnected):
113
- ```shell
114
- bundle exec bin/rails r -e production "BadIso8601Dates.report" > BadIso8601Dates.csv
115
- ```
116
- 1. When done, you can pull the report to your laptop as needed:
117
- ```shell
118
- scp sdr-infra:/opt/app/deploy/dor-services-app/BadIso8601Dates.csv .
119
- ```
94
+ See https://github.com/sul-dlss/dor-services-app/blob/main/README.md#running-reports
95
+
120
96
 
121
97
  ## Releasing a patch change
122
98
  A patch change is a change that (1) does not affect the data model; (2) does not alter the openapi.yml; and more broadly (3) does not matter if some applications have the change and others do not.
@@ -143,7 +119,7 @@ Send a note to `#dlss-infra-chg-mgmt` on Slack to let people know what is changi
143
119
  The release process is much like any other gem. While on main:
144
120
  1. Bump the version in `lib/cocina/models/version.rb`
145
121
  2. `bundle install` so that `Gemfile.lock` is updated.
146
- 3. Commit those changes.
122
+ 3. Commit those changes.
147
123
  4. Run:
148
124
  ```
149
125
  bundle exec rake release
@@ -179,11 +155,11 @@ Copy and paste the cocina-models schemas to each project's `openapi.yml`. By con
179
155
  If you updated the `openapi.yml` in step 3A, use the same PR for step 3B. Why? When [dor-services-app](https://github.com/sul-dlss/dor-services-app), for example, is updated to use the new models (via the auto-update script), these clients should be updated at the same time or there is risk of models produced by dor-services-app not being acceptable to the clients.
180
156
 
181
157
  1. Perform `bundle update --conservative cocina-models dor-services-client` in the services above and make PRs for those repos if they don't already exist. You may first need to update how these gems are pinned in the `Gemfile` in order to bump them.
182
- 2. Note that sdr-client is not currently used in these applications, but if it were, would also need to be bumped to the latest release.
158
+ 2. Note that sdr-client is not currently used in these applications, but if it were, would also need to be bumped to the latest release.
183
159
 
184
160
  #### Step 3C: Merge 'em
185
161
 
186
- Get the directly coupled services PRs merged before the deploy in step 5.
162
+ Get the directly coupled services PRs merged before the deploy in step 5.
187
163
 
188
164
  See the IMPORTANT note above about the timing of merging these PRs if you are waiting for dependency updates to make the updates to other dependent applications.
189
165
 
@@ -211,7 +187,7 @@ Create a branch and update cocina-models:
211
187
  ```
212
188
  bundle update --conservative cocina-models
213
189
  ```
214
- Once merged, it will deploy to stage via CD.
190
+ Once merged, it will deploy to stage via CD.
215
191
 
216
192
  ### Step 5: Deploy and test
217
193
 
@@ -228,7 +204,7 @@ It is safest to ensure _all_ the integration tests run cleanly. However, patch
228
204
 
229
205
  **[Turn off Google Books](https://sul-gbooks-prod.stanford.edu/features) when deploying to production.** This avoids failed deposit due to a temporary Cocina model mismatch. Unlike other applications, the deposits will fail without retry and require manual remediation.
230
206
 
231
- In addition to deploying infrastructure apps via sdr-deploy, tag and cut a release of purl-fetcher. That will trigger its deploy to production.
207
+ In addition to deploying infrastructure apps via sdr-deploy, tag and cut a release of purl-fetcher. That will trigger its deploy to production.
232
208
 
233
209
  ## Usage conventions
234
210
 
@@ -22,7 +22,7 @@ Gem::Specification.new do |spec|
22
22
  spec.bindir = 'exe'
23
23
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
24
24
  spec.require_paths = ['lib']
25
- spec.required_ruby_version = '>= 3.0'
25
+ spec.required_ruby_version = '>= 3.4'
26
26
 
27
27
  spec.add_dependency 'activesupport'
28
28
  spec.add_dependency 'deprecation'
@@ -99,6 +99,8 @@ contributor.note:
99
99
  description: Institution with which the contributor is associated.
100
100
  - value: citation status
101
101
  description: Indicator of whether the contributor should be included in the citation.
102
+ - value: contact email
103
+ description: Preferred email contact for contributor.
102
104
  - value: description
103
105
  description: Biographical information about the contributor.
104
106
  event:
@@ -106,6 +106,8 @@ _Path: contributor.note.type_
106
106
  * Institution with which the contributor is associated.
107
107
  * citation status
108
108
  * Indicator of whether the contributor should be included in the citation.
109
+ * contact email
110
+ * Preferred email contact for contributor.
109
111
  * description
110
112
  * Biographical information about the contributor.
111
113
  # Event types
@@ -22,7 +22,7 @@ module Cocina
22
22
  end
23
23
 
24
24
  def name
25
- "#{key || schema_doc.name}#{lite ? 'Lite' : ''}"
25
+ "#{key || schema_doc.name}#{'Lite' if lite}"
26
26
  end
27
27
 
28
28
  # Allows nullable values to be set to nil. This is useful when doing an
@@ -8,6 +8,7 @@ module Cocina
8
8
  # TitleBuilder selects the prefered title from the cocina object for solr indexing
9
9
  class TitleBuilder # rubocop:disable Metrics/ClassLength
10
10
  extend Deprecation
11
+
11
12
  # @param [Array<Cocina::Models::Title,Cocina::Models::DescriptiveValue>] titles the titles to consider
12
13
  # @param [Array<Cocina::Models::FolioCatalogLink>] catalog_links the folio catalog links to check for digital serials part labels
13
14
  # @param [Symbol] strategy ":first" is the strategy for selection when primary or display
@@ -5,23 +5,23 @@ module Cocina
5
5
  # A common interface for interrogating a model instance's type
6
6
  module Checkable
7
7
  def admin_policy?
8
- (self.class::TYPES & AdminPolicy::TYPES).any?
8
+ self.class::TYPES.intersect?(AdminPolicy::TYPES)
9
9
  end
10
10
 
11
11
  def collection?
12
- (self.class::TYPES & Collection::TYPES).any?
12
+ self.class::TYPES.intersect?(Collection::TYPES)
13
13
  end
14
14
 
15
15
  def dro?
16
- (self.class::TYPES & DRO::TYPES).any?
16
+ self.class::TYPES.intersect?(DRO::TYPES)
17
17
  end
18
18
 
19
19
  def file?
20
- (self.class::TYPES & File::TYPES).any?
20
+ self.class::TYPES.intersect?(File::TYPES)
21
21
  end
22
22
 
23
23
  def file_set?
24
- (self.class::TYPES & FileSet::TYPES).any?
24
+ self.class::TYPES.intersect?(FileSet::TYPES)
25
25
  end
26
26
  end
27
27
  end
@@ -97,7 +97,7 @@ module Cocina
97
97
  if parallel_name_values.size == 1
98
98
  contrib_name_value_slice = Cocina::Models::Builders::NameTitleGroupBuilder.value_slices(parallel_name_values.first)
99
99
  name_title_group = name_title_vals_index[contrib_name_value_slice]&.values&.first
100
- write_name_from_parallel(contributor, contributor.name.first, parallel_name_values, name_title_group, nil)
100
+ write_name_from_parallel(contributor, contributor.name.first, parallel_name_values.first, name_title_group, nil)
101
101
  elsif parallel_name_values.size == 2 && display_type_parallel_name
102
102
  contrib_name_value_slice = Cocina::Models::Builders::NameTitleGroupBuilder.value_slices(parallel_name_values.first)
103
103
  name_title_group = name_title_vals_index[contrib_name_value_slice]&.values&.first
@@ -91,8 +91,8 @@ module Cocina
91
91
 
92
92
  def geographic_and_geographic_code?(subject, subject_values)
93
93
  subject.type == 'place' &&
94
- subject_values.count(&:value) == 1 &&
95
- subject_values.count(&:code) == 1
94
+ subject_values.one?(&:value) &&
95
+ subject_values.one?(&:code)
96
96
  end
97
97
 
98
98
  # rubocop:disable Metrics/CyclomaticComplexity
@@ -7,9 +7,9 @@ module Cocina
7
7
  extend ActiveSupport::Concern
8
8
 
9
9
  class_methods do
10
- def new(attributes = default_attributes, safe = false, validate = true, &block)
10
+ def new(attributes = default_attributes, safe = false, validate = true, &)
11
11
  Validators::Validator.validate(self, attributes) if validate
12
- super(attributes, safe, &block)
12
+ super(attributes, safe, &)
13
13
  end
14
14
  end
15
15
 
@@ -61,13 +61,13 @@ module Cocina
61
61
  end
62
62
 
63
63
  def dro?
64
- (clazz::TYPES & DRO::TYPES).any?
64
+ clazz::TYPES.intersect?(DRO::TYPES)
65
65
  rescue NameError
66
66
  false
67
67
  end
68
68
 
69
69
  def collection?
70
- (clazz::TYPES & Collection::TYPES).any?
70
+ clazz::TYPES.intersect?(Collection::TYPES)
71
71
  rescue NameError
72
72
  false
73
73
  end
@@ -33,7 +33,7 @@ module Cocina
33
33
  end
34
34
 
35
35
  def dro?
36
- (clazz::TYPES & DRO::TYPES).any?
36
+ clazz::TYPES.intersect?(DRO::TYPES)
37
37
  rescue NameError
38
38
  false
39
39
  end
@@ -62,22 +62,30 @@ module Cocina
62
62
  end
63
63
 
64
64
  def validate_values_for_multiples(hash, path)
65
- return unless hash.count { |key, value| %i[value groupedValue structuredValue parallelValue].include?(key) && value.present? } > 1
65
+ return unless hash.count { |key, value| %w[value groupedValue structuredValue parallelValue].include?(key) && value.present? } > 1
66
66
 
67
67
  error_paths_multiple << path_to_s(path)
68
68
  end
69
69
 
70
70
  def validate_title_type(hash, path)
71
71
  # only apply to title.structuredValue, title.parallelValue.structuredValue, or relatedResource.title with a value
72
- return unless hash[:value] && (path.first == :title || related_resource_title?(path)) && path.include?(:structuredValue)
72
+ return unless hash[:value] && (structured_value_title?(path) || related_resource_title?(path))
73
73
 
74
74
  # if there is a "value" key, make sure there is also a "type" key, only for title.structuredValue
75
75
  error_paths_missing_title_type << path_to_s(path) unless hash[:type]
76
76
  end
77
77
 
78
78
  def related_resource_title?(path)
79
- # title is directly within relatedResource, e.g [:relatedResource, 0, :title, 0, :structuredValue, 0])
80
- path.first == :relatedResource && path[2] == :title
79
+ # title is within relatedResource, e.g ["relatedResource", 0, "title", 0, "structuredValue", 0])
80
+ structured_value_path = path[4] == 'structuredValue' || (path[4] == 'parallelValue' && path[6] == 'structuredValue')
81
+ path.first == 'relatedResource' && path[2] == 'title' && structured_value_path
82
+ end
83
+
84
+ def structured_value_title?(path)
85
+ # title path includes a structuredValue directly or within a parallelValue
86
+ # e.g. ["title", 0, "structuredValue", 0] or ["title", 0, "parallelValue", 0, "structuredValue", 0])
87
+ structured_value_path = path[2] == 'structuredValue' || (path[2] == 'parallelValue' && path[4] == 'structuredValue')
88
+ path.first == 'title' && structured_value_path
81
89
  end
82
90
 
83
91
  def path_to_s(path)
@@ -32,7 +32,7 @@ module Cocina
32
32
  end
33
33
 
34
34
  def dro?
35
- (clazz::TYPES & DRO::TYPES).any?
35
+ clazz::TYPES.intersect?(DRO::TYPES)
36
36
  rescue NameError
37
37
  false
38
38
  end
@@ -28,7 +28,7 @@ module Cocina
28
28
  attr_reader :clazz, :attributes
29
29
 
30
30
  def dro?
31
- (clazz::TYPES & DRO::TYPES).any? && attributes[:externalIdentifier].present?
31
+ clazz::TYPES.intersect?(DRO::TYPES) && attributes[:externalIdentifier].present?
32
32
  rescue NameError
33
33
  false
34
34
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Cocina
4
4
  module Models
5
- VERSION = '0.106.0'
5
+ VERSION = '0.107.1'
6
6
  end
7
7
  end
@@ -80,8 +80,8 @@ module Cocina
80
80
 
81
81
  REQUEST_ADMIN_POLICY_DEFAULTS = ADMIN_POLICY_DEFAULTS.except(:id)
82
82
 
83
- def self.build_dro_properties(id:, **kwargs)
84
- build_request_dro_properties(**kwargs)
83
+ def self.build_dro_properties(id:, **)
84
+ build_request_dro_properties(**)
85
85
  .merge(externalIdentifier: id)
86
86
  .tap do |props|
87
87
  props[:description][:purl] = "https://purl.stanford.edu/#{id.delete_prefix('druid:')}"
@@ -134,8 +134,8 @@ module Cocina
134
134
  Cocina::Models.build_request(build_request_dro_properties(**REQUEST_DRO_DEFAULTS.merge(attributes)))
135
135
  end
136
136
 
137
- def self.build_collection_properties(id:, **kwargs)
138
- build_request_collection_properties(**kwargs)
137
+ def self.build_collection_properties(id:, **)
138
+ build_request_collection_properties(**)
139
139
  .merge(externalIdentifier: id)
140
140
  .tap do |props|
141
141
  props[:description][:purl] = "https://purl.stanford.edu/#{id.delete_prefix('druid:')}"
@@ -194,8 +194,8 @@ module Cocina
194
194
  Cocina::Models.build_request(build_request_admin_policy_properties(**REQUEST_ADMIN_POLICY_DEFAULTS.merge(attributes)))
195
195
  end
196
196
 
197
- def self.build_admin_policy_properties(id:, **kwargs)
198
- build_request_admin_policy_properties(**kwargs)
197
+ def self.build_admin_policy_properties(id:, **)
198
+ build_request_admin_policy_properties(**)
199
199
  .merge(externalIdentifier: id)
200
200
  .tap do |props|
201
201
  props[:description][:purl] = "https://purl.stanford.edu/#{id.delete_prefix('druid:')}"
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cocina-models
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.106.0
4
+ version: 0.107.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Coyne
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2025-09-19 00:00:00.000000000 Z
10
+ date: 2025-10-22 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: activesupport
@@ -528,7 +528,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
528
528
  requirements:
529
529
  - - ">="
530
530
  - !ruby/object:Gem::Version
531
- version: '3.0'
531
+ version: '3.4'
532
532
  required_rubygems_version: !ruby/object:Gem::Requirement
533
533
  requirements:
534
534
  - - ">="