poise-python 1.3.0 → 1.4.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 +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
|