Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Toolchain object #71

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions lib/puppet/type/rustup_internal.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -86,17 +87,19 @@ 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]
end

# Do any normalization required for an entry in `should`.
def normalize_should_entry!(entry)
entry['name'] = provider.toolchains.normalize(entry['name'])
# `rustup` ignores the profile after the initial install. Thus, the
# profile key is irrelevant for detecting a change.
entry.delete('profile')
def normalize_should_entry(entry)
entry.normalized_name = provider.toolchains.normalize(entry.name)
entry
end
end

Expand Down
26 changes: 24 additions & 2 deletions lib/puppet_x/rustup/property/subresources.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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`?
Expand Down Expand Up @@ -113,8 +118,25 @@ def is_to_s(values)
if values.is_a? PuppetX::Rustup::Provider::Collection
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
2 changes: 1 addition & 1 deletion lib/puppet_x/rustup/provider/collection/subresources.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
7 changes: 3 additions & 4 deletions lib/puppet_x/rustup/provider/collection/targets.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 3 additions & 5 deletions lib/puppet_x/rustup/provider/collection/toolchains.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# frozen_string_literal: true

require_relative 'subresources'
require_relative '../toolchain'

# A toolchain subresource collection
class PuppetX::Rustup::Provider::Collection::Toolchains <
Expand All @@ -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

Expand Down
78 changes: 78 additions & 0 deletions lib/puppet_x/rustup/provider/toolchain.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# frozen_string_literal: true

require_relative '../provider'

# A toolchain subresource
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 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')
toolchain.normalized_name = name
toolchain
end
end