poise-languages 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/lib/poise_languages.rb +1 -0
- data/lib/poise_languages/command/mixin.rb +23 -14
- data/lib/poise_languages/scl/mixin.rb +12 -8
- data/lib/poise_languages/static.rb +34 -0
- data/lib/poise_languages/static/mixin.rb +127 -0
- data/lib/poise_languages/static/resource.rb +157 -0
- data/lib/poise_languages/system/mixin.rb +4 -3
- data/lib/poise_languages/utils.rb +2 -2
- data/lib/poise_languages/utils/which.rb +2 -0
- data/lib/poise_languages/version.rb +1 -1
- data/test/spec/command/mixin_spec.rb +5 -6
- data/test/spec/scl/mixin_spec.rb +38 -1
- data/test/spec/system/mixin_spec.rb +7 -2
- data/test/spec/utils/which_spec.rb +15 -0
- data/test/spec/utils_spec.rb +5 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a83f0d87752ae0d05c9559e572dcc877b4ff6383
|
4
|
+
data.tar.gz: 4d97ce1203bdbe9f54d070d2942be3ebdae14ad7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 364248c8d0541ec0f3fe00db0f9c260129214cf467008b5f77b19988a4c06d60a0aafef8698c7d190383ebb000b3a58f03b76f05ad01cdc2ef46d8d4d67df32c
|
7
|
+
data.tar.gz: 54c6bf4cfbce36e651b265f32c818f78ef1c5df358a2402fb26eb060a30df2820a9c467202836d005fd3ffe5fef9e4e5bd2bcded9df550f9cce5d32d17ddd8fe
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## v1.1.0
|
4
|
+
|
5
|
+
* Add helpers for installing from static archives.
|
6
|
+
* Improve auto-selection rules for system and SCL providers.
|
7
|
+
* Support SCL packages that depend on other SCL packages.
|
8
|
+
* Support Ruby 2.0 again.
|
9
|
+
|
3
10
|
## v1.0.0
|
4
11
|
|
5
12
|
* Initial release!
|
data/lib/poise_languages.rb
CHANGED
@@ -19,6 +19,7 @@ module PoiseLanguages
|
|
19
19
|
autoload :Command, 'poise_languages/command'
|
20
20
|
autoload :Error, 'poise_languages/error'
|
21
21
|
autoload :Scl, 'poise_languages/scl'
|
22
|
+
autoload :Static, 'poise_languages/static'
|
22
23
|
autoload :System, 'poise_languages/system'
|
23
24
|
autoload :Utils, 'poise_languages/utils'
|
24
25
|
autoload :VERSION, 'poise_languages/version'
|
@@ -17,9 +17,10 @@
|
|
17
17
|
require 'shellwords'
|
18
18
|
|
19
19
|
require 'chef/mixin/shell_out'
|
20
|
-
require 'chef/mixin/which'
|
21
20
|
require 'poise'
|
22
21
|
|
22
|
+
require 'poise_languages/utils'
|
23
|
+
|
23
24
|
|
24
25
|
module PoiseLanguages
|
25
26
|
module Command
|
@@ -39,7 +40,6 @@ module PoiseLanguages
|
|
39
40
|
# end
|
40
41
|
module Resource
|
41
42
|
include Poise::Resource
|
42
|
-
include Chef::Mixin::Which
|
43
43
|
poise_subresource(true)
|
44
44
|
|
45
45
|
private
|
@@ -51,7 +51,7 @@ module PoiseLanguages
|
|
51
51
|
# @param runtime [Symbol] Language runtime resource name.
|
52
52
|
# @param val [String, Chef::Resource, Poise::NOT_PASSED, nil] Accessor value.
|
53
53
|
# @return [String]
|
54
|
-
def language_command_runtime(name, runtime, val=Poise::NOT_PASSED)
|
54
|
+
def language_command_runtime(name, runtime, default_binary, val=Poise::NOT_PASSED)
|
55
55
|
unless val == Poise::NOT_PASSED
|
56
56
|
path_arg = parent_arg = nil
|
57
57
|
# Figure out which property we are setting.
|
@@ -80,7 +80,7 @@ module PoiseLanguages
|
|
80
80
|
set_or_return(name, path_arg, kind_of: [String, NilClass])
|
81
81
|
else
|
82
82
|
# Getter behavior. Using the ivar directly is kind of gross but oh well.
|
83
|
-
instance_variable_get(:"@#{name}") || default_language_command_runtime(name)
|
83
|
+
instance_variable_get(:"@#{name}") || default_language_command_runtime(name, default_binary)
|
84
84
|
end
|
85
85
|
end
|
86
86
|
|
@@ -89,12 +89,12 @@ module PoiseLanguages
|
|
89
89
|
# @api private
|
90
90
|
# @param name [Symbol] Language name.
|
91
91
|
# @return [String]
|
92
|
-
def default_language_command_runtime(name)
|
92
|
+
def default_language_command_runtime(name, default_binary)
|
93
93
|
parent = send(:"parent_#{name}")
|
94
94
|
if parent
|
95
95
|
parent.send(:"#{name}_binary")
|
96
96
|
else
|
97
|
-
which(name.to_s)
|
97
|
+
PoiseLanguages::Utils.which(default_binary || name.to_s)
|
98
98
|
end
|
99
99
|
end
|
100
100
|
|
@@ -122,8 +122,9 @@ module PoiseLanguages
|
|
122
122
|
# @param name [Symbol] Language name.
|
123
123
|
# @param runtime [Symbol] Language runtime resource name.
|
124
124
|
# @param timeout [Boolean] Enable the timeout attribute.
|
125
|
+
# @param default_binary [String] Name of the default language binary.
|
125
126
|
# @return [void]
|
126
|
-
def language_command_mixin(name, runtime: :"#{name}_runtime", timeout: true)
|
127
|
+
def language_command_mixin(name, runtime: :"#{name}_runtime", timeout: true, default_binary: nil)
|
127
128
|
# Create the parent attribute.
|
128
129
|
parent_attribute(name, type: runtime, optional: true)
|
129
130
|
|
@@ -132,13 +133,19 @@ module PoiseLanguages
|
|
132
133
|
|
133
134
|
# Create the main accessor for the parent/path.
|
134
135
|
define_method(name) do |val=Poise::NOT_PASSED|
|
135
|
-
language_command_runtime(name, runtime, val)
|
136
|
+
language_command_runtime(name, runtime, default_binary, val)
|
136
137
|
end
|
137
138
|
|
138
139
|
# Create the method to inherit settings from another resource.
|
139
|
-
|
140
|
+
define_method(:"#{name}_from_parent") do |resource|
|
140
141
|
language_command_runtime_from_parent(name, resource)
|
141
|
-
|
142
|
+
end
|
143
|
+
private :"#{name}_from_parent"
|
144
|
+
end
|
145
|
+
|
146
|
+
def language_command_default_binary(val=Poise::NOT_PASSED)
|
147
|
+
@language_command_default_binary = val if val != Poise::NOT_PASSED
|
148
|
+
@language_command_default_binary
|
142
149
|
end
|
143
150
|
|
144
151
|
# @api private
|
@@ -205,13 +212,15 @@ module PoiseLanguages
|
|
205
212
|
# @param name [Symbol] Language name.
|
206
213
|
# @return [void]
|
207
214
|
def language_command_mixin(name)
|
208
|
-
|
215
|
+
define_method(:"#{name}_shell_out") do |*command_args|
|
209
216
|
language_command_shell_out(name, *command_args)
|
210
|
-
|
217
|
+
end
|
218
|
+
private :"#{name}_shell_out"
|
211
219
|
|
212
|
-
|
220
|
+
define_method(:"#{name}_shell_out!") do |*command_args|
|
213
221
|
language_command_shell_out!(name, *command_args)
|
214
|
-
|
222
|
+
end
|
223
|
+
private :"#{name}_shell_out!"
|
215
224
|
end
|
216
225
|
|
217
226
|
# @api private
|
@@ -54,20 +54,22 @@ module PoiseLanguages
|
|
54
54
|
#
|
55
55
|
# @param path [String] Path to the enable file.
|
56
56
|
# @return [Hash<String, String>]
|
57
|
-
def parse_enable_file(path)
|
57
|
+
def parse_enable_file(path, env={})
|
58
58
|
# Doesn't exist yet, so running Python will fail anyway. Just make sure
|
59
59
|
# it fails in the expected way.
|
60
60
|
return {} unless File.exist?(path)
|
61
61
|
# Yes, this is a bash parser in regex. Feel free to be mad at me.
|
62
|
-
IO.readlines(path).inject(
|
62
|
+
IO.readlines(path).inject(env) do |memo, line|
|
63
63
|
if match = line.match(/^export (\w+)=(.*)$/)
|
64
|
-
memo[match[1]] = match[2].gsub(
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
end
|
64
|
+
memo[match[1]] = match[2].gsub(/\$(?:\{(\w+)(:\+:\$\{\w+\})?\}|(\w+))/) do
|
65
|
+
key = $1 || $3
|
66
|
+
value = (memo[key] || ENV[key]).to_s
|
67
|
+
value = ":#{value}" if $2 && !value.empty?
|
68
|
+
value
|
70
69
|
end
|
70
|
+
elsif match = line.match(/^\. scl_source enable (\w+)$/)
|
71
|
+
# Parse another file.
|
72
|
+
memo.update(parse_enable_file(::File.join('', 'opt', 'rh', match[1], 'enable'), memo))
|
71
73
|
end
|
72
74
|
memo
|
73
75
|
end
|
@@ -75,6 +77,8 @@ module PoiseLanguages
|
|
75
77
|
|
76
78
|
module ClassMethods
|
77
79
|
def provides_auto?(node, resource)
|
80
|
+
# They don't build 32-bit versions for these.
|
81
|
+
return false unless node['kernel']['machine'] == 'x86_64'
|
78
82
|
version = inversion_options(node, resource)['version']
|
79
83
|
!!find_scl_package(node, version)
|
80
84
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2015, Noah Kantrowitz
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
require 'poise/utils'
|
18
|
+
|
19
|
+
|
20
|
+
module PoiseLanguages
|
21
|
+
# Helpers for installing languages from static archives.
|
22
|
+
#
|
23
|
+
# @since 1.1.0
|
24
|
+
module Static
|
25
|
+
autoload :Mixin, 'poise_languages/static/mixin'
|
26
|
+
autoload :Resource, 'poise_languages/static/resource'
|
27
|
+
autoload :Provider, 'poise_languages/static/resource'
|
28
|
+
|
29
|
+
Poise::Utils.parameterized_module(self) do |opts|
|
30
|
+
require 'poise_languages/static/mixin'
|
31
|
+
include PoiseLanguages::Static::Mixin(opts)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2015, Noah Kantrowitz
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
require 'poise_languages/static/resource'
|
18
|
+
|
19
|
+
|
20
|
+
module PoiseLanguages
|
21
|
+
module Static
|
22
|
+
# Mixin for language providers to install from static archives.
|
23
|
+
#
|
24
|
+
# @since 1.1.0
|
25
|
+
module Mixin
|
26
|
+
private
|
27
|
+
|
28
|
+
def install_static
|
29
|
+
url = static_url
|
30
|
+
poise_languages_static static_folder do
|
31
|
+
source url
|
32
|
+
strip_components options['strip_components']
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def uninstall_static
|
37
|
+
install_static.tap do |r|
|
38
|
+
r.action(:uninstall)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def static_folder
|
43
|
+
options['path'] || ::File.join('', 'opt', "#{self.class.static_name}-#{options['static_version']}")
|
44
|
+
end
|
45
|
+
|
46
|
+
def static_url
|
47
|
+
options['url'] % static_url_variables
|
48
|
+
end
|
49
|
+
|
50
|
+
def static_url_variables
|
51
|
+
{
|
52
|
+
version: options['static_version'],
|
53
|
+
kernel: node['kernel']['name'].downcase,
|
54
|
+
machine: node['kernel']['machine'],
|
55
|
+
}
|
56
|
+
end
|
57
|
+
|
58
|
+
module ClassMethods
|
59
|
+
attr_accessor :static_name
|
60
|
+
attr_accessor :static_versions
|
61
|
+
attr_accessor :static_machines
|
62
|
+
attr_accessor :static_url
|
63
|
+
attr_accessor :static_strip_components
|
64
|
+
|
65
|
+
def provides_auto?(node, resource)
|
66
|
+
# Check that the version starts with our project name and the machine
|
67
|
+
# we are on is supported.
|
68
|
+
resource.version.to_s =~ /^#{static_name}(-|$)/ && static_machines.include?(static_machine_label(node))
|
69
|
+
end
|
70
|
+
|
71
|
+
# Set some default inversion provider options. Package name can't get
|
72
|
+
# a default value here because that would complicate the handling of
|
73
|
+
# {system_package_candidates}.
|
74
|
+
#
|
75
|
+
# @api private
|
76
|
+
def default_inversion_options(node, resource)
|
77
|
+
super.merge({
|
78
|
+
# Path to install the package. Defaults to /opt/name-version.
|
79
|
+
path: nil,
|
80
|
+
# Full version number for use in interpolation.
|
81
|
+
static_version: static_version(node, resource),
|
82
|
+
# Value to pass to tar --strip-components.
|
83
|
+
strip_components: static_strip_components,
|
84
|
+
# URL template to download from.
|
85
|
+
url: static_url,
|
86
|
+
})
|
87
|
+
end
|
88
|
+
|
89
|
+
def static_options(name: nil, versions: [], machines: %w{linux-i686 linux-x86_64}, url: nil, strip_components: 1)
|
90
|
+
raise PoiseLanguages::Error.new("Static archive URL is required, on #{self}") unless url
|
91
|
+
self.static_name = name || provides.to_s
|
92
|
+
self.static_versions = versions
|
93
|
+
self.static_machines = Set.new(machines)
|
94
|
+
self.static_url = url
|
95
|
+
self.static_strip_components = strip_components
|
96
|
+
end
|
97
|
+
|
98
|
+
def static_version(node, resource)
|
99
|
+
raw_version = resource.version.gsub(/^#{static_name}(-|$)/, '')
|
100
|
+
if static_versions.include?(raw_version)
|
101
|
+
raw_version
|
102
|
+
else
|
103
|
+
# Prefix match or just use the given version number if not found.
|
104
|
+
# This allow mild future proofing in some cases.
|
105
|
+
static_versions.find {|v| v.start_with?(raw_version) } || raw_version
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def static_machine_label(node)
|
110
|
+
"#{node['kernel']['name'].downcase}-#{node['kernel']['machine']}"
|
111
|
+
end
|
112
|
+
|
113
|
+
def included(klass)
|
114
|
+
super
|
115
|
+
klass.extend ClassMethods
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
extend ClassMethods
|
120
|
+
|
121
|
+
Poise::Utils.parameterized_module(self) do |opts|
|
122
|
+
static_options(opts)
|
123
|
+
end
|
124
|
+
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
@@ -0,0 +1,157 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2015, Noah Kantrowitz
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
require 'chef/resource'
|
18
|
+
require 'chef/provider'
|
19
|
+
require 'poise'
|
20
|
+
|
21
|
+
|
22
|
+
module PoiseLanguages
|
23
|
+
module Static
|
24
|
+
# A `poise_languages_static` resource to manage installing a language from
|
25
|
+
# static binary archives. This is an internal implementation detail of
|
26
|
+
# poise-languages.
|
27
|
+
#
|
28
|
+
# @api private
|
29
|
+
# @since 1.1.0
|
30
|
+
# @provides poise_languages_static
|
31
|
+
# @action install
|
32
|
+
# @action uninstall
|
33
|
+
class Resource < Chef::Resource
|
34
|
+
include Poise
|
35
|
+
provides(:poise_languages_static)
|
36
|
+
actions(:install, :uninstall)
|
37
|
+
|
38
|
+
# @!attribute path
|
39
|
+
# Directory to install to.
|
40
|
+
# @return [String]
|
41
|
+
attribute(:path, kind_of: String, name_attribute: true)
|
42
|
+
# @!attribute source
|
43
|
+
# URL to download from.
|
44
|
+
# @return [String]
|
45
|
+
attribute(:source, kind_of: String, required: true)
|
46
|
+
# @!attribute strip_components
|
47
|
+
# Value to pass to tar --strip-components.
|
48
|
+
# @return [String, Integer, nil]
|
49
|
+
attribute(:strip_components, kind_of: [String, Integer, NilClass], default: 1)
|
50
|
+
|
51
|
+
def cache_path
|
52
|
+
@cache_path ||= ::File.join(Chef::Config[:file_cache_path], source.split(/\//).last)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# The default provider for `poise_languages_static`.
|
57
|
+
#
|
58
|
+
# @api private
|
59
|
+
# @since 1.0
|
60
|
+
# @see Resource
|
61
|
+
# @provides poise_languages_static
|
62
|
+
class Provider < Chef::Provider
|
63
|
+
include Poise
|
64
|
+
provides(:poise_languages_static)
|
65
|
+
|
66
|
+
# The `install` action for the `poise_languages_static` resource.
|
67
|
+
#
|
68
|
+
# @return [void]
|
69
|
+
def action_install
|
70
|
+
notifying_block do
|
71
|
+
install_utils unless node.platform_family?('mac_os_x', 'windows')
|
72
|
+
create_directory
|
73
|
+
download_archive
|
74
|
+
# Unpack is handled as a notification from download_archive.
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# The `uninstall` action for the `poise_languages_static` resource.
|
79
|
+
#
|
80
|
+
# @return [void]
|
81
|
+
def action_uninstall
|
82
|
+
notifying_block do
|
83
|
+
delete_archive
|
84
|
+
delete_directory
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
def install_utils
|
91
|
+
package [].tap {|utils|
|
92
|
+
utils << 'tar' if new_resource.cache_path =~ /\.t(ar|gz|bz|xz)/
|
93
|
+
utils << 'bzip2' if new_resource.cache_path =~ /\.t?bz/
|
94
|
+
# This probably won't work on RHEL?
|
95
|
+
utils << 'xz-utils' if new_resource.cache_path =~ /\.t?xz/
|
96
|
+
}
|
97
|
+
end
|
98
|
+
|
99
|
+
def create_directory
|
100
|
+
directory new_resource.path do
|
101
|
+
user 0
|
102
|
+
group 0
|
103
|
+
mode '755'
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def download_archive
|
108
|
+
unpack_resource = unpack_archive
|
109
|
+
remote_file new_resource.cache_path do
|
110
|
+
source new_resource.source
|
111
|
+
owner 0
|
112
|
+
group 0
|
113
|
+
mode '644'
|
114
|
+
notifies :run, unpack_resource, :immediately
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def unpack_archive
|
119
|
+
# Build up the unpack command. Someday this will probably need to
|
120
|
+
# support unzip too.
|
121
|
+
cmd = %w{tar}
|
122
|
+
cmd << "--strip-components=#{new_resource.strip_components}" if new_resource.strip_components && new_resource.strip_components > 0
|
123
|
+
cmd << if new_resource.cache_path =~ /\.t?gz/
|
124
|
+
'-xzvf'
|
125
|
+
elsif new_resource.cache_path =~ /\.t?bz/
|
126
|
+
'-xjvf'
|
127
|
+
elsif new_resource.cache_path =~ /\.t?xz/
|
128
|
+
'-xJvf'
|
129
|
+
else
|
130
|
+
'-xvf'
|
131
|
+
end
|
132
|
+
cmd << new_resource.cache_path
|
133
|
+
|
134
|
+
execute 'unpack archive' do
|
135
|
+
# Run via notification from #download_archive.
|
136
|
+
action :nothing
|
137
|
+
command cmd
|
138
|
+
cwd new_resource.path
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def delete_archive
|
143
|
+
file new_resource.cache_path do
|
144
|
+
action :delete
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def delete_directory
|
149
|
+
directory new_resource.path do
|
150
|
+
action :delete
|
151
|
+
recursive true
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
@@ -92,12 +92,13 @@ module PoiseLanguages
|
|
92
92
|
end
|
93
93
|
|
94
94
|
module ClassMethods
|
95
|
-
# Install this as a default provider
|
96
|
-
#
|
95
|
+
# Install this as a default provider if nothing else matched. Might not
|
96
|
+
# work, but worth a try at least for unknown platforms. Windows is a
|
97
|
+
# whole different story, and OS X might work sometimes so at least try.
|
97
98
|
#
|
98
99
|
# @api private
|
99
100
|
def provides_auto?(node, resource)
|
100
|
-
|
101
|
+
!node.platform_family?('windows')
|
101
102
|
end
|
102
103
|
|
103
104
|
# Set some default inversion provider options. Package name can't get
|
@@ -36,8 +36,8 @@ module PoiseLanguages
|
|
36
36
|
else
|
37
37
|
Shellwords.split(cmd)
|
38
38
|
end
|
39
|
-
# Don't try to touch anything if the first value looks like a flag.
|
40
|
-
if cmd.first && !cmd.first.start_with?('-')
|
39
|
+
# Don't try to touch anything if the first value looks like a flag or a path.
|
40
|
+
if cmd.first && !cmd.first.start_with?('-') && !cmd.first.include?(::File::SEPARATOR)
|
41
41
|
# If which returns false, just leave it I guess.
|
42
42
|
cmd[0] = which(cmd.first, path: path) || cmd.first
|
43
43
|
end
|
@@ -32,6 +32,8 @@ module PoiseLanguages
|
|
32
32
|
# @param path [String, nil] Replacement $PATH value.
|
33
33
|
# @return [String, false]
|
34
34
|
def which(cmd, extra_path: %w{/bin /usr/bin /sbin /usr/sbin}, path: nil)
|
35
|
+
# If it was already absolute, just return that.
|
36
|
+
return cmd if cmd =~ /^(\/|([a-z]:)?\\)/i
|
35
37
|
# Allow passing something other than the real env var.
|
36
38
|
path ||= ENV['PATH']
|
37
39
|
# Based on Chef::Mixin::Which#which
|
@@ -24,6 +24,11 @@ describe PoiseLanguages::Command::Mixin do
|
|
24
24
|
end
|
25
25
|
provider(:mylang_runtime)
|
26
26
|
let(:runtime) { chef_run.mylang_runtime('parent') }
|
27
|
+
before do
|
28
|
+
allow(PoiseLanguages::Utils).to receive(:which) do |name|
|
29
|
+
"/which/#{name}"
|
30
|
+
end
|
31
|
+
end
|
27
32
|
|
28
33
|
describe PoiseLanguages::Command::Mixin::Resource do
|
29
34
|
resource(:poise_test) do
|
@@ -32,9 +37,6 @@ describe PoiseLanguages::Command::Mixin do
|
|
32
37
|
include klass
|
33
38
|
language_command_mixin(:mylang)
|
34
39
|
}
|
35
|
-
def which(name)
|
36
|
-
"/which/#{name}"
|
37
|
-
end
|
38
40
|
end
|
39
41
|
provider(:poise_test)
|
40
42
|
|
@@ -227,9 +229,6 @@ describe PoiseLanguages::Command::Mixin do
|
|
227
229
|
attribute(:command)
|
228
230
|
attribute(:expect)
|
229
231
|
attribute(:options, default: [])
|
230
|
-
def which(name)
|
231
|
-
"/which/#{name}"
|
232
|
-
end
|
233
232
|
end
|
234
233
|
|
235
234
|
describe '#$name_shell_out' do
|
data/test/spec/scl/mixin_spec.rb
CHANGED
@@ -142,10 +142,47 @@ EOH
|
|
142
142
|
end
|
143
143
|
it { is_expected.to eq({}) }
|
144
144
|
end # /context with a non-existent file
|
145
|
+
|
146
|
+
context 'with an scl_source line' do
|
147
|
+
# $ cat /opt/rh/nodejs010/enable
|
148
|
+
let(:content) { <<-EOH }
|
149
|
+
export PATH=/opt/rh/nodejs010/root/usr/bin${PATH:+:${PATH}}
|
150
|
+
export LD_LIBRARY_PATH=/opt/rh/nodejs010/root/usr/lib64${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}
|
151
|
+
export PYTHONPATH=/opt/rh/nodejs010/root/usr/lib/python2.7/site-packages${PYTHONPATH:+:${PYTHONPATH}}
|
152
|
+
export MANPATH=/opt/rh/nodejs010/root/usr/share/man:$MANPATH
|
153
|
+
. scl_source enable v8314
|
154
|
+
EOH
|
155
|
+
let(:v8_content) { <<-EOH }
|
156
|
+
export PATH=/opt/rh/v8314/root/usr/bin${PATH:+:${PATH}}
|
157
|
+
export LD_LIBRARY_PATH=/opt/rh/v8314/root/usr/lib64${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}
|
158
|
+
export PYTHONPATH=/opt/rh/v8314/root/usr/lib/python2.7/site-packages${PYTHONPATH:+:${PYTHONPATH}}
|
159
|
+
export MANPATH=/opt/rh/v8314/root/usr/share/man:$MANPATH
|
160
|
+
export PKG_CONFIG_PATH=/opt/rh/v8314/root/usr/lib64/pkgconfig${PKG_CONFIG_PATH:+:${PKG_CONFIG_PATH}}
|
161
|
+
export CPATH=/opt/rh/v8314/root/usr/include${CPATH:+:${CPATH}}
|
162
|
+
export LIBRARY_PATH=/opt/rh/v8314/root/usr/lib64${LIBRARY_PATH:+:${LIBRARY_PATH}}
|
163
|
+
EOH
|
164
|
+
|
165
|
+
before do
|
166
|
+
allow(File).to receive(:exist?).with('/opt/rh/v8314/enable').and_return(true)
|
167
|
+
allow(IO).to receive(:readlines).with('/opt/rh/v8314/enable').and_return(v8_content.split(/\n/))
|
168
|
+
end
|
169
|
+
|
170
|
+
it do
|
171
|
+
is_expected.to eq({
|
172
|
+
'PATH' => "/opt/rh/v8314/root/usr/bin:/opt/rh/nodejs010/root/usr/bin#{ENV['PATH'] ? ':' + ENV['PATH'] : ''}",
|
173
|
+
'LD_LIBRARY_PATH' => "/opt/rh/v8314/root/usr/lib64:/opt/rh/nodejs010/root/usr/lib64#{ENV['LD_LIBRARY_PATH'] ? ':' + ENV['LD_LIBRARY_PATH'] : ''}",
|
174
|
+
'PYTHONPATH' => "/opt/rh/v8314/root/usr/lib/python2.7/site-packages:/opt/rh/nodejs010/root/usr/lib/python2.7/site-packages#{ENV['PYTHONPATH'] ? ':' + ENV['PYTHONPATH'] : ''}",
|
175
|
+
'MANPATH' => "/opt/rh/v8314/root/usr/share/man:/opt/rh/nodejs010/root/usr/share/man:#{ENV['MANPATH']}",
|
176
|
+
'PKG_CONFIG_PATH' => "/opt/rh/v8314/root/usr/lib64/pkgconfig#{ENV['PKG_CONFIG_PATH'] ? ':' + ENV['PKG_CONFIG_PATH'] : ''}",
|
177
|
+
'CPATH' => "/opt/rh/v8314/root/usr/include#{ENV['CPATH'] ? ':' + ENV['CPATH'] : ''}",
|
178
|
+
'LIBRARY_PATH' => "/opt/rh/v8314/root/usr/lib64#{ENV['LIBRARY_PATH'] ? ':' + ENV['LIBRARY_PATH'] : ''}",
|
179
|
+
})
|
180
|
+
end
|
181
|
+
end # /context with an scl_source line
|
145
182
|
end # /describe #parse_enable_file
|
146
183
|
|
147
184
|
describe '.provides_auto?' do
|
148
|
-
let(:node) { double('node') }
|
185
|
+
let(:node) { double('node', :"[]" => {'machine' => 'x86_64'}) }
|
149
186
|
let(:new_resource) { double('resource') }
|
150
187
|
subject { provider(:poise_test).provides_auto?(node, new_resource) }
|
151
188
|
before do
|
@@ -152,11 +152,16 @@ describe PoiseLanguages::System::Mixin do
|
|
152
152
|
|
153
153
|
context 'on CentOS' do
|
154
154
|
let(:chefspec_options) { {platform: 'centos', version: '7.0'} }
|
155
|
-
it { is_expected.to be true}
|
155
|
+
it { is_expected.to be true }
|
156
156
|
end # /context on CentOS
|
157
157
|
|
158
|
+
context 'on Windows' do
|
159
|
+
let(:chefspec_options) { {platform: 'windows', version: '2012R2'} }
|
160
|
+
it { is_expected.to be false }
|
161
|
+
end # /context on Windows
|
162
|
+
|
158
163
|
context 'on an unknown platform' do
|
159
|
-
it { is_expected.to be
|
164
|
+
it { is_expected.to be true }
|
160
165
|
end # /context on an unknown platform
|
161
166
|
end # /describe .provides_auto?
|
162
167
|
|
@@ -66,4 +66,19 @@ describe PoiseLanguages::Utils::Which do
|
|
66
66
|
let(:executables) { {'/bin/myapp' => false, '/usr/bin/myapp' => false, '/sbin/myapp' => false, '/usr/sbin/myapp' => false} }
|
67
67
|
it { is_expected.to be false }
|
68
68
|
end # /context with a non-existent command
|
69
|
+
|
70
|
+
context 'with an absolute Unix path' do
|
71
|
+
let(:params) { ['/myapp'] }
|
72
|
+
it { is_expected.to eq '/myapp' }
|
73
|
+
end # /context with an absolute Unix path
|
74
|
+
|
75
|
+
context 'with an absolute Windows path' do
|
76
|
+
let(:params) { ['C:\\myapp'] }
|
77
|
+
it { is_expected.to eq 'C:\\myapp' }
|
78
|
+
end # /context with an absolute Windows path
|
79
|
+
|
80
|
+
context 'with an absolute UNC path' do
|
81
|
+
let(:params) { ['//myapp'] }
|
82
|
+
it { is_expected.to eq '//myapp' }
|
83
|
+
end # /context with an absolute UNC path
|
69
84
|
end
|
data/test/spec/utils_spec.rb
CHANGED
@@ -46,6 +46,11 @@ describe PoiseLanguages::Utils do
|
|
46
46
|
let(:which) { false }
|
47
47
|
it { is_expected.to eq 'myapp --port 8080' }
|
48
48
|
end # /context with an unknown command
|
49
|
+
|
50
|
+
context 'with a relative path' do
|
51
|
+
let(:cmd) { "#{File.join('.', 'myapp')} --port 8080" }
|
52
|
+
it { is_expected.to eq "#{File.join('.', 'myapp')} --port 8080" }
|
53
|
+
end # /context with a relative path
|
49
54
|
end # /describe #absolute_command
|
50
55
|
|
51
56
|
describe '#which' do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: poise-languages
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Noah Kantrowitz
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-09-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: halite
|
@@ -73,6 +73,9 @@ files:
|
|
73
73
|
- lib/poise_languages/scl.rb
|
74
74
|
- lib/poise_languages/scl/mixin.rb
|
75
75
|
- lib/poise_languages/scl/resource.rb
|
76
|
+
- lib/poise_languages/static.rb
|
77
|
+
- lib/poise_languages/static/mixin.rb
|
78
|
+
- lib/poise_languages/static/resource.rb
|
76
79
|
- lib/poise_languages/system.rb
|
77
80
|
- lib/poise_languages/system/mixin.rb
|
78
81
|
- lib/poise_languages/system/resource.rb
|