fastlane-plugin-xcconfig_actions 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 4ca1c026cc23d89211ae095590c38efdaf2f7a20
4
+ data.tar.gz: 65412a70fe01ce3a8e38874f422f918258688996
5
+ SHA512:
6
+ metadata.gz: 66d4512ca2e311265a018bbddc8fffd029d03e5d3bbcbf0871fce8432ea0adc927cd88c9611830554dcc5052472ff61a892f43f141f50adf67e59dc8eeff23b1
7
+ data.tar.gz: 1d7be32a98c6782cc670b3a5417494d7bb9f44d77f8da868d1baa531f4660286acc4fedac21388fb0e73458eb58dc4e7b8529a6f0563d896442fb909a9782d20
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2019 Maksym Grebenets <maksym.grebenets@cba.com.au>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,130 @@
1
+ # xcconfig_actions plugin
2
+
3
+ [![fastlane Plugin Badge](https://rawcdn.githack.com/fastlane/fastlane/master/fastlane/assets/plugin-badge.svg)](https://rubygems.org/gems/fastlane-plugin-xcconfig_actions)
4
+ [![version](https://badge.fury.io/gh/mgrebenets%2Ffastlane-plugin-xcconfig_actions.svg)](https://badge.fury.io/gh/mgrebenets%2Ffastlane-plugin-xcconfig_actions)
5
+ [![CircleCI](https://circleci.com/gh/mgrebenets/fastlane-plugin-xcconfig_actions.svg?style=svg)](https://circleci.com/gh/mgrebenets/fastlane-plugin-xcconfig_actions)
6
+
7
+ ## Getting Started
8
+
9
+ This project is a [_fastlane_](https://github.com/fastlane/fastlane) plugin. To get started with `fastlane-plugin-xcconfig_actions`, add it to your project by running:
10
+
11
+ ```bash
12
+ fastlane add_plugin xcconfig_actions
13
+ ```
14
+
15
+ ## About xcconfig_actions
16
+
17
+ Adds actions to fastlane to work with xcconfig files.
18
+
19
+ ### read_xcconfig
20
+
21
+ The `read_xcconfig` action reads contents of xcconfig file the same way Xcode would do, meaning
22
+
23
+ - Support for resolving variable references like `$(VAR)`
24
+ - Support for nested variable references like `$(VAR1_$(VAR2))`
25
+ - Support for `#include "other.xcconfig"` statements
26
+ - Support for project/target level inheritance mechanism
27
+
28
+ See [this xcconfig guide](https://pewpewthespells.com/blog/xcconfig_guide.html) for detailed explanation.
29
+
30
+ Things **not supported** at the moment:
31
+
32
+ - Conditional variable assignment, such as `FOO[sdk=macosx*] = 1`
33
+ - Use of `<DEVELOPER_DIR>` in include paths
34
+ - Use of curly braces in variable references, e.g. `${VAR}`
35
+
36
+ ### validate_xcconfig
37
+
38
+ Validate xcconfig using set of very opinionated rules:
39
+
40
+ - All included files must exist
41
+ - Include flow is unidirectional, i.e. top-down only:
42
+
43
+ ```c
44
+ #include "../level_up.xcconfig" // File is in parent directory.
45
+ ```
46
+
47
+ - Files do not include other files on the same level:
48
+
49
+ ```c
50
+ #include "same_level.xcconfig" // Included file is on the same level.
51
+ ```
52
+
53
+ - Files do not include other files more than 1 level down
54
+
55
+ ```c
56
+ #include "level1/level2/level2.xcconfig" // 2 levels down: level1/level2.
57
+ ```
58
+
59
+ - Duplicated includes are not allowed
60
+
61
+ ```c
62
+ #include "other.xcconfig"
63
+ #include "other.xcconfig" // Duplicated include.
64
+ ```
65
+
66
+ - Circular includes are not allowed
67
+
68
+ ```c
69
+ // example.xcconfig file
70
+ #include "example.xcconfig" // Include self creates circular include.
71
+ ```
72
+
73
+ Things **not supported** at the moment:
74
+
75
+ - Use of `<DEVELOPER_DIR>` in include paths
76
+
77
+ #### Rules Explanation
78
+
79
+ Xcconfigs are too easy to get out of hand.
80
+ Ability to use arbitrary include paths complicates usage of xcconfigs in quite a few ways:
81
+
82
+ - Hard to track where the variables are declared and the overwritten
83
+ - Xcode does not always report an error when a file is missing
84
+
85
+ These rules introduce convention to organizing xcconfigs.
86
+ The end goal is to make config files more manageable.
87
+
88
+ This helps greatly when configs are used in Xcode combined with project-level and target-level inheritance.
89
+
90
+ ## Example
91
+
92
+ Check out the [example `Fastfile`](fastlane/Fastfile) to see how to use this plugin. Try it by cloning the repo, running `fastlane install_plugins` and
93
+
94
+ ```shell
95
+ # Read xcconfig example.
96
+ bundle exec fastlane read
97
+
98
+ # Validate xcconfig example.
99
+ bundle exec fastlane validate
100
+ ```
101
+
102
+ ## Run tests for this plugin
103
+
104
+ To run both the tests, and code style validation, run
105
+
106
+ ```shell
107
+ rake
108
+ ```
109
+
110
+ To automatically fix many of the styling issues, use
111
+
112
+ ```shell
113
+ rubocop -a
114
+ ```
115
+
116
+ ## Issues and Feedback
117
+
118
+ For any other issues and feedback about this plugin, please submit it to this repository.
119
+
120
+ ## Troubleshooting
121
+
122
+ If you have trouble using plugins, check out the [Plugins Troubleshooting](https://docs.fastlane.tools/plugins/plugins-troubleshooting/) guide.
123
+
124
+ ## Using _fastlane_ Plugins
125
+
126
+ For more information about how the `fastlane` plugin system works, check out the [Plugins documentation](https://docs.fastlane.tools/plugins/create-plugin/).
127
+
128
+ ## About _fastlane_
129
+
130
+ _fastlane_ is the easiest way to automate beta deployments and releases for your iOS and Android apps. To learn more, check out [fastlane.tools](https://fastlane.tools).
@@ -0,0 +1,190 @@
1
+ require 'fastlane/action'
2
+ require 'json'
3
+ require_relative '../helper/xcconfig_actions_helper'
4
+
5
+ module Fastlane
6
+ module Actions
7
+ class ReadXcconfigAction < Action
8
+ def self.run(params)
9
+ path = params[:path]
10
+ parent = params[:parent]
11
+ srcroot = params[:srcroot] || Dir.pwd
12
+ target_name = params[:target_name]
13
+
14
+ config = read_config(path)
15
+
16
+ if params[:no_resolve]
17
+ json = config.to_json
18
+ else
19
+ parent_config = read_config(parent)
20
+
21
+ parent_config["SRCROOT"] = srcroot
22
+ parent_config["TARGET_NAME"] = target_name if target_name
23
+
24
+ resolved_parent_config = resolve_config(parent_config)
25
+ resolved_config = resolve_config(config, parent: resolved_parent_config)
26
+
27
+ json = resolved_parent_config.merge(resolved_config).to_json
28
+ end
29
+
30
+ if params[:output_path]
31
+ File.open(params[:output_path], "w") { |f| f.puts(json) }
32
+ else
33
+ return json
34
+ end
35
+ end
36
+
37
+ ###
38
+ # @!group Implementation
39
+ ###
40
+
41
+ # Read xcconfig value as a hash.
42
+ #
43
+ # @param [String] filename Xcconfig path.
44
+ # @return [Hash<String,String>] Dictionary of xcconfig values.
45
+ def self.read_config(filename)
46
+ # TODO: If filename starts with <DEVELOPER_DIR>, then need to resolve it first.
47
+ return {} if filename.nil? || !File.exist?(filename)
48
+
49
+ # Used to use Xcodeproj::Config.new(filename) here, but it just doesn't do the job,
50
+ # e.g. it resolves $(inherited) incorrectly, allowing it to work within the scope of one file
51
+ # without any parent config.
52
+
53
+ xcconfig = Helper::XcconfigActionsHelper.read_xcconfig(filename)
54
+ config = xcconfig[:config]
55
+ includes = xcconfig[:includes]
56
+
57
+ # Xcodeproj does not resolve overrides from included files, so do it manually.
58
+ resolved_includes_config = includes.reduce({}) do |resolved_config, include_path|
59
+ resolved_path = resolve_path(include_path, relative_to: filename)
60
+ resolved_config.merge(read_config(resolved_path))
61
+ end
62
+
63
+ config.merge(resolved_includes_config)
64
+ end
65
+
66
+ # Expand given path in relation to another path.
67
+ #
68
+ # Used to resolved '#include "relative/path.xcconfig"' includes.
69
+ #
70
+ # @param [String] path Path to expand.
71
+ # @param [String] relative_to Parent path to expand in relation to.
72
+ #
73
+ # @return [String] Expanded path.
74
+ def self.resolve_path(path, relative_to:)
75
+ # Absolute or special SDK paths need no resolving.
76
+ return path if path.start_with?("/", "<")
77
+
78
+ File.expand_path(File.join(File.dirname(relative_to), path))
79
+ end
80
+
81
+ # Resolve xcconfig value, i.e. expand any of the $() variable references.
82
+ #
83
+ # @param [String] value String value to resolve.
84
+ # @param [String] key Key under which this value is defined in xcconfig. This key will be used to pick up values from parent xcconfig.
85
+ # @param [Hash<String,String>] resolved Dictionary of already resolved values.
86
+ # @param [Hash<String,String>] parent Dictionary of parent xcconfig values.
87
+ #
88
+ # @return [String] Resolved value.
89
+ def self.resolve_value(value, key:, resolved: {}, parent: {})
90
+ matches = value.scan(/(\$\([^$\)]*\))/)
91
+
92
+ matches.each do |group|
93
+ group.each do |match|
94
+ var_name = match.delete("$()")
95
+ # If inherited, use value from parent config.
96
+ var_value = if var_name == "inherited"
97
+ parent[key]
98
+ else
99
+ resolved[var_name] || parent[var_name]
100
+ end
101
+ value.gsub!(match, var_value || "")
102
+ resolved[key] = value
103
+ end
104
+ end
105
+
106
+ # If there are still variables, keep resolving then.
107
+ value.include?("$(") ? resolve_value(value, key: key, resolved: resolved, parent: parent) : value
108
+ end
109
+
110
+ # Resolve xcconfig values using parent config.
111
+ #
112
+ # @param [Hash<String,String>] config Current dictionary of values.
113
+ # @param [Hash<String,String>] parent Resolved parent xcconfig values.
114
+ #
115
+ # @return [Hash<String,String>] Resolved xcconfig values.
116
+ def self.resolve_config(config, parent: {})
117
+ config.each do |k, v|
118
+ resolve_value(v, key: k, resolved: config, parent: parent)
119
+ end
120
+ config
121
+ end
122
+
123
+ ###
124
+ # @!group Info and Options
125
+ ###
126
+
127
+ def self.description
128
+ "Read and resolve contents of xcconfig file and return as JSON"
129
+ end
130
+
131
+ def self.authors
132
+ ["Maksym Grebenets"]
133
+ end
134
+
135
+ def self.return_value
136
+ "Parse and resolved build settings from xcconfig represented as JSON"
137
+ end
138
+
139
+ def self.details
140
+ ""
141
+ end
142
+
143
+ def self.available_options
144
+ [
145
+ FastlaneCore::ConfigItem.new(key: :path,
146
+ env_name: "XCCONFIG_ACTIONS_READ_PATH",
147
+ description: "Path to xcconfig to read",
148
+ optional: false,
149
+ type: String,
150
+ verify_block: proc do |value|
151
+ UI.user_error!("Couldn't find xcconfig at path: '#{value}'") unless File.exist?(value)
152
+ end),
153
+ FastlaneCore::ConfigItem.new(key: :parent,
154
+ env_name: "XCCONFIG_ACTIONS_READ_PARENT",
155
+ description: "Parent xcconfig file to inherit build settings from.\nThis is the xcconfig you'd set on the project level in Xcode",
156
+ optional: true,
157
+ type: String,
158
+ verify_block: proc do |value|
159
+ UI.user_error!("Couldn't find parent xcconfig at path: '#{value}'") if value && !File.exist?(value)
160
+ end),
161
+ FastlaneCore::ConfigItem.new(key: :no_resolve,
162
+ env_name: "XCCONFIG_ACTIONS_READ_NO_RESOLVE",
163
+ description: "Do not resolve variables in xcconfigs and read 'as is'",
164
+ default_value: false,
165
+ optional: true,
166
+ type: Boolean),
167
+ FastlaneCore::ConfigItem.new(key: :srcroot,
168
+ env_name: "XCCONFIG_ACTIONS_READ_SRCROOT",
169
+ description: "Value for SRCROOT build setting, default is current working directory",
170
+ optional: true,
171
+ type: String),
172
+ FastlaneCore::ConfigItem.new(key: :target_name,
173
+ env_name: "XCCONFIG_ACTIONS_READ_TARGET_NAME",
174
+ description: "Value for TARGET_NAME build setting",
175
+ optional: true,
176
+ type: String),
177
+ FastlaneCore::ConfigItem.new(key: :output_path,
178
+ env_name: "XCCONFIG_ACTIONS_READ_OUTPUT_PATH",
179
+ description: "Output path",
180
+ optional: true,
181
+ type: String)
182
+ ]
183
+ end
184
+
185
+ def self.is_supported?(platform)
186
+ true
187
+ end
188
+ end
189
+ end
190
+ end
@@ -0,0 +1,120 @@
1
+ require 'fastlane/action'
2
+ require_relative '../helper/xcconfig_actions_helper'
3
+
4
+ module Fastlane
5
+ module Actions
6
+ class ValidateXcconfigAction < Action
7
+ def self.run(params)
8
+ path = params[:path]
9
+ root_path = params[:root_path]
10
+
11
+ # Validate configs recursively.
12
+ validate_xcconfig(path, root_path: root_path, included_paths: [path], level: 0)
13
+ end
14
+
15
+ ###
16
+ # @!group Implementation
17
+ ###
18
+
19
+ # Validate xcconfig file.
20
+ # @param [String] xcconfig path to xcconfig.
21
+ # @param [String] root_path root path for all xcconfigs validated in this method.
22
+ # @param [Array<String>] list of files included so far, used to detect circular includes.
23
+ # @return [Array<String>] list of issues.
24
+ def self.validate_xcconfig(xcconfig, root_path:, included_paths: [], level: 0)
25
+ require "pathname"
26
+
27
+ relative_path = Pathname.new(xcconfig).relative_path_from(Pathname.new(root_path))
28
+ return ["File does not exist or is a directory: #{xcconfig}"] unless File.exist?(xcconfig) && File.file?(xcconfig)
29
+
30
+ config = Helper::XcconfigActionsHelper.read_xcconfig(xcconfig)
31
+ includes = config[:includes]
32
+
33
+ issues = includes.flat_map { |include_path| validate_include_path(include_path, xcconfig: relative_path) }
34
+ dupes = includes.select { |e| includes.count(e) > 1 }.uniq
35
+ issues << " #{relative_path}: Duplicate includes detected: #{dupes.join('\n')}" unless dupes.nil? || dupes.empty?
36
+ full_paths = includes.map { |path| Pathname.new(File.join(File.dirname(xcconfig), path)).cleanpath }
37
+ common_paths = included_paths & full_paths
38
+ unless common_paths.empty?
39
+ common_paths_string = common_paths.map { |p| " - #{p}" }.join("\n")
40
+ issues << "#{relative_path}: Circular includes detected, check the following files:\n#{common_paths_string}"
41
+ end
42
+
43
+ result = issues.empty? ? "✅" : "❌"
44
+ offset = " " * 4 * level + " └──"
45
+ UI.message("#{offset} #{result} #{relative_path}")
46
+
47
+ # If circular includes detected stop the recursion.
48
+ return issues unless common_paths.empty?
49
+
50
+ # Recursively validate the rest.
51
+ issues + full_paths.flat_map { |path| validate_xcconfig(path, root_path: root_path, included_paths: included_paths + full_paths, level: level + 1) }
52
+ end
53
+
54
+ # Validate xcconfig include path.
55
+ #
56
+ # @param [String] path include path to validate.
57
+ # @param [String] xcconfig path to xcconfig being validated.
58
+ # @return [Array<String>] list of issues.
59
+ def self.validate_include_path(path, xcconfig:)
60
+ issues = []
61
+ issues << "#{xcconfig}: Invalid bottom-up include flow, i.e. use of '..' in include path: #{path}" if path.include?("..")
62
+ issues << "#{xcconfig}: Including another xcconfig 2 or more levels down: #{path}" if path.count("/") > 1
63
+ issues << "#{xcconfig}: Including another xcconfig on the same level: #{path}" if path.count("/") < 1
64
+ issues
65
+ end
66
+
67
+ ###
68
+ # @!group Info and Options
69
+ ###
70
+
71
+ def self.description
72
+ "Validate xcconfig file"
73
+ end
74
+
75
+ def self.authors
76
+ ["Maksym Grebenets"]
77
+ end
78
+
79
+ def self.return_value
80
+ "List of validation issues"
81
+ end
82
+
83
+ def self.details
84
+ [
85
+ "Validation rules:",
86
+ "- All included files exist",
87
+ "- Include flow is unidirectional, i.e. top-down only",
88
+ "- Files do not include other files on the same level",
89
+ "- Files do not include other files more than 1 level down",
90
+ "- Files do not contain duplicate includes"
91
+ ].join("\n")
92
+ end
93
+
94
+ def self.available_options
95
+ [
96
+ FastlaneCore::ConfigItem.new(key: :path,
97
+ env_name: "XCCONFIG_ACTIONS_VALIDATE_PATH",
98
+ description: "Path to xcconfig to validate",
99
+ optional: false,
100
+ type: String,
101
+ verify_block: proc do |value|
102
+ UI.user_error!("Couldn't find xcconfig at path: '#{value}'") unless File.exist?(value)
103
+ end),
104
+ FastlaneCore::ConfigItem.new(key: :root_path,
105
+ env_name: "XCCONFIG_ACTIONS_VALIDATE_ROOT_PATH",
106
+ description: "Root path for all xcconfigs validated with this action",
107
+ optional: false,
108
+ type: String,
109
+ verify_block: proc do |value|
110
+ UI.user_error!("Couldn't find root xcconfig directory: '#{value}'") unless File.exist?(value)
111
+ end)
112
+ ]
113
+ end
114
+
115
+ def self.is_supported?(platform)
116
+ true
117
+ end
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,42 @@
1
+ require 'fastlane_core/ui/ui'
2
+
3
+ module Fastlane
4
+ UI = FastlaneCore::UI unless Fastlane.const_defined?("UI")
5
+
6
+ module Helper
7
+ class XcconfigActionsHelper
8
+ # class methods that you define here become available in your action
9
+ # as `Helper::XcconfigActionsHelper.your_method`
10
+ #
11
+ def self.show_message
12
+ UI.message("Hello from the xcconfig_actions plugin helper!")
13
+ end
14
+
15
+ # Read xcconfig and return hash with 'config' and 'includes' entries.
16
+ # 'config' containing the hash-map of resolved variables,
17
+ # 'includes' containing an array of include paths.
18
+ # The config values are not resolved.
19
+ def self.read_xcconfig(path)
20
+ # Get rid of comments and blank lines.
21
+ contents = File.read(path).gsub(%r{\s*//.*$}, "").gsub(/^$\n/, "")
22
+ # Collect all include statements.
23
+ includes_regex = /^\s*#include\s*"(.*)"$/
24
+ includes = contents.scan(includes_regex).flatten
25
+ # Get rid of include statements (makes it easier).
26
+ contents = contents.gsub(includes_regex, "")
27
+ # Collect all variable assignments.
28
+ config = contents.scan(/^\s*([^=]*)=(.*)$/).reduce({}) do |acc, e|
29
+ k = e[0].strip
30
+ v = e[1].strip
31
+ acc.merge({ k => v })
32
+ end
33
+
34
+ # Return.
35
+ {
36
+ config: config,
37
+ includes: includes
38
+ }
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,5 @@
1
+ module Fastlane
2
+ module XcconfigActions
3
+ VERSION = "1.0.0"
4
+ end
5
+ end
@@ -0,0 +1,16 @@
1
+ require 'fastlane/plugin/xcconfig_actions/version'
2
+
3
+ module Fastlane
4
+ module XcconfigActions
5
+ # Return all .rb files inside the "actions" and "helper" directory
6
+ def self.all_classes
7
+ Dir[File.expand_path('**/{actions,helper}/*.rb', File.dirname(__FILE__))]
8
+ end
9
+ end
10
+ end
11
+
12
+ # By default we want to import all available actions and helpers
13
+ # A plugin can contain any number of actions and plugins
14
+ Fastlane::XcconfigActions.all_classes.each do |current|
15
+ require current
16
+ end
metadata ADDED
@@ -0,0 +1,176 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fastlane-plugin-xcconfig_actions
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Maksym Grebenets
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-03-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: pry
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec_junit_formatter
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rubocop
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 0.56.0
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 0.56.0
97
+ - !ruby/object:Gem::Dependency
98
+ name: rubocop-require_tools
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: simplecov
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: fastlane
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: 2.116.1
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: 2.116.1
139
+ description:
140
+ email: maksym.grebenets@cba.com.au
141
+ executables: []
142
+ extensions: []
143
+ extra_rdoc_files: []
144
+ files:
145
+ - LICENSE
146
+ - README.md
147
+ - lib/fastlane/plugin/xcconfig_actions.rb
148
+ - lib/fastlane/plugin/xcconfig_actions/actions/read_xcconfig_action.rb
149
+ - lib/fastlane/plugin/xcconfig_actions/actions/validate_xcconfig_action.rb
150
+ - lib/fastlane/plugin/xcconfig_actions/helper/xcconfig_actions_helper.rb
151
+ - lib/fastlane/plugin/xcconfig_actions/version.rb
152
+ homepage: https://github.com/mgrebenets/fastlane-plugin-xcconfig_actions
153
+ licenses:
154
+ - MIT
155
+ metadata: {}
156
+ post_install_message:
157
+ rdoc_options: []
158
+ require_paths:
159
+ - lib
160
+ required_ruby_version: !ruby/object:Gem::Requirement
161
+ requirements:
162
+ - - ">="
163
+ - !ruby/object:Gem::Version
164
+ version: '0'
165
+ required_rubygems_version: !ruby/object:Gem::Requirement
166
+ requirements:
167
+ - - ">="
168
+ - !ruby/object:Gem::Version
169
+ version: '0'
170
+ requirements: []
171
+ rubyforge_project:
172
+ rubygems_version: 2.6.14
173
+ signing_key:
174
+ specification_version: 4
175
+ summary: Adds actions to fastlane to work with xcconfig files
176
+ test_files: []