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 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