poise-python 1.3.0 → 1.4.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 +6 -0
- data/README.md +6 -0
- data/lib/poise_python/python_providers/system.rb +1 -0
- data/lib/poise_python/resources/pip_requirements.rb +38 -5
- data/lib/poise_python/resources/python_package.rb +18 -7
- data/lib/poise_python/version.rb +1 -1
- data/test/spec/resources/pip_requirements_spec.rb +24 -1
- data/test/spec/resources/python_package_spec.rb +64 -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: a12da22a9f150574726a0269d44cb5eacbdcb924
|
4
|
+
data.tar.gz: 4ece1e0b399f553cf09a115ef1ccdf733454d86d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d45e0538ac533f844e9e8e9d0f8ce88edbb9b88594ecb8a5577fc8e44166aeb2a885e544e8a46aeb1593075a50e386d63c04e349e1ab9bc8b8b660ca903aad7a
|
7
|
+
data.tar.gz: db9ebcab6fb2dc3ebcb28eafc533d9e88223d53003703238d1398079546c2f3946c609292ba26922eb49da6df3f936f02c788f80887c9c22e90c46646f53fc8d
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
# Poise-Python Changelog
|
2
2
|
|
3
|
+
## v1.4.0
|
4
|
+
|
5
|
+
* Add system package names for Ubuntu 16.04.
|
6
|
+
* Add `options` and `cwd` properties to `pip_requirements` resource.
|
7
|
+
* Add `install_options` and `list_options` to `python_package` resource.
|
8
|
+
|
3
9
|
## v1.3.0
|
4
10
|
|
5
11
|
* Don't re-bootstrap very old pip if that is the configured version.
|
data/README.md
CHANGED
@@ -224,6 +224,9 @@ The `:purge` and `:reconfigure` actions are not supported.
|
|
224
224
|
* `user` – System user to install the package.
|
225
225
|
* `virtualenv` – Name of the `python_virtualenv` resource to use. This is
|
226
226
|
mutually exclusive with the `python` property.
|
227
|
+
* `options` – Options to pass to `pip`.
|
228
|
+
* `install_options` – Options to pass to `pip install` (and similar commands).
|
229
|
+
* `list_options` – Options to pass to `pip list` (and similar commands).
|
227
230
|
|
228
231
|
For other properties see the [Chef documentation](https://docs.chef.io/resource_package.html#attributes).
|
229
232
|
The `response_file`, `response_file_variables`, and `source` properties are not
|
@@ -283,7 +286,10 @@ notifications will only be triggered if a package is actually installed.
|
|
283
286
|
|
284
287
|
* `path` – Path to the requirements file, or a folder containing the
|
285
288
|
requirements file. *(name property)*
|
289
|
+
* `cwd` – Directory to run `pip` from. *(default: directory containing the
|
290
|
+
`requirements.txt`)*
|
286
291
|
* `group` – System group to install the packages.
|
292
|
+
* `options` – Command line options for use with `pip install`.
|
287
293
|
* `python` – Name of the `python_runtime` resource to use. If not specified, the
|
288
294
|
most recently declared `python_runtime` will be used. Can also be set to the
|
289
295
|
full path to a `python` binary.
|
@@ -14,6 +14,8 @@
|
|
14
14
|
# limitations under the License.
|
15
15
|
#
|
16
16
|
|
17
|
+
require 'shellwords'
|
18
|
+
|
17
19
|
require 'chef/provider'
|
18
20
|
require 'chef/resource'
|
19
21
|
require 'poise'
|
@@ -44,14 +46,36 @@ module PoisePython
|
|
44
46
|
# requirements file.
|
45
47
|
# @return [String]
|
46
48
|
attribute(:path, kind_of: String, name_attribute: true)
|
49
|
+
# @!attribute cwd
|
50
|
+
# Directory to run pip from. Defaults to the folder containing the
|
51
|
+
# requirements.txt.
|
52
|
+
# @return [String]
|
53
|
+
attribute(:cwd, kind_of: String, default: lazy { default_cwd })
|
47
54
|
# @!attribute group
|
48
55
|
# System group to install the package.
|
49
56
|
# @return [String, Integer, nil]
|
50
57
|
attribute(:group, kind_of: [String, Integer, NilClass])
|
58
|
+
# @!attribute options
|
59
|
+
# Options string to be used with `pip install`.
|
60
|
+
# @return [String, nil, false]
|
61
|
+
attribute(:options, kind_of: [String, NilClass, FalseClass])
|
51
62
|
# @!attribute user
|
52
63
|
# System user to install the package.
|
53
64
|
# @return [String, Integer, nil]
|
54
65
|
attribute(:user, kind_of: [String, Integer, NilClass])
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
# Default value for the {#cwd} property.
|
70
|
+
#
|
71
|
+
# @return [String]
|
72
|
+
def default_cwd
|
73
|
+
if ::File.directory?(path)
|
74
|
+
path
|
75
|
+
else
|
76
|
+
::File.dirname(path)
|
77
|
+
end
|
78
|
+
end
|
55
79
|
end
|
56
80
|
|
57
81
|
# The default provider for `pip_requirements`.
|
@@ -84,11 +108,20 @@ module PoisePython
|
|
84
108
|
# @param upgrade [Boolean] If we should use the --upgrade flag.
|
85
109
|
# @return [void]
|
86
110
|
def install_requirements(upgrade: false)
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
111
|
+
if new_resource.options
|
112
|
+
# Use a string because we have some options.
|
113
|
+
cmd = '-m pip.__main__ install'
|
114
|
+
cmd << ' --upgrade' if upgrade
|
115
|
+
cmd << " #{new_resource.options}"
|
116
|
+
cmd << " --requirement #{Shellwords.escape(requirements_path)}"
|
117
|
+
else
|
118
|
+
# No options, use an array to be slightly faster.
|
119
|
+
cmd = %w{-m pip.__main__ install}
|
120
|
+
cmd << '--upgrade' if upgrade
|
121
|
+
cmd << '--requirement'
|
122
|
+
cmd << requirements_path
|
123
|
+
end
|
124
|
+
output = python_shell_out!(cmd, user: new_resource.user, group: new_resource.group, cwd: new_resource.cwd).stdout
|
92
125
|
if output.include?('Successfully installed')
|
93
126
|
new_resource.updated_by_last_action(true)
|
94
127
|
end
|
@@ -100,6 +100,14 @@ EOH
|
|
100
100
|
# System group to install the package.
|
101
101
|
# @return [String, Integer, nil]
|
102
102
|
attribute(:group, kind_of: [String, Integer, NilClass])
|
103
|
+
# @!attribute install_options
|
104
|
+
# Options string to be used with `pip install`.
|
105
|
+
# @return [String, nil, false]
|
106
|
+
attribute(:install_options, kind_of: [String, NilClass, FalseClass], default: nil)
|
107
|
+
# @!attribute list_options
|
108
|
+
# Options string to be used with `pip list`.
|
109
|
+
# @return [String, nil, false]
|
110
|
+
attribute(:list_options, kind_of: [String, NilClass, FalseClass], default: nil)
|
103
111
|
# @!attribute user
|
104
112
|
# System user to install the package.
|
105
113
|
# @return [String, Integer, nil]
|
@@ -163,7 +171,7 @@ EOH
|
|
163
171
|
def check_package_versions(resource, version=new_resource.version)
|
164
172
|
version_data = Hash.new {|hash, key| hash[key] = {current: nil, candidate: nil} }
|
165
173
|
# Get the version for everything currently installed.
|
166
|
-
list = pip_command('list').stdout
|
174
|
+
list = pip_command('list', :list).stdout
|
167
175
|
parse_pip_list(list).each do |name, current|
|
168
176
|
# Merge current versions in to the data.
|
169
177
|
version_data[name][:current] = current
|
@@ -216,7 +224,7 @@ EOH
|
|
216
224
|
# @param version [String, Array<String>] Version(s) of package(s).
|
217
225
|
# @return [void]
|
218
226
|
def remove_package(name, version)
|
219
|
-
pip_command('uninstall', %w{--yes} + [name].flatten)
|
227
|
+
pip_command('uninstall', :install, %w{--yes} + [name].flatten)
|
220
228
|
end
|
221
229
|
|
222
230
|
private
|
@@ -251,15 +259,18 @@ EOH
|
|
251
259
|
# Run a pip command.
|
252
260
|
#
|
253
261
|
# @param pip_command [String, nil] The pip subcommand to run (eg. install).
|
262
|
+
# @param options_type [Symbol] Either `:install` to `:list` to select
|
263
|
+
# which extra options to use.
|
254
264
|
# @param pip_options [Array<String>] Options for the pip command.
|
255
265
|
# @param opts [Hash] Mixlib::ShellOut options.
|
256
266
|
# @return [Mixlib::ShellOut]
|
257
|
-
def pip_command(pip_command, pip_options=[], opts={})
|
267
|
+
def pip_command(pip_command, options_type, pip_options=[], opts={})
|
258
268
|
runner = opts.delete(:pip_runner) || %w{-m pip.__main__}
|
259
|
-
|
269
|
+
type_specific_options = new_resource.send(:"#{options_type}_options")
|
270
|
+
full_cmd = if new_resource.options || type_specific_options
|
260
271
|
# We have to use a string for this case to be safe because the
|
261
272
|
# options are a string and I don't want to try and parse that.
|
262
|
-
"#{runner.join(' ')} #{pip_command} #{new_resource.options} #{Shellwords.join(pip_options)}"
|
273
|
+
"#{runner.join(' ')} #{pip_command} #{new_resource.options} #{type_specific_options} #{Shellwords.join(pip_options)}"
|
263
274
|
else
|
264
275
|
# No special options, use an array to skip the extra /bin/sh.
|
265
276
|
runner + (pip_command ? [pip_command] : []) + pip_options
|
@@ -282,7 +293,7 @@ EOH
|
|
282
293
|
cmd = pip_requirements(name, version)
|
283
294
|
# Prepend --upgrade if needed.
|
284
295
|
cmd = %w{--upgrade} + cmd if upgrade
|
285
|
-
pip_command('install', cmd)
|
296
|
+
pip_command('install', :install, cmd)
|
286
297
|
end
|
287
298
|
|
288
299
|
# Run my hacked version of `pip list --outdated` with a specific set of
|
@@ -292,7 +303,7 @@ EOH
|
|
292
303
|
# @param requirements [Array<String>] Pip-formatted package requirements.
|
293
304
|
# @return [Mixlib::ShellOut]
|
294
305
|
def pip_outdated(requirements)
|
295
|
-
pip_command(nil, requirements, input: PIP_HACK_SCRIPT, pip_runner: %w{-})
|
306
|
+
pip_command(nil, :list, requirements, input: PIP_HACK_SCRIPT, pip_runner: %w{-})
|
296
307
|
end
|
297
308
|
|
298
309
|
# Parse the output from `pip list`. Returns a hash of package key to
|
data/lib/poise_python/version.rb
CHANGED
@@ -21,13 +21,14 @@ describe PoisePython::Resources::PipRequirements do
|
|
21
21
|
let(:pip_output) { '' }
|
22
22
|
let(:pip_user) { nil }
|
23
23
|
let(:pip_group) { nil }
|
24
|
+
let(:pip_cwd) { '/test' }
|
24
25
|
step_into(:pip_requirements)
|
25
26
|
before do
|
26
27
|
allow(File).to receive(:directory?).and_return(false)
|
27
28
|
allow(File).to receive(:directory?).with('/test').and_return(true)
|
28
29
|
end
|
29
30
|
before do
|
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))
|
31
|
+
expect_any_instance_of(PoisePython::Resources::PipRequirements::Provider).to receive(:python_shell_out!).with(pip_cmd, {user: pip_user, group: pip_group, cwd: pip_cwd}).and_return(double(stdout: pip_output))
|
31
32
|
end
|
32
33
|
|
33
34
|
context 'with a directory' do
|
@@ -88,4 +89,26 @@ describe PoisePython::Resources::PipRequirements do
|
|
88
89
|
|
89
90
|
it { is_expected.to install_pip_requirements('/test').with(updated?: true) }
|
90
91
|
end # /context with output
|
92
|
+
|
93
|
+
context 'with a cwd' do
|
94
|
+
let(:pip_cwd) { '/other' }
|
95
|
+
recipe do
|
96
|
+
pip_requirements '/test' do
|
97
|
+
cwd '/other'
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
it { is_expected.to install_pip_requirements('/test') }
|
102
|
+
end # /context with a cwd
|
103
|
+
|
104
|
+
context 'with options' do
|
105
|
+
let(:pip_cmd) { '-m pip.__main__ install --index-url=http://example --requirement /test/requirements.txt' }
|
106
|
+
recipe do
|
107
|
+
pip_requirements '/test' do
|
108
|
+
options '--index-url=http://example'
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
it { is_expected.to install_pip_requirements('/test') }
|
113
|
+
end # /context with options
|
91
114
|
end
|
@@ -18,6 +18,35 @@ require 'spec_helper'
|
|
18
18
|
|
19
19
|
describe PoisePython::Resources::PythonPackage do
|
20
20
|
describe PoisePython::Resources::PythonPackage::Resource do
|
21
|
+
describe '#response_file' do
|
22
|
+
recipe do
|
23
|
+
python_package 'foo' do
|
24
|
+
response_file 'bar'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
it { expect { subject }.to raise_error NoMethodError }
|
29
|
+
end # /describe #response_file
|
30
|
+
|
31
|
+
describe '#response_file_variables' do
|
32
|
+
recipe do
|
33
|
+
python_package 'foo' do
|
34
|
+
response_file_variables 'bar'
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
it { expect { subject }.to raise_error NoMethodError }
|
39
|
+
end # /describe #response_file_variables
|
40
|
+
|
41
|
+
describe '#source' do
|
42
|
+
recipe do
|
43
|
+
python_package 'foo' do
|
44
|
+
source 'bar'
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
it { expect { subject }.to raise_error NoMethodError }
|
49
|
+
end # /describe #source
|
21
50
|
end # /describe PoisePython::Resources::PythonPackage::Resource
|
22
51
|
|
23
52
|
describe PoisePython::Resources::PythonPackage::Provider do
|
@@ -67,6 +96,30 @@ describe PoisePython::Resources::PythonPackage do
|
|
67
96
|
its(:version) { is_expected.to be nil }
|
68
97
|
it { expect(candidate_version).to eq '1.0.0' }
|
69
98
|
end # /context with a package with extras
|
99
|
+
|
100
|
+
context 'with options' do
|
101
|
+
let(:package_name) { 'foo' }
|
102
|
+
before do
|
103
|
+
test_resource.options('--index-url=http://example')
|
104
|
+
stub_cmd("-m pip.__main__ list --index-url=http://example ", stdout: '')
|
105
|
+
stub_cmd("- --index-url=http://example foo", input: kind_of(String), stdout: '{"foo":"1.0.0"}')
|
106
|
+
end
|
107
|
+
|
108
|
+
its(:version) { is_expected.to be nil }
|
109
|
+
it { expect(candidate_version).to eq '1.0.0' }
|
110
|
+
end # /context with options
|
111
|
+
|
112
|
+
context 'with list options' do
|
113
|
+
let(:package_name) { 'foo' }
|
114
|
+
before do
|
115
|
+
test_resource.list_options('--index-url=http://example')
|
116
|
+
stub_cmd("-m pip.__main__ list --index-url=http://example ", stdout: '')
|
117
|
+
stub_cmd("- --index-url=http://example foo", input: kind_of(String), stdout: '{"foo":"1.0.0"}')
|
118
|
+
end
|
119
|
+
|
120
|
+
its(:version) { is_expected.to be nil }
|
121
|
+
it { expect(candidate_version).to eq '1.0.0' }
|
122
|
+
end # /context with list options
|
70
123
|
end # /describe #load_current_resource
|
71
124
|
|
72
125
|
describe 'actions' do
|
@@ -113,11 +166,21 @@ describe PoisePython::Resources::PythonPackage do
|
|
113
166
|
let(:candidate_version) { '1.0.0' }
|
114
167
|
before { test_resource.options('--editable') }
|
115
168
|
it do
|
116
|
-
stub_cmd('-m pip.__main__ install --editable
|
169
|
+
stub_cmd('-m pip.__main__ install --editable foo\\=\\=1.0.0')
|
117
170
|
subject
|
118
171
|
end
|
119
172
|
end # /context with options
|
120
173
|
|
174
|
+
context 'with install options' do
|
175
|
+
let(:package_name) { 'foo' }
|
176
|
+
let(:candidate_version) { '1.0.0' }
|
177
|
+
before { test_resource.install_options('--editable') }
|
178
|
+
it do
|
179
|
+
stub_cmd('-m pip.__main__ install --editable foo\\=\\=1.0.0')
|
180
|
+
subject
|
181
|
+
end
|
182
|
+
end # /context with install options
|
183
|
+
|
121
184
|
context 'with a package with extras' do
|
122
185
|
let(:package_name) { 'foo[bar]' }
|
123
186
|
let(:candidate_version) { '1.0.0' }
|
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.4.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: 2016-
|
11
|
+
date: 2016-06-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: halite
|