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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c530f8cfe183f6c43252af07d5f49a0d6780879e
4
- data.tar.gz: 89a616f770a38b3af82a251c896987e4ee1da41b
3
+ metadata.gz: a12da22a9f150574726a0269d44cb5eacbdcb924
4
+ data.tar.gz: 4ece1e0b399f553cf09a115ef1ccdf733454d86d
5
5
  SHA512:
6
- metadata.gz: 0570397e050997a489b5c2e49d97b089b54db503c8dde5e62cdc2ceda34a7c92d5f0c32c277f94d6f270f2bca7e5508f407a4f8c828e2428c7c07f0540873f7d
7
- data.tar.gz: 49f812c7ac151eff01b84a3732537aa1cba5cb4339e9e77af2d171495384429281c30b2f92f2e194cf79ae2dc5cc355571e175cabd05d520a2c77794d206e65f
6
+ metadata.gz: d45e0538ac533f844e9e8e9d0f8ce88edbb9b88594ecb8a5577fc8e44166aeb2a885e544e8a46aeb1593075a50e386d63c04e349e1ab9bc8b8b660ca903aad7a
7
+ data.tar.gz: db9ebcab6fb2dc3ebcb28eafc533d9e88223d53003703238d1398079546c2f3946c609292ba26922eb49da6df3f936f02c788f80887c9c22e90c46646f53fc8d
@@ -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.
@@ -33,6 +33,7 @@ module PoisePython
33
33
  '~> 6.0' => %w{python3.1 python2.6 python2.5},
34
34
  },
35
35
  ubuntu: {
36
+ '16.04' => %w{python3.5 python2.7},
36
37
  '14.04' => %w{python3.4 python2.7},
37
38
  '12.04' => %w{python3.2 python2.7},
38
39
  '10.04' => %w{python3.1 python2.6},
@@ -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
- cmd = %w{-m pip.__main__ install}
88
- cmd << '--upgrade' if upgrade
89
- cmd << '--requirement'
90
- cmd << requirements_path
91
- output = python_shell_out!(cmd, user: new_resource.user, group: new_resource.group).stdout
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
- full_cmd = if new_resource.options
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
@@ -16,5 +16,5 @@
16
16
 
17
17
 
18
18
  module PoisePython
19
- VERSION = '1.3.0'
19
+ VERSION = '1.4.0'
20
20
  end
@@ -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 foo\\=\\=1.0.0')
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.3.0
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-04-29 00:00:00.000000000 Z
11
+ date: 2016-06-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: halite