fastlane-plugin-xcconfig_actions 1.0.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 +7 -0
- data/LICENSE +21 -0
- data/README.md +130 -0
- data/lib/fastlane/plugin/xcconfig_actions/actions/read_xcconfig_action.rb +190 -0
- data/lib/fastlane/plugin/xcconfig_actions/actions/validate_xcconfig_action.rb +120 -0
- data/lib/fastlane/plugin/xcconfig_actions/helper/xcconfig_actions_helper.rb +42 -0
- data/lib/fastlane/plugin/xcconfig_actions/version.rb +5 -0
- data/lib/fastlane/plugin/xcconfig_actions.rb +16 -0
- metadata +176 -0
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
|
+
[](https://rubygems.org/gems/fastlane-plugin-xcconfig_actions)
|
4
|
+
[](https://badge.fury.io/gh/mgrebenets%2Ffastlane-plugin-xcconfig_actions)
|
5
|
+
[](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,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: []
|