windoo 1.0.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 +7 -0
- data/CHANGES.md +9 -0
- data/LICENSE.txt +177 -0
- data/README.md +222 -0
- data/lib/windoo/base_classes/array_manager.rb +335 -0
- data/lib/windoo/base_classes/criteria_manager.rb +327 -0
- data/lib/windoo/base_classes/criterion.rb +226 -0
- data/lib/windoo/base_classes/json_object.rb +472 -0
- data/lib/windoo/configuration.rb +221 -0
- data/lib/windoo/connection/actions.rb +152 -0
- data/lib/windoo/connection/attributes.rb +156 -0
- data/lib/windoo/connection/connect.rb +402 -0
- data/lib/windoo/connection/constants.rb +55 -0
- data/lib/windoo/connection/token.rb +489 -0
- data/lib/windoo/connection.rb +92 -0
- data/lib/windoo/converters.rb +31 -0
- data/lib/windoo/exceptions.rb +34 -0
- data/lib/windoo/mixins/api_collection.rb +408 -0
- data/lib/windoo/mixins/constants.rb +43 -0
- data/lib/windoo/mixins/default_connection.rb +75 -0
- data/lib/windoo/mixins/immutable.rb +34 -0
- data/lib/windoo/mixins/loading.rb +38 -0
- data/lib/windoo/mixins/patch/component.rb +102 -0
- data/lib/windoo/mixins/software_title/extension_attribute.rb +106 -0
- data/lib/windoo/mixins/utility.rb +23 -0
- data/lib/windoo/objects/capability.rb +82 -0
- data/lib/windoo/objects/capability_manager.rb +52 -0
- data/lib/windoo/objects/component.rb +99 -0
- data/lib/windoo/objects/component_criteria_manager.rb +26 -0
- data/lib/windoo/objects/component_criterion.rb +66 -0
- data/lib/windoo/objects/extension_attribute.rb +149 -0
- data/lib/windoo/objects/kill_app.rb +92 -0
- data/lib/windoo/objects/kill_app_manager.rb +89 -0
- data/lib/windoo/objects/patch.rb +235 -0
- data/lib/windoo/objects/patch_manager.rb +240 -0
- data/lib/windoo/objects/requirement.rb +85 -0
- data/lib/windoo/objects/requirement_manager.rb +52 -0
- data/lib/windoo/objects/software_title.rb +407 -0
- data/lib/windoo/validate.rb +548 -0
- data/lib/windoo/version.rb +15 -0
- data/lib/windoo/zeitwerk_config.rb +158 -0
- data/lib/windoo.rb +56 -0
- metadata +141 -0
@@ -0,0 +1,89 @@
|
|
1
|
+
# Copyright 2025 Pixar
|
2
|
+
#
|
3
|
+
# Licensed under the terms set forth in the LICENSE.txt file available at
|
4
|
+
# at the root of this project.
|
5
|
+
#
|
6
|
+
|
7
|
+
# frozen_string_literal: true
|
8
|
+
|
9
|
+
module Windoo
|
10
|
+
|
11
|
+
# An {Windoo::BaseClasses::ArrayManager ArrayManager} for dealing with the
|
12
|
+
# {Windoo::KillApp KillApps} of a {Windoo::Patch Patch}
|
13
|
+
#
|
14
|
+
# An instance of this is returned by {Patch#killApps}
|
15
|
+
class KillAppManager < Windoo::BaseClasses::ArrayManager
|
16
|
+
|
17
|
+
# Constants
|
18
|
+
##################################
|
19
|
+
|
20
|
+
MEMBER_CLASS = Windoo::KillApp
|
21
|
+
|
22
|
+
# Public Instance Methods
|
23
|
+
####################################
|
24
|
+
|
25
|
+
# Add a killApp to this patch
|
26
|
+
#
|
27
|
+
# A killApp idetifies apps that cannot be running while this patch
|
28
|
+
# is installed. If the user is voluntarily applying the patch, they
|
29
|
+
# will be asked to quit the killApp. If the patch is being applied
|
30
|
+
# automatically, it will be killed automatically.
|
31
|
+
#
|
32
|
+
# @param appName [String] The name of the application that
|
33
|
+
# cannot be running to install this patch. e.g. Safari.app
|
34
|
+
#
|
35
|
+
# @param bundleId [String] The bundle id of the application
|
36
|
+
# that cannot be running to install this patch,
|
37
|
+
# e.g. com.apple.Safari
|
38
|
+
#
|
39
|
+
# @return [Integer] The id of the new killApp
|
40
|
+
#
|
41
|
+
def add_killApp(appName:, bundleId:)
|
42
|
+
new_ka = Windoo::KillApp.create(
|
43
|
+
cnx: container.cnx,
|
44
|
+
container: container,
|
45
|
+
appName: appName,
|
46
|
+
bundleId: bundleId
|
47
|
+
)
|
48
|
+
|
49
|
+
# call the method from our superclass to add it to the array
|
50
|
+
add_member new_ka
|
51
|
+
new_ka.primary_id
|
52
|
+
end
|
53
|
+
|
54
|
+
# Update the details of an existing killApp
|
55
|
+
#
|
56
|
+
# Values not set in the params are left unchanged
|
57
|
+
#
|
58
|
+
# @param id [Integer] The killAppId of the desired killApp in the array
|
59
|
+
#
|
60
|
+
# @param attribs [Hash] The attribute(s) to update. See #add_killApp
|
61
|
+
#
|
62
|
+
# @return [Integer] The id of the updated killApp
|
63
|
+
#
|
64
|
+
def update_killApp(id, **attribs)
|
65
|
+
ka = update_member(id, **attribs)
|
66
|
+
ka.killAppId
|
67
|
+
end
|
68
|
+
|
69
|
+
# Delete a killApp
|
70
|
+
#
|
71
|
+
# @param id [Integer] The killAppId of the desired killApp in the array
|
72
|
+
#
|
73
|
+
# @return [Integer] The id of the deleted killApp
|
74
|
+
#
|
75
|
+
def delete_killApp(id)
|
76
|
+
delete_member(id).deleted_id
|
77
|
+
end
|
78
|
+
|
79
|
+
# Delete all the killApps
|
80
|
+
#
|
81
|
+
# @return [void]
|
82
|
+
#
|
83
|
+
def delete_all_killApps
|
84
|
+
delete_all_members
|
85
|
+
end
|
86
|
+
|
87
|
+
end # module KillAppManager
|
88
|
+
|
89
|
+
end # module Windoo
|
@@ -0,0 +1,235 @@
|
|
1
|
+
# Copyright 2025 Pixar
|
2
|
+
#
|
3
|
+
# Licensed under the terms set forth in the LICENSE.txt file available at
|
4
|
+
# at the root of this project.
|
5
|
+
|
6
|
+
# frozen_string_literal: true
|
7
|
+
|
8
|
+
module Windoo
|
9
|
+
|
10
|
+
# A patch represents a specific version of a Software Title.
|
11
|
+
class Patch < Windoo::BaseClasses::JSONObject
|
12
|
+
|
13
|
+
# Mixins
|
14
|
+
######################
|
15
|
+
|
16
|
+
include Windoo::Mixins::APICollection
|
17
|
+
include Windoo::Mixins::Patch::Component
|
18
|
+
|
19
|
+
# Constants
|
20
|
+
######################
|
21
|
+
|
22
|
+
RSRC_PATH = 'patches'
|
23
|
+
|
24
|
+
CONTAINER_CLASS = Windoo::SoftwareTitle
|
25
|
+
|
26
|
+
# Attributes
|
27
|
+
######################
|
28
|
+
|
29
|
+
JSON_ATTRIBUTES = {
|
30
|
+
|
31
|
+
# @!attribute patchId
|
32
|
+
# @return [Integer] The id number of this patch
|
33
|
+
patchId: {
|
34
|
+
class: :Integer,
|
35
|
+
identifier: :primary,
|
36
|
+
do_not_send: true,
|
37
|
+
readonly: true
|
38
|
+
},
|
39
|
+
|
40
|
+
# @!attribute softwareTitleId
|
41
|
+
# @return [Integer] The id number of the title which uses this patch
|
42
|
+
softwareTitleId: {
|
43
|
+
class: :Integer,
|
44
|
+
do_not_send: true,
|
45
|
+
readonly: true
|
46
|
+
},
|
47
|
+
|
48
|
+
# @!attribute absoluteOrderId
|
49
|
+
# @return [Integer] The zero-based position of this patch among
|
50
|
+
# all those used by the title. Should be identical to the Array index
|
51
|
+
# of this patch in the #patches attribute of the SoftwareTitle
|
52
|
+
# instance that uses this patch.
|
53
|
+
# NOTE: This can only be changed via methods called on the
|
54
|
+
# PatchManager that contains the patch.
|
55
|
+
absoluteOrderId: {
|
56
|
+
class: :Integer,
|
57
|
+
readonly: true
|
58
|
+
},
|
59
|
+
|
60
|
+
# @!attribute enabled
|
61
|
+
# @return [Boolean] Is this patch enabled?
|
62
|
+
enabled: {
|
63
|
+
class: :Boolean
|
64
|
+
},
|
65
|
+
|
66
|
+
# @!attribute version
|
67
|
+
# @return [String] The version on the title installed by this patch
|
68
|
+
version: {
|
69
|
+
class: :String,
|
70
|
+
required: true
|
71
|
+
},
|
72
|
+
|
73
|
+
# @!attribute releaseDate
|
74
|
+
# @return [Time] When this patch was released
|
75
|
+
releaseDate: {
|
76
|
+
class: :Time,
|
77
|
+
required: true,
|
78
|
+
to_ruby: :to_time,
|
79
|
+
to_api: :time_to_api
|
80
|
+
},
|
81
|
+
|
82
|
+
# @!attribute standalone
|
83
|
+
# @return [Boolean] Can this patch be installed as an initial installation?
|
84
|
+
# If not, it must be applied to an already-installed version of this title.
|
85
|
+
# NOTE: This is for reporting only, it is not used in patch policies
|
86
|
+
standalone: {
|
87
|
+
class: :Boolean
|
88
|
+
},
|
89
|
+
|
90
|
+
# @!attribute minimumOperatingSystem
|
91
|
+
# @return [String] The lowest version of the OS that can run this patch
|
92
|
+
# NOTE: This is for reporting only. If there is a minimumOperatingSystem
|
93
|
+
# You'll still need to specify it in the capabilities for this patch.
|
94
|
+
minimumOperatingSystem: {
|
95
|
+
class: :String,
|
96
|
+
required: true
|
97
|
+
},
|
98
|
+
|
99
|
+
# @!attribute reboot
|
100
|
+
# @return [Boolean] Does the patch require a reboot after installation?
|
101
|
+
reboot: {
|
102
|
+
class: :Boolean
|
103
|
+
},
|
104
|
+
|
105
|
+
# @!attribute killApps
|
106
|
+
# @return [Array<Windoo::KillApp>] The apps that must be quit before
|
107
|
+
# installing this patch
|
108
|
+
killApps: {
|
109
|
+
class: Windoo::KillAppManager,
|
110
|
+
do_not_send: true,
|
111
|
+
readonly: true
|
112
|
+
},
|
113
|
+
|
114
|
+
# @!attribute components
|
115
|
+
# @return [Array<Windoo::Component>] The components of this patch.
|
116
|
+
# NOTE: there can be only one!
|
117
|
+
component: {
|
118
|
+
class: Windoo::Component,
|
119
|
+
do_not_send: true,
|
120
|
+
readonly: true
|
121
|
+
},
|
122
|
+
|
123
|
+
# @!attribute capabilities
|
124
|
+
# @return [Array<Windoo::CapabilityManager>] The criteria which identify
|
125
|
+
# computers capable of running, and thus installing, this patch.
|
126
|
+
capabilities: {
|
127
|
+
class: Windoo::CapabilityManager,
|
128
|
+
do_not_send: true,
|
129
|
+
readonly: true
|
130
|
+
}
|
131
|
+
|
132
|
+
}.freeze
|
133
|
+
|
134
|
+
# Constructor
|
135
|
+
######################
|
136
|
+
|
137
|
+
def initialize(**init_data)
|
138
|
+
super
|
139
|
+
@capabilities = Windoo::CapabilityManager.new @capabilities, container: self
|
140
|
+
@killApps = Windoo::KillAppManager.new @killApps, container: self
|
141
|
+
end
|
142
|
+
|
143
|
+
# Public Instance Methods
|
144
|
+
##########################################
|
145
|
+
|
146
|
+
# Enable this Patch
|
147
|
+
def enable
|
148
|
+
return if enabled?
|
149
|
+
|
150
|
+
if capabilities.empty? || component.nil? || component.criteria.empty?
|
151
|
+
raise Windoo::MissingDataError,
|
152
|
+
'Patches must have at least one capability, and a component with at least one criterion, before they can be enabled'
|
153
|
+
end
|
154
|
+
|
155
|
+
self.enabled = true
|
156
|
+
|
157
|
+
# Update the currentVersion of our title to this version if this patch is the
|
158
|
+
# newest enabled patch
|
159
|
+
container.currentVersion = version if container.patches.all_enabled.first == self
|
160
|
+
|
161
|
+
:enabled
|
162
|
+
end
|
163
|
+
|
164
|
+
# Disable this Patch
|
165
|
+
def disable
|
166
|
+
return unless enabled?
|
167
|
+
|
168
|
+
self.enabled = false
|
169
|
+
:disabled
|
170
|
+
end
|
171
|
+
|
172
|
+
# Allow array managers to change the absoluteOrderId.
|
173
|
+
#
|
174
|
+
# @todo Only allow this to be called from a PatchManager.
|
175
|
+
#
|
176
|
+
# @param new_index [Integer] The new, zero-based index for this
|
177
|
+
# criterion.
|
178
|
+
#
|
179
|
+
# @return [Integer] the id of the updated criterion
|
180
|
+
#
|
181
|
+
def absoluteOrderId=(new_index)
|
182
|
+
new_value = validate_attr :absoluteOrderId, new_index
|
183
|
+
return if new_value == @absoluteOrderId
|
184
|
+
|
185
|
+
update_on_server :absoluteOrderId, new_value
|
186
|
+
@absoluteOrderId = new_value
|
187
|
+
end
|
188
|
+
|
189
|
+
# Update the local absoluteOrderId without updating it on
|
190
|
+
# the server.
|
191
|
+
#
|
192
|
+
# Why??
|
193
|
+
#
|
194
|
+
# Because changing the value on the server for one criterion
|
195
|
+
# using #absoluteOrderId= will automatically change it on the
|
196
|
+
# server for all the others.
|
197
|
+
#
|
198
|
+
# After changing one on the server and updating that one in the
|
199
|
+
# local array, the ArrayManager will use this, without
|
200
|
+
# updating the server, to change the value for all others in the
|
201
|
+
# array to match their array index.
|
202
|
+
#
|
203
|
+
# @todo Only allow this to be called from a PatchManager.
|
204
|
+
#
|
205
|
+
# @return [void]
|
206
|
+
def local_absoluteOrderId=(new_index)
|
207
|
+
@absoluteOrderId = new_index
|
208
|
+
end
|
209
|
+
|
210
|
+
# Private Instance Methods
|
211
|
+
##########################################
|
212
|
+
private
|
213
|
+
|
214
|
+
# See the section 'REQUIRED ITEMS WHEN MIXING IN'
|
215
|
+
# in the APICollection mixin.
|
216
|
+
def handle_create_response(post_response, container_id: nil)
|
217
|
+
@patchId = post_response[:patchId]
|
218
|
+
@absoluteOrderId = post_response[:absoluteOrderId]
|
219
|
+
|
220
|
+
@softwareTitleId = container_id
|
221
|
+
|
222
|
+
@patchId
|
223
|
+
end
|
224
|
+
|
225
|
+
# See the section 'REQUIRED ITEMS WHEN MIXING IN'
|
226
|
+
# in the APICollection mixin.
|
227
|
+
def handle_update_response(put_response)
|
228
|
+
@absoluteOrderId = put_response[:absoluteOrderId]
|
229
|
+
|
230
|
+
@patchId
|
231
|
+
end
|
232
|
+
|
233
|
+
end # class Patch
|
234
|
+
|
235
|
+
end # module Windoo
|
@@ -0,0 +1,240 @@
|
|
1
|
+
# Copyright 2025 Pixar
|
2
|
+
#
|
3
|
+
# Licensed under the terms set forth in the LICENSE.txt file available at
|
4
|
+
# at the root of this project.
|
5
|
+
#
|
6
|
+
|
7
|
+
# frozen_string_literal: true
|
8
|
+
|
9
|
+
module Windoo
|
10
|
+
|
11
|
+
# An {Windoo::BaseClasses::ArrayManager ArrayManager} for dealing with the
|
12
|
+
# {Windoo::Patch Patches} of a {Windoo::SoftwareTitle SoftwareTitle}
|
13
|
+
#
|
14
|
+
# An instance of this is returned by {SoftwareTitle#patches}
|
15
|
+
#
|
16
|
+
class PatchManager < Windoo::BaseClasses::ArrayManager
|
17
|
+
|
18
|
+
# Constants
|
19
|
+
####################################
|
20
|
+
|
21
|
+
MEMBER_CLASS = Windoo::Patch
|
22
|
+
|
23
|
+
# Public Instance Methods
|
24
|
+
####################################
|
25
|
+
|
26
|
+
# @return [Array<Windoo::Patch] An array of the currently enabled patches
|
27
|
+
############################
|
28
|
+
def all_enabled
|
29
|
+
@managed_array.select(&:enabled?)
|
30
|
+
end
|
31
|
+
|
32
|
+
# @return [Hash {Integer => String}] The Patch IDs => Version installed
|
33
|
+
# by the patch.
|
34
|
+
############################
|
35
|
+
def patchIds_to_versions
|
36
|
+
@managed_array.map { |p| [p.patchId, p.version] }.to_h
|
37
|
+
end
|
38
|
+
|
39
|
+
# @return [Hash {Integer => String}] The Versions => Patch ID installed
|
40
|
+
# by the patch.
|
41
|
+
############################
|
42
|
+
def versions_to_patchIds
|
43
|
+
@managed_array.map { |p| [p.version, p.patchId] }.to_h
|
44
|
+
end
|
45
|
+
|
46
|
+
# @return [Hash {Integer => String}] The Versions for this title
|
47
|
+
#
|
48
|
+
##################################
|
49
|
+
def all_versions
|
50
|
+
@managed_array.map(&:version)
|
51
|
+
end
|
52
|
+
|
53
|
+
# get a patch by id or version
|
54
|
+
#
|
55
|
+
# @param ident [Integer, String] the patchId or version to return
|
56
|
+
#
|
57
|
+
# @return [Windoo::Patch] the patch object for the ident
|
58
|
+
###########################
|
59
|
+
def patch(ident)
|
60
|
+
case ident
|
61
|
+
when Integer
|
62
|
+
find_by_attr(:patchId, ident)
|
63
|
+
when String
|
64
|
+
find_by_attr(:version, ident)
|
65
|
+
else
|
66
|
+
raise ArgumentError, 'ident must be an Integer patchId, or a String Version'
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# Add a Patch to this SoftwareTitle. NOTE: patches cannot be
|
71
|
+
# enabled when added, you must call 'enable' on them after creating
|
72
|
+
# any necessary sub-objects.
|
73
|
+
#
|
74
|
+
# Patches must be ordered from newest to oldest, and are indexed zero-based,
|
75
|
+
# like Ruby Arrays.
|
76
|
+
#
|
77
|
+
# By default, patches are added at the front, index 0,meaning the are the newest.
|
78
|
+
#
|
79
|
+
# To make the new patch appear later in the order, provide a zero-based
|
80
|
+
# integer as 'absoluteOrderId' (0, the first in the order, is the default).
|
81
|
+
# So to add this new patch as older than the first and second, use
|
82
|
+
# absoluteOrderId: 2
|
83
|
+
# All others will be adjusted automatically.
|
84
|
+
#
|
85
|
+
#
|
86
|
+
# @param version [String] The version of the title that is installed
|
87
|
+
# by this patch. Required.
|
88
|
+
#
|
89
|
+
# @param minimumOperatingSystem [String] The lowest OS version that
|
90
|
+
# this patch will run on. Required.
|
91
|
+
#
|
92
|
+
# @param releaseDate [Time, String] The date and time this patch
|
93
|
+
# became available. Will be stored as a UTC timestampe in ISO8601 format.
|
94
|
+
#
|
95
|
+
# @param reboot [Boolean] Does this patch require a reboot after installation?
|
96
|
+
#
|
97
|
+
# @param standalone [Boolean] Can this patch be installed as the initial
|
98
|
+
# install of this SoftwareTitle? If not, a previous version must already
|
99
|
+
# be installed before this one can be.
|
100
|
+
#
|
101
|
+
# @param absoluteOrderId [Integer] The zero-based position of this patch among
|
102
|
+
# all the others for this title. Ordered from newest to oldest. By default,
|
103
|
+
# this patch will be added at '0' the newest, first in the Array.
|
104
|
+
#
|
105
|
+
# @return [Integer] The id of the new Patch
|
106
|
+
############################
|
107
|
+
def add_patch(version:, minimumOperatingSystem:, releaseDate: nil, reboot: nil, standalone: nil, absoluteOrderId: 0)
|
108
|
+
new_patch = Windoo::Patch.create(
|
109
|
+
cnx: container.cnx,
|
110
|
+
container: container,
|
111
|
+
version: version,
|
112
|
+
minimumOperatingSystem: minimumOperatingSystem,
|
113
|
+
releaseDate: releaseDate,
|
114
|
+
reboot: reboot,
|
115
|
+
standalone: standalone,
|
116
|
+
absoluteOrderId: absoluteOrderId
|
117
|
+
)
|
118
|
+
|
119
|
+
# call the method from our superclass to add it to the array
|
120
|
+
add_member new_patch, index: absoluteOrderId
|
121
|
+
update_local_absoluteOrderIds
|
122
|
+
new_patch.patchId
|
123
|
+
end
|
124
|
+
|
125
|
+
# TODO: implement cloning? The clone resource
|
126
|
+
# just creates a bare one with no killApps, component or
|
127
|
+
# capabilities. So not sure its much of a win
|
128
|
+
# over doing it in ruby.
|
129
|
+
#
|
130
|
+
# def clone_patch(_patchId, new_version:)
|
131
|
+
# source_id = title.patches[-1].patchId
|
132
|
+
# new_version = '0.0.1a1'
|
133
|
+
# clone_url = "#{Windoo::Patch::RSRC_PATH}/#{source_id}/clone"
|
134
|
+
# data = Windoo.cnx.post clone_url, {version: new_version }.to_json
|
135
|
+
# newpatch = Windoo::Patch.new **data
|
136
|
+
# end
|
137
|
+
|
138
|
+
# Update a Patch in this SoftwareTitle.
|
139
|
+
# Do not use this to update absoluteOrderId, instead
|
140
|
+
# use #move_patch
|
141
|
+
#
|
142
|
+
# @param patchId [Integer] the id of the Patch to be updated.
|
143
|
+
#
|
144
|
+
# @param attribs [Hash] The attribute(s) to update. See #add_patch
|
145
|
+
#
|
146
|
+
# @return [Integer] The id of the updated Patch
|
147
|
+
############################
|
148
|
+
def update_patch(patchId, **attribs)
|
149
|
+
# TODO: use this to undo if we changed
|
150
|
+
# the absoluteOrderId but something about the
|
151
|
+
# API transaction failed
|
152
|
+
@managed_array.index { |p| p.patchId == patchId }
|
153
|
+
|
154
|
+
patch = update_member(patchId, **attribs)
|
155
|
+
|
156
|
+
if attribs[:absoluteOrderId]
|
157
|
+
move_member patch, index: patch.absoluteOrderId
|
158
|
+
update_local_absoluteOrderIds
|
159
|
+
end
|
160
|
+
|
161
|
+
patch.patchId
|
162
|
+
end
|
163
|
+
|
164
|
+
# Change the position of an existing patch in the array
|
165
|
+
# This just calls update_patch, with absoluteOrderId as
|
166
|
+
# the only attribute.
|
167
|
+
#
|
168
|
+
# @param patchId [Integer] The patchId of the patch to update.
|
169
|
+
#
|
170
|
+
# @param absoluteOrderId [Integer] The zero-based position to which you want to
|
171
|
+
# move the patch. So if you want to make it the third patch
|
172
|
+
# in the list, use 2.
|
173
|
+
#
|
174
|
+
# @return [Integer] the new absoluteOrderId
|
175
|
+
############################
|
176
|
+
def move_patch(patchId, absoluteOrderId:)
|
177
|
+
# Can't move it beyond the end of the array....
|
178
|
+
max_idx = @managed_array.size - 1
|
179
|
+
absoluteOrderId = max_idx if absoluteOrderId > max_idx
|
180
|
+
|
181
|
+
# ... or before the beginning
|
182
|
+
absoluteOrderId = 0 if absoluteOrderId.negative?
|
183
|
+
|
184
|
+
update_patch patchId, absoluteOrderId: absoluteOrderId
|
185
|
+
absoluteOrderId
|
186
|
+
end
|
187
|
+
|
188
|
+
# Delete a Patch from this SoftwareTitle
|
189
|
+
#
|
190
|
+
# When deleting a Patch via this method, it is deleted
|
191
|
+
# from the server immediately, there is no need to #save
|
192
|
+
# the SoftwareTitle
|
193
|
+
#
|
194
|
+
# @param patchId [Integer] the id of the Patch to be updated.
|
195
|
+
#
|
196
|
+
#
|
197
|
+
# @return [Integer] The id of the deleted Patch
|
198
|
+
############################
|
199
|
+
def delete_patch(patchId)
|
200
|
+
patch = delete_member(patchId)
|
201
|
+
|
202
|
+
# titles without a patch are not valid
|
203
|
+
# so must be disabled
|
204
|
+
patch.softwareTitle.disable if empty?
|
205
|
+
|
206
|
+
update_local_absoluteOrderIds
|
207
|
+
|
208
|
+
patchId
|
209
|
+
end
|
210
|
+
|
211
|
+
# Delete all the patches
|
212
|
+
#
|
213
|
+
# @return [void]
|
214
|
+
############################
|
215
|
+
def delete_all_patches
|
216
|
+
delete_all_members
|
217
|
+
# titles without a patch are not valid
|
218
|
+
# so must be disabled
|
219
|
+
@container.disable
|
220
|
+
end
|
221
|
+
|
222
|
+
# Private Instance Methods
|
223
|
+
####################################
|
224
|
+
private
|
225
|
+
|
226
|
+
# Update the local absoluteOrderId of Array members
|
227
|
+
# to match their array index, without updating the server
|
228
|
+
# cuz the server should have done it automatically
|
229
|
+
#
|
230
|
+
# @return [void]
|
231
|
+
###########################
|
232
|
+
def update_local_absoluteOrderIds
|
233
|
+
@managed_array.each_with_index do |patch, index|
|
234
|
+
patch.local_absoluteOrderId = index
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
end # class PatcheManager
|
239
|
+
|
240
|
+
end # module Windoo
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# Copyright 2025 Pixar
|
2
|
+
#
|
3
|
+
# Licensed under the terms set forth in the LICENSE.txt file available at
|
4
|
+
# at the root of this project.
|
5
|
+
#
|
6
|
+
|
7
|
+
# frozen_string_literal: true
|
8
|
+
|
9
|
+
module Windoo
|
10
|
+
|
11
|
+
# The class for dealing with Software Title Requirements in the
|
12
|
+
# TitleEditor
|
13
|
+
#
|
14
|
+
# A requirement is one criterion, a group of which define which computers
|
15
|
+
# have the title installed, regardless of version.
|
16
|
+
class Requirement < Windoo::BaseClasses::Criterion
|
17
|
+
|
18
|
+
# Mixins
|
19
|
+
######################
|
20
|
+
|
21
|
+
include Windoo::Mixins::APICollection
|
22
|
+
|
23
|
+
# Constants
|
24
|
+
######################
|
25
|
+
|
26
|
+
RSRC_PATH = 'requirements'
|
27
|
+
|
28
|
+
CONTAINER_CLASS = Windoo::SoftwareTitle
|
29
|
+
|
30
|
+
# Attributes
|
31
|
+
######################
|
32
|
+
|
33
|
+
JSON_ATTRIBUTES = {
|
34
|
+
|
35
|
+
# @!attribute requirementId
|
36
|
+
# @return [Integer] The id number of this requirement in the Title Editor
|
37
|
+
requirementId: {
|
38
|
+
class: :Integer,
|
39
|
+
identifier: :primary,
|
40
|
+
readonly: true
|
41
|
+
},
|
42
|
+
|
43
|
+
# @!attribute softwareTitleId
|
44
|
+
# @return [Integer] The id number of the title which uses this requirement
|
45
|
+
softwareTitleId: {
|
46
|
+
class: :Integer,
|
47
|
+
readonly: true
|
48
|
+
}
|
49
|
+
|
50
|
+
}.freeze
|
51
|
+
|
52
|
+
# Public Class Methods
|
53
|
+
######################
|
54
|
+
|
55
|
+
####
|
56
|
+
def self.fetch(*_args)
|
57
|
+
raise Windoo::UnsupportedError, 'Requirements are fetched as part of the SoftwareTitle that contains them'
|
58
|
+
end
|
59
|
+
|
60
|
+
# Private Instance Methods
|
61
|
+
##########################################
|
62
|
+
private
|
63
|
+
|
64
|
+
# See the section 'REQUIRED ITEMS WHEN MIXING IN'
|
65
|
+
# in the APICollection mixin.
|
66
|
+
def handle_create_response(post_response, container_id: nil)
|
67
|
+
@requirementId = post_response[:requirementId]
|
68
|
+
@absoluteOrderId = post_response[:absoluteOrderId]
|
69
|
+
@softwareTitleId = container_id
|
70
|
+
|
71
|
+
@requirementId
|
72
|
+
end
|
73
|
+
|
74
|
+
# See the section 'REQUIRED ITEMS WHEN MIXING IN'
|
75
|
+
# in the APICollection mixin.
|
76
|
+
def handle_update_response(put_response)
|
77
|
+
@and_or = put_response[:and] == false ? :or : :and
|
78
|
+
@absoluteOrderId = put_response[:absoluteOrderId]
|
79
|
+
|
80
|
+
@requirementId
|
81
|
+
end
|
82
|
+
|
83
|
+
end # class Requirement
|
84
|
+
|
85
|
+
end # Module Windoo
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# Copyright 2025 Pixar
|
2
|
+
#
|
3
|
+
# Licensed under the terms set forth in the LICENSE.txt file available at
|
4
|
+
# at the root of this project.
|
5
|
+
#
|
6
|
+
|
7
|
+
# frozen_string_literal: true
|
8
|
+
|
9
|
+
module Windoo
|
10
|
+
|
11
|
+
# A {Windoo::BaseClasses::CriteriaManager CriteriaManager} for dealing with the
|
12
|
+
# {Windoo::Requirement Requirements} of a {Windoo::SoftwareTitle SoftwareTitle}
|
13
|
+
#
|
14
|
+
# An instance of this is returned by {SoftwareTitle#requirements}
|
15
|
+
#
|
16
|
+
class RequirementManager < Windoo::BaseClasses::CriteriaManager
|
17
|
+
|
18
|
+
# Constants
|
19
|
+
######################
|
20
|
+
|
21
|
+
MEMBER_CLASS = Windoo::Requirement
|
22
|
+
|
23
|
+
# Public Instance Methods
|
24
|
+
#################################
|
25
|
+
|
26
|
+
# Override this method to disable the containing patch
|
27
|
+
# if there are no more capabilities.
|
28
|
+
#
|
29
|
+
def delete_criterion(id)
|
30
|
+
deleted_id = super
|
31
|
+
|
32
|
+
# Titles without a requirement are not valid
|
33
|
+
# so must be disabled
|
34
|
+
@container.disable if @managed_array.empty?
|
35
|
+
|
36
|
+
deleted_id
|
37
|
+
end
|
38
|
+
|
39
|
+
# Delete all the criteria
|
40
|
+
#
|
41
|
+
# @return [void]
|
42
|
+
#
|
43
|
+
def delete_all_criteria
|
44
|
+
delete_all_members
|
45
|
+
# titles without a requirement are not valid
|
46
|
+
# so must be disabled
|
47
|
+
@container.disable
|
48
|
+
end
|
49
|
+
|
50
|
+
end # class RequirementManager
|
51
|
+
|
52
|
+
end # Module Windoo
|