lib/capistrano-pyenv.rb in capistrano-pyenv-0.0.10 vs lib/capistrano-pyenv.rb in capistrano-pyenv-0.0.11

- old
+ new

@@ -5,17 +5,21 @@ module Capistrano module PyEnv def self.extended(configuration) configuration.load { namespace(:pyenv) { + _cset(:pyenv_root, "$HOME/.pyenv") _cset(:pyenv_path) { - capture("echo $HOME/.pyenv").chomp() + # expand to actual path to use this value since pyenv may be executed by users other than `:user`. + capture("echo #{pyenv_root.dump}").strip } + _cset(:pyenv_bin_path) { File.join(pyenv_path, "bin") } + _cset(:pyenv_shims_path) { File.join(pyenv_path, "shims") } _cset(:pyenv_bin) { - File.join(pyenv_path, 'bin', 'pyenv') + File.join(pyenv_bin_path, "pyenv") } - _cset(:pyenv_cmd) { # to use custom pyenv_path, we use `env` instead of cap's default_environment. + _cset(:pyenv_cmd) { "env PYENV_VERSION=#{pyenv_python_version.dump} #{pyenv_bin}" } _cset(:pyenv_repository, 'git://github.com/yyuu/pyenv.git') _cset(:pyenv_branch, 'master') @@ -30,13 +34,15 @@ _cset(:pyenv_use_virtualenv, false) _cset(:pyenv_virtualenv_python_version, '2.7.3') _cset(:pyenv_virtualenv_options, %w(--distribute --quiet --system-site-packages)) + _cset(:pyenv_install_dependencies, true) + desc("Setup pyenv.") task(:setup, :except => { :no_release => true }) { - dependencies + dependencies if pyenv_install_dependencies update configure build } after 'deploy:setup', 'pyenv:setup' @@ -76,13 +82,33 @@ task(:update, :except => { :no_release => true }) { pyenv_update_repository(pyenv_path, :scm => :git, :repository => pyenv_repository, :branch => pyenv_branch) plugins.update } + def setup_default_environment + env = fetch(:default_environment, {}).dup + env["PYENV_ROOT"] = pyenv_path + env["PATH"] = [ pyenv_shims_path, pyenv_bin_path, env.fetch("PATH", "$PATH") ].join(":") + set(:default_environment, env) + end + + _cset(:pyenv_define_default_environment, true) + # workaround for `multistage` of capistrano-ext. + # https://github.com/yyuu/capistrano-rbenv/pull/5 + if top.namespaces.key?(:multistage) + after "multistage:ensure" do + setup_default_environment if pyenv_define_default_environment + end + else + on :start do + setup_default_environment if pyenv_define_default_environment + end + end + desc("Purge pyenv.") task(:purge, :except => { :no_release => true }) { - run("rm -rf #{pyenv_path}") + run("rm -rf #{pyenv_path.dump}") } namespace(:plugins) { desc("Update pyenv plugins.") task(:update, :except => { :no_release => true }) { @@ -116,39 +142,53 @@ end } _cset(:pyenv_configure_script) { (<<-EOS).gsub(/^\s*/, '') # Configured by capistrano-pyenv. Do not edit directly. - export PATH="#{pyenv_path}/bin:$PATH" + export PATH=#{[ pyenv_bin_path, "$PATH"].join(":").dump} eval "$(pyenv init -)" EOS } + + def _update_config(script_file, file, tempfile) + execute = [] + ## (1) ensure copy source file exists + execute << "( test -f #{file.dump} || touch #{file.dump} )" + ## (2) copy originao config to temporary file + execute << "rm -f #{tempfile.dump}" # remove tempfile to preserve permissions of original file + execute << "cp -fp #{file.dump} #{tempfile.dump}" + ## (3) modify temporary file + execute << "sed -i -e '/^#{Regexp.escape(pyenv_configure_signature)}/,/^#{Regexp.escape(pyenv_configure_signature)}/d' #{tempfile.dump}" + execute << "echo #{pyenv_configure_signature.dump} >> #{tempfile.dump}" + execute << "cat #{script_file.dump} >> #{tempfile.dump}" + execute << "echo #{pyenv_configure_signature.dump} >> #{tempfile.dump}" + ## (4) update config only if it is needed + execute << "cp -fp #{file.dump} #{(file + ".orig").dump}" + execute << "( diff -u #{file.dump} #{tempfile.dump} || mv -f #{tempfile.dump} #{file.dump} )" + run(execute.join(" && ")) + end + + def update_config(script_file, file) + begin + tempfile = capture("mktemp /tmp/pyenv.XXXXXXXXXX").strip + _update_config(script_file, file, tempfile) + ensure + run("rm -f #{tempfile.dump}") rescue nil + end + end + _cset(:pyenv_configure_signature, '##pyenv:configure') task(:configure, :except => { :no_release => true }) { if fetch(:pyenv_use_configure, true) - script = File.join('/tmp', "pyenv.#{$$}") - config = [ pyenv_configure_files ].flatten - config_map = Hash[ config.map { |f| [f, File.join('/tmp', "#{File.basename(f)}.#{$$}")] } ] begin - execute = [] - put(pyenv_configure_script, script) - config_map.each { |file, temp| - ## (1) copy original config to temporaly file and then modify - execute << "( test -f #{file} || touch #{file} )" - execute << "cp -fp #{file} #{temp}" - execute << "sed -i -e '/^#{Regexp.escape(pyenv_configure_signature)}/,/^#{Regexp.escape(pyenv_configure_signature)}/d' #{temp}" - execute << "echo #{pyenv_configure_signature.dump} >> #{temp}" - execute << "cat #{script} >> #{temp}" - execute << "echo #{pyenv_configure_signature.dump} >> #{temp}" - ## (2) update config only if it is needed - execute << "cp -fp #{file} #{file}.orig" - execute << "( diff -u #{file} #{temp} || mv -f #{temp} #{file} )" - } - run(execute.join(' && ')) + script_file = capture("mktemp /tmp/pyenv.XXXXXXXXXX").strip + top.put(pyenv_configure_script, script_file) + [ pyenv_configure_files ].flatten.each do |file| + update_config(script_file, file) + end ensure - remove = [ script ] + config_map.values - run("rm -f #{remove.join(' ')}") rescue nil + run("rm -f #{script_file.dump}") rescue nil end end } _cset(:pyenv_platform) { @@ -217,9 +257,14 @@ end end run("#{pyenv_cmd} exec #{python} --version && #{pyenv_cmd} global #{pyenv_python_version}") } + + # call `pyenv rehash` to update shims. + def rehash() + run("#{pyenv_cmd} rehash") + end } } end end end