Module: Mxrb::OfficialMarketplace
- Defined in:
- lib/mxrb/official_marketplace.rb,
lib/mxrb/official_marketplace/lifecycle.rb,
lib/mxrb/official_marketplace/content_api.rb,
lib/mxrb/official_marketplace/dependency_resolver.rb,
lib/mxrb/official_marketplace/module_package_importer.rb,
lib/mxrb/official_marketplace/widget_package_installer.rb
Overview
Installer for official/community Mendix packages, separate from Ruby modules.
Defined Under Namespace
Classes: AuditResult, ContentApi, Credentials, Dependency, DependencyPlan, DependencyResolver, GitHubResolver, HttpClient, Installation, Installer, Lifecycle, LifecyclePlan, ModuleInstallation, ModulePackageAssets, ModulePackageImporter, ModulePackageInventory, ModulePackageReader, OfficialPackage, Package, PackageEnvelope, SecurityAuditor, WidgetBundleInventory, WidgetDependency, WidgetInstallation, WidgetPackageInstaller, WidgetPackageInventory
Constant Summary collapse
- CATALOG =
{ 'CommunityCommons' => 'mendix/CommunityCommons', 'UnitTesting' => 'mendix/UnitTesting' }.freeze
Class Method Summary collapse
- .lock(target) ⇒ Object
- .module_by_name(mpr, name) ⇒ Object
- .module_present?(mpr_path, name, module_id) ⇒ Boolean
- .tree_digest(path) ⇒ Object
- .verify(target) ⇒ Object
-
.verify_module(root, name, entry) ⇒ Object
rubocop:disable Metrics/AbcSize.
-
.verify_tree(root, entry) ⇒ Object
rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity.
-
.verify_widget(root, entry) ⇒ Object
rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity.
Class Method Details
.lock(target) ⇒ Object
44 45 46 47 48 49 |
# File 'lib/mxrb/official_marketplace.rb', line 44 def self.lock(target) path = File.join(File.(target), '.mxrb', 'marketplace.lock.json') File.file?(path) ? JSON.parse(File.read(path)) : { 'packages' => {} } rescue JSON::ParserError => e raise MarketplaceError, "invalid marketplace lockfile: #{e.}" end |
.module_by_name(mpr, name) ⇒ Object
110 111 112 |
# File 'lib/mxrb/official_marketplace.rb', line 110 def self.module_by_name(mpr, name) mpr.units_by_containment('Modules').find { mpr.parse_contents(_1)['Name'] == name } end |
.module_present?(mpr_path, name, module_id) ⇒ Boolean
98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/mxrb/official_marketplace.rb', line 98 def self.module_present?(mpr_path, name, module_id) return false unless File.file?(mpr_path) mpr = IO::MprFile.open(mpr_path, readonly: true) unit = module_id ? mpr.unit(module_id) : module_by_name(mpr, name) unit && mpr.parse_contents(unit)['Name'] == name rescue Error, SQLite3::Exception false ensure mpr&.close end |
.tree_digest(path) ⇒ Object
34 35 36 37 38 39 40 41 42 |
# File 'lib/mxrb/official_marketplace.rb', line 34 def self.tree_digest(path) digest = Digest::SHA256.new Dir.glob(File.join(path, '**', '*'), File::FNM_DOTMATCH).sort.each do |file| next unless File.file?(file) digest << file.delete_prefix("#{path}/") << "\0" << File.binread(file) end digest.hexdigest end |
.verify(target) ⇒ Object
51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/mxrb/official_marketplace.rb', line 51 def self.verify(target) root = File.(target) lock(root).fetch('packages').to_h do |name, entry| result = case entry['kind'] when 'module' then verify_module(root, name, entry) when 'widget' then (root, entry) else verify_tree(root, entry) end [name, result] end end |
.verify_module(root, name, entry) ⇒ Object
rubocop:disable Metrics/AbcSize
86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/mxrb/official_marketplace.rb', line 86 def self.verify_module(root, name, entry) # rubocop:disable Metrics/AbcSize archive = File.join(root, entry.fetch('archive')) actual = File.file?(archive) ? Digest::SHA256.file(archive).hexdigest : nil mpr_path = File.join(root, entry.fetch('destination')) present = module_present?(mpr_path, name, entry['module_id']) files_present = Array(entry['files']).all? { File.file?(File.join(root, _1)) } { valid: actual == entry['sha256'] && present && files_present, expected: entry['sha256'], actual:, module_present: present, files_present: } end |
.verify_tree(root, entry) ⇒ Object
rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
80 81 82 83 84 |
# File 'lib/mxrb/official_marketplace.rb', line 80 def self.verify_tree(root, entry) destination = File.join(root, entry.fetch('destination')) actual = File.directory?(destination) ? tree_digest(destination) : nil { valid: actual == entry['sha256'], expected: entry['sha256'], actual: } end |
.verify_widget(root, entry) ⇒ Object
rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/mxrb/official_marketplace.rb', line 64 def self.(root, entry) destination = File.join(root, entry.fetch('destination')) archive = File.join(root, entry.fetch('archive')) actual = File.file?(destination) ? Digest::SHA256.file(destination).hexdigest : nil cached = File.file?(archive) ? Digest::SHA256.file(archive).hexdigest : nil inventory = WidgetPackageInventory.read(destination) if actual == entry['sha256'] identity = inventory&.name == entry['widget_name'] && inventory&. == entry['widget_ids'] { valid: actual == entry['sha256'] && cached == entry['sha256'] && identity, expected: entry['sha256'], actual:, cached:, identity: } rescue MarketplaceError { valid: false, expected: entry['sha256'], actual:, cached:, identity: false } end |