From 3748c0d037c7afb9dde17c65328954146f80a094 Mon Sep 17 00:00:00 2001 From: Daniel Parks Date: Wed, 9 Nov 2022 04:16:57 -0800 Subject: [PATCH 1/3] PuppetX::Rustup::Provider::Toolchain --- lib/puppet/type/rustup_internal.rb | 9 ++++++--- lib/puppet_x/rustup/property/subresources.rb | 2 +- .../rustup/provider/collection/subresources.rb | 2 +- .../rustup/provider/collection/targets.rb | 7 +++---- .../rustup/provider/collection/toolchains.rb | 8 +++----- lib/puppet_x/rustup/provider/toolchain.rb | 16 ++++++++++++++++ 6 files changed, 30 insertions(+), 14 deletions(-) create mode 100644 lib/puppet_x/rustup/provider/toolchain.rb diff --git a/lib/puppet/type/rustup_internal.rb b/lib/puppet/type/rustup_internal.rb index 535919a..3cd3cb1 100644 --- a/lib/puppet/type/rustup_internal.rb +++ b/lib/puppet/type/rustup_internal.rb @@ -2,6 +2,7 @@ require 'puppet/parameter/boolean' require_relative '../../puppet_x/rustup/property/subresources' +require_relative '../../puppet_x/rustup/provider/toolchain' require_relative '../../puppet_x/rustup/util' Puppet::Type.newtype(:rustup_internal) do @@ -92,11 +93,13 @@ def ignore_removed_entries end # Do any normalization required for an entry in `should`. - def normalize_should_entry!(entry) - entry['name'] = provider.toolchains.normalize(entry['name']) + def normalize_should_entry(entry) # `rustup` ignores the profile after the initial install. Thus, the # profile key is irrelevant for detecting a change. - entry.delete('profile') + PuppetX::Rustup::Provider::Toolchain.new( + name: provider.toolchains.normalize(entry['name']), + ensure: entry['ensure'], + ) end end diff --git a/lib/puppet_x/rustup/property/subresources.rb b/lib/puppet_x/rustup/property/subresources.rb index cff8824..7f0141c 100644 --- a/lib/puppet_x/rustup/property/subresources.rb +++ b/lib/puppet_x/rustup/property/subresources.rb @@ -111,7 +111,7 @@ def validate_nil_or_non_empty_string(entry, attr) # rubocop:disable Naming/PredicateName def is_to_s(values) if values.is_a? PuppetX::Rustup::Provider::Collection - values = values.system + values = values.system.map { |subresource| subresource.to_h } end super(values) end diff --git a/lib/puppet_x/rustup/provider/collection/subresources.rb b/lib/puppet_x/rustup/provider/collection/subresources.rb index 6ed4303..f2066b2 100644 --- a/lib/puppet_x/rustup/provider/collection/subresources.rb +++ b/lib/puppet_x/rustup/provider/collection/subresources.rb @@ -49,7 +49,7 @@ def group_subresources_by_toolchain(requested) end @provider.toolchains.system.each do |toolchain| - yield toolchain['name'], by_toolchain.delete(toolchain['name']) || [] + yield toolchain.name, by_toolchain.delete(toolchain.name) || [] end # Find subresources that were requested for uninstalled toolchains. diff --git a/lib/puppet_x/rustup/provider/collection/targets.rb b/lib/puppet_x/rustup/provider/collection/targets.rb index 7114a48..c9a785d 100644 --- a/lib/puppet_x/rustup/provider/collection/targets.rb +++ b/lib/puppet_x/rustup/provider/collection/targets.rb @@ -7,13 +7,12 @@ class PuppetX::Rustup::Provider::Collection::Targets < PuppetX::Rustup::Provider::Collection::Subresources # Get targets installed on the system. def load - @system = @provider.toolchains.system.reduce([]) do |combined, info| - toolchain_name = info['name'] - combined + list_installed(toolchain_name).map do |target_name| + @system = @provider.toolchains.system.reduce([]) do |combined, toolchain| + combined + list_installed(toolchain.name).map do |target_name| { 'ensure' => 'present', 'name' => target_name, - 'toolchain' => toolchain_name, + 'toolchain' => toolchain.name, } end end diff --git a/lib/puppet_x/rustup/provider/collection/toolchains.rb b/lib/puppet_x/rustup/provider/collection/toolchains.rb index 1104ee1..01e6ad7 100644 --- a/lib/puppet_x/rustup/provider/collection/toolchains.rb +++ b/lib/puppet_x/rustup/provider/collection/toolchains.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true require_relative 'subresources' +require_relative '../toolchain' # A toolchain subresource collection class PuppetX::Rustup::Provider::Collection::Toolchains < @@ -20,11 +21,8 @@ def system_default # Get toolchains installed on the system. def load - @system = list_installed.map do |full_name| - { - 'ensure' => 'present', - 'name' => full_name, - } + @system = list_installed.map do |name| + PuppetX::Rustup::Provider::Toolchain.from_system(name) end end diff --git a/lib/puppet_x/rustup/provider/toolchain.rb b/lib/puppet_x/rustup/provider/toolchain.rb new file mode 100644 index 0000000..1b33f5f --- /dev/null +++ b/lib/puppet_x/rustup/provider/toolchain.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +require_relative '../provider' + +# A toolchain subresource +module PuppetX::Rustup::Provider + Toolchain = Struct.new(:name, :ensure, keyword_init: true) do + attr_accessor :normalized_name + + def self.from_system(name) + toolchain = new(name: name, ensure: 'present') + toolchain.normalized_name = name + toolchain + end + end +end From c0eed3899697f965a17da7c09d6ea7b5fa588ce4 Mon Sep 17 00:00:00 2001 From: Daniel Parks Date: Fri, 30 Dec 2022 21:47:46 -0800 Subject: [PATCH 2/3] WIP: munge requested toolchains to objects. --- lib/puppet/type/rustup_internal.rb | 12 ++-- lib/puppet_x/rustup/property/subresources.rb | 28 +++++++- lib/puppet_x/rustup/provider/toolchain.rb | 68 +++++++++++++++++++- 3 files changed, 97 insertions(+), 11 deletions(-) diff --git a/lib/puppet/type/rustup_internal.rb b/lib/puppet/type/rustup_internal.rb index 3cd3cb1..365e40b 100644 --- a/lib/puppet/type/rustup_internal.rb +++ b/lib/puppet/type/rustup_internal.rb @@ -87,6 +87,10 @@ def insync?(is) validate_in(entry, 'profile', ['minimal', 'default', 'complete']) end + munge do |entry| + PuppetX::Rustup::Provider::Toolchain.new(**entry) + end + # Whether or not to ignore toolchains on the system but not in the resource. def ignore_removed_entries !resource[:purge_toolchains] @@ -94,12 +98,8 @@ def ignore_removed_entries # Do any normalization required for an entry in `should`. def normalize_should_entry(entry) - # `rustup` ignores the profile after the initial install. Thus, the - # profile key is irrelevant for detecting a change. - PuppetX::Rustup::Provider::Toolchain.new( - name: provider.toolchains.normalize(entry['name']), - ensure: entry['ensure'], - ) + entry.normalized_name = provider.toolchains.normalize(entry.name) + entry end end diff --git a/lib/puppet_x/rustup/property/subresources.rb b/lib/puppet_x/rustup/property/subresources.rb index 7f0141c..389b048 100644 --- a/lib/puppet_x/rustup/property/subresources.rb +++ b/lib/puppet_x/rustup/property/subresources.rb @@ -17,7 +17,12 @@ class Subresources < Set # entry within in the set. If two entries have the same identity, then it # is an error. def entry_identity(entry) - entry.reject { |k| k == 'ensure' }.hash + h = entry.to_h.reject { |k| k == 'ensure' } + if entry['normalized_name'] + h[:name] = entry['normalized_name'] + end + Puppet.notice("entry_identity(#{entry.inspect}) == #{h.inspect}.hash == #{h.hash.inspect}") + h.hash end # Does this entry in `should` have the equivalent of `ensure => absent`? @@ -111,10 +116,27 @@ def validate_nil_or_non_empty_string(entry, attr) # rubocop:disable Naming/PredicateName def is_to_s(values) if values.is_a? PuppetX::Rustup::Provider::Collection - values = values.system.map { |subresource| subresource.to_h } + values = values.system end - super(values) + super(values.map { |subresource| subresource.to_h }) end # rubocop:enable Naming/PredicateName + + # Format new values for display. + # + # Often we use a subresource class to handle subresource collections in the + # provider, which interferes with the display of changed values. + # + # @param values [Array] the values to format as a string + # @return [String] a pretty printing string + def should_to_s(values) + super(values.map { |subresource| subresource.to_h }) + end + + # Check if entries with the same identity are different. + def entry_changed?(is_entry, should_entry) + Puppet.notice("is(#{is_entry.inspect}) != shoud(#{should_entry.inspect}): #{is_entry != should_entry}") + is_entry != should_entry + end end end diff --git a/lib/puppet_x/rustup/provider/toolchain.rb b/lib/puppet_x/rustup/provider/toolchain.rb index 1b33f5f..9df505d 100644 --- a/lib/puppet_x/rustup/provider/toolchain.rb +++ b/lib/puppet_x/rustup/provider/toolchain.rb @@ -4,8 +4,72 @@ # A toolchain subresource module PuppetX::Rustup::Provider - Toolchain = Struct.new(:name, :ensure, keyword_init: true) do - attr_accessor :normalized_name + class Toolchain + class << self + def property(name) + attr_accessor(name) + @properties ||= [] + @properties << name + end + + def parameter(name) + attr_accessor(name) + @parameters ||= [] + @parameters << name + end + + def properties + @properties || [] + end + + def parameters + @parameters || [] + end + end + + property :name + property :ensure + parameter :profile + parameter :normalized_name + + def initialize(**kwargs) + kwargs.each do |key, value| + self[key] = value + end + end + + def to_h + h = {} + self.class.properties.each do |key| + h[key] = send(key) + end + # FIXME: parameters + h + end + + # Validate members against the property and parameter list rather than just + # trying to `send()` to avoid being able to call any function ending with + # "=" just by passing the right hash to the constructor. + def valid_member?(key) + key = key.to_sym + self.class.properties.include?(key) || self.class.parameters.include?(key) + end + + def validate_member(key) + unless valid_member?(key) + raise NameError, "invalid member #{key.inspect}" + end + end + + def [](key) + validate_member(key) + send(key) + end + + def []=(key, value) + validate_member(key) + send("#{key}=", value) + end def self.from_system(name) toolchain = new(name: name, ensure: 'present') From 6a3b96d0a39af2dd8a3ce4d3b6ea6e63bf7bed36 Mon Sep 17 00:00:00 2001 From: Daniel Parks Date: Sat, 15 Apr 2023 21:36:22 -0700 Subject: [PATCH 3/3] Indent fix --- lib/puppet_x/rustup/provider/toolchain.rb | 114 +++++++++++----------- 1 file changed, 56 insertions(+), 58 deletions(-) diff --git a/lib/puppet_x/rustup/provider/toolchain.rb b/lib/puppet_x/rustup/provider/toolchain.rb index 9df505d..cdeeb50 100644 --- a/lib/puppet_x/rustup/provider/toolchain.rb +++ b/lib/puppet_x/rustup/provider/toolchain.rb @@ -3,78 +3,76 @@ require_relative '../provider' # A toolchain subresource -module PuppetX::Rustup::Provider - class Toolchain - class << self - def property(name) - attr_accessor(name) - @properties ||= [] - @properties << name - end +class PuppetX::Rustup::Provider::Toolchain + class << self + def property(name) + attr_accessor(name) + @properties ||= [] + @properties << name + end - def parameter(name) - attr_accessor(name) - @parameters ||= [] - @parameters << name - end + def parameter(name) + attr_accessor(name) + @parameters ||= [] + @parameters << name + end - def properties - @properties || [] - end + def properties + @properties || [] + end - def parameters - @parameters || [] - end + def parameters + @parameters || [] end + end - property :name - property :ensure - parameter :profile - parameter :normalized_name + property :name + property :ensure + parameter :profile + parameter :normalized_name - def initialize(**kwargs) - kwargs.each do |key, value| - self[key] = value - end + def initialize(**kwargs) + kwargs.each do |key, value| + self[key] = value end + end - def to_h - h = {} - self.class.properties.each do |key| - h[key] = send(key) - end - # FIXME: parameters - h + def to_h + h = {} + self.class.properties.each do |key| + h[key] = send(key) end + # FIXME: parameters + h + end - # Validate members against the property and parameter list rather than just - # trying to `send()` to avoid being able to call any function ending with - # "=" just by passing the right hash to the constructor. - def valid_member?(key) - key = key.to_sym - self.class.properties.include?(key) || self.class.parameters.include?(key) - end + # Validate members against the property and parameter list rather than just + # trying to `send()` to avoid being able to call any function ending with + # "=" just by passing the right hash to the constructor. + def valid_member?(key) + key = key.to_sym + self.class.properties.include?(key) || self.class.parameters.include?(key) + end - def validate_member(key) - unless valid_member?(key) - raise NameError, "invalid member #{key.inspect}" - end + def validate_member(key) + unless valid_member?(key) + raise NameError, "invalid member #{key.inspect}" end + end - def [](key) - validate_member(key) - send(key) - end + def [](key) + validate_member(key) + send(key) + end - def []=(key, value) - validate_member(key) - send("#{key}=", value) - end + def []=(key, value) + validate_member(key) + send("#{key}=", value) + end - def self.from_system(name) - toolchain = new(name: name, ensure: 'present') - toolchain.normalized_name = name - toolchain - end + def self.from_system(name) + toolchain = new(name: name, ensure: 'present') + toolchain.normalized_name = name + toolchain end end