Skip to content

Commit

Permalink
Add profile parameter for toolchains
Browse files Browse the repository at this point in the history
This allows the profile to be set when installing toolchains. It only
has an effect during the initial install. All it does is decide which
components are installed by default.
  • Loading branch information
danielparks committed Sep 20, 2022
1 parent 619bb35 commit 387ddcb
Show file tree
Hide file tree
Showing 9 changed files with 119 additions and 10 deletions.
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ rustup::global::target { 'x86_64-unknown-linux-musl nightly': }
## Limitations

* This does not allow management of components.
* This does not allow management of profiles.
* This does not support Windows.

## Reference
Expand Down
42 changes: 40 additions & 2 deletions REFERENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
### Data types

* [`Rustup::OptionalStringOrArray`](#rustupoptionalstringorarray): Convenience type to make params easier to read
* [`Rustup::Profile`](#rustupprofile): Profile for toolchain installation

## Classes

Expand Down Expand Up @@ -469,6 +470,7 @@ The following parameters are available in the `rustup::global::toolchain` define

* [`ensure`](#ensure)
* [`toolchain`](#toolchain)
* [`profile`](#profile)

##### <a name="ensure"></a>`ensure`

Expand All @@ -488,6 +490,18 @@ The name of the toolchain to install, e.g. "stable".

Default value: `$name`

##### <a name="profile"></a>`profile`

Data type: `Rustup::Profile`

Profile to use for installation. This determines which components will be
installed initially.

Changing this for an existing installation will not have an effect even if
it causes an update, i.e. when `ensure => latest` is set.

Default value: `'default'`

### <a name="rustuptarget"></a>`rustup::target`

You can name this two ways to automatically set the parameters:
Expand Down Expand Up @@ -564,6 +578,7 @@ The following parameters are available in the `rustup::toolchain` defined type:
* [`ensure`](#ensure)
* [`rustup`](#rustup)
* [`toolchain`](#toolchain)
* [`profile`](#profile)

##### <a name="ensure"></a>`ensure`

Expand Down Expand Up @@ -593,6 +608,18 @@ the `$name` of the resource follows the rules above.

Default value: `(': ')[1]`

##### <a name="profile"></a>`profile`

Data type: `Rustup::Profile`

Profile to use for installation. This determines which components will be
installed initially.

Changing this for an existing installation will not have an effect even if
it causes an update, i.e. when `ensure => latest` is set.

Default value: `'default'`

## Resource types

### <a name="rustup_internal"></a>`rustup_internal`
Expand Down Expand Up @@ -630,7 +657,7 @@ Default value: `present`
The targets to install or remove.

Each target must be a Hash with three entries:
* `ensure`: one of `present` and `absent`
* `ensure`: one of `present` or `absent`
* `target`: the name of the target
* `toolchain`: the name of the toolchain or `undef` to indicate the
default toolchain
Expand All @@ -640,8 +667,9 @@ Each target must be a Hash with three entries:
The toolchains to install, update, or remove.

Each toolchain must be a Hash with two entries:
* `ensure`: one of `present`, `latest`, and `absent`
* `ensure`: one of `present`, `latest`, or `absent`
* `toolchain`: the name of the toolchain
* `profile`: one of `minimal`, `default`, or `complete`

#### Parameters

Expand Down Expand Up @@ -752,3 +780,13 @@ Alias of
Variant[Undef, String[1], Array[String[1]]]
```

### <a name="rustupprofile"></a>`Rustup::Profile`

`default` is a keyword in Puppet, so it must always be wrapped in quotes.

Alias of

```puppet
Enum[minimal, 'default', complete]
```

9 changes: 6 additions & 3 deletions lib/puppet/provider/rustup_internal/default.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ def toolchains_real

# Load toolchains from the system
#
# Does not try to set the `profile`, since it’s meaningless after the initial
# installation of the toolchain.
#
# Saves the toolchains to @toolchains_cache.
def load_toolchains
@toolchains_cache = toolchain_list.map do |full_name|
Expand Down Expand Up @@ -367,7 +370,7 @@ def manage_toolchains
toolchain_uninstall(info['toolchain'])
end
elsif found.nil? || info['ensure'] == 'latest'
toolchain_install(info['toolchain'])
toolchain_install(info['toolchain'], profile: info['profile'])
end
end

Expand Down Expand Up @@ -434,9 +437,9 @@ def check_default_toolchain(unmanaged)
end

# Install or update a toolchain
def toolchain_install(toolchain)
def toolchain_install(toolchain, profile: 'default')
rustup 'toolchain', 'install', '--no-self-update', '--force-non-host', \
toolchain
'--profile', profile, toolchain
end

# Uninstall a toolchain
Expand Down
18 changes: 14 additions & 4 deletions lib/puppet/type/rustup_internal.rb
Original file line number Diff line number Diff line change
Expand Up @@ -67,15 +67,16 @@ def insync?(is)
The toolchains to install, update, or remove.
Each toolchain must be a Hash with two entries:
* `ensure`: one of `present`, `latest`, and `absent`
* `ensure`: one of `present`, `latest`, or `absent`
* `toolchain`: the name of the toolchain
* `profile`: one of `minimal`, `default`, or `complete`
END

validate do |entry|
# WTF: properties validate each element of a passed array.
unless entry.is_a?(Hash) && entry.length == 2
unless entry.is_a?(Hash) && entry.length == 3
raise Puppet::Error,
'Expected toolchain Hash with two entries, got %s' % entry.inspect
'Expected toolchain Hash with 3 entries, got %s' % entry.inspect
end

unless ['present', 'latest', 'absent'].any? entry['ensure']
Expand All @@ -88,6 +89,12 @@ def insync?(is)
raise Puppet::Error, 'Expected toolchain Hash entry "toolchain" to ' \
'be a non-empty string, got %s' % entry['toolchain'].inspect
end

unless ['minimal', 'default', 'complete'].any? entry['profile']
raise Puppet::Error, 'Expected toolchain Hash entry "profile" to be ' \
'one of ("minimal", "default", "complete"), got %s' \
% entry['profile'].inspect
end
end

# Whether or not to ignore toolchains on the system but not in the resource.
Expand All @@ -98,6 +105,9 @@ def ignore_removed_entries
# Do any normalization required for an entry in `should`
def normalize_should_entry!(entry)
entry['toolchain'] = provider.normalize_toolchain_name(entry['toolchain'])
# `rustup` ignores the profile after the initial install. Thus, the
# profile key is irrelevant for detecting a change.
entry.delete('profile')
end
end

Expand All @@ -112,7 +122,7 @@ def normalize_should_entry!(entry)
The targets to install or remove.
Each target must be a Hash with three entries:
* `ensure`: one of `present` and `absent`
* `ensure`: one of `present` or `absent`
* `target`: the name of the target
* `toolchain`: the name of the toolchain or `undef` to indicate the
default toolchain
Expand Down
8 changes: 8 additions & 0 deletions manifests/global/toolchain.pp
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,23 @@
# * `absent` - uninstall toolchain.
# @param toolchain
# The name of the toolchain to install, e.g. "stable".
# @param profile
# Profile to use for installation. This determines which components will be
# installed initially.
#
# Changing this for an existing installation will not have an effect even if
# it causes an update, i.e. when `ensure => latest` is set.
define rustup::global::toolchain (
Enum[present, latest, absent] $ensure = present,
String[1] $toolchain = $name,
Rustup::Profile $profile = 'default',
) {
include rustup::global

rustup::toolchain { "${rustup::global::user}: ${name}":
ensure => $ensure,
rustup => $rustup::global::user,
toolchain => $toolchain,
profile => $profile,
}
}
1 change: 1 addition & 0 deletions manifests/init.pp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
{
ensure => present,
toolchain => $toolchain,
profile => 'default',
}
}

Expand Down
8 changes: 8 additions & 0 deletions manifests/toolchain.pp
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,23 @@
# @param toolchain
# The name of the toolchain to install, e.g. "stable". Automatically set if
# the `$name` of the resource follows the rules above.
# @param profile
# Profile to use for installation. This determines which components will be
# installed initially.
#
# Changing this for an existing installation will not have an effect even if
# it causes an update, i.e. when `ensure => latest` is set.
define rustup::toolchain (
Enum[present, latest, absent] $ensure = present,
String[1] $rustup = $name.split(': ')[0],
String[1] $toolchain = $name.split(': ')[1],
Rustup::Profile $profile = 'default',
) {
Rustup_internal <| title == $rustup |> {
toolchains +> [{
ensure => $ensure,
toolchain => $toolchain,
profile => $profile,
}],
}
}
38 changes: 38 additions & 0 deletions spec/acceptance/user_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,44 @@
end
end

# Profiles only work on initial install, so the toolchain must be new.
context 'supports multi-resource install with profile and explicit target' do
it do
idempotent_apply(<<~'END')
rustup { 'vagrant': }
rustup::toolchain { 'vagrant: beta':
profile => minimal,
}
rustup::target { 'vagrant: default beta': }
END
end

toolchains = Dir['/home/vagrant/.rustup/toolchains/beta-*-linux-gnu']
describe toolchains do
its(:length) { is_expected.to eq 1 }
end

toolchain_path = toolchains.first

describe file("#{toolchain_path}/bin/rustc") do
it { is_expected.to be_file }
it { is_expected.to be_executable }
it { is_expected.to be_owned_by 'vagrant' }
end

describe file("#{toolchain_path}/bin/rustfmt") do
it { is_expected.not_to exist }
end

describe command_as_vagrant('rustup +beta target list') do
its(:stdout) do
is_expected.to match(%r{-unknown-linux-.* \(installed\)$})
end
its(:stderr) { is_expected.to eq '' }
its(:exit_status) { is_expected.to eq 0 }
end
end

context 'supports installing non-host toolchain' do
target = 'x86_64-pc-windows-gnu'
toolchain = "stable-#{target}"
Expand Down
4 changes: 4 additions & 0 deletions types/profile.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# @summary Profile for toolchain installation
#
# `default` is a keyword in Puppet, so it must always be wrapped in quotes.
type Rustup::Profile = Enum[minimal, 'default', complete]

0 comments on commit 387ddcb

Please # to comment.