Top Level Namespace

Defined Under Namespace

Modules: ChefPowerShellModule, FFI Classes: Chef, ChefPowerShell, String

Constant Summary collapse

REQUIRED_DLLS =

Required DLL files that must be present in chefembeddedbin

[
  "vcruntime140.dll",
  "vcruntime140_1.dll",
  "ijwhost.dll",
  "msvcp140.dll",
].freeze

Instance Method Summary collapse

Instance Method Details

#file_needs_update?(source, dest) ⇒ Boolean

Returns:

  • (Boolean)


81
82
83
84
85
86
87
88
89
90
# File 'ext/chef-powershell/extconf.rb', line 81

def file_needs_update?(source, dest)
  return true unless File.exist?(dest)

  # Compare file sizes and modification times
  source_stat = File.stat(source)
  dest_stat = File.stat(dest)

  # Update if sizes differ or source is newer
  source_stat.size != dest_stat.size || source_stat.mtime > dest_stat.mtime
end

#find_chef_embedded_binObject



45
46
47
48
49
50
51
52
53
54
55
56
# File 'ext/chef-powershell/extconf.rb', line 45

def find_chef_embedded_bin
  # Use RbConfig to find the embedded bin directory
  # This works because Chef installs gems into its embedded Ruby
  embedded_bin_path = RbConfig::CONFIG["bindir"]

  # Verify the path exists and normalize it
  if embedded_bin_path && File.directory?(embedded_bin_path)
    return embedded_bin_path.tr("\\", "/")
  end

  nil
end

#find_source_dllsObject



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'ext/chef-powershell/extconf.rb', line 58

def find_source_dlls
  # Look for DLLs in the gem's bin directory structure
  # They should be in bin/ruby_bin_folder/<ARCH>/
  gem_bin_dir = File.expand_path("../../bin", __dir__)
  arch = ENV["PROCESSOR_ARCHITECTURE"] || "AMD64"

  possible_locations = [
    File.join(gem_bin_dir, "ruby_bin_folder", arch),
    gem_bin_dir,
  ]

  possible_locations.each do |location|
    if File.directory?(location)
      # Check if at least one required DLL exists here
      if REQUIRED_DLLS.any? { |dll| File.exist?(File.join(location, dll)) }
        return location
      end
    end
  end

  nil
end

#install_dllsObject



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
# File 'ext/chef-powershell/extconf.rb', line 92

def install_dlls
  log "Checking for required PowerShell DLL files..."

  # Find the Chef embedded bin directory
  target_dir = find_chef_embedded_bin

  unless target_dir
    log "WARNING: Could not locate Chef embedded bin directory."
    log "DLL files will not be installed automatically."
    log "If you are using Chef, please ensure the following DLLs are in chef/embedded/bin:"
    REQUIRED_DLLS.each { |dll| log "  - #{dll}" }
    return
  end

  log "Found Chef embedded bin directory: #{target_dir}"

  # Find source DLLs
  source_dir = find_source_dlls

  unless source_dir
    arch = ENV["PROCESSOR_ARCHITECTURE"] || "AMD64"
    log "WARNING: Could not locate source DLL files in gem installation."
    log "Expected location: bin/ruby_bin_folder/#{arch}/"
    log "DLL files will not be installed."
    return
  end

  log "Found source DLLs in: #{source_dir}"

  # Copy each required DLL if present and needs updating
  installed = []
  updated = []
  missing = []
  skipped = []

  REQUIRED_DLLS.each do |dll|
    source_file = File.join(source_dir, dll)
    dest_file = File.join(target_dir, dll)

    unless File.exist?(source_file)
      missing << dll
      next
    end

    begin
      if File.exist?(dest_file)
        if file_needs_update?(source_file, dest_file)
          FileUtils.cp(source_file, dest_file, preserve: true)
          updated << dll
          log "Updated: #{dll}"
        else
          skipped << dll
        end
      else
        FileUtils.cp(source_file, dest_file, preserve: true)
        installed << dll
        log "Installed: #{dll}"
      end
    rescue => e
      log "ERROR: Failed to copy #{dll}: #{e.message}"
    end
  end

  # Summary
  log "Installation complete:"
  log "  - Newly installed: #{installed.length}" unless installed.empty?
  log "  - Updated: #{updated.length}" unless updated.empty?
  log "  - Already up-to-date: #{skipped.length}" unless skipped.empty?
  log "  - Missing from source: #{missing.length}" unless missing.empty?

  if missing.any?
    log "WARNING: The following DLL files were not found in the gem:"
    missing.each { |dll| log "  - #{dll}" }
  end
end

#log(message) ⇒ Object



41
42
43
# File 'ext/chef-powershell/extconf.rb', line 41

def log(message)
  puts "[chef-powershell] #{message}"
end