poise-python 1.1.2 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -0
- data/README.md +2 -0
- data/lib/poise_python/python_command_mixin.rb +5 -1
- data/lib/poise_python/python_providers.rb +1 -0
- data/lib/poise_python/python_providers/dummy.rb +10 -1
- data/lib/poise_python/python_providers/portable_pypy.rb +1 -1
- data/lib/poise_python/python_providers/system.rb +3 -3
- data/lib/poise_python/resources/pip_requirements.rb +9 -1
- data/lib/poise_python/resources/python_package.rb +29 -6
- data/lib/poise_python/resources/python_runtime_test.rb +34 -3
- data/lib/poise_python/resources/python_virtualenv.rb +1 -1
- data/lib/poise_python/version.rb +1 -1
- data/test/integration/default/serverspec/default_spec.rb +1 -1
- data/test/spec/python_providers/portable_pypy3_spec.rb +1 -0
- data/test/spec/python_providers/portable_pypy_spec.rb +3 -2
- data/test/spec/python_providers/scl_spec.rb +1 -0
- data/test/spec/python_providers/system_spec.rb +20 -2
- data/test/spec/resources/pip_requirements_spec.rb +26 -4
- data/test/spec/resources/python_package_spec.rb +172 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6f954d22962ad5f19fbefef8ce992f18bc0f8b73
|
4
|
+
data.tar.gz: 91a35461eaecb05a6e3e5dee93e9b4d551d95403
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b108843aca7b5c9f6c4db0f991c88c6179c8b91f406bcb44ae4df0b90ff02106080aa4e53610454f2ce4108c00238b973f119ce4f46cbea88a9eaef47be17c2a
|
7
|
+
data.tar.gz: 60273ff1bc570326fee7b2875210ff4f748dd0620332aeb3bbaa211a83d64ec514c63453f1c216f5444ef5f8f81817c1d286b8837c2f49e9151d3024facb6952
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,15 @@
|
|
1
1
|
# Poise-Python Changelog
|
2
2
|
|
3
|
+
## v1.2.0
|
4
|
+
|
5
|
+
* Add support for passing `user` and `group` to `pip_requirements`.
|
6
|
+
* Allow passing a virtualenv resource object to the `virtualenv` property.
|
7
|
+
* Update PyPy release versions.
|
8
|
+
* Make the `python_virtualenv` resource check for `./bin/python` for idempotence
|
9
|
+
instead of the base path.
|
10
|
+
* Support for packages with extras in `python_package`.
|
11
|
+
* Support for point releases (7.1, 8.1, etc) of Debian in the `system` provider.
|
12
|
+
|
3
13
|
## v1.1.2
|
4
14
|
|
5
15
|
* Fix `PythonPackage#response_file_variables` for the Chef 12.6 initializer.
|
data/README.md
CHANGED
@@ -277,9 +277,11 @@ notifications will only be triggered if a package is actually installed.
|
|
277
277
|
|
278
278
|
* `path` – Path to the requirements file, or a folder containing the
|
279
279
|
requirements file. *(name property)*
|
280
|
+
* `group` – System group to install the packages.
|
280
281
|
* `python` – Name of the `python_runtime` resource to use. If not specified, the
|
281
282
|
most recently declared `python_runtime` will be used. Can also be set to the
|
282
283
|
full path to a `python` binary.
|
284
|
+
* `user` – System user to install the packages.
|
283
285
|
* `virtualenv` – Name of the `python_virtualenv` resource to use. This is
|
284
286
|
mutually exclusive with the `python` property.
|
285
287
|
|
@@ -34,7 +34,11 @@ module PoisePython
|
|
34
34
|
# @param name [String] Name of the virtualenv resource.
|
35
35
|
# @return [void]
|
36
36
|
def virtualenv(name)
|
37
|
-
|
37
|
+
if name.is_a?(PoisePython::Resources::PythonVirtualenv::Resource)
|
38
|
+
parent_python(name)
|
39
|
+
else
|
40
|
+
parent_python("python_virtualenv[#{name}]")
|
41
|
+
end
|
38
42
|
end
|
39
43
|
end
|
40
44
|
|
@@ -31,6 +31,7 @@ module PoisePython
|
|
31
31
|
autoload :Base, 'poise_python/python_providers/base'
|
32
32
|
|
33
33
|
Chef::Platform::ProviderPriorityMap.instance.priority(:python_runtime, [
|
34
|
+
PoisePython::PythonProviders::Dummy,
|
34
35
|
PoisePython::PythonProviders::PortablePyPy3,
|
35
36
|
PoisePython::PythonProviders::PortablePyPy,
|
36
37
|
PoisePython::PythonProviders::Scl,
|
@@ -27,9 +27,18 @@ module PoisePython
|
|
27
27
|
class Dummy < Base
|
28
28
|
provides(:dummy)
|
29
29
|
|
30
|
+
# Enable by default on ChefSpec.
|
31
|
+
#
|
32
|
+
# @api private
|
33
|
+
def self.provides_auto?(node, _resource)
|
34
|
+
node.platform?('chefspec')
|
35
|
+
end
|
36
|
+
|
37
|
+
# Manual overrides for dummy data.
|
38
|
+
#
|
39
|
+
# @api private
|
30
40
|
def self.default_inversion_options(node, resource)
|
31
41
|
super.merge({
|
32
|
-
# Manual overrides for dummy data.
|
33
42
|
python_binary: ::File.join('', 'python'),
|
34
43
|
python_environment: nil,
|
35
44
|
})
|
@@ -26,7 +26,7 @@ module PoisePython
|
|
26
26
|
provides(:portable_pypy)
|
27
27
|
include PoiseLanguages::Static(
|
28
28
|
name: 'pypy',
|
29
|
-
versions: %w{2.6 2.5.1 2.5 2.4 2.3.1 2.3 2.2.1 2.2 2.1 2.0.2},
|
29
|
+
versions: %w{4.0.1 2.6.1 2.5.1 2.5 2.4 2.3.1 2.3 2.2.1 2.2 2.1 2.0.2},
|
30
30
|
machines: %w{linux-i686 linux-x86_64},
|
31
31
|
url: 'https://bitbucket.org/squeaky/portable-pypy/downloads/pypy-%{version}-%{kernel}_%{machine}-portable.tar.bz2'
|
32
32
|
)
|
@@ -28,9 +28,9 @@ module PoisePython
|
|
28
28
|
provides(:system)
|
29
29
|
packages('python', {
|
30
30
|
debian: {
|
31
|
-
'8' => %w{python3.4 python2.7},
|
32
|
-
'7' => %w{python3.2 python2.7 python2.6},
|
33
|
-
'6' => %w{python3.1 python2.6 python2.5},
|
31
|
+
'~> 8.0' => %w{python3.4 python2.7},
|
32
|
+
'~> 7.0' => %w{python3.2 python2.7 python2.6},
|
33
|
+
'~> 6.0' => %w{python3.1 python2.6 python2.5},
|
34
34
|
},
|
35
35
|
ubuntu: {
|
36
36
|
'14.04' => %w{python3.4 python2.7},
|
@@ -44,6 +44,14 @@ module PoisePython
|
|
44
44
|
# requirements file.
|
45
45
|
# @return [String]
|
46
46
|
attribute(:path, kind_of: String, name_attribute: true)
|
47
|
+
# @!attribute group
|
48
|
+
# System group to install the package.
|
49
|
+
# @return [String, Integer, nil]
|
50
|
+
attribute(:group, kind_of: [String, Integer, NilClass])
|
51
|
+
# @!attribute user
|
52
|
+
# System user to install the package.
|
53
|
+
# @return [String, Integer, nil]
|
54
|
+
attribute(:user, kind_of: [String, Integer, NilClass])
|
47
55
|
end
|
48
56
|
|
49
57
|
# The default provider for `pip_requirements`.
|
@@ -80,7 +88,7 @@ module PoisePython
|
|
80
88
|
cmd << '--upgrade' if upgrade
|
81
89
|
cmd << '--requirement'
|
82
90
|
cmd << requirements_path
|
83
|
-
output = python_shell_out!(cmd).stdout
|
91
|
+
output = python_shell_out!(cmd, user: new_resource.user, group: new_resource.group).stdout
|
84
92
|
if output.include?('Successfully installed')
|
85
93
|
new_resource.updated_by_last_action(true)
|
86
94
|
end
|
@@ -91,7 +91,6 @@ EOH
|
|
91
91
|
Poise::Helpers::ChefspecMatchers.create_matcher(:python_package, action)
|
92
92
|
end
|
93
93
|
|
94
|
-
|
95
94
|
# @!attribute group
|
96
95
|
# System group to install the package.
|
97
96
|
# @return [String, Integer, nil]
|
@@ -165,7 +164,7 @@ EOH
|
|
165
164
|
version_data[name][:current] = current
|
166
165
|
end
|
167
166
|
# Check for newer candidates.
|
168
|
-
outdated = pip_outdated(pip_requirements(resource.package_name, version)).stdout
|
167
|
+
outdated = pip_outdated(pip_requirements(resource.package_name, version, parse: true)).stdout
|
169
168
|
parse_pip_outdated(outdated).each do |name, candidate|
|
170
169
|
# Merge candidates in to the existing versions.
|
171
170
|
version_data[name][:candidate] = candidate
|
@@ -176,13 +175,13 @@ EOH
|
|
176
175
|
@candidate_version = []
|
177
176
|
versions = []
|
178
177
|
[resource.package_name].flatten.each do |name|
|
179
|
-
ver = version_data[name.downcase]
|
178
|
+
ver = version_data[parse_package_name(name).downcase]
|
180
179
|
versions << ver[:current]
|
181
180
|
@candidate_version << ver[:candidate]
|
182
181
|
end
|
183
182
|
resource.version(versions)
|
184
183
|
else
|
185
|
-
ver = version_data[resource.package_name.downcase]
|
184
|
+
ver = version_data[parse_package_name(resource.package_name).downcase]
|
186
185
|
resource.version(ver[:current])
|
187
186
|
@candidate_version = ver[:candidate]
|
188
187
|
end
|
@@ -223,11 +222,16 @@ EOH
|
|
223
222
|
# @param name [String, Array<String>] Name or names for the packages.
|
224
223
|
# @param version [String, Array<String>] Version or versions for the
|
225
224
|
# packages.
|
225
|
+
# @param parse [Boolean] Use parsed package names.
|
226
226
|
# @return [Array<String>]
|
227
|
-
def pip_requirements(name, version)
|
227
|
+
def pip_requirements(name, version, parse: false)
|
228
228
|
[name].flatten.zip([version].flatten).map do |n, v|
|
229
|
+
n = parse_package_name(n) if parse
|
229
230
|
v = v.to_s.strip
|
230
|
-
if
|
231
|
+
if n =~ /:\/\//
|
232
|
+
# Probably a URI.
|
233
|
+
n
|
234
|
+
elsif v.empty?
|
231
235
|
# No version requirement, send through unmodified.
|
232
236
|
n
|
233
237
|
elsif v =~ /^\d/
|
@@ -322,6 +326,25 @@ EOH
|
|
322
326
|
end
|
323
327
|
end
|
324
328
|
|
329
|
+
# Regexp for package URLs.
|
330
|
+
PACKAGE_NAME_URL = /:\/\/.*?#egg=(.*)$/
|
331
|
+
|
332
|
+
# Regexp for extras.
|
333
|
+
PACKAGE_NAME_EXTRA = /^(.*?)\[.*?\]$/
|
334
|
+
|
335
|
+
# Find the underlying name from a pip input sequence.
|
336
|
+
#
|
337
|
+
# @param raw_name [String] Raw package name.
|
338
|
+
# @return [String]
|
339
|
+
def parse_package_name(raw_name)
|
340
|
+
case raw_name
|
341
|
+
when PACKAGE_NAME_URL, PACKAGE_NAME_EXTRA
|
342
|
+
$1
|
343
|
+
else
|
344
|
+
raw_name
|
345
|
+
end
|
346
|
+
end
|
347
|
+
|
325
348
|
end
|
326
349
|
end
|
327
350
|
end
|
@@ -40,7 +40,7 @@ module PoisePython
|
|
40
40
|
attribute(:path, kind_of: String, default: lazy { default_path })
|
41
41
|
|
42
42
|
def default_path
|
43
|
-
::File.join('', '
|
43
|
+
::File.join('', 'opt', "python_test_#{name}")
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
@@ -58,7 +58,9 @@ module PoisePython
|
|
58
58
|
def action_run
|
59
59
|
notifying_block do
|
60
60
|
# Top level directory for this test.
|
61
|
-
directory new_resource.path
|
61
|
+
directory new_resource.path do
|
62
|
+
mode '777'
|
63
|
+
end
|
62
64
|
|
63
65
|
# Install and log the version.
|
64
66
|
python_runtime new_resource.name do
|
@@ -128,6 +130,34 @@ EOH
|
|
128
130
|
end
|
129
131
|
test_import('requests')
|
130
132
|
test_import('six')
|
133
|
+
|
134
|
+
# Create a non-root user and test installing with it.
|
135
|
+
test_user = "py#{new_resource.name}"
|
136
|
+
test_home = ::File.join('', 'home', test_user)
|
137
|
+
group test_user do
|
138
|
+
system true
|
139
|
+
end
|
140
|
+
user test_user do
|
141
|
+
comment "Test user for python_runtime_test #{new_resource.name}"
|
142
|
+
gid test_user
|
143
|
+
home test_home
|
144
|
+
shell '/bin/false'
|
145
|
+
system true
|
146
|
+
end
|
147
|
+
directory test_home do
|
148
|
+
mode '700'
|
149
|
+
group test_user
|
150
|
+
user test_user
|
151
|
+
end
|
152
|
+
test_venv = python_virtualenv ::File.join(test_home, 'env') do
|
153
|
+
python new_resource.name
|
154
|
+
user test_user
|
155
|
+
end
|
156
|
+
python_package 'attrs' do
|
157
|
+
user test_user
|
158
|
+
virtualenv test_venv
|
159
|
+
end
|
160
|
+
test_import('attrs', 'attr', python: nil, virtualenv: test_venv, user: test_user)
|
131
161
|
end
|
132
162
|
end
|
133
163
|
|
@@ -157,7 +187,7 @@ EOH
|
|
157
187
|
end
|
158
188
|
end
|
159
189
|
|
160
|
-
def test_import(name, path=name, python: new_resource.name, virtualenv: nil)
|
190
|
+
def test_import(name, path=name, python: new_resource.name, virtualenv: nil, user: nil)
|
161
191
|
# Only queue up this resource once, the ivar is just for tracking.
|
162
192
|
@python_import_test ||= file ::File.join(new_resource.path, 'import_version.py') do
|
163
193
|
user 'root'
|
@@ -175,6 +205,7 @@ EOH
|
|
175
205
|
|
176
206
|
python_execute "#{@python_import_test.path} #{name} #{::File.join(new_resource.path, "import_#{path}")}" do
|
177
207
|
python python if python
|
208
|
+
user user if user
|
178
209
|
virtualenv virtualenv if virtualenv
|
179
210
|
end
|
180
211
|
end
|
data/lib/poise_python/version.rb
CHANGED
@@ -20,7 +20,7 @@ set :backend, :exec
|
|
20
20
|
# Set up the shared example for python_runtime_test.
|
21
21
|
RSpec.shared_examples 'a python_runtime_test' do |python_name, version=nil|
|
22
22
|
let(:python_name) { python_name }
|
23
|
-
let(:python_path) { File.join('', '
|
23
|
+
let(:python_path) { File.join('', 'opt', "python_test_#{python_name}") }
|
24
24
|
# Helper for all the file checks.
|
25
25
|
def self.assert_file(rel_path, should_exist=true, &block)
|
26
26
|
describe rel_path do
|
@@ -24,6 +24,7 @@ describe PoisePython::PythonProviders::PortablePyPy do
|
|
24
24
|
step_into(:python_runtime)
|
25
25
|
recipe do
|
26
26
|
python_runtime 'test' do
|
27
|
+
provider_no_auto 'dummy'
|
27
28
|
version node['poise_python_version']
|
28
29
|
virtualenv_version false
|
29
30
|
end
|
@@ -37,7 +38,7 @@ describe PoisePython::PythonProviders::PortablePyPy do
|
|
37
38
|
|
38
39
|
context 'with version pypy' do
|
39
40
|
let(:python_version) { 'pypy' }
|
40
|
-
it_behaves_like 'portablepypy provider', 'pypy-
|
41
|
+
it_behaves_like 'portablepypy provider', 'pypy-4.0.1'
|
41
42
|
end # /context with version pypy
|
42
43
|
|
43
44
|
context 'with version pypy-2.4' do
|
@@ -53,6 +54,6 @@ describe PoisePython::PythonProviders::PortablePyPy do
|
|
53
54
|
end
|
54
55
|
end
|
55
56
|
|
56
|
-
it { is_expected.to uninstall_poise_languages_static('/opt/pypy-
|
57
|
+
it { is_expected.to uninstall_poise_languages_static('/opt/pypy-4.0.1') }
|
57
58
|
end # /context action :uninstall
|
58
59
|
end
|
@@ -25,14 +25,15 @@ describe PoisePython::PythonProviders::System do
|
|
25
25
|
step_into(:python_runtime)
|
26
26
|
recipe do
|
27
27
|
python_runtime 'test' do
|
28
|
+
provider_no_auto 'dummy'
|
28
29
|
version node['poise_python_version']
|
29
30
|
virtualenv_version false
|
30
31
|
end
|
31
32
|
end
|
32
33
|
|
33
|
-
shared_examples_for 'system provider' do |candidates, pkg|
|
34
|
+
shared_examples_for 'system provider' do |candidates=nil, pkg|
|
34
35
|
it { expect(python_runtime.provider_for_action(:install)).to be_a described_class }
|
35
|
-
it { expect(system_package_candidates).to eq candidates }
|
36
|
+
it { expect(system_package_candidates).to eq candidates } if candidates
|
36
37
|
it { is_expected.to install_poise_languages_system(pkg) }
|
37
38
|
it do
|
38
39
|
expect_any_instance_of(described_class).to receive(:install_system_packages)
|
@@ -64,6 +65,23 @@ describe PoisePython::PythonProviders::System do
|
|
64
65
|
it_behaves_like 'system provider', %w{python2.3 python23 python}, 'python2.3'
|
65
66
|
end # /context with version 2.3
|
66
67
|
|
68
|
+
context 'on Debian 8.1' do
|
69
|
+
before { chefspec_options.update(platform: 'debian', version: '8.1') }
|
70
|
+
it_behaves_like 'system provider', 'python3.4'
|
71
|
+
end # /context on Debian 8.1
|
72
|
+
|
73
|
+
context 'on CentOS 7' do
|
74
|
+
before { chefspec_options.update(platform: 'centos', version: '7.0') }
|
75
|
+
recipe do
|
76
|
+
python_runtime 'test' do
|
77
|
+
provider :system
|
78
|
+
version node['poise_python_version']
|
79
|
+
virtualenv_version false
|
80
|
+
end
|
81
|
+
end
|
82
|
+
it_behaves_like 'system provider', 'python'
|
83
|
+
end # /context on Debian 8.1
|
84
|
+
|
67
85
|
context 'action :uninstall' do
|
68
86
|
recipe do
|
69
87
|
python_runtime 'test' do
|
@@ -17,19 +17,20 @@
|
|
17
17
|
require 'spec_helper'
|
18
18
|
|
19
19
|
describe PoisePython::Resources::PipRequirements do
|
20
|
-
let(:pip_cmd) { }
|
20
|
+
let(:pip_cmd) { %w{-m pip.__main__ install --requirement /test/requirements.txt} }
|
21
21
|
let(:pip_output) { '' }
|
22
|
+
let(:pip_user) { nil }
|
23
|
+
let(:pip_group) { nil }
|
22
24
|
step_into(:pip_requirements)
|
23
25
|
before do
|
24
26
|
allow(File).to receive(:directory?).and_return(false)
|
25
27
|
allow(File).to receive(:directory?).with('/test').and_return(true)
|
26
28
|
end
|
27
29
|
before do
|
28
|
-
expect_any_instance_of(PoisePython::Resources::PipRequirements::Provider).to receive(:python_shell_out!).with(pip_cmd).and_return(double(stdout: pip_output))
|
30
|
+
expect_any_instance_of(PoisePython::Resources::PipRequirements::Provider).to receive(:python_shell_out!).with(pip_cmd, {user: pip_user, group: pip_group}).and_return(double(stdout: pip_output))
|
29
31
|
end
|
30
32
|
|
31
33
|
context 'with a directory' do
|
32
|
-
let(:pip_cmd) { %w{-m pip.__main__ install --requirement /test/requirements.txt} }
|
33
34
|
recipe do
|
34
35
|
pip_requirements '/test'
|
35
36
|
end
|
@@ -46,6 +47,28 @@ describe PoisePython::Resources::PipRequirements do
|
|
46
47
|
it { is_expected.to install_pip_requirements('/test/reqs.txt') }
|
47
48
|
end # /context with a file
|
48
49
|
|
50
|
+
context 'with a user' do
|
51
|
+
let(:pip_user) { 'testuser' }
|
52
|
+
recipe do
|
53
|
+
pip_requirements '/test' do
|
54
|
+
user 'testuser'
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
it { is_expected.to install_pip_requirements('/test') }
|
59
|
+
end # /context with a user
|
60
|
+
|
61
|
+
context 'with a group' do
|
62
|
+
let(:pip_group) { 'testgroup' }
|
63
|
+
recipe do
|
64
|
+
pip_requirements '/test' do
|
65
|
+
group 'testgroup'
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
it { is_expected.to install_pip_requirements('/test') }
|
70
|
+
end # /context with a group
|
71
|
+
|
49
72
|
context 'action :upgrade' do
|
50
73
|
let(:pip_cmd) { %w{-m pip.__main__ install --upgrade --requirement /test/requirements.txt} }
|
51
74
|
recipe do
|
@@ -58,7 +81,6 @@ describe PoisePython::Resources::PipRequirements do
|
|
58
81
|
end # /context action :upgrade
|
59
82
|
|
60
83
|
context 'with output' do
|
61
|
-
let(:pip_cmd) { %w{-m pip.__main__ install --requirement /test/requirements.txt} }
|
62
84
|
let(:pip_output) { 'Successfully installed' }
|
63
85
|
recipe do
|
64
86
|
pip_requirements '/test'
|
@@ -21,7 +21,157 @@ describe PoisePython::Resources::PythonPackage do
|
|
21
21
|
end # /describe PoisePython::Resources::PythonPackage::Resource
|
22
22
|
|
23
23
|
describe PoisePython::Resources::PythonPackage::Provider do
|
24
|
-
let(:
|
24
|
+
let(:test_resource) { nil }
|
25
|
+
let(:test_provider) { described_class.new(test_resource, chef_run.run_context) }
|
26
|
+
def stub_cmd(cmd, **options)
|
27
|
+
output_options = {error?: options.delete(:error?) || false, stdout: options.delete(:stdout) || '', stderr: options.delete(:stderr) || ''}
|
28
|
+
expect(test_provider).to receive(:python_shell_out!).with(cmd, options).and_return(double("python #{cmd} return", **output_options))
|
29
|
+
end
|
30
|
+
|
31
|
+
describe '#load_current_resource' do
|
32
|
+
let(:package_name) { nil }
|
33
|
+
let(:package_version) { nil }
|
34
|
+
let(:test_resource) { PoisePython::Resources::PythonPackage::Resource.new(package_name, chef_run.run_context).tap {|r| r.version(package_version) if package_version } }
|
35
|
+
let(:candidate_version) { subject; test_provider.candidate_version }
|
36
|
+
subject { test_provider.load_current_resource }
|
37
|
+
|
38
|
+
context 'with package_name foo' do
|
39
|
+
let(:package_name) { 'foo' }
|
40
|
+
before do
|
41
|
+
stub_cmd(%w{-m pip.__main__ list}, stdout: '')
|
42
|
+
stub_cmd(%w{- list --outdated foo}, input: kind_of(String), stdout: "foo (Current: 0 Latest: 1.0.0 [wheel])\n")
|
43
|
+
end
|
44
|
+
|
45
|
+
its(:version) { is_expected.to be nil }
|
46
|
+
it { expect(candidate_version).to eq '1.0.0' }
|
47
|
+
end # /context with package_name foo
|
48
|
+
|
49
|
+
context 'with package_name ["foo", "bar"]' do
|
50
|
+
let(:package_name) { %w{foo bar} }
|
51
|
+
before do
|
52
|
+
stub_cmd(%w{-m pip.__main__ list}, stdout: '')
|
53
|
+
stub_cmd(%w{- list --outdated foo bar}, input: kind_of(String), stdout: "foo (Current: 0 Latest: 1.0.0 [wheel])\nbar (Current: 0 Latest: 2.0.0 [wheel])\n")
|
54
|
+
end
|
55
|
+
|
56
|
+
its(:version) { is_expected.to eq [nil, nil] }
|
57
|
+
it { expect(candidate_version).to eq %w{1.0.0 2.0.0} }
|
58
|
+
end # /context with package_name ["foo", "bar"]
|
59
|
+
|
60
|
+
context 'with a package with extras' do
|
61
|
+
let(:package_name) { 'foo[bar]' }
|
62
|
+
before do
|
63
|
+
stub_cmd(%w{-m pip.__main__ list}, stdout: '')
|
64
|
+
stub_cmd(%w{- list --outdated foo}, input: kind_of(String), stdout: "foo (Current: 0 Latest: 1.0.0 [wheel])\n")
|
65
|
+
end
|
66
|
+
|
67
|
+
its(:version) { is_expected.to be nil }
|
68
|
+
it { expect(candidate_version).to eq '1.0.0' }
|
69
|
+
end # /context with a package with extras
|
70
|
+
end # /describe #load_current_resource
|
71
|
+
|
72
|
+
describe 'actions' do
|
73
|
+
let(:package_name) { nil }
|
74
|
+
let(:current_version) { nil }
|
75
|
+
let(:candidate_version) { nil }
|
76
|
+
let(:test_resource) { PoisePython::Resources::PythonPackage::Resource.new(package_name, chef_run.run_context) }
|
77
|
+
subject { test_provider.run_action }
|
78
|
+
before do
|
79
|
+
current_version = self.current_version
|
80
|
+
candidate_version = self.candidate_version
|
81
|
+
allow(test_provider).to receive(:load_current_resource) do
|
82
|
+
current_resource = double('current_resource', package_name: package_name, version: current_version)
|
83
|
+
test_provider.instance_eval do
|
84
|
+
@current_resource = current_resource
|
85
|
+
@candidate_version = candidate_version
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
describe 'action :install' do
|
91
|
+
before { test_provider.action = :install }
|
92
|
+
|
93
|
+
context 'with package_name foo' do
|
94
|
+
let(:package_name) { 'foo' }
|
95
|
+
let(:candidate_version) { '1.0.0' }
|
96
|
+
it do
|
97
|
+
stub_cmd(%w{-m pip.__main__ install foo==1.0.0})
|
98
|
+
subject
|
99
|
+
end
|
100
|
+
end # /context with package_name foo
|
101
|
+
|
102
|
+
context 'with package_name ["foo", "bar"]' do
|
103
|
+
let(:package_name) { %w{foo bar} }
|
104
|
+
let(:candidate_version) { %w{1.0.0 2.0.0} }
|
105
|
+
it do
|
106
|
+
stub_cmd(%w{-m pip.__main__ install foo==1.0.0 bar==2.0.0})
|
107
|
+
subject
|
108
|
+
end
|
109
|
+
end # /context with package_name ["foo", "bar"]
|
110
|
+
|
111
|
+
context 'with options' do
|
112
|
+
let(:package_name) { 'foo' }
|
113
|
+
let(:candidate_version) { '1.0.0' }
|
114
|
+
before { test_resource.options('--editable') }
|
115
|
+
it do
|
116
|
+
stub_cmd('-m pip.__main__ install --editable foo\\=\\=1.0.0')
|
117
|
+
subject
|
118
|
+
end
|
119
|
+
end # /context with options
|
120
|
+
|
121
|
+
context 'with a package with extras' do
|
122
|
+
let(:package_name) { 'foo[bar]' }
|
123
|
+
let(:candidate_version) { '1.0.0' }
|
124
|
+
it do
|
125
|
+
stub_cmd(%w{-m pip.__main__ install foo[bar]==1.0.0})
|
126
|
+
subject
|
127
|
+
end
|
128
|
+
end # /context with a package with extras
|
129
|
+
end # /describe action :install
|
130
|
+
|
131
|
+
describe 'action :upgrade' do
|
132
|
+
before { test_provider.action = :upgrade }
|
133
|
+
|
134
|
+
context 'with package_name foo' do
|
135
|
+
let(:package_name) { 'foo' }
|
136
|
+
let(:candidate_version) { '1.0.0' }
|
137
|
+
it do
|
138
|
+
stub_cmd(%w{-m pip.__main__ install --upgrade foo==1.0.0})
|
139
|
+
subject
|
140
|
+
end
|
141
|
+
end # /context with package_name foo
|
142
|
+
|
143
|
+
context 'with package_name ["foo", "bar"]' do
|
144
|
+
let(:package_name) { %w{foo bar} }
|
145
|
+
let(:candidate_version) { %w{1.0.0 2.0.0} }
|
146
|
+
it do
|
147
|
+
stub_cmd(%w{-m pip.__main__ install --upgrade foo==1.0.0 bar==2.0.0})
|
148
|
+
subject
|
149
|
+
end
|
150
|
+
end # /context with package_name ["foo", "bar"]
|
151
|
+
end # /describe action :upgrade
|
152
|
+
|
153
|
+
describe 'action :remove' do
|
154
|
+
before { test_provider.action = :remove }
|
155
|
+
|
156
|
+
context 'with package_name foo' do
|
157
|
+
let(:package_name) { 'foo' }
|
158
|
+
let(:current_version) { '1.0.0' }
|
159
|
+
it do
|
160
|
+
stub_cmd(%w{-m pip.__main__ uninstall --yes foo})
|
161
|
+
subject
|
162
|
+
end
|
163
|
+
end # /context with package_name foo
|
164
|
+
|
165
|
+
context 'with package_name ["foo", "bar"]' do
|
166
|
+
let(:package_name) { %w{foo bar} }
|
167
|
+
let(:current_version) { %w{1.0.0 2.0.0} }
|
168
|
+
it do
|
169
|
+
stub_cmd(%w{-m pip.__main__ uninstall --yes foo bar})
|
170
|
+
subject
|
171
|
+
end
|
172
|
+
end # /context with package_name ["foo", "bar"]
|
173
|
+
end # /describe action :remove
|
174
|
+
end # /describe actions
|
25
175
|
|
26
176
|
describe '#parse_pip_outdated' do
|
27
177
|
let(:text) { '' }
|
@@ -41,6 +191,17 @@ Fabric (Current: 1.9.1 Latest: 1.10.2 [wheel])
|
|
41
191
|
EOH
|
42
192
|
it { is_expected.to eq({'boto' => '2.38.0', 'botocore' => '1.1.1', 'certifi' => '2015.4.28', 'cffi' => '1.1.2', 'fabric' => '1.10.2'}) }
|
43
193
|
end # /context with standard content
|
194
|
+
|
195
|
+
context 'with malformed content' do
|
196
|
+
let(:text) { <<-EOH }
|
197
|
+
boto (Current: 2.25.0 Latest: 2.38.0 [wheel])
|
198
|
+
botocore (Current: 0.56.0 Latest: 1.1.1 [wheel])
|
199
|
+
certifi (Current: 14.5.14 Latest: 2015.4.28 [wheel])
|
200
|
+
cffi (Current: 0.8.1 Latest: 1.1.2 [sdist])
|
201
|
+
Fabric (Future: 1.9.1 [wheel])
|
202
|
+
EOH
|
203
|
+
it { is_expected.to eq({'boto' => '2.38.0', 'botocore' => '1.1.1', 'certifi' => '2015.4.28', 'cffi' => '1.1.2'}) }
|
204
|
+
end # /context with malformed content
|
44
205
|
end # /describe #parse_pip_outdated
|
45
206
|
|
46
207
|
describe '#parse_pip_list' do
|
@@ -60,6 +221,16 @@ flake8 (2.1.0.dev0)
|
|
60
221
|
EOH
|
61
222
|
it { is_expected.to eq({'eventlet' => '0.12.1', 'fabric' => '1.9.1', 'fabric-rundeck' => '1.2', 'flake8' => '2.1.0.dev0'}) }
|
62
223
|
end # /context with standard content
|
224
|
+
|
225
|
+
context 'with malformed content' do
|
226
|
+
let(:text) { <<-EOH }
|
227
|
+
eventlet (0.12.1)
|
228
|
+
Fabric (1.9.1)
|
229
|
+
fabric-rundeck (1.2, /Users/coderanger/src/bal/fabric-rundeck)
|
230
|
+
flake 8 (2.1.0.dev0)
|
231
|
+
EOH
|
232
|
+
it { is_expected.to eq({'eventlet' => '0.12.1', 'fabric' => '1.9.1', 'fabric-rundeck' => '1.2'}) }
|
233
|
+
end # /context with malformed content
|
63
234
|
end # /describe #parse_pip_list
|
64
235
|
end # /describe PoisePython::Resources::PythonPackage::Provider
|
65
236
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: poise-python
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.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:
|
11
|
+
date: 2016-01-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: halite
|