cocina-models 0.101.1 → 0.103.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 +4 -4
- data/.rubocop.yml +9 -0
- data/Gemfile.lock +7 -7
- data/README.md +29 -17
- data/lib/cocina/models/builders/title_builder.rb +10 -6
- data/lib/cocina/models/mapping/to_mods/title.rb +30 -20
- data/lib/cocina/models/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 439375f55b48b22cc891dde1fb31519f9b08a42b9128894cf04f643a5644a027
|
4
|
+
data.tar.gz: 7f7a68b92f272e867d6243485d4ed68c1741128c6e93785a1879b811ca0ece63
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e23f7d1949ee04c1dba3bea6b64620f0ad816bde8ee02666e8af6b3c3057c86d326f586f696572e8cf0f3ba01c191444cd7501f81a8eede6fcaa45682b69fdfb
|
7
|
+
data.tar.gz: 1b215531fa86e0f049f7c38bd8819c3ae47f849d66b7217da376761e09131f1c23e60b448ae404c66ee6024f6b4f570966a07398719360739182c99e5a2649d1
|
data/.rubocop.yml
CHANGED
@@ -512,3 +512,12 @@ Style/ItAssignment: # new in 1.70
|
|
512
512
|
Enabled: true
|
513
513
|
Style/RedundantFormat: # new in 1.72
|
514
514
|
Enabled: true
|
515
|
+
|
516
|
+
Style/ComparableBetween: # new in 1.74
|
517
|
+
Enabled: true
|
518
|
+
Style/HashFetchChain: # new in 1.75
|
519
|
+
Enabled: true
|
520
|
+
Style/ItBlockParameter: # new in 1.75
|
521
|
+
Enabled: true
|
522
|
+
RSpec/IncludeExamples: # new in 3.6
|
523
|
+
Enabled: true
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
cocina-models (0.
|
4
|
+
cocina-models (0.103.1)
|
5
5
|
activesupport
|
6
6
|
deprecation
|
7
7
|
dry-struct (~> 1.0)
|
@@ -43,7 +43,7 @@ GEM
|
|
43
43
|
openapi_parser (~> 1.0)
|
44
44
|
rack (>= 1.5)
|
45
45
|
concurrent-ruby (1.3.5)
|
46
|
-
connection_pool (2.5.
|
46
|
+
connection_pool (2.5.2)
|
47
47
|
deprecation (1.1.0)
|
48
48
|
activesupport
|
49
49
|
diff-lcs (1.6.1)
|
@@ -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.
|
81
|
+
json (2.11.3)
|
82
82
|
json_schema (0.21.0)
|
83
83
|
jsonpath (1.1.5)
|
84
84
|
multi_json
|
@@ -88,12 +88,12 @@ GEM
|
|
88
88
|
mini_portile2 (2.8.8)
|
89
89
|
minitest (5.25.5)
|
90
90
|
multi_json (1.15.0)
|
91
|
-
nokogiri (1.18.
|
91
|
+
nokogiri (1.18.8)
|
92
92
|
mini_portile2 (~> 2.8.2)
|
93
93
|
racc (~> 1.4)
|
94
94
|
openapi_parser (1.0.0)
|
95
95
|
optimist (3.2.1)
|
96
|
-
parallel (1.
|
96
|
+
parallel (1.27.0)
|
97
97
|
parser (3.3.8.0)
|
98
98
|
ast (~> 2.4.1)
|
99
99
|
racc
|
@@ -120,7 +120,7 @@ GEM
|
|
120
120
|
rspec-support (3.13.2)
|
121
121
|
rspec_junit_formatter (0.6.0)
|
122
122
|
rspec-core (>= 2, < 4, != 2.12.0)
|
123
|
-
rubocop (1.75.
|
123
|
+
rubocop (1.75.3)
|
124
124
|
json (~> 2.3)
|
125
125
|
language_server-protocol (~> 3.17.0.2)
|
126
126
|
lint_roller (~> 1.1.0)
|
@@ -137,7 +137,7 @@ GEM
|
|
137
137
|
rubocop-rake (0.7.1)
|
138
138
|
lint_roller (~> 1.1)
|
139
139
|
rubocop (>= 1.72.1)
|
140
|
-
rubocop-rspec (3.
|
140
|
+
rubocop-rspec (3.6.0)
|
141
141
|
lint_roller (~> 1.1)
|
142
142
|
rubocop (~> 1.72, >= 1.72.1)
|
143
143
|
ruby-progressbar (1.13.0)
|
data/README.md
CHANGED
@@ -123,23 +123,28 @@ A patch change is a change that (1) does not affect the data model; (2) does not
|
|
123
123
|
|
124
124
|
A patch change can be released as part of regular dependency updates or selectively released for individual applications.
|
125
125
|
|
126
|
-
## Releasing major or minor change
|
127
|
-
|
128
|
-
NOTE: If dependency updates are about to be released, you have the option of shortening the process and stopping after Step 3. This is because Steps 4 onwards will be taken care of by the regular dependency updates process (basically the updating of cocina-models, dor-services-client and sdr-client as needed in the rest of the associated apps). You still do need to manually bump some gems and the pinned version of cocina-models in a couple apps and get those PRs approved and merged, as described in Steps 1-3 below.
|
129
|
-
|
130
|
-
IMPORTANT: If you do opt to skip steps 4 onward, you should NOT merge the cocina-models bump dor-services-app and sdr-api PRs you created in step 3 until you are ready to finish the dependency updates process. You can have them reviewed and approved, but if you merge, you will greatly increase the risk of issues if the main branch of DSA or sdr-api are deployed after steps 1-3 are complete but before the rest of the apps are updated to use the new cocina-models via regular dependency updates. The fix for this is to either roll-back DSA and sdr-api to the previous release tag, or proceed forwards with step 4-5.
|
126
|
+
## Releasing a major or minor change
|
131
127
|
|
132
128
|
Before you release a major or minor change, think about if this release will include new validations. Even if your change didn't make any changes that would affect validation, there may be other unreleased changes since the previous version of the gem was cut and released. Best practice is to scan back through the commit history until you get to the last version bump and see if there any significant changes that may affect validation.
|
133
129
|
|
134
130
|
If unsure, ask the team or ask for help to just run the validation report anyway (as described above).
|
135
131
|
|
132
|
+
### Partial release process
|
133
|
+
NOTE: If dependency updates are about to be released, you have the option of shortening the process and stopping after Step 3. This is because Steps 4 onwards will be taken care of by the regular dependency updates process (basically the updating of cocina-models, dor-services-client and sdr-client as needed in the rest of the associated apps). You still do need to manually bump some gems and the pinned version of cocina-models in the directly coupled apps and get those PRs approved and merged, as described in Steps 1-3 below.
|
134
|
+
|
135
|
+
IMPORTANT: If you do opt to skip steps 4 onward, you should NOT merge the dor-services-app and sdr-api PRs you created in step 3 until you are ready to finish the dependency updates process. You can have them reviewed and approved, but if you merge, you will greatly increase the risk of issues if the main branch of DSA or sdr-api are deployed after steps 1-3 are complete but before the rest of the apps are updated to use the new cocina-models via regular dependency updates. The fix for this is to either roll back DSA and sdr-api to the previous release tag, or proceed forwards with step 4-5.
|
136
|
+
|
136
137
|
### Step 0: Share intent to change the models
|
137
138
|
|
138
139
|
Send a note to `#dlss-infra-chg-mgmt` on Slack to let people know what is changing and when.
|
139
140
|
|
140
141
|
### Step 1: Cut the release
|
141
142
|
|
142
|
-
The release process is much like any other gem.
|
143
|
+
The release process is much like any other gem. While on main:
|
144
|
+
1. Bump the version in `lib/cocina/models/version.rb`
|
145
|
+
2. `bundle install` so that `Gemfile.lock` is updated.
|
146
|
+
3. Commit those changes.
|
147
|
+
4. Run:
|
143
148
|
```
|
144
149
|
bundle exec rake release
|
145
150
|
```
|
@@ -147,7 +152,11 @@ which pushes the gem to rubygems.org.
|
|
147
152
|
|
148
153
|
### Step 2: Update client gems coupled to the models
|
149
154
|
|
150
|
-
Release new versions of [sdr-client](https://github.com/sul-dlss/sdr-client) and [dor-services-client](https://github.com/sul-dlss/dor-services-client/)
|
155
|
+
Release new versions of [sdr-client](https://github.com/sul-dlss/sdr-client) and [dor-services-client](https://github.com/sul-dlss/dor-services-client/):
|
156
|
+
1. Pin the new cocina-models version in the clients' `gemspec` files.
|
157
|
+
2. Bump the version as described in each client's README release instructions.
|
158
|
+
|
159
|
+
Applications such as [Argo](https://github.com/sul-dlss/argo) and [Dor-Services-App](https://github.com/sul-dlss/dor-services-app) depend on these gems using the same models.
|
151
160
|
|
152
161
|
### Step 3: Update services directly coupled to the models
|
153
162
|
|
@@ -156,27 +165,31 @@ This list of services is known to include:
|
|
156
165
|
* [sul-dlss/sdr-api](https://github.com/sul-dlss/sdr-api)
|
157
166
|
* [sul-dlss/dor-services-app](https://github.com/sul-dlss/dor-services-app/)
|
158
167
|
|
159
|
-
**NOTE**: You can skip step 3A if there have not been any changes to the `cocina-models` OpenAPI spec since the prior release.
|
160
168
|
|
161
169
|
#### Step 3A: Update API specifications
|
162
170
|
|
163
|
-
|
171
|
+
**NOTE**: You can skip step 3A if there have not been any changes to the `cocina-models` OpenAPI spec since the prior release.
|
172
|
+
|
173
|
+
The cocina-models gem is used in applications that have an API specification that accepts Cocina models. Make sure that the `openapi.yml` for these two applications includes the `openapi.yml` schema changes made in cocina-models.
|
164
174
|
|
165
|
-
|
175
|
+
Copy and paste the cocina-models schemas to each project's `openapi.yml`. By convention, these schemas are listed first, followed by the application-specific schemas.
|
166
176
|
|
167
177
|
#### Step 3B: Bump gems and create the PRs
|
168
178
|
|
169
|
-
If
|
179
|
+
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.
|
170
180
|
|
171
|
-
|
181
|
+
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.
|
172
183
|
|
173
184
|
#### Step 3C: Merge 'em
|
174
185
|
|
175
|
-
Get the directly coupled services PRs merged before the deploy in step 5.
|
186
|
+
Get the directly coupled services PRs merged before the deploy in step 5.
|
187
|
+
|
188
|
+
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.
|
176
189
|
|
177
190
|
### Step 4: Update other dependent applications
|
178
191
|
|
179
|
-
|
192
|
+
All applications that use cocina-models should be updated and released at the same time. "Cocina Level 2" describes this set of updates. The applications that use cocina-models are those in [this list](https://github.com/sul-dlss/access-update-scripts/blob/master/infrastructure/projects.yml) that are NOT marked with `cocina_level2: false`.
|
180
193
|
|
181
194
|
There are scripts to help with updating other dependent applications:
|
182
195
|
|
@@ -192,14 +205,13 @@ If for some reason the above method does not work, the sul-dlss/access-update-sc
|
|
192
205
|
```
|
193
206
|
REPOS_PATH=infrastructure GH_ACCESS_TOKEN=abc123 COCINA_LEVEL2= ./merge-all.rb
|
194
207
|
```
|
195
|
-
### Step 5: Deploy
|
208
|
+
### Step 5: Deploy and test
|
196
209
|
|
210
|
+
#### Step 5A: Deploy to Stage or QA
|
197
211
|
[sul-dlss/sdr-deploy](https://github.com/sul-dlss/sdr-deploy) has a flag (-c) in the deploy script to limit deploys to cocina dependent applications. Refer to instructions in the [sdr-deploy/README](https://github.com/sul-dlss/sdr-deploy/blob/main/README.md#only-deploy-repos-related-to-cocina-models-update).
|
198
212
|
|
199
213
|
Note that running the integration tests is currently the best way we have to check for unintended effects and/or bugs when rolling out cocina-models changes.
|
200
214
|
|
201
|
-
#### Step 5A: Deploy to QA and/or Stage
|
202
|
-
|
203
215
|
#### Step 5B: Run infrastructure_integration_tests
|
204
216
|
|
205
217
|
It is safest to ensure _all_ the integration tests run cleanly. However, patch releases of cocina-models may only warrant running individual tests that exercise the changes.
|
@@ -38,9 +38,11 @@ module Cocina
|
|
38
38
|
# the "full title" is the title WITH subtitle, part name, etc. We want to able able to index it separately so
|
39
39
|
# we can boost matches on it in search results (boost matching this string higher than other titles present)
|
40
40
|
# @param [Array<Cocina::Models::Title,Cocina::Models::DescriptiveValue>] titles the titles to consider
|
41
|
+
# @param [Array<Cocina::Models::FolioCatalogLink>] catalog_links the folio catalog links to check for digital serials part labels
|
41
42
|
# @return [Array<String>] the full title value(s) for Solr - array due to possible parallelValue
|
42
|
-
def self.full_title(titles)
|
43
|
-
|
43
|
+
def self.full_title(titles, catalog_links: [])
|
44
|
+
part_label = catalog_links.find { |link| link.catalog == 'folio' }&.partLabel
|
45
|
+
[new(strategy: :first, add_punctuation: false, only_one_parallel_value: false, part_label: part_label).build(titles)].flatten.compact
|
44
46
|
end
|
45
47
|
|
46
48
|
# "additional titles" are all title data except for full_title. We want to able able to index it separately so
|
@@ -68,7 +70,6 @@ module Cocina
|
|
68
70
|
end
|
69
71
|
|
70
72
|
# @param [Array<Cocina::Models::Title>] cocina_titles the titles to consider
|
71
|
-
# @param [String, nil] part_label the partLabel to add to the title for digital serials
|
72
73
|
# @return [String, Array] the title value for Solr - for :first strategy, a string; for :all strategy, an array
|
73
74
|
# (e.g. title displayed in blacklight search results vs boosting values for search result rankings)
|
74
75
|
#
|
@@ -78,7 +79,8 @@ module Cocina
|
|
78
79
|
cocina_title = other_title(cocina_titles) if cocina_title.blank?
|
79
80
|
if strategy == :first
|
80
81
|
result = extract_title(cocina_title)
|
81
|
-
add_part_label(result)
|
82
|
+
result = add_part_label(result) if part_label.present?
|
83
|
+
result
|
82
84
|
else
|
83
85
|
result = cocina_titles.map { |ctitle| extract_title(ctitle) }.flatten
|
84
86
|
if only_one_parallel_value? && result.length == 1
|
@@ -106,8 +108,8 @@ module Cocina
|
|
106
108
|
|
107
109
|
def add_part_label(title)
|
108
110
|
# when a digital serial
|
109
|
-
title =
|
110
|
-
title
|
111
|
+
title = title.sub(/[ .,]*$/, '').to_s
|
112
|
+
add_punctuation? ? "#{title}, #{part_label}" : "#{title} #{part_label}"
|
111
113
|
end
|
112
114
|
|
113
115
|
def extract_title(cocina_title)
|
@@ -245,6 +247,8 @@ module Cocina
|
|
245
247
|
padding = non_sorting_padding(cocina_title, value)
|
246
248
|
result = add_non_sorting_value(result, value, padding)
|
247
249
|
when 'part name', 'part number'
|
250
|
+
# even if there is a partLabel, use any existing structuredValue
|
251
|
+
# part name/number that remains for non-digital serials purposes
|
248
252
|
if part_name_number.blank?
|
249
253
|
part_name_number = part_name_number(cocina_title.structuredValue)
|
250
254
|
result = if !add_punctuation?
|
@@ -11,30 +11,29 @@ module Cocina
|
|
11
11
|
TAG_NAME = Cocina::Models::Mapping::FromMods::Title::TYPES.invert.merge('activity dates' => 'date').freeze
|
12
12
|
NAME_TYPES = ['name', 'forename', 'surname', 'life dates', 'term of address'].freeze
|
13
13
|
|
14
|
+
def self.write(...)
|
15
|
+
new(...).write
|
16
|
+
end
|
17
|
+
|
14
18
|
# @params [Nokogiri::XML::Builder] xml
|
15
19
|
# @params [Array<Cocina::Models::Title>] titles
|
20
|
+
# @params [IdGenerator] id_generator
|
16
21
|
# @params [Array<Cocina::Models::Contributor>] contributors
|
17
22
|
# @params [Hash] additional_attrs for title
|
18
|
-
# @params [
|
19
|
-
|
20
|
-
|
21
|
-
id_generator: id_generator).write
|
22
|
-
end
|
23
|
-
|
24
|
-
def initialize(xml:, titles:, additional_attrs:, contributors: [], id_generator: {})
|
23
|
+
# @params [Array<Cocina::Models::CatalogLink>] catalog_links a list of catalog
|
24
|
+
# links which may contain part label and sort key information
|
25
|
+
def initialize(xml:, titles:, id_generator:, contributors: [], additional_attrs: {}, catalog_links: []) # rubocop:disable Metrics/ParameterLists
|
25
26
|
@xml = xml
|
26
27
|
@titles = titles
|
28
|
+
@id_generator = id_generator
|
27
29
|
@contributors = contributors
|
28
|
-
@name_title_vals_index = {}
|
29
30
|
@additional_attrs = additional_attrs
|
30
|
-
@
|
31
|
+
@catalog_links = catalog_links
|
32
|
+
@name_title_vals_index = {}
|
31
33
|
end
|
32
34
|
|
33
|
-
# rubocop:disable Metrics/AbcSize
|
34
|
-
|
35
|
-
# rubocop:disable Metrics/CyclomaticComplexity
|
36
|
-
def write
|
37
|
-
titles.each do |title|
|
35
|
+
def write # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
|
36
|
+
titles.each do |title| # rubocop:disable Metrics/BlockLength
|
38
37
|
name_title_vals_index = name_title_vals_index_for(title)
|
39
38
|
|
40
39
|
if title.valueAt
|
@@ -78,13 +77,10 @@ module Cocina
|
|
78
77
|
end
|
79
78
|
end
|
80
79
|
end
|
81
|
-
# rubocop:enable Metrics/AbcSize
|
82
|
-
# rubocop:enable Metrics/BlockLength
|
83
|
-
# rubocop:enable Metrics/CyclomaticComplexity
|
84
80
|
|
85
81
|
private
|
86
82
|
|
87
|
-
attr_reader :xml, :titles, :contributors, :name_title_vals_index, :id_generator, :additional_attrs
|
83
|
+
attr_reader :xml, :titles, :contributors, :name_title_vals_index, :id_generator, :additional_attrs, :catalog_links
|
88
84
|
|
89
85
|
def write_xlink(title:)
|
90
86
|
attrs = { 'xlink:href' => title.valueAt }
|
@@ -173,10 +169,24 @@ module Cocina
|
|
173
169
|
title_info_attrs = title_info_attrs_for(title).merge(title_info_attrs)
|
174
170
|
xml.titleInfo(with_uri_info(title, title_info_attrs)) do
|
175
171
|
title_parts = flatten_structured_value(title)
|
176
|
-
|
172
|
+
write_title_parts!(title_parts: title_parts_without_names(title_parts), title: title)
|
173
|
+
end
|
174
|
+
end
|
177
175
|
|
178
|
-
|
176
|
+
def write_title_parts!(title_parts:, title:)
|
177
|
+
# If title parts contain the main title and a part label has been
|
178
|
+
# recorded in a catalog link, short-circuit the usual title part
|
179
|
+
# parsing and pull the part label from the catalog link instead of
|
180
|
+
# from descriptive metadata
|
181
|
+
if (main_title = title_parts.find { |part| part.type == 'main title' }&.value) &&
|
182
|
+
(part_label = catalog_links.find { |link| link.catalog == 'folio' && link.partLabel.present? }&.partLabel)
|
183
|
+
xml.title(main_title)
|
184
|
+
xml.partNumber(part_label)
|
185
|
+
else
|
186
|
+
title_parts.each do |title_part|
|
179
187
|
title_type = tag_name_for(title_part)
|
188
|
+
raise "Unknown title type for: #{title_part.to_h}" unless title_type
|
189
|
+
|
180
190
|
title_value = title_value_for(title_part, title_type, title)
|
181
191
|
xml.public_send(title_type, title_value) if title_part.note.blank?
|
182
192
|
end
|
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.
|
4
|
+
version: 0.103.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Justin Coyne
|
8
8
|
bindir: exe
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-04-
|
10
|
+
date: 2025-04-29 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: activesupport
|