diff --git a/lib/pdk/cli.rb b/lib/pdk/cli.rb index f9a0489aa..516a192f3 100644 --- a/lib/pdk/cli.rb +++ b/lib/pdk/cli.rb @@ -159,6 +159,7 @@ def self.puppet_dev_option(dsl) require 'pdk/cli/build' require 'pdk/cli/config' require 'pdk/cli/convert' + require 'pdk/cli/env' require 'pdk/cli/get' require 'pdk/cli/new' require 'pdk/cli/set' diff --git a/lib/pdk/cli/env.rb b/lib/pdk/cli/env.rb new file mode 100644 index 000000000..9b196565c --- /dev/null +++ b/lib/pdk/cli/env.rb @@ -0,0 +1,52 @@ +module PDK::CLI + @env_cmd = @base_cmd.define_command do + name 'env' + usage _('env') + summary _('(Experimental) Output environment variables for specific Puppet context') + description _(<<-EOF +[experimental] Aids in setting a CLI context for a specified version of Puppet by outputting export commands for necessary environment variables. +EOF + ) + + PDK::CLI.puppet_version_options(self) + PDK::CLI.puppet_dev_option(self) + + run do |opts, args, _cmd| + require 'pdk/util' + require 'pdk/util/ruby_version' + + PDK::CLI::Util.validate_puppet_version_opts(opts) + + PDK::CLI::Util.analytics_screen_view('env') + + # Ensure that the correct Ruby is activated before running command. + puppet_env = PDK::CLI::Util.puppet_from_opts_or_env(opts) + PDK::Util::RubyVersion.use(puppet_env[:ruby_version]) + + resolved_env = { + 'PDK_RESOLVED_PUPPET_VERSION': puppet_env[:gemset][:puppet], + 'PDK_RESOLVED_RUBY_VERSION': puppet_env[:ruby_version], + } + + resolved_env['GEM_HOME'] = PDK::Util::RubyVersion.gem_home + gem_path = PDK::Util::RubyVersion.gem_path + resolved_env['GEM_PATH'] = gem_path.empty? ? resolved_env['GEM_HOME'] : gem_path + + # Make sure invocation of Ruby prefers our private installation. + package_binpath = PDK::Util.package_install? ? File.join(PDK::Util.pdk_package_basedir, 'bin') : nil + + resolved_env['PATH'] = [ + PDK::Util::RubyVersion.bin_path, + File.join(resolved_env['GEM_HOME'], 'bin'), + PDK::Util::RubyVersion.gem_paths_raw.map { |gem_path_raw| File.join(gem_path_raw, 'bin') }, + package_binpath, + PDK::Util::Env['PATH'], + ].compact.flatten.join(File::PATH_SEPARATOR) + + resolved_env.each do |var, val| + puts "export #{var}=\"#{val}\"" + end + exit 0 + end + end +end diff --git a/spec/unit/pdk/cli/env_spec.rb b/spec/unit/pdk/cli/env_spec.rb new file mode 100644 index 000000000..f75bdc792 --- /dev/null +++ b/spec/unit/pdk/cli/env_spec.rb @@ -0,0 +1,90 @@ +require 'spec_helper' +require 'pdk/cli' + +describe 'Running `pdk env`' do + let(:command_args) { ['env'] } + let(:command_result) { { exit_code: 0 } } + + context 'when it calls env successfully' do + after(:each) do + expect { + PDK::CLI.run(command_args) + }.to exit_zero + end + + before(:each) do + allow(PDK::Util::RubyVersion).to receive(:gem_home).and_return("/opt/puppetlabs/pdk/share/cache/ruby/2.4.0") + allow(PDK::Util::RubyVersion).to receive(:gem_path).and_return("/opt/puppetlabs/pdk/private/ruby/2.4.3/lib") + allow(PDK::Util::RubyVersion).to receive(:bin_path).and_return("/opt/puppetlabs/pdk/private/ruby/2.4.3/bin") + allow(PDK::Util::RubyVersion).to receive(:gem_paths_raw).and_return(["/opt/puppetlabs/pdk/private/ruby/2.4.3/lib"]) + allow(PDK::Util::Env).to receive(:[]).and_call_original + allow(PDK::Util::Env).to receive(:[]).with('PATH').and_return('/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin') + + allow(PDK::CLI::Util).to receive(:puppet_from_opts_or_env) + .and_return(ruby_version: '2.4.3', gemset: { puppet: '5.4.0' }) + allow(PDK::Util::RubyVersion).to receive(:use) + end + + context 'and called with no arguments' do + it 'sends a "env" screen view to analytics' do + expect(analytics).to receive(:screen_view).with( + 'env', + output_format: 'default', + ruby_version: RUBY_VERSION, + ) + end + + it 'outputs export commands for environment variables' do + output_regexes = [ + /export PDK_RESOLVED_PUPPET_VERSION="\d\.\d+\.\d+"/, + /export PDK_RESOLVED_RUBY_VERSION="\d\.\d+\.\d+"/, + /export GEM_HOME=.*/, + /export GEM_PATH=.*/, + /export PATH=.*/ + ] + + output_regexes.each do |regex| + expect($stdout).to receive(:puts).with(a_string_matching(regex)) + end + end + end + + context 'and called with a puppet version' do + let(:command_args) { super() + %w[--puppet-version=6] } + + it 'outputs export commands for environment variables' do + output_regexes = [ + /export PDK_RESOLVED_PUPPET_VERSION="\d\.\d+\.\d+"/, + /export PDK_RESOLVED_RUBY_VERSION="\d\.\d+\.\d+"/, + /export GEM_HOME=.*/, + /export GEM_PATH=.*/, + /export PATH=.*/ + ] + + output_regexes.each do |regex| + expect($stdout).to receive(:puts).with(a_string_matching(regex)) + end + end + + # context 'with a conflicting environment variable' do + # before(:each) do + # allow(PDK::Util::Env).to receive(:[]).with('PDK_PUPPET_VERSION').and_return('5.1') + # end + + # it 'outputs export commands for environment variables' do + # output_regexes = [ + # /export PDK_RESOLVED_PUPPET_VERSION="\d\.\d+\.\d+"/, + # /export PDK_RESOLVED_RUBY_VERSION="\d\.\d+\.\d+"/, + # /export GEM_HOME=.*/, + # /export GEM_PATH=.*/, + # /export PATH=.*/ + # ] + + # output_regexes.each do |regex| + # expect($stdout).to receive(:puts).with(a_string_matching(regex)) + # end + # end + # end + end + end +end