Class: Mxrb::OfficialMarketplace::Lifecycle

Inherits:
Object
  • Object
show all
Defined in:
lib/mxrb/official_marketplace/lifecycle.rb

Overview

Transactional lifecycle for modules already recorded in marketplace.lock.json.

Instance Method Summary collapse

Constructor Details

#initialize(target:, mpr:, installer:) ⇒ Lifecycle

rubocop:disable Metrics/ClassLength



94
95
96
97
98
# File 'lib/mxrb/official_marketplace/lifecycle.rb', line 94

def initialize(target:, mpr:, installer:)
  @target = File.expand_path(target)
  @mpr = mpr && File.expand_path(mpr)
  @installer = installer
end

Instance Method Details

#installed(identifier) ⇒ Object

Raises:



100
101
102
103
104
105
106
107
108
109
# File 'lib/mxrb/official_marketplace/lifecycle.rb', line 100

def installed(identifier)
  pair = packages.find do |name, entry|
    name.casecmp(identifier.to_s).zero? || entry['content_id'].to_s == identifier.to_s
  end
  raise MarketplaceError, "Marketplace package #{identifier.inspect} is not installed" unless pair
  raise MarketplaceError, "Marketplace package #{pair.first.inspect} is not an imported module" \
    unless pair.last['kind'] == 'module'

  pair
end

#mpr_path(entry) ⇒ Object

Raises:



111
112
113
114
115
116
# File 'lib/mxrb/official_marketplace/lifecycle.rb', line 111

def mpr_path(entry)
  path = safe_path(entry.fetch('destination'))
  raise MarketplaceError, 'selected MPR does not match the Marketplace lock' if @mpr && @mpr != path

  path
end

#plan_remove(identifier) ⇒ Object

rubocop:disable Metrics/AbcSize, Metrics/MethodLength



119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/mxrb/official_marketplace/lifecycle.rb', line 119

def plan_remove(identifier)
  name, entry = installed(identifier)
  mpr = mpr_path(entry)
  ids = target_unit_ids(mpr, entry)
  inventory = cached_inventory(entry)
  shared = shared_files(name)
  blockers = base_blockers(entry, inventory, ids)
  blockers << "locked module name does not match cached package #{inventory.name}" if inventory.name != name
  blockers.concat(external_reference_blockers(mpr, ids))
  blockers.concat(modified_asset_blockers(inventory, name))
  removable = inventory.files.keys - shared
  changes = ["delete #{ids.size} MPR units", "delete #{removable.size} package assets",
             'delete cached package and lock entry']
  LifecyclePlan.new(
    action: :remove, name:, installed_version: entry['version'], target_version: nil,
    changes:, blockers:
  ) { apply_remove(name, entry, mpr, ids, removable) }
end

#plan_update(identifier, archive, package) ⇒ Object

rubocop:disable Metrics/AbcSize, Metrics/MethodLength



140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'lib/mxrb/official_marketplace/lifecycle.rb', line 140

def plan_update(identifier, archive, package)
  name, entry = installed(identifier)
  mpr = mpr_path(entry)
  current_ids = target_unit_ids(mpr, entry)
  current = cached_inventory(entry)
  replacement = ModulePackageInventory.read(archive)
  missing_ids = current_ids - replacement.unit_ids
  blockers = base_blockers(entry, current, current_ids)
  blockers << "replacement module name changed from #{name} to #{replacement.name}" if replacement.name != name
  blockers << 'replacement module identity changed' if replacement.module_id != entry['module_id']
  blockers << "downloaded package version #{replacement.version} does not match #{package.version}" \
    unless package_version_matches?(replacement.version, package.version)
  blockers << "version #{package.version} is already installed" if package.version.to_s == entry['version'].to_s
  blockers.concat(external_reference_blockers(mpr, missing_ids))
  blockers.concat(modified_asset_blockers(current, name))
  obsolete = current.files.keys - replacement.files.keys - shared_files(name)
  changes = ["replace #{current_ids.size} MPR units with #{replacement.unit_ids.size}",
             "install #{replacement.files.size} package assets",
             "delete #{obsolete.size} obsolete package assets", 'replace cache and lock metadata']
  LifecyclePlan.new(
    action: :update, name:, installed_version: entry['version'], target_version: package.version,
    changes:, blockers:
  ) { apply_update(entry, mpr, current_ids, obsolete, archive, package, replacement) }
end