diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f32d8d..3a05159 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # pyenv Changelog +## Unreleased + +- Add `:upgrade` action to the pyenv_pip resource + ## 3.3.2 (2020-08-05) - Do not attempt to rehash in a system-wide install diff --git a/README.md b/README.md index e43fba0..190f58a 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,12 @@ pyenv_pip 'requests' do end ``` +The pyenv_pip resource has the following actions: + +* `:install` - Default. Install a python package. If a version is specified, install the specified version of the python package. +* `:upgrade` - Install/upgrade a python package. Call `install` command with `--upgrade` flag. If version is not specified, latest version will be installed. +* `:uninstall` - Uninstall a python package. + ## Global ```ruby diff --git a/resources/pip.rb b/resources/pip.rb index bc05516..b1769c9 100644 --- a/resources/pip.rb +++ b/resources/pip.rb @@ -59,6 +59,29 @@ end end +action :upgrade do + upgrade_target = if new_resource.version + "#{new_resource.package_name}==#{new_resource.version}" + else + new_resource.package_name.to_s + end + + pip_args = "install --upgrade #{new_resource.options} #{upgrade_target}" + + # without virtualenv, upgrade package with system's pip + command = if new_resource.virtualenv + "#{new_resource.virtualenv}/bin/pip #{pip_args}" + else + "pip #{pip_args}" + end + + pyenv_script new_resource.package_name do + code command + user new_resource.user if new_resource.user + only_if { require_upgrade? } + end +end + action :uninstall do uninstall_mode = if new_resource.requirement '--requirement' @@ -86,6 +109,25 @@ include Chef::Pyenv::ScriptHelpers def require_install? + current_version = get_current_version + return true unless current_version + + unless new_resource.version + Chef::Log.debug("already installed: #{new_resource.package_name} #{current_version}") + return false + end + + is_different_version?(current_version) + end + + def require_upgrade? + current_version = get_current_version + return true unless current_version + + is_different_version?(current_version) + end + + def get_current_version current_version = nil show = pip_command("show #{new_resource.package_name}").stdout show.split(/\n+/).each do |line| @@ -94,14 +136,11 @@ def require_install? Chef::Log.debug("current_version: #{new_resource.package_name} #{current_version}") unless current_version Chef::Log.debug("not installed: #{new_resource.package_name}") - return true - end - - unless new_resource.version - Chef::Log.debug("already installed: #{new_resource.package_name} #{current_version}") - return false end + current_version + end + def is_different_version?(current_version) if current_version != new_resource.version Chef::Log.debug("different version installed: #{new_resource.package_name} current=#{current_version} candidate=#{new_resource.version}") true @@ -111,3 +150,4 @@ def require_install? end end end + diff --git a/test/fixtures/cookbooks/test/files/requirements.txt b/test/fixtures/cookbooks/test/files/requirements.txt index e719d14..8f8e14f 100644 --- a/test/fixtures/cookbooks/test/files/requirements.txt +++ b/test/fixtures/cookbooks/test/files/requirements.txt @@ -1,2 +1,3 @@ fire==0.1.2 -requests==2.18.1 \ No newline at end of file +requests==2.18.1 +urllib3==1.24.3 diff --git a/test/fixtures/cookbooks/test/recipes/system_install.rb b/test/fixtures/cookbooks/test/recipes/system_install.rb index 3738c74..254a296 100644 --- a/test/fixtures/cookbooks/test/recipes/system_install.rb +++ b/test/fixtures/cookbooks/test/recipes/system_install.rb @@ -36,6 +36,12 @@ requirement true end +pyenv_pip 'urllib3' do + virtualenv venv_root + action :upgrade + version '1.25.11' +end + pyenv_pip 'requests' do virtualenv venv_root action :uninstall diff --git a/test/integration/system_install/controls/system_install.rb b/test/integration/system_install/controls/system_install.rb index 3d6a1ad..975b6ea 100644 --- a/test/integration/system_install/controls/system_install.rb +++ b/test/integration/system_install/controls/system_install.rb @@ -36,7 +36,13 @@ its('stdout') { should match('Version: 16.2.0') } end - desc 'Pip should install package requests inside virtualenv according to requirements.txt' + desc 'Pip should upgrade package urllib3 inside virtualenv' + describe bash("sudo -H bash -c 'source /etc/profile.d/pyenv.sh && #{venv_root}/bin/pip show urllib3'") do + its('exit_status') { should eq(0) } + its('stdout') { should match('Version: 1.25.11') } + end + + desc 'Pip should install package fire inside virtualenv according to requirements.txt' describe bash("sudo -H bash -c 'source /etc/profile.d/pyenv.sh && #{venv_root}/bin/pip show fire'") do its('exit_status') { should eq(0) } its('stdout') { should match('Version: 0.1.2') } diff --git a/test/integration/user_install/controls/user_install.rb b/test/integration/user_install/controls/user_install.rb index be50ad8..c3bb712 100644 --- a/test/integration/user_install/controls/user_install.rb +++ b/test/integration/user_install/controls/user_install.rb @@ -37,7 +37,7 @@ its('stdout') { should match('Version: 16.2.0') } end - desc 'Pip should install package requests inside virtualenv according to requirements.txt' + desc 'Pip should install package fire inside virtualenv according to requirements.txt' describe bash("sudo -H -u #{user} bash -c 'source /etc/profile.d/pyenv.sh && #{venv_root}/bin/pip show fire'") do its('exit_status') { should eq(0) } its('stdout') { should match('Version: 0.1.2') }