diff --git a/.gitignore b/.gitignore index de301ca..b115128 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ spec/fixtures/dump-key vendor install .bundle +*.gem diff --git a/.rubocop.yml b/.rubocop.yml index 9220fbe..d3163ee 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -4,7 +4,7 @@ inherit_from: #- cocoapods-keys ------------------------------------------------------------- -Style/FileName: +Naming/FileName: Exclude: - bin/* - Rakefile diff --git a/.rubocop_cocoapods.yml b/.rubocop_cocoapods.yml index 3deb027..c5eb65f 100644 --- a/.rubocop_cocoapods.yml +++ b/.rubocop_cocoapods.yml @@ -1,4 +1,6 @@ AllCops: + NewCops: enable + SuggestExtensions: false Include: - ./Rakefile - ./Gemfile @@ -8,44 +10,47 @@ AllCops: # At the moment not ready to be used # https://github.com/bbatsov/rubocop/issues/947 -Documentation: +Style/Documentation: Enabled: false #- CocoaPods -----------------------------------------------------------------# # We adopted raise instead of fail. -SignalException: +Style/SignalException: EnforcedStyle: only_raise # They are idiomatic -AssignmentInCondition: +Lint/AssignmentInCondition: Enabled: false # Allow backticks -AsciiComments: +Style/AsciiComments: Enabled: false # Indentation clarifies logic branches in implementations -IfUnlessModifier: +Style/IfUnlessModifier: Enabled: false # No enforced convention here. -SingleLineBlockParams: +Style/SingleLineBlockParams: Enabled: false # We only add the comment when needed. -Encoding: +Style/Encoding: + Enabled: false + +Style/FrozenStringLiteralComment: Enabled: false Layout/MultilineOperationIndentation: EnforcedStyle: indented # Clashes with CLAide Command#validate! -GuardClause: +Style/GuardClause: Enabled: false # Not always desirable: lib/claide/command/plugins_helper.rb:12:15 -Next: +Style/Next: Enabled: false # Arbitrary max lengths for classes simply do not work and enabling this will @@ -74,16 +79,16 @@ Metrics/CyclomaticComplexity: #- CocoaPods support for Ruby 1.8.7 ------------------------------------------# -HashSyntax: +Style/HashSyntax: EnforcedStyle: hash_rockets -Lambda: +Style/Lambda: Enabled: false -DotPosition: +Layout/DotPosition: EnforcedStyle: trailing -EachWithObject: +Style/EachWithObject: Enabled: false Style/SpecialGlobalVars: @@ -92,20 +97,20 @@ Style/SpecialGlobalVars: #- CocoaPods specs -----------------------------------------------------------# # Allow for `should.match /regexp/`. -AmbiguousRegexpLiteral: +Lint/AmbiguousRegexpLiteral: Exclude: - spec/**/* # Allow `object.should == object` syntax. -Void: +Lint/Void: Exclude: - spec/**/* -ClassAndModuleChildren: +Style/ClassAndModuleChildren: Exclude: - spec/**/* -UselessComparison: +Lint/BinaryOperatorWithIdenticalOperands: Exclude: - spec/**/* diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 3e45176..8308a4b 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -23,7 +23,7 @@ Lint/Void: # Offense count: 38 # Configuration parameters: AllowURI, URISchemes. -Metrics/LineLength: +Layout/LineLength: Max: 173 # Offense count: 1 @@ -31,7 +31,7 @@ Metrics/PerceivedComplexity: Max: 9 # Offense count: 4 -Style/AccessorMethodName: +Naming/AccessorMethodName: Enabled: false # Offense count: 1 diff --git a/.travis.yml b/.travis.yml index 618eeb1..ee9a775 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,3 @@ language: objective-c -install: bundle install --deployment +install: bundle install script: bundle exec rake spec diff --git a/CHANGELOG.md b/CHANGELOG.md index e4df3cf..9aeb073 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,48 @@ ## Master +## 2.3.0 + +* Switched dependencies for the keychain, should fix m-class OS issues . [tritter] + +## 2.2.1 + +* Fixed Keys.m generation when there are empty-string keys. [rogerluan] + +## 2.2.0 + +* Revised template which doesn't allow for secrets to appear in the binaries in modern Xcode builds. [ashfurrow] + +## 2.1.0 + +* Add the ability to manually specify keys when running `pod keys generate`. [fwal] + +## 2.0.7 + +* Fix keys not recorded in YML on first run. [ileitch] + +## 2.0.6 + +* Makes list of keys unique on the yaml file [leoformaggio] + +## 2.0.4 - 2.0.5 + +* Handles more CIs [SlaunchaMan] + +## 2.0.3 + +?? + +## 2.0.2 + +* Sets a minimum iOS target of 8.0 [orta] + +## 2.0.1 + +* Handles more CI types [m-ruhl] + ## 2.0.0 -* Handles casing correctly in generated key names [breaking] [marcelofabri] +* Handles casing correctly in generated key names [breaking] [marcelofabri] * Adds Nullability notations to default erb template [Skogetroll] * Use properties for accessing key values instead of functions [breaking, for swift] [Skogetroll] * Don't ask for keys on the command line when running on CI. [dantoml] diff --git a/Gemfile b/Gemfile index 680e915..bc348ea 100644 --- a/Gemfile +++ b/Gemfile @@ -3,5 +3,6 @@ source 'https://rubygems.org' # Specify your gem's dependencies in cocoapods-keys.gemspec gemspec -gem 'cocoapods', '1.0.0.beta.6' -gem 'activesupport', '< 5' \ No newline at end of file +gem 'cocoapods', '>= 1.11' +gem 'activesupport', '>= 5' +gem 'ruby-keychain', :require => 'keychain' \ No newline at end of file diff --git a/Gemfile.lock b/Gemfile.lock index 66de00c..665e239 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,116 +1,157 @@ PATH remote: . specs: - cocoapods-keys (2.0.0) + cocoapods-keys (2.2.1) dotenv - osx_keychain + keychain GEM remote: https://rubygems.org/ specs: - CFPropertyList (2.3.5) - RubyInline (3.12.4) - ZenTest (~> 4.3) - ZenTest (4.11.1) - activesupport (4.2.9) - i18n (~> 0.7) - minitest (~> 5.1) - thread_safe (~> 0.3, >= 0.3.4) - tzinfo (~> 1.1) - ast (2.3.0) - claide (1.0.2) - cocoapods (1.0.0.beta.6) - activesupport (>= 4.0.2) - claide (>= 1.0.0.beta.3, < 2.0) - cocoapods-core (= 1.0.0.beta.6) - cocoapods-deintegrate (>= 1.0.0.beta.1, < 2.0) - cocoapods-downloader (>= 1.0.0.beta.2, < 2.0) - cocoapods-plugins (>= 1.0.0.beta.1, < 2.0) - cocoapods-search (>= 1.0.0.beta.1, < 2.0) - cocoapods-stats (>= 1.0.0.beta.3, < 2.0) - cocoapods-trunk (>= 1.0.0.beta.2, < 2.0) - cocoapods-try (>= 1.0.0.beta.3, < 2.0) - colored (~> 1.2) + CFPropertyList (3.0.5) + rexml + activesupport (6.1.7) + concurrent-ruby (~> 1.0, >= 1.0.2) + i18n (>= 1.6, < 2) + minitest (>= 5.1) + tzinfo (~> 2.0) + zeitwerk (~> 2.3) + addressable (2.8.1) + public_suffix (>= 2.0.2, < 6.0) + algoliasearch (1.27.5) + httpclient (~> 2.8, >= 2.8.3) + json (>= 1.5.1) + ast (2.4.2) + atomos (0.1.3) + claide (1.1.0) + cocoapods (1.11.3) + addressable (~> 2.8) + claide (>= 1.0.2, < 2.0) + cocoapods-core (= 1.11.3) + cocoapods-deintegrate (>= 1.0.3, < 2.0) + cocoapods-downloader (>= 1.4.0, < 2.0) + cocoapods-plugins (>= 1.0.0, < 2.0) + cocoapods-search (>= 1.0.0, < 2.0) + cocoapods-trunk (>= 1.4.0, < 2.0) + cocoapods-try (>= 1.1.0, < 2.0) + colored2 (~> 3.1) escape (~> 0.0.4) - fourflusher (~> 0.3.0) - molinillo (~> 0.4.4) + fourflusher (>= 2.3.0, < 3.0) + gh_inspector (~> 1.0) + molinillo (~> 0.8.0) nap (~> 1.0) - xcodeproj (>= 1.0.0.beta.3, < 2.0) - cocoapods-core (1.0.0.beta.6) - activesupport (>= 4.0.2) + ruby-macho (>= 1.0, < 3.0) + xcodeproj (>= 1.21.0, < 2.0) + cocoapods-core (1.11.3) + activesupport (>= 5.0, < 7) + addressable (~> 2.8) + algoliasearch (~> 1.0) + concurrent-ruby (~> 1.1) fuzzy_match (~> 2.0.4) nap (~> 1.0) - cocoapods-deintegrate (1.0.1) - cocoapods-downloader (1.1.3) + netrc (~> 0.11) + public_suffix (~> 4.0) + typhoeus (~> 1.0) + cocoapods-deintegrate (1.0.5) + cocoapods-downloader (1.6.3) cocoapods-plugins (1.0.0) nap - cocoapods-search (1.0.0) - cocoapods-stats (1.0.0) - cocoapods-trunk (1.2.0) + cocoapods-search (1.0.1) + cocoapods-trunk (1.6.0) nap (>= 0.8, < 2.0) - netrc (= 0.7.8) - cocoapods-try (1.1.0) - colored (1.2) + netrc (~> 0.11) + cocoapods-try (1.2.0) colored2 (3.1.2) - diff-lcs (1.3) - dotenv (2.2.1) + concurrent-ruby (1.1.10) + crypt (2.2.1) + diff-lcs (1.5.0) + dotenv (2.8.1) escape (0.0.4) - fourflusher (0.3.2) + ethon (0.16.0) + ffi (>= 1.15.0) + ffi (1.15.5) + fourflusher (2.3.1) fuzzy_match (2.0.4) - i18n (0.8.4) - minitest (5.10.2) - molinillo (0.4.5) - nanaimo (0.2.3) + gh_inspector (1.1.3) + highline (2.0.3) + httpclient (2.8.3) + i18n (1.12.0) + concurrent-ruby (~> 1.0) + json (2.6.2) + keychain (0.2.3) + crypt (>= 1.1.4) + highline (>= 1.4.0) + minitest (5.16.3) + molinillo (0.8.0) + nanaimo (0.3.0) nap (1.1.0) - netrc (0.7.8) - osx_keychain (1.0.1) - RubyInline (~> 3) - parallel (1.11.2) - parser (2.4.0.0) - ast (~> 2.2) - powerpack (0.1.1) - rainbow (2.2.2) - rake - rake (12.0.0) - rspec (3.6.0) - rspec-core (~> 3.6.0) - rspec-expectations (~> 3.6.0) - rspec-mocks (~> 3.6.0) - rspec-core (3.6.0) - rspec-support (~> 3.6.0) - rspec-expectations (3.6.0) + netrc (0.11.0) + og-corefoundation (0.2.3) + ffi + parallel (1.22.1) + parser (3.1.3.0) + ast (~> 2.4.1) + public_suffix (4.0.7) + rainbow (3.1.1) + rake (13.0.6) + regexp_parser (2.6.1) + rexml (3.2.5) + rspec (3.12.0) + rspec-core (~> 3.12.0) + rspec-expectations (~> 3.12.0) + rspec-mocks (~> 3.12.0) + rspec-core (3.12.0) + rspec-support (~> 3.12.0) + rspec-expectations (3.12.0) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.6.0) - rspec-mocks (3.6.0) + rspec-support (~> 3.12.0) + rspec-mocks (3.12.0) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.6.0) - rspec-support (3.6.0) - rubocop (0.49.1) + rspec-support (~> 3.12.0) + rspec-support (3.12.0) + rubocop (1.39.0) + json (~> 2.3) parallel (~> 1.10) - parser (>= 2.3.3.1, < 3.0) - powerpack (~> 0.1) - rainbow (>= 1.99.1, < 3.0) + parser (>= 3.1.2.1) + rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 1.8, < 3.0) + rexml (>= 3.2.5, < 4.0) + rubocop-ast (>= 1.23.0, < 2.0) ruby-progressbar (~> 1.7) - unicode-display_width (~> 1.0, >= 1.0.1) - ruby-progressbar (1.8.1) - thread_safe (0.3.6) - tzinfo (1.2.3) - thread_safe (~> 0.1) - unicode-display_width (1.3.0) - xcodeproj (1.5.0) - CFPropertyList (~> 2.3.3) + unicode-display_width (>= 1.4.0, < 3.0) + rubocop-ast (1.24.0) + parser (>= 3.1.1.0) + ruby-keychain (0.4.0) + ffi + og-corefoundation (~> 0.2.0) + ruby-macho (2.5.1) + ruby-progressbar (1.11.0) + typhoeus (1.4.0) + ethon (>= 0.9.0) + tzinfo (2.0.5) + concurrent-ruby (~> 1.0) + unicode-display_width (2.3.0) + xcodeproj (1.22.0) + CFPropertyList (>= 2.3.3, < 4.0) + atomos (~> 0.1.3) claide (>= 1.0.2, < 2.0) colored2 (~> 3.1) - nanaimo (~> 0.2.3) + nanaimo (~> 0.3.0) + rexml (~> 3.2.4) + zeitwerk (2.6.6) PLATFORMS - ruby + arm64-darwin-22 DEPENDENCIES - activesupport (< 5) - bundler (~> 1.3) - cocoapods (= 1.0.0.beta.6) + activesupport (>= 5) + bundler (~> 2.3) + cocoapods (>= 1.11) cocoapods-keys! rake rspec - rubocop + rubocop (> 1.38) + ruby-keychain + +BUNDLED WITH + 2.3.26 diff --git a/README.md b/README.md index dd732cf..f808d2a 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,12 @@ -![Build Status](https://travis-ci.org/orta/cocoapods-keys.svg) +[![Build Status](https://travis-ci.org/orta/cocoapods-keys.svg?branch=master)](https://travis-ci.org/orta/cocoapods-keys) -A key value store for enviroment and application keys. +A key value store for environment and application keys. -Its good security practice to keep production keys out of developer hands. CocoaPods-keys makes it easy to have per-user config settings stored securely in the developer's keychain, and not in the application source. It is a plugin that once installed will run on every `pod install` or `pod update`. +It's good security practice to keep production keys out of the developer's hands. CocoaPods-keys make it easy to have per-user config settings stored securely in the developer's keychain, and not in the application source. It is a plugin that once installed will run on every `pod install` or `pod update`. + +## Alternatives + +CocoaPods Keys has had a great run since its creation in 2014, and still works perfectly fine today. If you're interested in a fresh re-think of the concept, check out https://github.com/rogerluan/arkana ## Requirements @@ -34,6 +38,9 @@ plugin 'cocoapods-keys', { ... ]} ``` +> Please do not use dash in key names ([Reason why here in this issue #197](https://github.com/orta/cocoapods-keys/issues/197)). +> +> For example, convert any key like this `WRONGLY-DEFINED-KEY` to `CorrectlyDefinedKey`. Then running `pod install` will prompt for the keys not yet set and you can ensure everyone has the same setup. @@ -42,23 +49,23 @@ Then running `pod install` will prompt for the keys not yet set and you can ensu You can save keys on a per-project basis by running the command: - $ pod keys set KEY VALUE + $ bundle exec pod keys set KEY VALUE You can list all known keys by running: - $ pod keys + $ bundle exec pod keys For example: ``` sh $ cd MyApplication - $ pod keys set "NetworkAPIToken" "AH2ZMiraGQbyUd9GkNTNfWEdxlwXcmHciEOH" + $ bundle exec pod keys set "NetworkAPIToken" "AH2ZMiraGQbyUd9GkNTNfWEdxlwXcmHciEOH" Saved NetworkAPIToken to MyApplication. - $ pod keys set "AnalyticsToken" "6TYKGVCn7sBSBFpwfSUCclzDoSBtEXw7" + $ bundle exec pod keys set "AnalyticsToken" "6TYKGVCn7sBSBFpwfSUCclzDoSBtEXw7" Saved AnalyticsToken to MyApplication. - $ pod keys + $ bundle exec pod keys Keys for MyApplication ├ NetworkAPIToken - AH2ZMiraGQbyUd9GkNTNfWEdxlwXcmHciEOH └ AnalyticsToken - 6TYKGVCn7sBSBFpwfSUCclzDoSBtEXw7 @@ -67,7 +74,7 @@ For example: └ redditAPIToken & mixpanelAPIToken ``` -After the next `pod install` or `pod update` keys will add a new `Keys` pod to your Pods project, supporting both static libraries and frameworks. *Note* you have to include `plugin 'cocoapods-keys'` in the Podfile for Keys to register that it should work. This provides an API to your keys from Cocoa code. For example the application code above would look like: +After the next `pod install` or `pod update` keys will add a new `Keys` pod to your Pods project, supporting both static libraries and frameworks. *Note* You have to include `plugin 'cocoapods-keys'` in the Podfile for Keys to register that it should work. This provides an API to your keys from Cocoa code. For example, the application code above would look like: ``` objc @@ -95,25 +102,25 @@ Some documentation is also available to [use cocoapods-keys in Swift projects](S CocoaPods-keys has 3 other commands: - * `pod keys get [key] [optional project]` + * `bundle exec pod keys get [key] [optional project]` 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. + * `bundle exec pod keys rm [key] [optional 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` + If Wildcards are included, it will remove the keys matching the pattern. E.g.: `bundle exec 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 `bundle exec pod keys rm "*"` or `bundle exec pod keys rm --all` - * `pod keys generate [optional project]` + * `bundle exec pod keys generate [optional project]` Will generate the obfuscated Objective-C keys class (mainly used internally). #### Continuous Integration -It's rarely a good idea to mess around with the keychain in your CI, so keys will look for an environment var with the same string before looking in the keychain. Also you could create a `.env` file in your project folder. +It's rarely a good idea to mess around with the keychain in your CI, so keys will look for an environment var with the same string before looking in the keychain. Also, you could create a `.env` file in your project folder. #### Maintainance State -CocoaPods Keys is effectively "done" software from Artsy's perspective. It has done everything we've needed for years. So, I wouldn't recommend making issues requesting new features, simply because we won't be building them ourselves. We'll definitely continue making sure it works etc though, we use it in production. +CocoaPods Keys is effectively "done" software from Artsy's perspective. It has done everything we've needed for years. So, I wouldn't recommend making issues requesting new features, simply because we won't be building them ourselves. We'll definitely continue making sure it works etc. though, we use it in production. #### Security @@ -121,11 +128,11 @@ Key security is difficult. Right now even the biggest apps get their keys [leake > Putting this in the context of, "should you be storing keys in software", is more appropriate. Many companies do this. It's never a good idea. -> When developers do that, other developers can use debuggers and string searching commands to extract those keys from the running application. There are numerous talks on how to do that, but leave that as an exercise to the reader to find those talks. +> When developers do that, other developers can use debuggers and string searching commands to extract those keys from the running application. There are numerous talks on how to do that, but leave that as an exercise for the reader to find those talks. > Many people believe that obfuscating these keys in code will help. It usually won't because you can just run a debugger and find the fully functional keys. -So in summary, the ideal way to store keys is to not store keys. In reality though most Apps embed keys, and this does that and adds some rudimentary obfuscation to the keys. A well motivated app cracker could probably extract this within a few minutes however. +So in summary, the ideal way to store keys is to not store keys. In reality, though most Apps embed keys, and this does that and adds some rudimentary obfuscation to the keys. A well motivated app cracker could probably extract this within a few minutes however. #### Thanks diff --git a/SWIFT_PROJECTS.md b/SWIFT_PROJECTS.md index 63e32fb..d130f59 100644 --- a/SWIFT_PROJECTS.md +++ b/SWIFT_PROJECTS.md @@ -1,7 +1,7 @@ # Using CocoaPods-Keys in Swift projects Once you've followed the setup instructions described in the [Usage](README.md#usage) -section of the README, you have two choices. +section of the README, you are ready to use `Keys` from Swift. ## Importing the framework diff --git a/cocoapods_keys.gemspec b/cocoapods_keys.gemspec index f3bf6c0..5d47de8 100644 --- a/cocoapods_keys.gemspec +++ b/cocoapods_keys.gemspec @@ -18,12 +18,12 @@ Gem::Specification.new do |spec| spec.test_files = spec.files.grep(%r{^(test|spec|features)/}) spec.require_paths = ["lib"] - spec.add_runtime_dependency "osx_keychain" + spec.add_runtime_dependency "ruby-keychain" spec.add_runtime_dependency "dotenv" # spec.add_runtime_dependency "cocoapods", "> 1" - spec.add_development_dependency "bundler", "~> 1.3" + spec.add_development_dependency "bundler", "~> 2.3" spec.add_development_dependency "rake" spec.add_development_dependency "rspec" - spec.add_development_dependency "rubocop" + spec.add_development_dependency "rubocop", "> 1.38" end diff --git a/lib/cocoapods_keys.rb b/lib/cocoapods_keys.rb index 4b91c2a..b266d46 100644 --- a/lib/cocoapods_keys.rb +++ b/lib/cocoapods_keys.rb @@ -1,3 +1,3 @@ module CocoaPodsKeys - VERSION = '2.0.0'.freeze + VERSION = '2.3.0'.freeze end diff --git a/lib/key_master.rb b/lib/key_master.rb index a2a88a2..063f4f8 100644 --- a/lib/key_master.rb +++ b/lib/key_master.rb @@ -80,11 +80,11 @@ def verify_keychain_integrity def render_erb(erb_template) erb = (Pathname(__dir__).parent + 'templates' + erb_template).read - ERB.new(erb, nil, '-').result(binding) + ERB.new(erb, trim_mode: '-').result(binding) end def key_data_arrays - Hash[@indexed_keys.map { |key, value| [key, value.map { |i| name + "Data[#{i}]" }.join(', ')] }] + Hash[@indexed_keys.map { |key, value| [key, value.map { |i| '[' + name + "Data characterAtIndex:#{i}]" }.join(', ')] }] end end end diff --git a/lib/keyring.rb b/lib/keyring.rb index 24baea5..6015ddf 100644 --- a/lib/keyring.rb +++ b/lib/keyring.rb @@ -1,4 +1,6 @@ -require 'osx_keychain' +require 'keychain' +require 'base64' +require 'json' module CocoaPodsKeys class Keyring @@ -27,11 +29,17 @@ def self.keychain_prefix end def keychain - @keychain ||= OSXKeychain.new + @keychain ||= Keychain.generic_passwords end def save(key, value) - keychain[self.class.keychain_prefix + name, key] = value + item = keychain.where(service: self.class.keychain_prefix + name, account: key).first + if item + item.password = value + item.save! + else + keychain.create(service: self.class.keychain_prefix + name, password: value, account: key) + end end def keychain_data @@ -53,7 +61,7 @@ def keychain_has_key?(key) end def keychain_value(key) - ENV[key] || keychain[self.class.keychain_prefix + name, key] + ENV[key] || keychain.where(service: self.class.keychain_prefix + name, account: key).first&.password end def camel_cased_keys diff --git a/lib/keyring_liberator.rb b/lib/keyring_liberator.rb index 32e3935..93c2709 100644 --- a/lib/keyring_liberator.rb +++ b/lib/keyring_liberator.rb @@ -47,7 +47,7 @@ def self.prompt_if_already_existing(keyring) def self.save_keyring(keyring) keys_dir.mkpath - if !ENV['TRAVIS'] && !ENV['TEAMCITY_VERSION'] && !ENV['CIRCLECI'] + unless ci? prompt_if_already_existing(keyring) end yaml_path_for_path(keyring.path).open('w') { |f| f.write(YAML.dump(keyring.to_hash)) } @@ -67,5 +67,12 @@ def self.get_keyring_at_path(path) end private_class_method :get_keyring_at_path + + def self.ci? + %w([JENKINS_HOME TRAVIS CIRCLECI CI TEAMCITY_VERSION GO_PIPELINE_NAME bamboo_buildKey GITLAB_CI XCS]).each do |current| + return true if ENV.key?(current) + end + false + end end end diff --git a/lib/pod/command/keys/generate.rb b/lib/pod/command/keys/generate.rb index ed4cb73..a6d6141 100644 --- a/lib/pod/command/keys/generate.rb +++ b/lib/pod/command/keys/generate.rb @@ -16,14 +16,19 @@ class Generate < Keys self.arguments = [CLAide::Argument.new('project_name', false)] + def self.options + [['--keys=key1,key2...', 'An array of keys to add if no keyring is found']].concat(super) + end + def initialize(argv) @project_name = argv.shift_argument + @keys = argv.option('keys', '').split(',') super end def run Dotenv.load - keyring = get_current_keyring + keyring = get_current_keyring || CocoaPodsKeys::Keyring.new(@project_name, '/', @keys) if keyring diff --git a/lib/pod/command/keys/set.rb b/lib/pod/command/keys/set.rb index 9ed2b94..6023f87 100644 --- a/lib/pod/command/keys/set.rb +++ b/lib/pod/command/keys/set.rb @@ -40,6 +40,7 @@ def run keyring = get_current_keyring || create_keyring keyring.keys << @key_name.tr('-', '_') + keyring.keys.uniq! CocoaPodsKeys::KeyringLiberator.save_keyring keyring keyring.save @key_name, @key_value diff --git a/lib/preinstaller.rb b/lib/preinstaller.rb index 1b96be2..eede7d6 100644 --- a/lib/preinstaller.rb +++ b/lib/preinstaller.rb @@ -42,7 +42,7 @@ def setup # and prompt for their value if needed. keys.each do |key| unless keyring.keychain_has_key?(key) - if ENV['CI'] + if ci? raise Pod::Informative, "CocoaPods-Keys could not find a key named: #{key}" end @@ -65,13 +65,12 @@ def setup setter.run end end - CocoaPodsKeys::KeyringLiberator.save_keyring(keyring) existing_keyring || !keys.empty? end def check_for_multiple_keyrings(project, current_dir) - if !ENV['TRAVIS'] && !ENV['TEAMCITY_VERSION'] && !ENV['CIRCLECI'] + unless ci? ui = Pod::UserInterface keyrings = KeyringLiberator.get_all_keyrings_named(project) if keyrings.count > 1 @@ -85,5 +84,12 @@ def check_for_multiple_keyrings(project, current_dir) end end end + + def ci? + %w([JENKINS_HOME TRAVIS CIRCLECI CI TEAMCITY_VERSION GO_PIPELINE_NAME bamboo_buildKey GITLAB_CI XCS]).each do |current| + return true if ENV.key?(current) + end + false + end end end diff --git a/spec/fixtures/Podfile b/spec/fixtures/Podfile index d969a3c..2e81977 100644 --- a/spec/fixtures/Podfile +++ b/spec/fixtures/Podfile @@ -4,5 +4,5 @@ plugin 'cocoapods-keys', { :keys => [ 'KeyWithData', 'KeyWithoutData', - ] + ], } diff --git a/spec/keyring_spec.rb b/spec/keyring_spec.rb index dfc067e..57ebc0e 100644 --- a/spec/keyring_spec.rb +++ b/spec/keyring_spec.rb @@ -17,7 +17,7 @@ expect(keyring.keychain_data).to eq('ARMyKey' => 'Hello') end - it 'looks up keys from the OSXKeychain' do + it 'looks up keys from Keychain Access' do keyring = Keyring.new('test', '/', ['ARMyKey']) keyring.instance_variable_set(:@keychain, FakeKeychain.new('KeychainKey' => 'abcde')) expect(keyring.keychain_has_key?('KeychainKey')).to be_truthy diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 108ee3d..c6d1152 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -16,12 +16,22 @@ def fixture(name) c.color = true end +class FakeKeychainItem + attr_accessor :password + + def initialize(password) + @password = password + end +end + class FakeKeychain def initialize(data) @data = data end - def [](_, key) - @data[key] + def where(conditions) + password = @data[conditions[:account]] + item = FakeKeychainItem.new(password) + [item] end end diff --git a/templates/Keys.m.erb b/templates/Keys.m.erb index 763ae43..f5ade22 100644 --- a/templates/Keys.m.erb +++ b/templates/Keys.m.erb @@ -4,51 +4,43 @@ // For more information see https://github.com/orta/cocoapods-keys // -#import #import #import "<%= @name %>.h" -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wincomplete-implementation" +@interface <%= @name %> () -@implementation <%= @name %> -<% @keys.each do |key, value| %> - @dynamic <%= key %>;<% end %> +<% @keys.each do |key, value| %>@property (nonatomic, copy) NSString *<%= key %>; +<% end %> -#pragma clang diagnostic pop +@end -+ (BOOL)resolveInstanceMethod:(SEL)name -{ - NSString *key = NSStringFromSelector(name); - NSString * (*implementation)(<%= name %> *, SEL) = NULL; -<% @keys.each do |key, value| %> - if ([key isEqualToString:@"<%= key %>"]) { - implementation = _podKeys<%= Digest::MD5.hexdigest(key) %>; - } -<% end %> - if (!implementation) { - return [super resolveInstanceMethod:name]; - } +@implementation <%= @name %> - return class_addMethod([self class], name, (IMP)implementation, "@@:"); -} -<% @keys.each do |key, value| %> -static NSString *_podKeys<%= Digest::MD5.hexdigest(key) %>(<%= name %> *self, SEL _cmd) +- (instancetype)init { - <% if @indexed_keys.length > 0 %> + if (!(self = [super init])) { return nil; } + + <% @keys.each do |key, value| %> <% if @indexed_keys[key].length > 0 %> - char cString[<%= @indexed_keys[key].length + 1 %>] = { <%= key_data_arrays[key] %>, '\0' }; + char <%= key %>CString[<%= @indexed_keys[key].length + 1 %>] = { <%= key_data_arrays[key] %>, '\0' }; <% else %> - char cString[1] = { '\0' }; + char <%= key %>CString[<%= @indexed_keys[key].length + 1 %>] = { '\0' }; + <% end %> + _<%= key %> = <% if @indexed_keys.length > 0 %> + <% if @indexed_keys[key].length > 0 %> + [NSString stringWithCString:<%= key %>CString encoding:NSUTF8StringEncoding]; + <% else %> + @""; + <% end %> + <% else %> + @""; + <% end %> <% end %> - return [NSString stringWithCString:cString encoding:NSUTF8StringEncoding]; - <% else %> - return @""; - <% end %> + + return self; } -<% end %> -static char <%= name %>Data[<%= @data_length %>] = "<%= @data.gsub('\\', '\\\\\\').gsub('"', '\\"') if @data %>"; +static NSString *<%= name %>Data = @"<%= @data.gsub('\\', '\\\\\\').gsub('"', '\\"') if @data %>"; - (NSString *)description { diff --git a/templates/Keys.podspec.json b/templates/Keys.podspec.json index 1b1671e..5d33eae 100644 --- a/templates/Keys.podspec.json +++ b/templates/Keys.podspec.json @@ -1,6 +1,6 @@ { "name": "Keys", - "version": "1.0.0", + "version": "1.0.1", "summary": "Injected podspec used by CocoaPods-Keys plugin.", "description": "This is intended to be used as an injected podspec template \n used by the [CocoaPods-Keys plugin](https://github.com/orta/cocoapods-keys).\n\n It should *not* be referenced outside of that context. \n", "homepage": "https://github.com/orta/cocoapods-keys", @@ -17,7 +17,13 @@ "git": "https://github.com/orta/cocoapods-keys.git", "tag": "23" }, + "platforms": { + "ios": "5.0", + "osx": "10.7", + "watchos": "2.0", + "tvos": "9.0" + }, "source_files": "*.{h,m,swift}", "frameworks": "Foundation", "requires_arc": true -} \ No newline at end of file +}