1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
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
|
#
# Copyright:: Copyright 2009-2018, Chef Software Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
require "chef/resource"
class Chef
class Resource
class CpanModule < Chef::Resource
resource_name :cpan_module
provides :cpan_module
description "Use the cpan_module resource to install or uninstall perl CPAN modules."
introduced "14.0"
property :module_name,
String,
description: "The name of the module if it's different than the name of the resource.",
name_property: true
property :force,
[TrueClass, FalseClass],
description: "To force the install within cpanm.",
default: false
property :test,
[TrueClass, FalseClass],
description: "To do a test install.",
default: false
property :version,
String,
description: "Any version string cpanm would find acceptable."
property :cwd,
String,
description: "A path to change into before running cpanm."
property :cpanm_binary,
String,
description: "The path of the cpanm binary.",
default: "cpanm"
action :install do
description "Install the module."
declare_resource(:execute, "CPAN :install #{new_resource.module_name}") do
cwd current_working_dir
command cpanm_install_cmd
environment "HOME" => current_working_dir, "PATH" => "/usr/local/bin:/usr/bin:/bin"
not_if { module_exists_new_enough }
end
end
action :uninstall do
description "Uninstall the module."
declare_resource(:execute, "CPAN :uninstall #{new_resource.module_name}") do
cwd current_working_dir
command cpanm_uninstall_cmd
only_if { module_exists? }
end
end
action_class do
def module_exists_new_enough
existing_version = parse_cpan_version
return false if existing_version.empty? # mod doesn't exist
return true if new_resource.version.nil? # mod exists and version is unimportant
@comparator, @pending_version = new_resource.version.split(" ", 2)
@current_vers = Gem::Version.new(existing_version)
@pending_vers = Gem::Version.new(@pending_version)
@current_vers.method(@comparator).call(@pending_vers)
end
def parse_cpan_version
mod_ver_cmd = Mixlib::ShellOut.new("perl -M#{new_resource.module_name} -e 'print $#{new_resource.module_name}::VERSION;' 2> /dev/null")
mod_ver_cmd.run_command
mod_ver = mod_ver_cmd.stdout
return mod_ver if mod_ver.empty?
# remove leading v and convert underscores to dots since gems parses them wrong
mod_ver.gsub!(/v_?(\d)/, '\\1')
mod_ver.tr!("_", ".")
# in the event that this command outputs whatever it feels like, only keep the first vers number!
version_match = /(^[0-9.]*)/.match(mod_ver)
version_match[0]
end
def module_exists?
!shell_out("perl", "-M", new_resource.module_name, "-e", "1").error?
end
def cpanm_install_cmd
@cmd = "#{new_resource.cpanm_binary} --quiet "
@cmd += "--force " if new_resource.force
@cmd += "--notest " unless new_resource.test
@cmd += new_resource.module_name
@cmd += parsed_version
@cmd
end
def cpanm_uninstall_cmd
@cmd = "#{new_resource.cpanm_binary} "
@cmd += "--force " if new_resource.force
@cmd += "--uninstall "
@cmd += new_resource.module_name
@cmd
end
# a bit of a stub, could use a version parser for really consistent experience
def parsed_version
return "~\"#{new_resource.version}\"" if new_resource.version
""
end
def command_path
return 'C:\\strawberry\\perl\\bin' if platform?("windows")
"/usr/local/bin:/usr/bin:/bin"
end
def current_working_dir
return new_resource.cwd if new_resource.cwd
return "/var/root" if platform?("mac_os_x")
return 'C:\\' if platform?("windows")
"/root"
end
end
end
end
end
|