cocoapods-keys 1.2.1 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +10 -0
- data/.rubocop_cocoapods.yml +116 -0
- data/.rubocop_todo.yml +39 -0
- data/CHANGELOG.md +5 -1
- data/Gemfile.lock +19 -1
- data/README.md +22 -19
- data/Rakefile +3 -2
- data/SWIFT_PROJECTS.md +31 -0
- data/cocoapods_keys.gemspec +1 -0
- data/lib/cocoapods_keys.rb +1 -1
- data/lib/cocoapods_plugin.rb +1 -1
- data/lib/key_master.rb +20 -14
- data/lib/keyring.rb +6 -7
- data/lib/keyring_liberator.rb +13 -15
- data/lib/name_whisperer.rb +28 -32
- data/lib/plugin.rb +44 -30
- data/lib/pod/command/keys.rb +1 -3
- data/lib/pod/command/keys/get.rb +9 -12
- data/lib/pod/command/keys/list.rb +21 -24
- data/lib/pod/command/keys/rm.rb +18 -19
- data/lib/pod/command/keys/set.rb +8 -10
- data/lib/preinstaller.rb +15 -13
- data/spec/functional_spec.rb +7 -16
- data/spec/key_master_spec.rb +4 -36
- data/spec/keyring_liberator_spec.rb +11 -12
- data/spec/plugin_spec.rb +193 -1
- data/spec/spec_helper.rb +5 -4
- metadata +20 -2
data/lib/keyring.rb
CHANGED
@@ -1,21 +1,21 @@
|
|
1
|
-
require
|
1
|
+
require 'osx_keychain'
|
2
2
|
|
3
3
|
module CocoaPodsKeys
|
4
4
|
class Keyring
|
5
5
|
attr_accessor :keys, :path, :name
|
6
6
|
|
7
|
-
def initialize(name, path, keys=[])
|
8
|
-
@name = name
|
7
|
+
def initialize(name, path, keys = [])
|
8
|
+
@name = name.to_s
|
9
9
|
@path = path
|
10
10
|
@keys = keys
|
11
11
|
end
|
12
12
|
|
13
13
|
def self.from_hash(hash)
|
14
|
-
new(hash[
|
14
|
+
new(hash['name'], hash['path'], hash['keys'])
|
15
15
|
end
|
16
16
|
|
17
17
|
def to_hash
|
18
|
-
{
|
18
|
+
{ 'keys' => @keys, 'path' => @path, 'name' => @name }
|
19
19
|
end
|
20
20
|
|
21
21
|
def code_name
|
@@ -23,7 +23,7 @@ module CocoaPodsKeys
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def self.keychain_prefix
|
26
|
-
|
26
|
+
'cocoapods-keys-'
|
27
27
|
end
|
28
28
|
|
29
29
|
def save(key, value)
|
@@ -37,6 +37,5 @@ module CocoaPodsKeys
|
|
37
37
|
@keys.map { |key| [key, keychain[self.class.keychain_prefix + name, key]] }
|
38
38
|
]
|
39
39
|
end
|
40
|
-
|
41
40
|
end
|
42
41
|
end
|
data/lib/keyring_liberator.rb
CHANGED
@@ -1,40 +1,39 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
1
|
+
require 'digest'
|
2
|
+
require 'yaml'
|
3
|
+
require 'pathname'
|
4
4
|
|
5
5
|
module CocoaPodsKeys
|
6
6
|
class KeyringLiberator
|
7
|
-
|
8
7
|
# Gets given a gives back a Keyring for the project
|
9
8
|
# by basically parsing it out of ~/.cocoapods/keys/"pathMD5".yml
|
10
9
|
|
11
10
|
def self.keys_dir
|
12
|
-
|
11
|
+
Pathname('~/.cocoapods/keys/').expand_path
|
13
12
|
end
|
14
13
|
|
15
14
|
def self.yaml_path_for_path(path)
|
16
|
-
sha = Digest::MD5.hexdigest(path)
|
17
|
-
|
15
|
+
sha = Digest::MD5.hexdigest(path.to_s)
|
16
|
+
keys_dir + (sha + '.yml')
|
18
17
|
end
|
19
18
|
|
20
19
|
def self.get_keyring(path)
|
21
20
|
get_keyring_at_path(yaml_path_for_path(path))
|
22
21
|
end
|
23
|
-
|
22
|
+
|
24
23
|
def self.get_keyring_named(name)
|
25
|
-
|
24
|
+
get_all_keyrings.find { |k| k.name == name }
|
26
25
|
end
|
27
26
|
|
28
27
|
def self.save_keyring(keyring)
|
29
|
-
|
28
|
+
keys_dir.mkpath
|
30
29
|
|
31
|
-
|
30
|
+
yaml_path_for_path(keyring.path).open('w') { |f| f.write(YAML.dump(keyring.to_hash)) }
|
32
31
|
end
|
33
32
|
|
34
33
|
def self.get_all_keyrings
|
35
|
-
return [] unless
|
34
|
+
return [] unless keys_dir.directory?
|
36
35
|
rings = []
|
37
|
-
|
36
|
+
Pathname.glob(keys_dir + '*.yml').each do |path|
|
38
37
|
rings << get_keyring_at_path(path)
|
39
38
|
end
|
40
39
|
rings
|
@@ -43,8 +42,7 @@ module CocoaPodsKeys
|
|
43
42
|
private
|
44
43
|
|
45
44
|
def self.get_keyring_at_path(path)
|
46
|
-
Keyring.from_hash(YAML.load(
|
45
|
+
Keyring.from_hash(YAML.load(path.read)) if path.file?
|
47
46
|
end
|
48
|
-
|
49
47
|
end
|
50
48
|
end
|
data/lib/name_whisperer.rb
CHANGED
@@ -1,44 +1,40 @@
|
|
1
1
|
require 'cocoapods'
|
2
2
|
|
3
3
|
module CocoaPodsKeys
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
user_xcodeproj = xcodeproj_from_podfile(podfile)
|
10
|
-
end
|
11
|
-
user_xcodeproj ||= self.search_folders_for_xcodeproj
|
12
|
-
user_xcodeproj.gsub(".xcodeproj", "")
|
4
|
+
class NameWhisperer
|
5
|
+
def self.get_project_name
|
6
|
+
podfile = Pod::Config.instance.podfile
|
7
|
+
if podfile
|
8
|
+
user_xcodeproj = xcodeproj_from_podfile(podfile)
|
13
9
|
end
|
10
|
+
user_xcodeproj ||= search_folders_for_xcodeproj
|
11
|
+
user_xcodeproj.basename('.xcodeproj')
|
12
|
+
end
|
14
13
|
|
15
|
-
|
14
|
+
private
|
16
15
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
end
|
21
|
-
nil
|
16
|
+
def self.xcodeproj_from_podfile(podfile)
|
17
|
+
unless podfile.target_definition_list.empty?
|
18
|
+
return podfile.target_definition_list.first.user_project_path
|
22
19
|
end
|
20
|
+
end
|
23
21
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
end
|
38
|
-
answer
|
39
|
-
|
22
|
+
def self.search_folders_for_xcodeproj
|
23
|
+
xcodeprojects = Pathname.glob('**/*.xcodeproj')
|
24
|
+
if xcodeprojects.length == 1
|
25
|
+
Pathname(xcodeprojects.first).basename
|
26
|
+
else
|
27
|
+
error_message = (xcodeprojects.length > 1) ? 'found too many' : "couldn't find any"
|
28
|
+
UI.puts 'CocoaPods-Keys ' + error_message + ' Xcode projects. Please give a name for this project.'
|
29
|
+
|
30
|
+
answer = ''
|
31
|
+
loop do
|
32
|
+
UI.print ' > '
|
33
|
+
answer = UI.gets.strip
|
34
|
+
break if answer.length > 0
|
40
35
|
end
|
36
|
+
answer
|
41
37
|
end
|
42
|
-
|
43
38
|
end
|
39
|
+
end
|
44
40
|
end
|
data/lib/plugin.rb
CHANGED
@@ -1,48 +1,65 @@
|
|
1
1
|
require 'cocoapods-core'
|
2
|
+
require 'fileutils'
|
3
|
+
require 'active_support/core_ext/hash/indifferent_access'
|
2
4
|
|
3
5
|
module CocoaPodsKeys
|
4
6
|
class << self
|
7
|
+
include FileUtils
|
5
8
|
|
6
9
|
def setup
|
7
10
|
require 'preinstaller'
|
8
11
|
|
9
12
|
PreInstaller.new(user_options).setup
|
10
|
-
|
13
|
+
|
14
|
+
keys_path = Pod::Config.instance.installation_root + 'Pods/CocoaPodsKeys/'
|
15
|
+
|
11
16
|
# move our podspec in to the Pods
|
12
|
-
|
13
|
-
podspec_path =
|
14
|
-
|
15
|
-
|
17
|
+
mkdir_p keys_path
|
18
|
+
podspec_path = Pathname(__dir__) + '../templates' + 'Keys.podspec.json'
|
19
|
+
cp podspec_path, keys_path
|
20
|
+
|
16
21
|
# Get all the keys
|
17
22
|
local_user_options = user_options || {}
|
18
|
-
project = local_user_options.fetch(
|
19
|
-
keyring = KeyringLiberator.get_keyring_named(project) || KeyringLiberator.get_keyring(
|
20
|
-
raise Pod::Informative,
|
21
|
-
|
23
|
+
project = local_user_options.fetch('project') { CocoaPodsKeys::NameWhisperer.get_project_name }
|
24
|
+
keyring = KeyringLiberator.get_keyring_named(project) || KeyringLiberator.get_keyring(Pathname.pwd)
|
25
|
+
raise Pod::Informative, 'Could not load keyring' unless keyring
|
26
|
+
|
22
27
|
# Create the h & m files in the same folder as the podspec
|
23
28
|
key_master = KeyMaster.new(keyring)
|
24
|
-
interface_file =
|
25
|
-
implementation_file =
|
26
|
-
|
29
|
+
interface_file = keys_path + (key_master.name + '.h')
|
30
|
+
implementation_file = keys_path + (key_master.name + '.m')
|
31
|
+
|
27
32
|
File.write(interface_file, key_master.interface)
|
28
33
|
File.write(implementation_file, key_master.implementation)
|
29
|
-
|
34
|
+
|
30
35
|
# Add our template podspec
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
36
|
+
add_keys_to_pods(keys_path, user_options)
|
37
|
+
end
|
38
|
+
|
39
|
+
def add_keys_to_pods(keys_path, options)
|
40
|
+
keys_targets = options['target'] || options['targets']
|
41
|
+
|
42
|
+
if keys_targets
|
43
|
+
# Get a list of targets, even if only one was specified
|
44
|
+
keys_target_list = ([] << keys_targets).flatten
|
45
|
+
|
46
|
+
# Iterate through each target specified in the Keys plugin
|
47
|
+
keys_target_list.each do |keys_target|
|
48
|
+
# Find a matching Pod target
|
49
|
+
pod_target = podfile.root_target_definitions.flat_map(&:children).find do |target|
|
50
|
+
target.label == "Pods-#{keys_target}"
|
51
|
+
end
|
52
|
+
|
53
|
+
if pod_target
|
54
|
+
pod_target.store_pod 'Keys', :path => keys_path.to_path
|
55
|
+
else
|
56
|
+
Pod::UI.puts "Could not find a target named '#{keys_target}' in your Podfile. Stopping keys".red
|
57
|
+
end
|
41
58
|
end
|
42
59
|
|
43
60
|
else
|
44
61
|
# otherwise let it go in global
|
45
|
-
podfile.pod 'Keys', :path =>
|
62
|
+
podfile.pod 'Keys', :path => keys_path.to_path
|
46
63
|
end
|
47
64
|
end
|
48
65
|
|
@@ -53,13 +70,10 @@ module CocoaPodsKeys
|
|
53
70
|
end
|
54
71
|
|
55
72
|
def user_options
|
56
|
-
options = podfile.plugins[
|
73
|
+
options = podfile.plugins['cocoapods-keys']
|
57
74
|
# Until CocoaPods provides a HashWithIndifferentAccess, normalize the hash keys here.
|
58
75
|
# See https://github.com/CocoaPods/CocoaPods/issues/3354
|
59
|
-
options.
|
60
|
-
normalized_hash[key.to_s] = value
|
61
|
-
normalized_hash
|
62
|
-
end
|
76
|
+
options.with_indifferent_access
|
63
77
|
end
|
64
78
|
end
|
65
79
|
end
|
@@ -74,7 +88,7 @@ module Pod
|
|
74
88
|
end
|
75
89
|
|
76
90
|
def validates_for_keys
|
77
|
-
|
91
|
+
podfile && podfile.plugins && !podfile.plugins['cocoapods-keys'].nil?
|
78
92
|
end
|
79
93
|
end
|
80
94
|
end
|
data/lib/pod/command/keys.rb
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
module Pod
|
2
2
|
class Command
|
3
|
-
|
4
3
|
class Keys < Command
|
5
4
|
require 'pod/command/keys/list'
|
6
5
|
require 'pod/command/keys/set'
|
7
6
|
require 'pod/command/keys/get'
|
8
7
|
require 'pod/command/keys/rm'
|
9
8
|
|
10
|
-
self.summary =
|
9
|
+
self.summary = 'A key value store for environment settings in Cocoa Apps.'
|
11
10
|
|
12
11
|
self.description = <<-DESC
|
13
12
|
CocoaPods Keys will store sensitive data in your Mac's keychain. Then on running pod install they will be installed into your app's source code via the Pods library.
|
@@ -15,7 +14,6 @@ module Pod
|
|
15
14
|
|
16
15
|
self.abstract_command = true
|
17
16
|
self.default_subcommand = 'list'
|
18
|
-
|
19
17
|
end
|
20
18
|
end
|
21
19
|
end
|
data/lib/pod/command/keys/get.rb
CHANGED
@@ -1,12 +1,11 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require 'keyring_liberator'
|
2
|
+
require 'name_whisperer'
|
3
3
|
|
4
4
|
module Pod
|
5
5
|
class Command
|
6
6
|
class Keys
|
7
|
-
|
8
7
|
class Get < Keys
|
9
|
-
self.summary =
|
8
|
+
self.summary = 'Print a values of a key.'
|
10
9
|
|
11
10
|
self.description = <<-DESC
|
12
11
|
Outputs the value of a key to SDTOUT
|
@@ -26,33 +25,31 @@ module Pod
|
|
26
25
|
def validate!
|
27
26
|
super
|
28
27
|
verify_podfile_exists!
|
29
|
-
help!
|
28
|
+
help! 'A key name is required for lookup.' unless @key_name
|
30
29
|
end
|
31
30
|
|
32
31
|
def run
|
33
32
|
keyring = get_current_keyring
|
34
|
-
|
35
|
-
|
36
|
-
return
|
33
|
+
unless keyring
|
34
|
+
raise Informative, 'Could not find a project for this folder'
|
37
35
|
end
|
38
36
|
|
39
37
|
if keyring.keys.include? @key_name
|
40
38
|
data = keyring.keychain_data
|
41
|
-
puts data[@key_name]
|
39
|
+
UI.puts data[@key_name]
|
42
40
|
else
|
43
|
-
|
41
|
+
raise Informative, 'Could not find value'
|
44
42
|
end
|
45
43
|
end
|
46
44
|
|
47
45
|
def get_current_keyring
|
48
|
-
current_dir =
|
46
|
+
current_dir = Pathname.pwd
|
49
47
|
keyring = CocoaPodsKeys::KeyringLiberator.get_keyring current_dir
|
50
48
|
if !keyring && @project_name
|
51
49
|
return CocoaPodsKeys::KeyringLiberator.get_keyring_named @project_name
|
52
50
|
end
|
53
51
|
keyring
|
54
52
|
end
|
55
|
-
|
56
53
|
end
|
57
54
|
end
|
58
55
|
end
|
@@ -3,9 +3,8 @@ require 'keyring_liberator'
|
|
3
3
|
module Pod
|
4
4
|
class Command
|
5
5
|
class Keys
|
6
|
-
|
7
6
|
class List < Keys
|
8
|
-
self.summary =
|
7
|
+
self.summary = 'Lists all known keys and values.'
|
9
8
|
|
10
9
|
self.description = <<-DESC
|
11
10
|
Shows all the current keys and values for your current working directory.
|
@@ -14,41 +13,39 @@ module Pod
|
|
14
13
|
DESC
|
15
14
|
|
16
15
|
def run
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
16
|
+
# List all settings for current app
|
17
|
+
this_keyring = CocoaPodsKeys::KeyringLiberator.get_keyring(Pathname.pwd)
|
18
|
+
if this_keyring
|
19
|
+
display_current_keyring this_keyring
|
20
|
+
end
|
21
|
+
|
22
|
+
# List all known bundle ids
|
23
|
+
|
24
|
+
all_keyrings = CocoaPodsKeys::KeyringLiberator.get_all_keyrings
|
25
|
+
all_keyrings.each do |keyring|
|
26
|
+
display_keyring(keyring) if !this_keyring || keyring.path != this_keyring.path
|
27
|
+
end
|
29
28
|
end
|
30
29
|
|
31
30
|
def display_current_keyring(keyring)
|
32
|
-
puts "Keys for #{keyring.name}"
|
31
|
+
UI.puts "Keys for #{keyring.name}"
|
33
32
|
data = keyring.keychain_data
|
34
33
|
data.each_with_index do |(key, value), index|
|
35
|
-
prefix = (index == data.length - 1) ?
|
36
|
-
puts prefix + " #{key} - #{ value}"
|
34
|
+
prefix = (index == data.length - 1) ? ' └ ' : ' ├ '
|
35
|
+
UI.puts prefix + " #{key} - #{ value}"
|
37
36
|
end
|
38
|
-
puts
|
37
|
+
UI.puts
|
39
38
|
end
|
40
39
|
|
41
40
|
def display_keyring(keyring)
|
42
|
-
puts "#{keyring.name} - #{keyring.path}"
|
41
|
+
UI.puts "#{keyring.name} - #{keyring.path}"
|
43
42
|
if keyring.keys.length == 1
|
44
|
-
puts
|
43
|
+
UI.puts ' └ ' + keyring.keys[0]
|
45
44
|
else
|
46
|
-
puts
|
45
|
+
UI.puts ' └ ' + keyring.keys[0...-1].join(' ') + ' & ' + keyring.keys[-1]
|
47
46
|
end
|
48
|
-
puts
|
47
|
+
UI.puts
|
49
48
|
end
|
50
|
-
|
51
|
-
|
52
49
|
end
|
53
50
|
end
|
54
51
|
end
|
data/lib/pod/command/keys/rm.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
1
|
+
require 'keyring_liberator'
|
2
|
+
require 'keyring'
|
3
|
+
require 'name_whisperer'
|
4
|
+
require 'shellwords'
|
4
5
|
|
5
6
|
module Pod
|
6
7
|
class Command
|
7
8
|
class Keys
|
8
|
-
|
9
9
|
class Rm < Keys
|
10
|
-
self.summary =
|
10
|
+
self.summary = 'Remove a key-value pair from a project.'
|
11
11
|
|
12
12
|
self.description = <<-DESC
|
13
13
|
Remove a key, and it's value from a project
|
@@ -26,45 +26,44 @@ module Pod
|
|
26
26
|
def validate!
|
27
27
|
super
|
28
28
|
verify_podfile_exists!
|
29
|
-
help!
|
29
|
+
help! 'A key name is required for lookup.' unless @key_name
|
30
30
|
end
|
31
31
|
|
32
32
|
def run
|
33
33
|
keyring = get_current_keyring
|
34
|
-
|
35
|
-
|
36
|
-
return
|
34
|
+
unless keyring
|
35
|
+
raise Informative, 'Could not find a project to remove the key from.'
|
37
36
|
end
|
38
37
|
|
39
38
|
if keyring.keys.include? @key_name
|
40
|
-
keyring.save(@key_name,
|
39
|
+
keyring.save(@key_name, '')
|
41
40
|
keyring.keys.delete @key_name
|
42
41
|
CocoaPodsKeys::KeyringLiberator.save_keyring(keyring)
|
43
42
|
|
44
43
|
prefix = CocoaPodsKeys::Keyring.keychain_prefix
|
45
|
-
|
44
|
+
login = prefix + keyring.name
|
45
|
+
delete_generic = `security delete-generic-password -a #{@key_name.shellescape} -l #{login.shellescape} 2>&1`
|
46
46
|
|
47
|
-
if delete_generic.include?
|
48
|
-
|
49
|
-
elsif delete_generic.include?
|
50
|
-
|
47
|
+
if delete_generic.include? 'security: SecKeychainSearchCopyNext: The specified item could not be found in the keychain.'
|
48
|
+
raise Informative, "Removed value for #{@key_name}, but could not delete from Keychain."
|
49
|
+
elsif delete_generic.include? 'password has been deleted.'
|
50
|
+
raise Informative, "Removed value for #{@key_name}, and deleted associated key in Keychain."
|
51
51
|
else
|
52
|
-
|
52
|
+
raise Informative, "Removed value for #{@key_name}."
|
53
53
|
end
|
54
54
|
else
|
55
|
-
|
55
|
+
raise Informative, "Could not find key named #{@key_name}."
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
59
59
|
def get_current_keyring
|
60
|
-
current_dir =
|
60
|
+
current_dir = Pathname.pwd
|
61
61
|
keyring = CocoaPodsKeys::KeyringLiberator.get_keyring current_dir
|
62
62
|
if !keyring && @project_name
|
63
63
|
return CocoaPodsKeys::KeyringLiberator.get_keyring_named @project_name
|
64
64
|
end
|
65
65
|
keyring
|
66
66
|
end
|
67
|
-
|
68
67
|
end
|
69
68
|
end
|
70
69
|
end
|