Skip to content

Commit 42be1f3

Browse files
committed
Add extra_index parameter to python::pip
Add extra_index parameter to python::pip, corresponding to the pip command line option --extra-index-url, allowing packages to be installed from a local repository while dependencies are pulled from pypi.
1 parent ef2df5b commit 42be1f3

File tree

4 files changed

+74
-7
lines changed

4 files changed

+74
-7
lines changed

REFERENCE.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,7 @@ The following parameters are available in the `python::pip` defined type:
685685
* [`owner`](#owner)
686686
* [`group`](#group)
687687
* [`index`](#index)
688+
* [`extra_index`](#extra_index)
688689
* [`proxy`](#proxy)
689690
* [`editable`](#editable)
690691
* [`environment`](#environment)
@@ -766,6 +767,14 @@ Base URL of Python package index.
766767

767768
Default value: ``false``
768769

770+
##### <a name="extra_index"></a>`extra_index`
771+
772+
Data type: `Variant[Boolean,String[1]]`
773+
774+
Base URL of extra Python package index.
775+
776+
Default value: ``false``
777+
769778
##### <a name="proxy"></a>`proxy`
770779

771780
Data type: `Optional[Stdlib::HTTPUrl]`

manifests/pip.pp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
# @param owner The owner of the virtualenv being manipulated.
1010
# @param group The group of the virtualenv being manipulated.
1111
# @param index Base URL of Python package index.
12+
# @param extra_index Base URL of extra Python package index.
1213
# @param proxy Proxy server to use for outbound connections.
1314
# @param editable If true the package is installed as an editable resource.
1415
# @param environment Additional environment variables required to install the packages.
@@ -57,6 +58,7 @@
5758
Optional[String[1]] $group = getvar('python::params::group'),
5859
Optional[Python::Umask] $umask = undef,
5960
Variant[Boolean,String[1]] $index = false,
61+
Variant[Boolean,String[1]] $extra_index = false,
6062
Optional[Stdlib::HTTPUrl] $proxy = undef,
6163
Any $egg = false,
6264
Boolean $editable = false,
@@ -114,6 +116,11 @@
114116
default => "--index-url=${index}",
115117
}
116118

119+
$pypi_extra_index = $extra_index ? {
120+
false => '',
121+
default => "--extra-index-url=${extra_index}",
122+
}
123+
117124
$proxy_flag = $proxy ? {
118125
undef => '',
119126
default => "--proxy=${proxy}",
@@ -173,7 +180,7 @@
173180
}
174181

175182
$pip_install = "${pip_env} --log ${log}/pip.log install"
176-
$pip_common_args = "${pypi_index} ${proxy_flag} ${install_editable} ${source}"
183+
$pip_common_args = "${pypi_index} ${pypi_extra_index} ${proxy_flag} ${install_editable} ${source}"
177184

178185
# Explicit version out of VCS when PIP supported URL is provided
179186
if $source =~ /^'(git\+|hg\+|bzr\+|svn\+)(http|https|ssh|svn|sftp|ftp|lp|git)(:\/\/).+'$/ {
@@ -204,7 +211,8 @@
204211
# Note: we DO need to repeat ourselves with "from version" in both grep and sed as on some systems pip returns
205212
# more than one line with paretheses.
206213
$latest_version = join( [
207-
"${pip_install} ${pypi_index} ${proxy_flag} ${install_args} ${install_editable} ${real_pkgname}==notreallyaversion 2>&1",
214+
"${pip_install} ${pypi_index} ${pypi_extra_index} ${proxy_flag}",
215+
" ${install_args} ${install_editable} ${real_pkgname}==notreallyaversion 2>&1",
208216
' | grep -oP "\(from versions: .*\)" | sed -E "s/\(from versions: (.*?, )*(.*)\)/\2/g"',
209217
' | tr -d "[:space:]"',
210218
])

spec/acceptance/pip_spec.rb

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class { 'python':
3131
end
3232

3333
# rubocop:disable RSpec/RepeatedExampleGroupDescription
34+
# rubocop:disable RSpec/RepeatedExampleGroupBody
3435
describe command('/opt/test-venv/bin/pip list') do
3536
its(:exit_status) { is_expected.to eq 0 }
3637
its(:stdout) { is_expected.to match %r{agent.* 0\.1\.2} }
@@ -74,5 +75,40 @@ class { 'python':
7475
its(:exit_status) { is_expected.to eq 0 }
7576
its(:stdout) { is_expected.not_to match %r{agent.* 0\.1\.2} }
7677
end
78+
79+
context 'install package via extra_index' do
80+
it 'works with no errors' do
81+
pp = <<-PUPPET
82+
class { 'python':
83+
version => '3',
84+
dev => 'present',
85+
}
86+
87+
python::pyvenv { '/opt/test-venv':
88+
ensure => 'present',
89+
systempkgs => false,
90+
mode => '0755',
91+
pip_version => '<= 20.3.4',
92+
}
93+
94+
python::pip { 'agent package via extra_index':
95+
virtualenv => '/opt/test-venv',
96+
pkgname => 'agent',
97+
index => 'invalid',
98+
extra_index => 'https://pypi.org/simple',
99+
ensure => '0.1.2',
100+
}
101+
PUPPET
102+
103+
apply_manifest(pp, catch_failures: true)
104+
apply_manifest(pp, catch_changes: true)
105+
end
106+
end
107+
108+
describe command('/opt/test-venv/bin/pip list') do
109+
its(:exit_status) { is_expected.to eq 0 }
110+
its(:stdout) { is_expected.to match %r{agent.* 0\.1\.2} }
111+
end
112+
# rubocop:enable RSpec/RepeatedExampleGroupBody
77113
# rubocop:enable RSpec/RepeatedExampleGroupDescription
78114
end

spec/defines/pip_spec.rb

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@
7676
context 'adds proxy to install command if proxy set' do
7777
let(:params) { { proxy: 'http://my.proxy:3128' } }
7878

79-
it { is_expected.to contain_exec('pip_install_rpyc').with_command('pip --log /tmp/pip.log install --proxy=http://my.proxy:3128 rpyc') }
79+
it { is_expected.to contain_exec('pip_install_rpyc').with_command('pip --log /tmp/pip.log install --proxy=http://my.proxy:3128 rpyc') }
8080
end
8181
end
8282

@@ -90,7 +90,21 @@
9090
context 'adds index to install command if index set' do
9191
let(:params) { { index: 'http://www.example.com/simple/' } }
9292

93-
it { is_expected.to contain_exec('pip_install_rpyc').with_command('pip --log /tmp/pip.log install --index-url=http://www.example.com/simple/ rpyc') }
93+
it { is_expected.to contain_exec('pip_install_rpyc').with_command('pip --log /tmp/pip.log install --index-url=http://www.example.com/simple/ rpyc') }
94+
end
95+
end
96+
97+
describe 'extra_index as' do
98+
context 'defaults to empty' do
99+
let(:params) { {} }
100+
101+
it { is_expected.not_to contain_exec('pip_install_rpyc').with_command(%r{--extra-index-url}) }
102+
end
103+
104+
context 'adds extra_index to install command if extra_index set' do
105+
let(:params) { { extra_index: 'http://www.example.com/extra/simple/' } }
106+
107+
it { is_expected.to contain_exec('pip_install_rpyc').with_command('pip --log /tmp/pip.log install --extra-index-url=http://www.example.com/extra/simple/ rpyc') }
94108
end
95109
end
96110

@@ -107,7 +121,7 @@
107121
context 'adds install_args to install command if install_args set' do
108122
let(:params) { { install_args: '--pre' } }
109123

110-
it { is_expected.to contain_exec('pip_install_rpyc').with_command('pip --log /tmp/pip.log install --pre rpyc') }
124+
it { is_expected.to contain_exec('pip_install_rpyc').with_command('pip --log /tmp/pip.log install --pre rpyc') }
111125
end
112126
end
113127

@@ -171,13 +185,13 @@
171185
context 'suceeds with no extras' do
172186
let(:params) { {} }
173187

174-
it { is_expected.to contain_exec('pip_install_requests').with_command('pip --log /tmp/pip.log install requests') }
188+
it { is_expected.to contain_exec('pip_install_requests').with_command('pip --log /tmp/pip.log install requests') }
175189
end
176190

177191
context 'succeeds with extras' do
178192
let(:params) { { extras: ['security'] } }
179193

180-
it { is_expected.to contain_exec('pip_install_requests').with_command('pip --log /tmp/pip.log install requests[security]') }
194+
it { is_expected.to contain_exec('pip_install_requests').with_command('pip --log /tmp/pip.log install requests[security]') }
181195
end
182196
end
183197
end

0 commit comments

Comments
 (0)