Skip to content

Commit

Permalink
Merge pull request #125 from chrisfsampaio/rm-batch
Browse files Browse the repository at this point in the history
Adding the option to remove multiple keys at once by using wildcard
  • Loading branch information
ashfurrow committed Jan 1, 2016
2 parents 55ab294 + 2b31fd0 commit ee6dd63
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 21 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,10 @@ CocoaPods-keys has 3 other commands:
Which will output the value of the key to STDOUT, useful for scripting.
* `pod keys rm [key] [optional project]`
Will remove a key from a project.
Will remove a key from a project.
If Wildcards are included, it will remove the keys matching the pattern. E.g.: `pod keys rm "G*og*"` will remove *all* the keys that begin with 'G', have 'og' in the middle and end with anything.
To nuke all the keys, run either `pod keys rm "*"` or `pod keys rm --all`
* `pod keys generate [optional project]`
Will generate the obfuscated Objective-C keys class (mainly used internally).
Expand Down
76 changes: 56 additions & 20 deletions lib/pod/command/keys/rm.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,39 @@ module Pod
class Command
class Keys
class Rm < Keys
self.summary = 'Remove a key-value pair from a project.'
self.summary = 'Removes key-value pairs from a project.'

self.description = <<-DESC
Remove a key, and it's value from a project
Removes a key, and it's value from a project.
If Wildcards are included, it will remove the keys matching the pattern.
E.g.: `pod keys rm \"G*og*\"` will remove *all* the keys that begin
with 'G', have 'og' in the middle and end with anything.
To nuke all the keys, run either `pod keys rm "*"` or `pod keys rm --all`
A second optional operator can be done to force a project name.
DESC

self.arguments = [CLAide::Argument.new('key', true), CLAide::Argument.new('project_name', false)]

def self.options
[[
'--all', 'Remove all the stored keys without asking'
]].concat(super)
end

def initialize(argv)
@key_name = argv.shift_argument
@project_name = argv.shift_argument
@wipe_all = argv.flag?('all')
super
end

def validate!
super
verify_podfile_exists!
help! 'A key name is required for lookup.' unless @key_name
help! 'A key name is required for lookup.' unless @key_name || @wipe_all
end

def run
Expand All @@ -35,26 +48,49 @@ def run
raise Informative, 'Could not find a project to remove the key from.'
end

if keyring.keys.include? @key_name
keyring.save(@key_name, '')
keyring.keys.delete @key_name
CocoaPodsKeys::KeyringLiberator.save_keyring(keyring)

prefix = CocoaPodsKeys::Keyring.keychain_prefix
login = prefix + keyring.name
delete_generic = `security delete-generic-password -a #{@key_name.shellescape} -l #{login.shellescape} 2>&1`

if delete_generic.include? 'security: SecKeychainSearchCopyNext: The specified item could not be found in the keychain.'
raise Informative, "Removed value for #{@key_name}, but could not delete from Keychain."
elsif delete_generic.include? 'password has been deleted.'
raise Informative, "Removed value for #{@key_name}, and deleted associated key in Keychain."
else
raise Informative, "Removed value for #{@key_name}."
end
if @wipe_all
@key_name = '*'
end

matching_keys = matches(keyring.keys)
if matching_keys.count > 0
messages = matching_keys.map { |e| delete_key(e, keyring) }
raise Informative, messages.join("\n")
else
raise Informative, "Could not find key that matched \"#{@key_name}\"."
end
end

def delete_key(key, keyring)
keyring.save(key, '')
keyring.keys.delete key
CocoaPodsKeys::KeyringLiberator.save_keyring(keyring)

prefix = CocoaPodsKeys::Keyring.keychain_prefix
login = prefix + keyring.name
delete_generic = `security delete-generic-password -a #{key.shellescape} -l #{login.shellescape} 2>&1`

if delete_generic.include? 'security: SecKeychainSearchCopyNext: The specified item could not be found in the keychain.'
return "Removed value for #{key}, but could not delete from Keychain."
elsif delete_generic.include? 'password has been deleted.'
return "Removed value for #{key}, and deleted associated key in Keychain."
else
raise Informative, "Could not find key named #{@key_name}."
return "Removed value for #{key}."
end
end

def matches(keys)
if @key_name.include? '*'
return keys.select { |e| e =~ create_regex(@key_name) }
else
return keys.select { |e| e == @key_name }
end
end

def create_regex(pattern)
regex_str = "^#{pattern.gsub('*', '.*')}$"
Regexp.new(regex_str)
end
end
end
end
Expand Down

0 comments on commit ee6dd63

Please sign in to comment.