Class: PuppetX::Rustup::Provider::Collection::Toolchains

Inherits:
Subresources
  • Object
show all
Defined in:
lib/puppet_x/rustup/provider/collection/toolchains.rb

Overview

A toolchain subresource collection

Instance Method Summary collapse

Constructor Details

#initialize(provider) ⇒ Toolchains

Returns a new instance of Toolchains.



8
9
10
11
# File 'lib/puppet_x/rustup/provider/collection/toolchains.rb', line 8

def initialize(provider)
  super
  @system_default = :unset
end

Instance Method Details

#install(subresource) ⇒ Object

Install or update a toolchain



348
349
350
351
352
# File 'lib/puppet_x/rustup/provider/collection/toolchains.rb', line 348

def install(subresource)
  @provider.rustup 'toolchain', 'install', '--no-self-update',
    '--force-non-host', '--profile', subresource['profile'] || 'default',
    subresource['name']
end

#list_installedObject

Load installed toolchains from system as an array of strings

This also sets @system_default.



318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
# File 'lib/puppet_x/rustup/provider/collection/toolchains.rb', line 318

def list_installed
  @system_default = nil
  unless @provider.exists? && @provider.user_exists?
    # If rustup isn’t installed, then no toolchains can exist. If the user
    # doesn’t exist then either this resource is ensure => absent and
    # everything will be deleted, or an error will be raised when it tries to
    # install rustup for a non-existent user.
    return []
  end

  @provider.rustup('toolchain', 'list')
    .lines(chomp: true)
    .reject { |line| line == 'no installed toolchains' }
    .map do |line|
      toolchain, state = line.split(' ', 2)
      if state
        if %r{\A\(.*\)\z}.match? state
          if state[1..-2].split(%r{,\s*}).include?('default')
            @system_default = toolchain
          end
        else
          raise Puppet::Error,
            "Could not parse line in toolchain list: #{line.inspect}"
        end
      end
      toolchain
    end
end

#loadObject

Get toolchains installed on the system.



22
23
24
25
26
27
28
29
# File 'lib/puppet_x/rustup/provider/collection/toolchains.rb', line 22

def load
  @system = list_installed.map do |full_name|
    {
      'ensure' => 'present',
      'name' => full_name,
    }
  end
end

#manage(requested, purge, requested_default) ⇒ Object

Install and uninstall toolchains as appropriate

Note that this does not update the internal state after changing the system. You must call toolchains.load after this function if you need the toolchain state to be correct.

This takes ‘resource` as a parameter instead of using the set value of this collection because the value isn’t set if it is initially unchanged. That means if the values on the system change after `load` was called but before this method was called, we won’t be able to tell.



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/puppet_x/rustup/provider/collection/toolchains.rb', line 41

def manage(requested, purge, requested_default)
  if requested_default
    requested_default = normalize(requested_default)
    validate_default(requested_default, requested, purge)
  end

  unmanaged = manage_group(system, requested)

  if requested_default
    update_default(requested_default)
  end

  if purge
    uninstall_all(unmanaged)
  end
end

#normalize(name) ⇒ Object

Normalize a toolchain name (not nil).

There are some flaws in this.

* This is kludged together. I didn’t take the time to figure out all the
  edge cases that rustup deals with.

* It will break as soon as rust adds a new triple to run toolchains on.


66
67
68
69
70
71
72
73
74
75
76
# File 'lib/puppet_x/rustup/provider/collection/toolchains.rb', line 66

def normalize(name)
  if name.nil?
    raise ArgumentError, 'normalize expects a string, not nil'
  end

  parse_partial(name)
    .map
    .with_index { |part, i| part || @provider.default_toolchain_triple[i] }
    .compact
    .join('-')
end

#parse_partial(input) ⇒ Object

Parse a partial toolchain descriptor into its parts.

FIXME: this will break as soon as Rust adds a new platform for the toolchain to run on.



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
# File 'lib/puppet_x/rustup/provider/collection/toolchains.rb', line 82

def parse_partial(input)
  # From https://github.com/rust-lang/rustup/blob/f4f46e03e009fbaf3d1ae77e1e45f3334c9f9be8/src/dist/triple/known.rs
  # rubocop:disable Style/StringLiterals
  # typos:ignore-start
  archs = [
    "aarch64",
    "aarch64_be",
    "amdgcn",
    "arm",
    "arm64_32",
    "arm64e",
    "arm64ec",
    "armeb",
    "armebv7r",
    "armv4t",
    "armv5te",
    "armv6",
    "armv6k",
    "armv7",
    "armv7a",
    "armv7k",
    "armv7r",
    "armv7s",
    "armv8r",
    "avr",
    "bpfeb",
    "bpfel",
    "csky",
    "hexagon",
    "i386",
    "i586",
    "i686",
    "loongarch32",
    "loongarch64",
    "m68k",
    "mips",
    "mips64",
    "mips64el",
    "mipsel",
    "mipsisa32r6",
    "mipsisa32r6el",
    "mipsisa64r6",
    "mipsisa64r6el",
    "msp430",
    "nvptx64",
    "powerpc",
    "powerpc64",
    "powerpc64le",
    "riscv32",
    "riscv32e",
    "riscv32em",
    "riscv32emc",
    "riscv32gc",
    "riscv32i",
    "riscv32im",
    "riscv32ima",
    "riscv32imac",
    "riscv32imafc",
    "riscv32imc",
    "riscv64",
    "riscv64a23",
    "riscv64gc",
    "riscv64imac",
    "s390x",
    "sparc",
    "sparc64",
    "sparcv9",
    "thumbv4t",
    "thumbv5te",
    "thumbv6m",
    "thumbv7a",
    "thumbv7em",
    "thumbv7m",
    "thumbv7neon",
    "thumbv8m.base",
    "thumbv8m.main",
    "wasm32",
    "wasm32v1",
    "wasm64",
    "x86_64",
    "x86_64h",
    "xtensa",
  ].join('|')
  oses = [
    "amd-amdhsa",
    "apple-darwin",
    "apple-ios",
    "apple-tvos",
    "apple-visionos",
    "apple-watchos",
    "esp-espidf",
    "esp32-espidf",
    "esp32-none",
    "esp32s2-espidf",
    "esp32s2-none",
    "esp32s3-espidf",
    "esp32s3-none",
    "fortanix-unknown",
    "ibm-aix",
    "kmc-solid_asp3",
    "linux",
    "lynx-lynxos178",
    "mti-none",
    "nintendo-3ds",
    "nintendo-switch",
    "none",
    "nuttx-eabi",
    "nuttx-eabihf",
    "nvidia-cuda",
    "openwrt-linux",
    "pc-cygwin",
    "pc-nto",
    "pc-solaris",
    "pc-windows",
    "risc0-zkvm",
    "rtems-eabihf",
    "sony-psp",
    "sony-psx",
    "sony-vita",
    "sun-solaris",
    "unikraft-linux",
    "unknown-dragonfly",
    "unknown-emscripten",
    "unknown-freebsd",
    "unknown-fuchsia",
    "unknown-haiku",
    "unknown-hermit",
    "unknown-hurd",
    "unknown-illumos",
    "unknown-l4re",
    "unknown-linux",
    "unknown-managarm",
    "unknown-motor",
    "unknown-netbsd",
    "unknown-none",
    "unknown-nto",
    "unknown-nuttx",
    "unknown-openbsd",
    "unknown-redox",
    "unknown-teeos",
    "unknown-trusty",
    "unknown-uefi",
    "unknown-unknown",
    "unknown-xous",
    "uwp-windows",
    "vex-v5",
    "wali-linux",
    "wasip1",
    "wasip1-threads",
    "wasip2",
    "wasip3",
    "win7-windows",
    "wrs-vxworks",
  ].join('|')
  envs = [
    "android",
    "androideabi",
    "eabi",
    "eabihf",
    "elf",
    "freestanding",
    "gnu",
    "gnu_ilp32",
    "gnuabi64",
    "gnuabiv2",
    "gnuabiv2hf",
    "gnueabi",
    "gnueabihf",
    "gnullvm",
    "gnuspe",
    "gnux32",
    "macabi",
    "mlibc",
    "msvc",
    "musl",
    "muslabi64",
    "musleabi",
    "musleabihf",
    "muslspe",
    "newlibeabihf",
    "none",
    "ohos",
    "qnx700",
    "qnx710",
    "qnx710_iosock",
    "qnx800",
    "sgx",
    "sim",
    "softfloat",
    "spe",
    "uclibc",
    "uclibceabi",
    "uclibceabihf",
  ].join('|')
  # typos:ignore-end
  # rubocop:enable Style/StringLiterals
  re = %r{\A(.*?)(?:-(#{archs}))?(?:-(#{oses}))?(?:-(#{envs}))?\Z}
  match = re.match(input)
  if match.nil?
    [nil, nil, nil, nil]
  else
    match[1, 4]
  end
end

#system_defaultObject

Get the real default toolchain on the system



14
15
16
17
18
19
# File 'lib/puppet_x/rustup/provider/collection/toolchains.rb', line 14

def system_default
  if @system_default == :unset
    load
  end
  @system_default
end

#uninstall(subresource) ⇒ Object

Uninstall a toolchain



355
356
357
# File 'lib/puppet_x/rustup/provider/collection/toolchains.rb', line 355

def uninstall(subresource)
  @provider.rustup 'toolchain', 'uninstall', subresource['name']
end

#update_default(toolchain) ⇒ Object

Save default toolchain to system



308
309
310
311
312
313
# File 'lib/puppet_x/rustup/provider/collection/toolchains.rb', line 308

def update_default(toolchain)
  if toolchain != @system_default
    @provider.rustup 'default', toolchain
    @system_default = toolchain
  end
end

#validate_default(normalized_default, requested_toolchains, purge) ⇒ Object

Validate that the default toolchain is or will be installed



288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
# File 'lib/puppet_x/rustup/provider/collection/toolchains.rb', line 288

def validate_default(normalized_default, requested_toolchains, purge)
  found = requested_toolchains.find do |info|
    normalize(info['name']) == normalized_default
  end

  if found
    if found['ensure'] == 'absent'
      raise Puppet::Error, "Requested #{normalized_default.inspect} as " \
        'default toolchain, but also set it to ensure => absent'
    end
  elsif !installed?(normalized_default)
    raise Puppet::Error, "Requested #{normalized_default.inspect} as " \
      'default toolchain, but it is not installed'
  elsif purge
    raise Puppet::Error, "Requested #{normalized_default.inspect} as " \
      'default toolchain, but it is being purged'
  end
end