poise-python 1.2.1 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/.kitchen.yml +1 -6
  3. data/.travis.yml +7 -6
  4. data/CHANGELOG.md +7 -0
  5. data/Gemfile +3 -1
  6. data/README.md +9 -3
  7. data/Rakefile +1 -1
  8. data/chef/attributes/default.rb +1 -1
  9. data/chef/recipes/default.rb +1 -1
  10. data/lib/poise_python.rb +1 -1
  11. data/lib/poise_python/cheftie.rb +1 -1
  12. data/lib/poise_python/error.rb +1 -1
  13. data/lib/poise_python/python_command_mixin.rb +1 -1
  14. data/lib/poise_python/python_providers.rb +3 -1
  15. data/lib/poise_python/python_providers/base.rb +3 -3
  16. data/lib/poise_python/python_providers/dummy.rb +1 -1
  17. data/lib/poise_python/python_providers/msi.rb +64 -0
  18. data/lib/poise_python/python_providers/portable_pypy.rb +1 -1
  19. data/lib/poise_python/python_providers/portable_pypy3.rb +1 -1
  20. data/lib/poise_python/python_providers/scl.rb +1 -1
  21. data/lib/poise_python/python_providers/system.rb +3 -3
  22. data/lib/poise_python/resources.rb +1 -1
  23. data/lib/poise_python/resources/pip_requirements.rb +1 -1
  24. data/lib/poise_python/resources/python_execute.rb +1 -1
  25. data/lib/poise_python/resources/python_package.rb +14 -6
  26. data/lib/poise_python/resources/python_runtime.rb +1 -1
  27. data/lib/poise_python/resources/python_runtime_pip.rb +45 -28
  28. data/lib/poise_python/resources/python_runtime_test.rb +35 -32
  29. data/lib/poise_python/resources/python_virtualenv.rb +6 -2
  30. data/lib/poise_python/utils.rb +1 -1
  31. data/lib/poise_python/utils/python_encoder.rb +1 -1
  32. data/lib/poise_python/version.rb +2 -2
  33. data/poise-python.gemspec +4 -4
  34. data/test/{cookbooks/poise-python_test → cookbook}/metadata.rb +1 -1
  35. data/test/cookbook/recipes/default.rb +78 -0
  36. data/{Berksfile → test/gemfiles/chef-12.1.gemfile} +3 -12
  37. data/test/gemfiles/chef-12.2.gemfile +19 -0
  38. data/test/gemfiles/chef-12.3.gemfile +19 -0
  39. data/test/gemfiles/chef-12.4.gemfile +21 -0
  40. data/test/gemfiles/chef-12.5.gemfile +19 -0
  41. data/test/gemfiles/chef-12.6.gemfile +19 -0
  42. data/test/gemfiles/chef-12.gemfile +2 -2
  43. data/test/gemfiles/master.gemfile +3 -1
  44. data/test/integration/default/serverspec/default_spec.rb +23 -9
  45. data/test/spec/python_command_mixin_spec.rb +1 -1
  46. data/test/spec/python_providers/dummy_spec.rb +1 -1
  47. data/test/spec/python_providers/portable_pypy3_spec.rb +1 -1
  48. data/test/spec/python_providers/portable_pypy_spec.rb +1 -1
  49. data/test/spec/python_providers/scl_spec.rb +1 -1
  50. data/test/spec/python_providers/system_spec.rb +1 -1
  51. data/test/spec/resources/pip_requirements_spec.rb +1 -1
  52. data/test/spec/resources/python_package_spec.rb +1 -1
  53. data/test/spec/resources/python_runtime_pip_spec.rb +1 -1
  54. data/test/spec/resources/python_virtualenv_spec.rb +1 -1
  55. data/test/spec/spec_helper.rb +1 -1
  56. data/test/spec/utils/python_encoder_spec.rb +1 -1
  57. data/test/spec/utils_spec.rb +1 -1
  58. metadata +26 -15
  59. data/.kitchen.travis.yml +0 -9
  60. data/test/cookbooks/poise-python_test/recipes/default.rb +0 -65
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: bef0f55828842107d9397608ee63c0a08007f6d4
4
- data.tar.gz: 05b4a93226b282e4b1708f7ec29d7b9f40d6baad
3
+ metadata.gz: c530f8cfe183f6c43252af07d5f49a0d6780879e
4
+ data.tar.gz: 89a616f770a38b3af82a251c896987e4ee1da41b
5
5
  SHA512:
6
- metadata.gz: d7084145bf568d242e6c33a1a8560d23ff49de234b2c3e9358e5cee8478dc26ebdd7259db6f86d43db7ab3693efe05d99d5d14cb117e01f892a184b8eed19a93
7
- data.tar.gz: 55016a0d57459240bfd38c140628e743011beccfce1130dd6fbb09baa8b8a4221090b8c64e91423bfdf156394d2909104e368552b1f7796f14686205dbfcd21e
6
+ metadata.gz: 0570397e050997a489b5c2e49d97b089b54db503c8dde5e62cdc2ceda34a7c92d5f0c32c277f94d6f270f2bca7e5508f407a4f8c828e2428c7c07f0540873f7d
7
+ data.tar.gz: 49f812c7ac151eff01b84a3732537aa1cba5cb4339e9e77af2d171495384429281c30b2f92f2e194cf79ae2dc5cc355571e175cabd05d520a2c77794d206e65f
data/.kitchen.yml CHANGED
@@ -1,8 +1,3 @@
1
1
  ---
2
2
  #<% require 'poise_boiler' %>
3
- <%= PoiseBoiler.kitchen(platforms: 'linux') %>
4
-
5
- suites:
6
- - name: default
7
- run_list:
8
- - recipe[poise-python_test]
3
+ <%= PoiseBoiler.kitchen %>
data/.travis.yml CHANGED
@@ -4,18 +4,19 @@ cache: bundler
4
4
  language: ruby
5
5
  rvm:
6
6
  - '2.2'
7
- addons:
8
- apt:
9
- packages:
10
- - libgecode-dev
11
7
  env:
12
8
  global:
13
- - USE_SYSTEM_GECODE=true
14
- - KITCHEN_LOCAL_YAML=.kitchen.travis.yml
15
9
  - secure: j4GV/0NXC6p/+XxgK2isMCzccR7ry8cxLJZZbJN5P+958lLGmYtPPsfAN+aRzcR3Uc/alLcsjXvceCjJWU7qYpkN1x9cn564J1X3OIOygi6xdYQIMLL5Guxp01QYabFlrmZeUnTVMTkdR1H4aRrpzW4kTuc5hbIZaJl0enEe1Dd+vbCw2GOTXFnPTeLDCaCSNXXhXmqqWD64leFR2PTwx8fwrXyCB/bDRXhFdsFA5Q/tCGW7PDaYujbqSCegpuz+uvHoM5S2k2XY3pShWZm9WcmEzCLEfhOGCc1s+ia7TZ0iV7kzEq11mNTdSl6nJtBUiKsgqw1TRPFhhUj2Bp/K+cNsd06rtFE3In2zbqbgyJ0qnyQHs2FZO//ve8bug+B0lA3i6SantruS1Fc9NjwjqzOmqmaqNhnVl1jEQTOB3JUC465QShySF0aJtjE5khD7PzGwCw6cqhPBLH5ZTmqCYvl/egYLMlvVr1Nboa+0YFdzUqoTFJpRTsu89l8+1+Eu9pvHn0CwsjWmEVHahIw/GEBjhLPDinquJNxWz1q49ozlohntbRmWhbgzz6D4wPrbBdyW7rYm8p6d2sOy6Op2zsVv4c7Dj3pcLLd9J5o6RaNxf4wLd5VFLNJR6/wldsZXGxV/iP16oyasabYIQYZNbP0U1hZiUpLQ5cvKYc6xRTM=
10
+ before_install: "gem install bundler"
16
11
  bundler_args: "--binstubs=$PWD/bin --jobs 3 --retry 3"
17
12
  script:
18
13
  - "./bin/rake travis"
19
14
  gemfile:
20
15
  - test/gemfiles/chef-12.gemfile
16
+ - test/gemfiles/chef-12.1.gemfile
17
+ - test/gemfiles/chef-12.2.gemfile
18
+ - test/gemfiles/chef-12.3.gemfile
19
+ - test/gemfiles/chef-12.4.gemfile
20
+ - test/gemfiles/chef-12.5.gemfile
21
+ - test/gemfiles/chef-12.6.gemfile
21
22
  - test/gemfiles/master.gemfile
data/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Poise-Python Changelog
2
2
 
3
+ ## v1.3.0
4
+
5
+ * Don't re-bootstrap very old pip if that is the configured version.
6
+ * Support for bootstrapping with a specific version of pip.
7
+ * [#40](https://github.com/poise/poise-python/pulls/40) Support for Python 3 system packages on Amazon Linux.
8
+ * Experimental Windows support.
9
+
3
10
  ## v1.2.1
4
11
 
5
12
  * Compatibility with Pip 8.0.
data/Gemfile CHANGED
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright 2015, Noah Kantrowitz
2
+ # Copyright 2015-2016, Noah Kantrowitz
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License");
5
5
  # you may not use this file except in compliance with the License.
@@ -29,5 +29,7 @@ end
29
29
 
30
30
  dev_gem 'halite'
31
31
  dev_gem 'poise'
32
+ dev_gem 'poise-archive'
32
33
  dev_gem 'poise-boiler'
33
34
  dev_gem 'poise-languages'
35
+ dev_gem 'poise-profiler'
data/README.md CHANGED
@@ -32,9 +32,15 @@ pip_requirements '/opt/myapp/requirements.txt'
32
32
  This cookbook can install at least Python 2.7, Python 3, and PyPy on all
33
33
  supported platforms (Debian, Ubuntu, RHEL, CentOS, Fedora).
34
34
 
35
+ ### Windows Support
36
+
37
+ The latest version of `poise-python` includes basic support for managing Python
38
+ on Windows. This currently doesn't support Python 3.5, but everything should be
39
+ working. Consider this support tested but experimental at this time.
40
+
35
41
  ## Requirements
36
42
 
37
- Chef 12 or newer is required.
43
+ Chef 12.1 or newer is required.
38
44
 
39
45
  ## Attributes
40
46
 
@@ -325,7 +331,7 @@ end
325
331
  The `scl` provider installs Python using the [Software Collections](https://www.softwarecollections.org/)
326
332
  packages. This is only available on RHEL, CentOS, and Fedora. SCL offers more
327
333
  recent versions of Python than the system packages for the most part. If an SCL
328
- package exists for the requests version, it will be used in preference to the
334
+ package exists for the requested version, it will be used in preference to the
329
335
  `system` provider.
330
336
 
331
337
  ```ruby
@@ -397,7 +403,7 @@ The Poise test server infrastructure is sponsored by [Rackspace](https://rackspa
397
403
 
398
404
  ## License
399
405
 
400
- Copyright 2015, Noah Kantrowitz
406
+ Copyright 2015-2016, Noah Kantrowitz
401
407
 
402
408
  Licensed under the Apache License, Version 2.0 (the "License");
403
409
  you may not use this file except in compliance with the License.
data/Rakefile CHANGED
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright 2015, Noah Kantrowitz
2
+ # Copyright 2015-2016, Noah Kantrowitz
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License");
5
5
  # you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright 2015, Noah Kantrowitz
2
+ # Copyright 2015-2016, Noah Kantrowitz
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License");
5
5
  # you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright 2015, Noah Kantrowitz
2
+ # Copyright 2015-2016, Noah Kantrowitz
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License");
5
5
  # you may not use this file except in compliance with the License.
data/lib/poise_python.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright 2015, Noah Kantrowitz
2
+ # Copyright 2015-2016, Noah Kantrowitz
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License");
5
5
  # you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright 2015, Noah Kantrowitz
2
+ # Copyright 2015-2016, Noah Kantrowitz
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License");
5
5
  # you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright 2015, Noah Kantrowitz
2
+ # Copyright 2015-2016, Noah Kantrowitz
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License");
5
5
  # you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright 2015, Noah Kantrowitz
2
+ # Copyright 2015-2016, Noah Kantrowitz
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License");
5
5
  # you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright 2015, Noah Kantrowitz
2
+ # Copyright 2015-2016, Noah Kantrowitz
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License");
5
5
  # you may not use this file except in compliance with the License.
@@ -17,6 +17,7 @@
17
17
  require 'chef/platform/provider_priority_map'
18
18
 
19
19
  require 'poise_python/python_providers/dummy'
20
+ require 'poise_python/python_providers/msi'
20
21
  require 'poise_python/python_providers/portable_pypy'
21
22
  require 'poise_python/python_providers/portable_pypy3'
22
23
  require 'poise_python/python_providers/scl'
@@ -32,6 +33,7 @@ module PoisePython
32
33
 
33
34
  Chef::Platform::ProviderPriorityMap.instance.priority(:python_runtime, [
34
35
  PoisePython::PythonProviders::Dummy,
36
+ PoisePython::PythonProviders::Msi,
35
37
  PoisePython::PythonProviders::PortablePyPy3,
36
38
  PoisePython::PythonProviders::PortablePyPy,
37
39
  PoisePython::PythonProviders::Scl,
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright 2015, Noah Kantrowitz
2
+ # Copyright 2015-2016, Noah Kantrowitz
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License");
5
5
  # you may not use this file except in compliance with the License.
@@ -146,7 +146,7 @@ module PoisePython
146
146
  # Captured because #options conflicts with Chef::Resource::Package#options.
147
147
  wheel_version = options[:wheel_version]
148
148
  return unless wheel_version
149
- Chef::Log.debug("[#{new_resource}] Installing setuptools #{wheel_version == true ? 'latest' : wheel_version}")
149
+ Chef::Log.debug("[#{new_resource}] Installing wheel #{wheel_version == true ? 'latest' : wheel_version}")
150
150
  # Install wheel via pip.
151
151
  python_package 'wheel' do
152
152
  parent_python new_resource
@@ -162,7 +162,7 @@ module PoisePython
162
162
  virtualenv_version = options[:virtualenv_version]
163
163
  return unless virtualenv_version
164
164
  # Check if the venv module exists.
165
- cmd = shell_out([python_binary, '-m', 'venv', '-h'], environment: python_environment)
165
+ cmd = poise_shell_out([python_binary, '-m', 'venv', '-h'], environment: python_environment)
166
166
  return unless cmd.error?
167
167
  Chef::Log.debug("[#{new_resource}] Installing virtualenv #{virtualenv_version == true ? 'latest' : virtualenv_version}")
168
168
  # Install virtualenv via pip.
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright 2015, Noah Kantrowitz
2
+ # Copyright 2015-2016, Noah Kantrowitz
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License");
5
5
  # you may not use this file except in compliance with the License.
@@ -0,0 +1,64 @@
1
+ #
2
+ # Copyright 2016, Noah Kantrowitz
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require 'chef/resource'
18
+
19
+ require 'poise_python/error'
20
+ require 'poise_python/python_providers/base'
21
+
22
+
23
+ module PoisePython
24
+ module PythonProviders
25
+ class Msi < Base
26
+ provides(:msi)
27
+
28
+ MSI_VERSIONS = %w{3.4.4 3.3.5 3.2.5 3.1.4 3.0.1 2.7.10 2.6.5 2.5.4}
29
+
30
+ def self.provides_auto?(node, resource)
31
+ # Only enable by default on Windows and not for Python 3.5 because that
32
+ # uses the win_binaries provider.
33
+ node.platform_family?('windows') #&& resource.version != '3' && ::Gem::Requirement.create('< 3.5').satisfied_by(::Gem::Version.create(new_resource.version))
34
+ end
35
+
36
+ def python_binary
37
+ return options['python_binary'] if options['python_binary']
38
+ if package_version =~ /^(\d+)\.(\d+)\./
39
+ ::File.join(ENV['SystemDrive'], "Python#{$1}#{$2}", 'python.exe')
40
+ else
41
+ raise "Can't find Python binary for #{package_version}"
42
+ end
43
+ end
44
+
45
+ private
46
+
47
+ def install_python
48
+ version = package_version
49
+ windows_package 'python' do
50
+ source "https://www.python.org/ftp/python/#{version}/python-#{version}#{node['machine'] == 'x86_64' ? '.amd64' : ''}.msi"
51
+ end
52
+ end
53
+
54
+ def uninstall_python
55
+ raise NotImplementedError
56
+ end
57
+
58
+ def package_version
59
+ MSI_VERSIONS.find {|ver| ver.start_with?(new_resource.version) } || new_resource.version
60
+ end
61
+
62
+ end
63
+ end
64
+ end
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright 2015, Noah Kantrowitz
2
+ # Copyright 2015-2016, Noah Kantrowitz
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License");
5
5
  # you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright 2015, Noah Kantrowitz
2
+ # Copyright 2015-2016, Noah Kantrowitz
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License");
5
5
  # you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright 2015, Noah Kantrowitz
2
+ # Copyright 2015-2016, Noah Kantrowitz
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License");
5
5
  # you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright 2015, Noah Kantrowitz
2
+ # Copyright 2015-2016, Noah Kantrowitz
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License");
5
5
  # you may not use this file except in compliance with the License.
@@ -37,10 +37,10 @@ module PoisePython
37
37
  '12.04' => %w{python3.2 python2.7},
38
38
  '10.04' => %w{python3.1 python2.6},
39
39
  },
40
- rhel: {default: %w{python}},
40
+ redhat: {default: %w{python}},
41
41
  centos: {default: %w{python}},
42
42
  fedora: {default: %w{python3 python}},
43
- amazon: {default: %w{python27 python26 python}},
43
+ amazon: {default: %w{python34 python27 python26 python}},
44
44
  })
45
45
 
46
46
  # Output value for the Python binary we are installing. Seems to match
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright 2015, Noah Kantrowitz
2
+ # Copyright 2015-2016, Noah Kantrowitz
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License");
5
5
  # you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright 2015, Noah Kantrowitz
2
+ # Copyright 2015-2016, Noah Kantrowitz
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License");
5
5
  # you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright 2015, Noah Kantrowitz
2
+ # Copyright 2015-2016, Noah Kantrowitz
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License");
5
5
  # you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright 2015, Noah Kantrowitz
2
+ # Copyright 2015-2016, Noah Kantrowitz
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License");
5
5
  # you may not use this file except in compliance with the License.
@@ -33,12 +33,18 @@ module PoisePython
33
33
  # install. Probably not 100% bulletproof.
34
34
  PIP_HACK_SCRIPT = <<-EOH
35
35
  import json
36
+ import re
36
37
  import sys
37
38
 
39
+ import pip
40
+ # Don't use pkg_resources because I don't want to require it before this anyway.
41
+ if re.match(r'0|1|6\\.0', pip.__version__):
42
+ sys.stderr.write('The python_package resource requires pip >= 6.1.0, currently '+pip.__version__+'\\n')
43
+ sys.exit(1)
44
+
38
45
  from pip.commands import InstallCommand
39
46
  from pip.index import PackageFinder
40
47
  from pip.req import InstallRequirement
41
- from pip._vendor import pkg_resources
42
48
 
43
49
 
44
50
  packages = {}
@@ -49,15 +55,17 @@ with cmd._build_session(options) as session:
49
55
  index_urls = []
50
56
  else:
51
57
  index_urls = [options.index_url] + options.extra_index_urls
52
- finder = PackageFinder(
58
+ finder_options = dict(
53
59
  find_links=options.find_links,
54
- format_control=options.format_control,
55
60
  index_urls=index_urls,
56
- trusted_hosts=options.trusted_hosts,
57
61
  allow_all_prereleases=options.pre,
58
62
  process_dependency_links=options.process_dependency_links,
63
+ trusted_hosts=options.trusted_hosts,
59
64
  session=session,
60
65
  )
66
+ if getattr(options, 'format_control', None):
67
+ finder_options['format_control'] = options.format_control
68
+ finder = PackageFinder(**finder_options)
61
69
  find_all = getattr(finder, 'find_all_candidates', getattr(finder, '_find_all_versions', None))
62
70
  for arg in args:
63
71
  req = InstallRequirement.from_line(arg)
@@ -293,7 +301,7 @@ EOH
293
301
  # @param text [String] Output to parse.
294
302
  # @return [Hash<String, String>]
295
303
  def parse_pip_list(text)
296
- text.split(/\n/).inject({}) do |memo, line|
304
+ text.split(/\r?\n/).inject({}) do |memo, line|
297
305
  # Example of a line:
298
306
  # boto (2.25.0)
299
307
  if md = line.match(/^(\S+)\s+\(([^\s,]+).*\)$/i)
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright 2015, Noah Kantrowitz
2
+ # Copyright 2015-2016, Noah Kantrowitz
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License");
5
5
  # you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright 2015, Noah Kantrowitz
2
+ # Copyright 2015-2016, Noah Kantrowitz
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License");
5
5
  # you may not use this file except in compliance with the License.
@@ -28,6 +28,8 @@ module PoisePython
28
28
  module PythonRuntimePip
29
29
  # URL for the default get-pip.py script.
30
30
  DEFAULT_GET_PIP_URL = 'https://bootstrap.pypa.io/get-pip.py'
31
+ # Earliest version of pip we will try upgrading in-place.
32
+ PIP_INPLACE_VERSION = Gem::Version.create('7.0.0')
31
33
 
32
34
  # A `python_runtime_pip` resource to install/upgrade pip itself. This is
33
35
  # used internally by `python_runtime` and is not intended to be a public
@@ -72,8 +74,12 @@ module PoisePython
72
74
  #
73
75
  # @return [void]
74
76
  def action_install
77
+ Chef::Log.debug("[#{new_resource}] Installing pip #{new_resource.version || 'latest'}, currently #{current_resource.version || 'not installed'}")
78
+ if new_resource.version && current_resource.version == new_resource.version
79
+ Chef::Log.debug("[#{new_resource}] Pip #{current_resource.version} is already at requested version")
80
+ return # Desired version is installed, even if ancient.
75
81
  # If you have older than 7.0.0, we're re-bootstraping because lolno.
76
- if current_resource.version && Gem::Version.create(current_resource.version) >= Gem::Version.create('7.0.0')
82
+ elsif current_resource.version && Gem::Version.create(current_resource.version) >= PIP_INPLACE_VERSION
77
83
  install_pip
78
84
  else
79
85
  bootstrap_pip
@@ -99,31 +105,39 @@ module PoisePython
99
105
  # @return [void]
100
106
  def bootstrap_pip
101
107
  # Always updated if we have hit this point.
102
- new_resource.updated_by_last_action(true)
103
- # Pending https://github.com/pypa/pip/issues/1087.
104
- if new_resource.version
105
- Chef::Log.warn("pip does not support bootstrapping a specific version, see https://github.com/pypa/pip/issues/1087.")
106
- end
107
- # Use a temp file to hold the installer.
108
- Tempfile.create(['get-pip', '.py']) do |temp|
109
- # Download the get-pip.py.
110
- get_pip = Chef::HTTP.new(new_resource.get_pip_url).get('')
111
- # Write it to the temp file.
112
- temp.write(get_pip)
113
- # Close the file to flush it.
114
- temp.close
115
- # Run the install. This probably needs some handling for proxies et
116
- # al. Disable setuptools and wheel as we will install those later.
117
- # Use the environment vars instead of CLI arguments so I don't have
118
- # to deal with bootstrap versions that don't support --no-wheel.
119
- poise_shell_out!([new_resource.parent.python_binary, temp.path], environment: new_resource.parent.python_environment.merge('PIP_NO_SETUPTOOLS' => '1', 'PIP_NO_WHEEL' => '1'))
120
- end
121
- new_pip_version = pip_version
122
- if new_resource.version && new_pip_version != new_resource.version
123
- # We probably want to downgrade, which is silly but ¯\_(ツ)_/¯.
124
- # Can be removed once https://github.com/pypa/pip/issues/1087 is fixed.
125
- current_resource.version(new_pip_version)
126
- install_pip
108
+ converge_by("Bootstrapping pip #{new_resource.version || 'latest'} from #{new_resource.get_pip_url}") do
109
+ # Use a temp file to hold the installer.
110
+ # Put `Tempfile.create` back when Chef on Windows has a newer Ruby.
111
+ # Tempfile.create(['get-pip', '.py']) do |temp|
112
+ temp = Tempfile.new(['get-pip', '.py'])
113
+ begin
114
+ # Download the get-pip.py.
115
+ get_pip = Chef::HTTP.new(new_resource.get_pip_url).get('')
116
+ # Write it to the temp file.
117
+ temp.write(get_pip)
118
+ # Close the file to flush it.
119
+ temp.close
120
+ # Run the install. This probably needs some handling for proxies et
121
+ # al. Disable setuptools and wheel as we will install those later.
122
+ # Use the environment vars instead of CLI arguments so I don't have
123
+ # to deal with bootstrap versions that don't support --no-wheel.
124
+ boostrap_cmd = [new_resource.parent.python_binary, temp.path, '--upgrade', '--force-reinstall']
125
+ boostrap_cmd << "pip==#{new_resource.version}" if new_resource.version
126
+ Chef::Log.debug("[#{new_resource}] Running pip bootstrap command: #{boostrap_cmd.join(' ')}")
127
+ poise_shell_out!(boostrap_cmd, environment: new_resource.parent.python_environment.merge('PIP_NO_SETUPTOOLS' => '1', 'PIP_NO_WHEEL' => '1'))
128
+ ensure
129
+ temp.close unless temp.closed?
130
+ temp.unlink
131
+ end
132
+ new_pip_version = pip_version
133
+ if new_resource.version && new_pip_version != new_resource.version
134
+ # We probably want to downgrade, which is silly but ¯\_(ツ)_/¯.
135
+ # Can be removed once https://github.com/pypa/pip/issues/1087 is fixed.
136
+ # That issue is fixed, leaving a bit longer for older vendored scripts.
137
+ Chef::Log.debug("[#{new_resource}] Pip bootstrap installed #{new_pip_version}, trying to install again for #{new_resource.version}")
138
+ current_resource.version(new_pip_version)
139
+ install_pip
140
+ end
127
141
  end
128
142
  end
129
143
 
@@ -140,6 +154,7 @@ module PoisePython
140
154
  return if current_resource.version
141
155
  end
142
156
 
157
+ Chef::Log.debug("[#{new_resource}] Installing pip #{new_resource.version} via itself")
143
158
  notifying_block do
144
159
  # Use pip to upgrade (or downgrade) itself.
145
160
  python_package 'pip' do
@@ -155,7 +170,9 @@ module PoisePython
155
170
  #
156
171
  # @return [String, nil]
157
172
  def pip_version
158
- cmd = poise_shell_out([new_resource.parent.python_binary, '-m', 'pip.__main__', '--version'], environment: new_resource.parent.python_environment)
173
+ version_cmd = [new_resource.parent.python_binary, '-m', 'pip.__main__', '--version']
174
+ Chef::Log.debug("[#{new_resource}] Running pip version command: #{version_cmd.join(' ')}")
175
+ cmd = poise_shell_out(version_cmd, environment: new_resource.parent.python_environment)
159
176
  if cmd.error?
160
177
  # Not installed, probably.
161
178
  nil