fastlane 1.92.0 → 1.93.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/lib/assets/AvailablePlugins.md.erb +24 -0
- data/lib/fastlane.rb +13 -6
- data/lib/fastlane/action_collector.rb +35 -2
- data/lib/fastlane/actions/actions_helper.rb +4 -0
- data/lib/fastlane/commands_generator.rb +61 -1
- data/lib/fastlane/lane.rb +1 -1
- data/lib/fastlane/lane_manager.rb +6 -2
- data/lib/fastlane/one_off.rb +7 -1
- data/lib/fastlane/plugins/plugin_fetcher.rb +59 -0
- data/lib/fastlane/plugins/plugin_generator.rb +86 -0
- data/lib/fastlane/plugins/plugin_generator_ui.rb +19 -0
- data/lib/fastlane/plugins/plugin_info.rb +47 -0
- data/lib/fastlane/plugins/plugin_info_collector.rb +150 -0
- data/lib/fastlane/plugins/plugin_manager.rb +358 -0
- data/lib/fastlane/plugins/plugin_search.rb +46 -0
- data/lib/fastlane/plugins/plugins.rb +11 -0
- data/lib/fastlane/plugins/template/%gem_name%.gemspec.erb +26 -0
- data/lib/fastlane/plugins/template/Gemfile +3 -0
- data/lib/fastlane/plugins/template/LICENSE.erb +21 -0
- data/lib/fastlane/plugins/template/README.md.erb +31 -0
- data/lib/fastlane/plugins/template/Rakefile +1 -0
- data/lib/fastlane/plugins/template/lib/fastlane/plugin/%plugin_name%.rb.erb +16 -0
- data/lib/fastlane/plugins/template/lib/fastlane/plugin/%plugin_name%/actions/%plugin_name%_action.rb.erb +35 -0
- data/lib/fastlane/plugins/template/lib/fastlane/plugin/%plugin_name%/helper/%plugin_name%_helper.rb.erb +12 -0
- data/lib/fastlane/plugins/template/lib/fastlane/plugin/%plugin_name%/version.rb.erb +5 -0
- data/lib/fastlane/plugins/template/spec/%plugin_name%_action_spec.rb.erb +9 -0
- data/lib/fastlane/plugins/template/spec/spec_helper.rb.erb +10 -0
- data/lib/fastlane/runner.rb +34 -12
- data/lib/fastlane/version.rb +1 -1
- metadata +60 -27
- data/lib/fastlane/actions/xcake.rb +0 -35
@@ -0,0 +1,150 @@
|
|
1
|
+
module Fastlane
|
2
|
+
class PluginInfoCollector
|
3
|
+
def initialize(ui = PluginGeneratorUI.new)
|
4
|
+
@ui = ui
|
5
|
+
end
|
6
|
+
|
7
|
+
def collect_info(initial_name = nil)
|
8
|
+
plugin_name = collect_plugin_name(initial_name)
|
9
|
+
author = collect_author(detect_author)
|
10
|
+
email = collect_email(detect_email)
|
11
|
+
summary = collect_summary
|
12
|
+
|
13
|
+
PluginInfo.new(plugin_name, author, email, summary)
|
14
|
+
end
|
15
|
+
|
16
|
+
#
|
17
|
+
# Plugin name
|
18
|
+
#
|
19
|
+
|
20
|
+
def collect_plugin_name(initial_name = nil)
|
21
|
+
plugin_name = initial_name
|
22
|
+
first_try = true
|
23
|
+
|
24
|
+
loop do
|
25
|
+
if !first_try || plugin_name.to_s.empty?
|
26
|
+
plugin_name = @ui.input("\nWhat would you like to be the name of your plugin?")
|
27
|
+
end
|
28
|
+
first_try = false
|
29
|
+
|
30
|
+
unless plugin_name_valid?(plugin_name)
|
31
|
+
fixed_name = fix_plugin_name(plugin_name)
|
32
|
+
|
33
|
+
if plugin_name_valid?(fixed_name)
|
34
|
+
plugin_name = fixed_name if @ui.confirm("\nWould '#{fixed_name}' be okay to use for your plugin name?")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
break if plugin_name_valid?(plugin_name)
|
39
|
+
|
40
|
+
if plugin_name_taken?(plugin_name)
|
41
|
+
# Plugin name is already taken on RubyGems
|
42
|
+
@ui.message("\nPlugin name '#{plugin_name}' is already taken on RubyGems, please choose a different one.")
|
43
|
+
else
|
44
|
+
# That's a naming error
|
45
|
+
@ui.message("\nPlugin names can only contain lower case letters, numbers, and underscores")
|
46
|
+
@ui.message("and should not contain 'fastlane' or 'plugin'.")
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
plugin_name
|
51
|
+
end
|
52
|
+
|
53
|
+
def plugin_name_valid?(name)
|
54
|
+
# Only lower case letters, numbers and underscores allowed
|
55
|
+
/^[a-z0-9_]+$/ =~ name &&
|
56
|
+
# Does not contain the words 'fastlane' or 'plugin' since those will become
|
57
|
+
# part of the gem name
|
58
|
+
[/fastlane/, /plugin/].none? { |regex| regex =~ name } &&
|
59
|
+
# Plugin name isn't taken on RubyGems yet
|
60
|
+
!plugin_name_taken?(name)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Checks if the plugin name is still free on RubyGems
|
64
|
+
def plugin_name_taken?(name)
|
65
|
+
require 'open-uri'
|
66
|
+
require 'json'
|
67
|
+
url = "https://rubygems.org/api/v1/gems/#{name}.json"
|
68
|
+
response = JSON.parse(open(url).read)
|
69
|
+
return !!response['version']
|
70
|
+
rescue
|
71
|
+
false
|
72
|
+
end
|
73
|
+
|
74
|
+
# Applies a series of replacement rules to turn the requested plugin name into one
|
75
|
+
# that is acceptable, returning that suggestion
|
76
|
+
def fix_plugin_name(name)
|
77
|
+
name = name.to_s.downcase
|
78
|
+
fixes = {
|
79
|
+
/[\- ]/ => '_', # dashes and spaces become underscores
|
80
|
+
/[^a-z0-9_]/ => '', # anything other than lower case letters, numbers and underscores is removed
|
81
|
+
/fastlane[_]?/ => '', # 'fastlane' or 'fastlane_' is removed
|
82
|
+
/plugin[_]?/ => '' # 'plugin' or 'plugin_' is removed
|
83
|
+
}
|
84
|
+
fixes.each do |regex, replacement|
|
85
|
+
name = name.gsub(regex, replacement)
|
86
|
+
end
|
87
|
+
name
|
88
|
+
end
|
89
|
+
|
90
|
+
#
|
91
|
+
# Author
|
92
|
+
#
|
93
|
+
|
94
|
+
def detect_author
|
95
|
+
git_name = Helper.backticks('git config --get user.name', print: $verbose).strip
|
96
|
+
return git_name.empty? ? nil : git_name
|
97
|
+
end
|
98
|
+
|
99
|
+
def collect_author(initial_author = nil)
|
100
|
+
return initial_author if author_valid?(initial_author)
|
101
|
+
author = nil
|
102
|
+
loop do
|
103
|
+
author = @ui.input("\nWhat is the plugin author's name?")
|
104
|
+
break if author_valid?(author)
|
105
|
+
|
106
|
+
@ui.message('An author name is required.')
|
107
|
+
end
|
108
|
+
|
109
|
+
author
|
110
|
+
end
|
111
|
+
|
112
|
+
def author_valid?(author)
|
113
|
+
!author.to_s.strip.empty?
|
114
|
+
end
|
115
|
+
|
116
|
+
#
|
117
|
+
# Email
|
118
|
+
#
|
119
|
+
|
120
|
+
def detect_email
|
121
|
+
git_email = Helper.backticks('git config --get user.email', print: $verbose).strip
|
122
|
+
return git_email.empty? ? nil : git_email
|
123
|
+
end
|
124
|
+
|
125
|
+
def collect_email(initial_email = nil)
|
126
|
+
return initial_email || @ui.input("\nWhat is the plugin author's email address?")
|
127
|
+
end
|
128
|
+
|
129
|
+
#
|
130
|
+
# Summary
|
131
|
+
#
|
132
|
+
|
133
|
+
def collect_summary
|
134
|
+
summary = nil
|
135
|
+
loop do
|
136
|
+
summary = @ui.input("\nPlease enter a short summary of this fastlane plugin:")
|
137
|
+
break if summary_valid?(summary)
|
138
|
+
|
139
|
+
@ui.message('A summary is required.')
|
140
|
+
end
|
141
|
+
|
142
|
+
summary
|
143
|
+
end
|
144
|
+
|
145
|
+
def summary_valid?(summary)
|
146
|
+
!summary.to_s.strip.empty?
|
147
|
+
end
|
148
|
+
|
149
|
+
end
|
150
|
+
end
|
@@ -0,0 +1,358 @@
|
|
1
|
+
module Fastlane
|
2
|
+
class PluginManager
|
3
|
+
require "bundler"
|
4
|
+
|
5
|
+
PLUGINFILE_NAME = "Pluginfile".freeze
|
6
|
+
DEFAULT_GEMFILE_PATH = "Gemfile".freeze
|
7
|
+
AUTOGENERATED_LINE = "# Autogenerated by fastlane\n#\n# Ensure this file is checked in to source control!\n\n"
|
8
|
+
GEMFILE_SOURCE_LINE = "source \"https://rubygems.org\"\n"
|
9
|
+
FASTLANE_PLUGIN_PREFIX = "fastlane-plugin-"
|
10
|
+
TROUBLESHOOTING_URL = "https://github.com/fastlane/fastlane/blob/master/fastlane/docs/PluginsTroubleshooting.md"
|
11
|
+
|
12
|
+
#####################################################
|
13
|
+
# @!group Reading the files and their paths
|
14
|
+
#####################################################
|
15
|
+
|
16
|
+
def gemfile_path
|
17
|
+
# This is pretty important, since we don't know what kind of
|
18
|
+
# Gemfile the user has (e.g. Gemfile, gems.rb, or custom env variable)
|
19
|
+
Bundler::SharedHelpers.default_gemfile.to_s
|
20
|
+
rescue Bundler::GemfileNotFound
|
21
|
+
nil
|
22
|
+
end
|
23
|
+
|
24
|
+
def pluginfile_path
|
25
|
+
if FastlaneFolder.path
|
26
|
+
return File.join(FastlaneFolder.path, PLUGINFILE_NAME)
|
27
|
+
else
|
28
|
+
return nil
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def gemfile_content
|
33
|
+
File.read(gemfile_path) if gemfile_path && File.exist?(gemfile_path)
|
34
|
+
end
|
35
|
+
|
36
|
+
def pluginfile_content
|
37
|
+
File.read(pluginfile_path) if pluginfile_path && File.exist?(pluginfile_path)
|
38
|
+
end
|
39
|
+
|
40
|
+
#####################################################
|
41
|
+
# @!group Helpers
|
42
|
+
#####################################################
|
43
|
+
|
44
|
+
def self.plugin_prefix
|
45
|
+
FASTLANE_PLUGIN_PREFIX
|
46
|
+
end
|
47
|
+
|
48
|
+
# Returns an array of gems that are added to the Gemfile or Pluginfile
|
49
|
+
def available_gems
|
50
|
+
return [] unless gemfile_path
|
51
|
+
dsl = Bundler::Dsl.evaluate(gemfile_path, nil, true)
|
52
|
+
return dsl.dependencies.map(&:name)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Returns an array of fastlane plugins that are added to the Gemfile or Pluginfile
|
56
|
+
# The returned array contains the string with their prefixes (e.g. fastlane-plugin-xcversion)
|
57
|
+
def available_plugins
|
58
|
+
available_gems.keep_if do |current|
|
59
|
+
current.start_with?(self.class.plugin_prefix)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# Check if a plugin is added as dependency to either the
|
64
|
+
# Gemfile or the Pluginfile
|
65
|
+
def plugin_is_added_as_dependency?(plugin_name)
|
66
|
+
UI.user_error!("fastlane plugins must start with '#{self.class.plugin_prefix}' string") unless plugin_name.start_with?(self.class.plugin_prefix)
|
67
|
+
return available_plugins.include?(plugin_name)
|
68
|
+
end
|
69
|
+
|
70
|
+
#####################################################
|
71
|
+
# @!group Modifying dependencies
|
72
|
+
#####################################################
|
73
|
+
|
74
|
+
def add_dependency(plugin_name)
|
75
|
+
UI.user_error!("fastlane is not setup for this project, make sure you have a fastlane folder") unless pluginfile_path
|
76
|
+
plugin_name = self.class.plugin_prefix + plugin_name unless plugin_name.start_with?(self.class.plugin_prefix)
|
77
|
+
|
78
|
+
unless plugin_is_added_as_dependency?(plugin_name)
|
79
|
+
content = pluginfile_content || AUTOGENERATED_LINE
|
80
|
+
|
81
|
+
line_to_add = "gem '#{plugin_name}'"
|
82
|
+
line_to_add += gem_dependency_suffix(plugin_name)
|
83
|
+
UI.verbose("Adding line: #{line_to_add}")
|
84
|
+
|
85
|
+
content += "#{line_to_add}\n"
|
86
|
+
File.write(pluginfile_path, content)
|
87
|
+
UI.success("Plugin '#{plugin_name}' was added to '#{pluginfile_path}'")
|
88
|
+
end
|
89
|
+
|
90
|
+
# We do this *after* creating the Plugin file
|
91
|
+
# Since `bundle exec` would be broken if something fails on the way
|
92
|
+
ensure_plugins_attached!
|
93
|
+
|
94
|
+
true
|
95
|
+
end
|
96
|
+
|
97
|
+
# Get a suffix (e.g. `path` or `git` for the gem dependency)
|
98
|
+
def gem_dependency_suffix(plugin_name)
|
99
|
+
return "" unless self.class.fetch_gem_info_from_rubygems(plugin_name).nil?
|
100
|
+
|
101
|
+
selection_git_url = "Git URL"
|
102
|
+
selection_path = "Local Path"
|
103
|
+
selection_rubygems = "RubyGems.org ('#{plugin_name}' seems to not be available there)"
|
104
|
+
selection = UI.select(
|
105
|
+
"Seems like the plugin is not available on RubyGems, what do you want to do?",
|
106
|
+
[selection_git_url, selection_path, selection_rubygems]
|
107
|
+
)
|
108
|
+
|
109
|
+
if selection == selection_git_url
|
110
|
+
git_url = UI.input('Please enter the URL to the plugin, including the protocol (e.g. https:// or git://)')
|
111
|
+
return ", git: '#{git_url}'"
|
112
|
+
elsif selection == selection_path
|
113
|
+
path = UI.input('Please enter the relative path to the plugin you want to use. It has to point to the directory containing the .gemspec file')
|
114
|
+
return ", path: '#{path}'"
|
115
|
+
elsif selection == selection_rubygems
|
116
|
+
return ""
|
117
|
+
else
|
118
|
+
UI.user_error!("Unknown input #{selection}")
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
# Modify the user's Gemfile to load the plugins
|
123
|
+
def attach_plugins_to_gemfile!(path_to_gemfile)
|
124
|
+
content = gemfile_content || (AUTOGENERATED_LINE + GEMFILE_SOURCE_LINE)
|
125
|
+
|
126
|
+
# We have to make sure fastlane is also added to the Gemfile, since we now use
|
127
|
+
# bundler to run fastlane
|
128
|
+
content += "\ngem 'fastlane'\n" unless available_gems.include?('fastlane')
|
129
|
+
content += "\n#{self.class.code_to_attach}\n"
|
130
|
+
|
131
|
+
File.write(path_to_gemfile, content)
|
132
|
+
end
|
133
|
+
|
134
|
+
#####################################################
|
135
|
+
# @!group Accessing RubyGems
|
136
|
+
#####################################################
|
137
|
+
|
138
|
+
def self.fetch_gem_info_from_rubygems(gem_name)
|
139
|
+
require 'open-uri'
|
140
|
+
require 'json'
|
141
|
+
url = "https://rubygems.org/api/v1/gems/#{gem_name}.json"
|
142
|
+
begin
|
143
|
+
JSON.parse(open(url).read)
|
144
|
+
rescue
|
145
|
+
nil
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
#####################################################
|
150
|
+
# @!group Installing and updating dependencies
|
151
|
+
#####################################################
|
152
|
+
|
153
|
+
# Warning: This will exec out
|
154
|
+
# This is necessary since the user might be prompted for their password
|
155
|
+
def install_dependencies!
|
156
|
+
# Using puts instead of `UI` to have the same style as the `echo`
|
157
|
+
puts "Installing plugin dependencies..."
|
158
|
+
ensure_plugins_attached!
|
159
|
+
with_clean_bundler_env do
|
160
|
+
cmd = "bundle install"
|
161
|
+
cmd << " --quiet" unless $verbose
|
162
|
+
cmd << " && echo 'Successfully installed plugins'"
|
163
|
+
UI.command(cmd) if $verbose
|
164
|
+
exec(cmd)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
# Warning: This will exec out
|
169
|
+
# This is necessary since the user might be prompted for their password
|
170
|
+
def update_dependencies!
|
171
|
+
puts "Updating plugin dependencies..."
|
172
|
+
ensure_plugins_attached!
|
173
|
+
with_clean_bundler_env do
|
174
|
+
cmd = "bundle update"
|
175
|
+
cmd << " --quiet" unless $verbose
|
176
|
+
cmd << " && echo 'Successfully updated plugins'"
|
177
|
+
UI.command(cmd) if $verbose
|
178
|
+
exec(cmd)
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
def with_clean_bundler_env
|
183
|
+
# There is an interesting problem with using exec to call back into Bundler
|
184
|
+
# The `bundle ________` command that we exec, inherits all of the Bundler
|
185
|
+
# state we'd already built up during this run. That was causing the command
|
186
|
+
# to fail, telling us to install the Gem we'd just introduced, even though
|
187
|
+
# that is exactly what we are trying to do!
|
188
|
+
#
|
189
|
+
# Bundler.with_clean_env solves this problem by resetting Bundler state before the
|
190
|
+
# exec'd call gets merged into this process.
|
191
|
+
|
192
|
+
Bundler.with_clean_env do
|
193
|
+
yield if block_given?
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
#####################################################
|
198
|
+
# @!group Initial setup
|
199
|
+
#####################################################
|
200
|
+
|
201
|
+
def setup
|
202
|
+
UI.important("It looks like fastlane plugins are not yet set up for this project.")
|
203
|
+
|
204
|
+
path_to_gemfile = gemfile_path || DEFAULT_GEMFILE_PATH
|
205
|
+
|
206
|
+
if gemfile_content.to_s.length > 0
|
207
|
+
UI.important("fastlane will modify your existing Gemfile at path '#{path_to_gemfile}'")
|
208
|
+
else
|
209
|
+
UI.important("fastlane will create a new Gemfile at path '#{path_to_gemfile}'")
|
210
|
+
end
|
211
|
+
|
212
|
+
UI.important("This change is neccessary for fastlane plugins to work")
|
213
|
+
|
214
|
+
unless UI.confirm("Should fastlane modify the Gemfile at path '#{path_to_gemfile}' for you?")
|
215
|
+
UI.important("Please add the following code to '#{path_to_gemfile}':")
|
216
|
+
puts ""
|
217
|
+
puts self.class.code_to_attach.magenta # we use `puts` instead of `UI` to make it easier to copy and paste
|
218
|
+
UI.user_error!("Please update '#{path_to_gemfile} and run fastlane again")
|
219
|
+
end
|
220
|
+
|
221
|
+
attach_plugins_to_gemfile!(path_to_gemfile)
|
222
|
+
UI.success("Successfully modified '#{path_to_gemfile}'")
|
223
|
+
end
|
224
|
+
|
225
|
+
# The code required to load the Plugins file
|
226
|
+
def self.code_to_attach
|
227
|
+
if FastlaneFolder.path
|
228
|
+
fastlane_folder_name = File.basename(FastlaneFolder.path)
|
229
|
+
else
|
230
|
+
fastlane_folder_name = "fastlane"
|
231
|
+
end
|
232
|
+
"plugins_path = File.join(File.dirname(__FILE__), '#{fastlane_folder_name}', '#{PluginManager::PLUGINFILE_NAME}')\n" \
|
233
|
+
"eval(File.read(plugins_path), binding) if File.exist?(plugins_path)"
|
234
|
+
end
|
235
|
+
|
236
|
+
# Makes sure, the user's Gemfile actually loads the Plugins file
|
237
|
+
def plugins_attached?
|
238
|
+
gemfile_path && gemfile_content.include?(self.class.code_to_attach)
|
239
|
+
end
|
240
|
+
|
241
|
+
def ensure_plugins_attached!
|
242
|
+
return if plugins_attached?
|
243
|
+
self.setup
|
244
|
+
end
|
245
|
+
|
246
|
+
#####################################################
|
247
|
+
# @!group Requiring the plugins
|
248
|
+
#####################################################
|
249
|
+
|
250
|
+
# Iterate over all available plugins
|
251
|
+
# which follow the naming convention
|
252
|
+
# fastlane-plugin-[plugin_name]
|
253
|
+
# This will make sure to load the action
|
254
|
+
# and all its helpers
|
255
|
+
def load_plugins
|
256
|
+
UI.verbose("Checking if there are any plugins that should be loaded...")
|
257
|
+
|
258
|
+
loaded_plugins = false
|
259
|
+
available_plugins.each do |gem_name|
|
260
|
+
UI.verbose("Loading '#{gem_name}' plugin")
|
261
|
+
begin
|
262
|
+
# BEFORE requiring the gem, we get a list of loaded actions
|
263
|
+
# This way we can check inside `store_plugin_reference` if
|
264
|
+
# any actions were overwritten
|
265
|
+
self.loaded_fastlane_actions.concat(Fastlane::Actions.constants)
|
266
|
+
|
267
|
+
require gem_name.tr("-", "/") # from "fastlane-plugin-xcversion" to "fastlane/plugin/xcversion"
|
268
|
+
store_plugin_reference(gem_name)
|
269
|
+
loaded_plugins = true
|
270
|
+
rescue => ex
|
271
|
+
UI.error("Error loading plugin '#{gem_name}': #{ex}")
|
272
|
+
|
273
|
+
# We'll still add it to the table, to make the error
|
274
|
+
# much more visible and obvious
|
275
|
+
self.plugin_references[gem_name] = {
|
276
|
+
version_number: Fastlane::ActionCollector.determine_version(gem_name),
|
277
|
+
actions: []
|
278
|
+
}
|
279
|
+
end
|
280
|
+
end
|
281
|
+
|
282
|
+
if !loaded_plugins && self.pluginfile_content.to_s.include?(PluginManager.plugin_prefix)
|
283
|
+
UI.error("It seems like you wanted to load some plugins, however they couldn't be loaded")
|
284
|
+
UI.error("Please follow the troubleshooting guide: #{TROUBLESHOOTING_URL}")
|
285
|
+
end
|
286
|
+
|
287
|
+
print_plugin_information(self.plugin_references) unless self.plugin_references.empty?
|
288
|
+
end
|
289
|
+
|
290
|
+
# Prints a table all the plugins that were loaded
|
291
|
+
def print_plugin_information(references)
|
292
|
+
rows = references.collect do |current|
|
293
|
+
if current[1][:actions].empty?
|
294
|
+
# Something is wrong with this plugin, no available actions
|
295
|
+
[current[0].red, current[1][:version_number], "No actions found".red]
|
296
|
+
else
|
297
|
+
[current[0], current[1][:version_number], current[1][:actions].join("\n")]
|
298
|
+
end
|
299
|
+
end
|
300
|
+
|
301
|
+
puts Terminal::Table.new({
|
302
|
+
rows: rows,
|
303
|
+
title: "Used plugins".green,
|
304
|
+
headings: ["Plugin", "Version", "Action"]
|
305
|
+
})
|
306
|
+
puts ""
|
307
|
+
end
|
308
|
+
|
309
|
+
#####################################################
|
310
|
+
# @!group Reference between plugins to actions
|
311
|
+
#####################################################
|
312
|
+
|
313
|
+
# Connection between plugins and their actions
|
314
|
+
# Example value of plugin_references
|
315
|
+
# => {"fastlane-plugin-ruby" => {
|
316
|
+
# version_number: "0.1.0",
|
317
|
+
# actions: [:rspec, :rubocop]
|
318
|
+
# }}
|
319
|
+
def plugin_references
|
320
|
+
@plugin_references ||= {}
|
321
|
+
end
|
322
|
+
|
323
|
+
# Contains an array of symbols for the action classes
|
324
|
+
def loaded_fastlane_actions
|
325
|
+
@fastlane_actions ||= []
|
326
|
+
end
|
327
|
+
|
328
|
+
def store_plugin_reference(gem_name)
|
329
|
+
module_name = gem_name.gsub(PluginManager.plugin_prefix, '').fastlane_class
|
330
|
+
# We store a collection of the imported plugins
|
331
|
+
# This way we can tell which action came from what plugin
|
332
|
+
# (a plugin may contain any number of actions)
|
333
|
+
version_number = Fastlane::ActionCollector.determine_version(gem_name)
|
334
|
+
references = Fastlane.const_get(module_name).all_classes.collect do |path|
|
335
|
+
next unless File.dirname(path).end_with?("/actions") # we only want to match actions
|
336
|
+
|
337
|
+
File.basename(path).gsub("_action", "").gsub(".rb", "").to_sym # the _action is optional
|
338
|
+
end
|
339
|
+
references.compact!
|
340
|
+
|
341
|
+
# Check if this overwrites a built-in action and
|
342
|
+
# show a warning if that's the case
|
343
|
+
references.each do |current_ref|
|
344
|
+
# current_ref is a symbol, e.g. :emoji_fetcher
|
345
|
+
class_name = (current_ref.to_s.fastlane_class + 'Action').to_sym
|
346
|
+
|
347
|
+
if self.loaded_fastlane_actions.include?(class_name)
|
348
|
+
UI.important("Plugin '#{module_name}' overwrites already loaded action '#{current_ref}'")
|
349
|
+
end
|
350
|
+
end
|
351
|
+
|
352
|
+
self.plugin_references[gem_name] = {
|
353
|
+
version_number: version_number,
|
354
|
+
actions: references
|
355
|
+
}
|
356
|
+
end
|
357
|
+
end
|
358
|
+
end
|