poise-python 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +11 -0
  3. data/.kitchen.travis.yml +9 -0
  4. data/.kitchen.yml +8 -0
  5. data/.travis.yml +21 -0
  6. data/.yardopts +7 -0
  7. data/Berksfile +28 -0
  8. data/Gemfile +33 -0
  9. data/LICENSE +201 -0
  10. data/README.md +399 -0
  11. data/Rakefile +17 -0
  12. data/chef/attributes/default.rb +24 -0
  13. data/chef/recipes/default.rb +20 -0
  14. data/lib/poise_python.rb +25 -0
  15. data/lib/poise_python/cheftie.rb +18 -0
  16. data/lib/poise_python/error.rb +23 -0
  17. data/lib/poise_python/python_command_mixin.rb +45 -0
  18. data/lib/poise_python/python_providers.rb +35 -0
  19. data/lib/poise_python/python_providers/base.rb +177 -0
  20. data/lib/poise_python/python_providers/portable_pypy.rb +96 -0
  21. data/lib/poise_python/python_providers/scl.rb +77 -0
  22. data/lib/poise_python/python_providers/system.rb +86 -0
  23. data/lib/poise_python/resources.rb +31 -0
  24. data/lib/poise_python/resources/pip_requirements.rb +102 -0
  25. data/lib/poise_python/resources/python_execute.rb +83 -0
  26. data/lib/poise_python/resources/python_package.rb +322 -0
  27. data/lib/poise_python/resources/python_runtime.rb +114 -0
  28. data/lib/poise_python/resources/python_runtime_pip.rb +167 -0
  29. data/lib/poise_python/resources/python_runtime_test.rb +185 -0
  30. data/lib/poise_python/resources/python_virtualenv.rb +164 -0
  31. data/lib/poise_python/utils.rb +63 -0
  32. data/lib/poise_python/utils/python_encoder.rb +73 -0
  33. data/lib/poise_python/version.rb +20 -0
  34. data/poise-python.gemspec +41 -0
  35. data/test/cookbooks/poise-python_test/metadata.rb +18 -0
  36. data/test/cookbooks/poise-python_test/recipes/default.rb +40 -0
  37. data/test/gemfiles/chef-12.gemfile +19 -0
  38. data/test/gemfiles/master.gemfile +23 -0
  39. data/test/integration/default/serverspec/default_spec.rb +102 -0
  40. data/test/spec/python_command_mixin_spec.rb +115 -0
  41. data/test/spec/python_providers/portable_pypy_spec.rb +68 -0
  42. data/test/spec/python_providers/scl_spec.rb +75 -0
  43. data/test/spec/python_providers/system_spec.rb +81 -0
  44. data/test/spec/resources/pip_requirements_spec.rb +69 -0
  45. data/test/spec/resources/python_package_spec.rb +65 -0
  46. data/test/spec/resources/python_runtime_pip_spec.rb +33 -0
  47. data/test/spec/resources/python_virtualenv_spec.rb +103 -0
  48. data/test/spec/spec_helper.rb +19 -0
  49. data/test/spec/utils/python_encoder_spec.rb +79 -0
  50. data/test/spec/utils_spec.rb +86 -0
  51. metadata +170 -0
@@ -0,0 +1,23 @@
1
+ #
2
+ # Copyright 2015, 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
+ eval_gemfile File.expand_path('../../../Gemfile', __FILE__)
18
+
19
+ gem 'chef', github: 'chef/chef'
20
+ gem 'halite', github: 'poise/halite'
21
+ gem 'poise', github: 'poise/poise'
22
+ gem 'poise-boiler', github: 'poise/poise-boiler'
23
+ gem 'poise-languages', github: 'poise/poise-languages'
@@ -0,0 +1,102 @@
1
+ #
2
+ # Copyright 2015, 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 'serverspec'
18
+ set :backend, :exec
19
+
20
+ # Set up the shared example for python_runtime_test.
21
+ RSpec.shared_examples 'a python_runtime_test' do |python_name, version=nil|
22
+ let(:python_name) { python_name }
23
+ let(:python_path) { File.join('', 'root', "python_test_#{python_name}") }
24
+ # Helper for all the file checks.
25
+ def self.assert_file(rel_path, should_exist=true, &block)
26
+ describe rel_path do
27
+ subject { file(File.join(python_path, rel_path)) }
28
+ # Do nothing for nil.
29
+ if should_exist == true
30
+ it { is_expected.to be_a_file }
31
+ elsif should_exist == false
32
+ it { is_expected.to_not exist }
33
+ end
34
+ instance_eval(&block) if block
35
+ end
36
+ end
37
+
38
+ describe 'python_runtime' do
39
+ assert_file('version') do
40
+ its(:content) { is_expected.to start_with version } if version
41
+ end
42
+ end
43
+
44
+ describe 'python_package' do
45
+ describe 'sqlparse' do
46
+ assert_file('import_sqlparse_before', false)
47
+ assert_file('import_sqlparse_mid')
48
+ assert_file('import_sqlparse_after', false)
49
+ assert_file('sentinel_sqlparse')
50
+ assert_file('sentinel_sqlparse2', false)
51
+ end
52
+
53
+ describe 'setuptools' do
54
+ assert_file('sentinel_setuptools', false)
55
+ end
56
+
57
+ describe 'pep8' do
58
+ assert_file('import_pep8')
59
+ end
60
+
61
+ describe 'pytz' do
62
+ assert_file('import_pytz')
63
+ end
64
+ end
65
+
66
+ describe 'python_virtualenv' do
67
+ assert_file('venv', nil) do
68
+ it { is_expected.to be_a_directory }
69
+ end
70
+ assert_file('import_pytest', false)
71
+ assert_file('import_pytest_venv')
72
+ end
73
+
74
+ describe 'pip_requirements' do
75
+ assert_file('import_requests') do
76
+ its(:content) { is_expected.to eq '2.7.0' }
77
+ end
78
+ assert_file('import_six') do
79
+ its(:content) { is_expected.to eq '1.8.0' }
80
+ end
81
+ end
82
+ end
83
+
84
+ describe 'python 2' do
85
+ it_should_behave_like 'a python_runtime_test', '2', '2'
86
+ end
87
+
88
+ describe 'python 3' do
89
+ it_should_behave_like 'a python_runtime_test', '3', '3'
90
+ end
91
+
92
+ describe 'pypy' do
93
+ it_should_behave_like 'a python_runtime_test', 'pypy'
94
+ end
95
+
96
+ describe 'system provider', unless: File.exist?('/no_system') do
97
+ it_should_behave_like 'a python_runtime_test', 'system'
98
+ end
99
+
100
+ describe 'scl provider', unless: File.exist?('/no_scl') do
101
+ it_should_behave_like 'a python_runtime_test', 'scl'
102
+ end
@@ -0,0 +1,115 @@
1
+ #
2
+ # Copyright 2015, 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 'spec_helper'
18
+
19
+ describe PoisePython::PythonCommandMixin do
20
+ describe PoisePython::PythonCommandMixin::Resource do
21
+ resource(:poise_test) do
22
+ include described_class
23
+ end
24
+ provider(:poise_test)
25
+
26
+ describe '#python' do
27
+ let(:python) { chef_run.python_runtime('test') }
28
+
29
+ context 'with an implicit parent' do
30
+ recipe do
31
+ python_runtime 'test' do
32
+ provider :system
33
+ end
34
+ poise_test 'test'
35
+ end
36
+
37
+ it { is_expected.to run_poise_test('test').with(parent_python: python, python: '/usr/bin/python') }
38
+ end # /context with an implicit parent
39
+
40
+ context 'with a parent resource' do
41
+ recipe do
42
+ r = python_runtime 'test' do
43
+ provider :system
44
+ end
45
+ poise_test 'test' do
46
+ python r
47
+ end
48
+ end
49
+
50
+ it { is_expected.to run_poise_test('test').with(parent_python: python, python: '/usr/bin/python') }
51
+ end # /context with a parent resource
52
+
53
+ context 'with a parent resource name' do
54
+ recipe do
55
+ python_runtime 'test' do
56
+ provider :system
57
+ end
58
+ poise_test 'test' do
59
+ python 'test'
60
+ end
61
+ end
62
+
63
+ it { is_expected.to run_poise_test('test').with(parent_python: python, python: '/usr/bin/python') }
64
+ end # /context with a parent resource name
65
+
66
+ context 'with a parent resource name that looks like a path' do
67
+ let(:python) { chef_run.python_runtime('/usr/bin/other') }
68
+ recipe do
69
+ python_runtime '/usr/bin/other' do
70
+ provider :system
71
+ end
72
+ poise_test 'test' do
73
+ python '/usr/bin/other'
74
+ end
75
+ end
76
+
77
+ it { is_expected.to run_poise_test('test').with(parent_python: python, python: '/usr/bin/python') }
78
+ end # /context with a parent resource name that looks like a path
79
+
80
+ context 'with a path' do
81
+ recipe do
82
+ poise_test 'test' do
83
+ python '/usr/bin/other'
84
+ end
85
+ end
86
+
87
+ it { is_expected.to run_poise_test('test').with(parent_python: nil, python: '/usr/bin/other') }
88
+ end # /context with a path
89
+
90
+ context 'with a path and an implicit parent' do
91
+ recipe do
92
+ python_runtime 'test' do
93
+ provider :system
94
+ end
95
+ poise_test 'test' do
96
+ python '/usr/bin/other'
97
+ end
98
+ end
99
+
100
+ it { is_expected.to run_poise_test('test').with(parent_python: python, python: '/usr/bin/other') }
101
+ end # /context with a path and an implicit parent
102
+
103
+ context 'with an invalid parent' do
104
+ recipe do
105
+ poise_test 'test' do
106
+ python 'test'
107
+ end
108
+ end
109
+
110
+ it { expect { subject }.to raise_error Chef::Exceptions::ResourceNotFound }
111
+ end # /context with an invalid parent
112
+
113
+ end # /describe #python
114
+ end # /describe PoisePython::PythonCommandMixin::Resource
115
+ end
@@ -0,0 +1,68 @@
1
+ #
2
+ # Copyright 2015, 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 'spec_helper'
18
+
19
+ describe PoisePython::PythonProviders::PortablePyPy do
20
+ let(:python_version) { nil }
21
+ let(:chefspec_options) { {platform: 'ubuntu', version: '14.04'} }
22
+ let(:default_attributes) { {poise_python_version: python_version} }
23
+ let(:python_runtime) { chef_run.python_runtime('test') }
24
+ step_into(:python_runtime)
25
+ recipe do
26
+ python_runtime 'test' do
27
+ version node['poise_python_version']
28
+ virtualenv_version false
29
+ end
30
+ end
31
+
32
+ shared_examples_for 'portablepypy provider' do |name|
33
+ it { expect(python_runtime.provider_for_action(:install)).to be_a described_class }
34
+ it { is_expected.to create_remote_file(File.join(Chef::Config[:file_cache_path], "#{name}.tar.bz2")).with(source: "https://bitbucket.org/squeaky/portable-pypy/downloads/#{name}.tar.bz2") }
35
+ it { expect(python_runtime.python_binary).to eq "/opt/#{name}/bin/pypy"}
36
+ end
37
+
38
+ context 'with version pypy' do
39
+ let(:python_version) { 'pypy' }
40
+ it_behaves_like 'portablepypy provider', 'pypy-2.6-linux_x86_64-portable'
41
+ end # /context with version pypy
42
+
43
+ context 'with version pypy-2.4' do
44
+ let(:python_version) { 'pypy-2.4' }
45
+ it_behaves_like 'portablepypy provider', 'pypy-2.4-linux_x86_64-portable'
46
+ end # /context with version pypy-2.4
47
+
48
+ context 'with version pypy3' do
49
+ let(:python_version) { 'pypy3' }
50
+ it_behaves_like 'portablepypy provider', 'pypy3-2.4-linux_x86_64-portable'
51
+ end # /context with version pypy3
52
+
53
+ context 'with version pypy3-2.3.1' do
54
+ let(:python_version) { 'pypy3-2.3.1' }
55
+ it_behaves_like 'portablepypy provider', 'pypy3-2.3.1-linux_x86_64-portable'
56
+ end # /context with version pypy3-2.3.1
57
+
58
+ context 'action :uninstall' do
59
+ recipe do
60
+ python_runtime 'test' do
61
+ version 'pypy'
62
+ action :uninstall
63
+ end
64
+ end
65
+
66
+ it { is_expected.to delete_directory('/opt/pypy-2.6-linux_x86_64-portable').with(recursive: true) }
67
+ end # /context action :uninstall
68
+ end
@@ -0,0 +1,75 @@
1
+ #
2
+ # Copyright 2015, 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 'spec_helper'
18
+
19
+ describe PoisePython::PythonProviders::Scl do
20
+ let(:python_version) { '' }
21
+ let(:chefspec_options) { {platform: 'centos', version: '7.0'} }
22
+ let(:default_attributes) { {poise_python_version: python_version} }
23
+ let(:python_runtime) { chef_run.python_runtime('test') }
24
+ step_into(:python_runtime)
25
+ recipe do
26
+ python_runtime 'test' do
27
+ version node['poise_python_version']
28
+ virtualenv_version false
29
+ end
30
+ end
31
+
32
+ shared_examples_for 'scl provider' do |pkg|
33
+ it { expect(python_runtime.provider_for_action(:install)).to be_a described_class }
34
+ it { is_expected.to install_poise_languages_scl(pkg) }
35
+ it do
36
+ expect_any_instance_of(described_class).to receive(:install_scl_package)
37
+ run_chef
38
+ end
39
+ end
40
+
41
+ context 'with version ""' do
42
+ let(:python_version) { '' }
43
+ it_behaves_like 'scl provider', 'rh-python34'
44
+ end # /context with version ""
45
+
46
+ context 'with version "2"' do
47
+ let(:python_version) { '2' }
48
+ it_behaves_like 'scl provider', 'python27'
49
+ end # /context with version "2"
50
+
51
+ context 'with version "3"' do
52
+ let(:python_version) { '3' }
53
+ it_behaves_like 'scl provider', 'rh-python34'
54
+ end # /context with version "3"
55
+
56
+ context 'with version "3.3"' do
57
+ let(:python_version) { '3.3' }
58
+ it_behaves_like 'scl provider', 'python33'
59
+ end # /context with version "3.3"
60
+
61
+ context 'action :uninstall' do
62
+ recipe do
63
+ python_runtime 'test' do
64
+ action :uninstall
65
+ version node['poise_python_version']
66
+ end
67
+ end
68
+
69
+ it do
70
+ expect_any_instance_of(described_class).to receive(:uninstall_scl_package)
71
+ run_chef
72
+ end
73
+ it { expect(python_runtime.provider_for_action(:uninstall)).to be_a described_class }
74
+ end # /context action :uninstall
75
+ end
@@ -0,0 +1,81 @@
1
+ #
2
+ # Copyright 2015, 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 'spec_helper'
18
+
19
+ describe PoisePython::PythonProviders::System do
20
+ let(:python_version) { '' }
21
+ let(:chefspec_options) { {platform: 'ubuntu', version: '14.04'} }
22
+ let(:default_attributes) { {poise_python_version: python_version} }
23
+ let(:python_runtime) { chef_run.python_runtime('test') }
24
+ let(:system_package_candidates) { python_runtime.provider_for_action(:install).send(:system_package_candidates, python_version) }
25
+ step_into(:python_runtime)
26
+ recipe do
27
+ python_runtime 'test' do
28
+ version node['poise_python_version']
29
+ virtualenv_version false
30
+ end
31
+ end
32
+
33
+ shared_examples_for 'system provider' do |candidates, pkg|
34
+ it { expect(python_runtime.provider_for_action(:install)).to be_a described_class }
35
+ it { expect(system_package_candidates).to eq candidates }
36
+ it { is_expected.to install_poise_languages_system(pkg) }
37
+ it do
38
+ expect_any_instance_of(described_class).to receive(:install_system_packages)
39
+ run_chef
40
+ end
41
+ end
42
+
43
+ context 'with version ""' do
44
+ let(:python_version) { '' }
45
+ it_behaves_like 'system provider', %w{python3.5 python35 python3.4 python34 python3.3 python33 python3.2 python32 python3.1 python31 python3.0 python30 python3 python2.7 python27 python2.6 python26 python2.5 python25 python}, 'python3.4'
46
+ end # /context with version ""
47
+
48
+ context 'with version 2' do
49
+ let(:python_version) { '2' }
50
+ it_behaves_like 'system provider', %w{python2.7 python27 python2.6 python26 python2.5 python25 python}, 'python2.7'
51
+ end # /context with version 2
52
+
53
+ context 'with version 3' do
54
+ let(:python_version) { '3' }
55
+ it_behaves_like 'system provider', %w{python3.5 python35 python3.4 python34 python3.3 python33 python3.2 python32 python3.1 python31 python3.0 python30 python3 python}, 'python3.4'
56
+ end # /context with version 3
57
+
58
+ context 'with version 2.3' do
59
+ let(:python_version) { '2.3' }
60
+ before do
61
+ default_attributes['poise-python'] ||= {}
62
+ default_attributes['poise-python']['test'] = {'package_name' => 'python2.3'}
63
+ end
64
+ it_behaves_like 'system provider', %w{python2.3 python23 python}, 'python2.3'
65
+ end # /context with version 2.3
66
+
67
+ context 'action :uninstall' do
68
+ recipe do
69
+ python_runtime 'test' do
70
+ action :uninstall
71
+ version node['poise_python_version']
72
+ end
73
+ end
74
+
75
+ it do
76
+ expect_any_instance_of(described_class).to receive(:uninstall_system_packages)
77
+ run_chef
78
+ end
79
+ it { expect(python_runtime.provider_for_action(:uninstall)).to be_a described_class }
80
+ end # /context action :uninstall
81
+ end