Last active
December 9, 2015 11:11
-
-
Save sue445/4b8013ad19a3f5917aee to your computer and use it in GitHub Desktop.
specinfra-plain_sudoの一部
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# lib/specinfra/plain_sudo.rb | |
require "specinfra/plain_sudo/version" | |
require "specinfra" | |
require "active_support/all" | |
module Specinfra | |
module PlainSudo | |
# Your code goes here... | |
end | |
end | |
Specinfra::Backend::Ssh.class_eval do | |
require "specinfra/plain_sudo/build_command_with_plain_sudo" | |
alias_method_chain :build_command, :plain_sudo | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# lib/specinfra/plain_sudo/build_command_with_plain_sudo.rb | |
module Specinfra | |
module PlainSudo | |
# sudoできないコマンドを列挙 | |
CAN_NOT_SUDO_COMMANDS = %w(cd export umask) | |
# 引数のcommandにsudoをつけていいかどうかのチェック | |
def self.can_sudo?(command) | |
# 誤爆防止の為後ろに空白をいれたものでチェックする | |
if CAN_NOT_SUDO_COMMANDS.map{ |c| "#{c} " }.any?{ |c| command.start_with?(c) } | |
# sudoできないコマンドに1つでもマッチしてたらsudoできないようにする | |
false | |
else | |
true | |
end | |
end | |
end | |
end | |
def build_command_with_plain_sudo(original_command) | |
return build_command_without_plain_sudo(original_command) unless sudo? | |
return original_command if original_command.include?("sudo ") | |
# 環境変数とコマンドで分割する | |
# 例) KEY1='VALUE1' KEY2="VALUE2" ls /tmp だと | |
# environment: KEY1='VALUE1' KEY2="VALUE2" | |
# commands : ls /tmp | |
matched_data = %r( | |
^(?<environment>(\w+=["']?\w+["']?\s*)+) | |
(?<commands>.+)$ | |
)x.match(original_command) | |
if matched_data | |
environment = matched_data[:environment].strip | |
commands = matched_data[:commands] | |
else | |
environment = nil | |
commands = original_command | |
end | |
formatted_command = | |
commands.split("&&").map do |command| | |
command.strip! | |
if Specinfra::PlainSudo.can_sudo?(command) | |
"sudo #{command}" | |
else | |
# sudo cd 〜 などができないため | |
command | |
end | |
end.join(" && ") | |
[environment, formatted_command].compact.join(" ") | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# spec/specinfra/plain_sudo_spec.rb | |
describe Specinfra::Backend::Ssh do | |
let(:backend){ Specinfra::Backend::Ssh.instance } | |
describe "#build_command" do | |
subject{ backend.build_command(command) } | |
before do | |
# sudoじゃない場合はオリジナルのメソッドが呼ばれるはずなのでテスト不要 | |
allow(backend).to receive(:sudo?){ true } | |
end | |
context "コマンドにsudoが含まれていない時" do | |
context "コマンドにcdが含まれていない時" do | |
let(:command){ "sl -l ." } | |
it { should eq "sudo sl -l ." } | |
end | |
context "コマンドにcdが含まれている時" do | |
let(:command){ "cd /usr/local/rbenv && git ls-remote origin HEAD | cut -f1" } | |
it { should eq "cd /usr/local/rbenv && sudo git ls-remote origin HEAD | cut -f1" } | |
end | |
context "コマンドにumaskが含まれている時" do | |
let(:command){ "umask 002 && mkdir /tmp/hoge" } | |
it { should eq "umask 002 && sudo mkdir /tmp/hoge" } | |
end | |
context "コマンドに環境変数が含まれている時" do | |
let(:command){ %q(KEY1='VALUE1' KEY2="VALUE2" ls /tmp) } | |
it { should eq %q(KEY1='VALUE1' KEY2="VALUE2" sudo ls /tmp) } | |
end | |
end | |
context "コマンドにsudoが含まれている時" do | |
let(:command){ "sudo sl -l ." } | |
it { should eq "sudo sl -l ." } | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment