fastlane 1.92.0 → 1.93.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3c67117c9fa728e8d4a628cd5ab40a74f615dfd1
|
4
|
+
data.tar.gz: 1397336e43b8257f610df1af93f04532a8480d18
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c7400de730419a6c95102c79d32c623a267da6e540c2620241e12d645da46648d3433e36a8c344b5e0e49076607c75c0932e107ace0a4bb4dc0607e1d3666805
|
7
|
+
data.tar.gz: f91ff6eb451eff605418e3dc2416402bb7affc8448df7114ffcf13094e402772b74759d8f04b2e0de6f3e2abdaf21fa0e7e46774ce7bd78942d731df1c845b26
|
@@ -0,0 +1,24 @@
|
|
1
|
+
### Available Plugins
|
2
|
+
|
3
|
+
To get an up to date list of all available plugins run
|
4
|
+
|
5
|
+
```
|
6
|
+
fastlane search_plugins
|
7
|
+
```
|
8
|
+
|
9
|
+
To search for a specific plugin
|
10
|
+
|
11
|
+
```
|
12
|
+
fastlane search_plugins [search_query]
|
13
|
+
```
|
14
|
+
|
15
|
+
You can find more information about how to start using plugins in [Plugins.md](https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Plugins.md).
|
16
|
+
|
17
|
+
#### List of plugins
|
18
|
+
|
19
|
+
| Plugin Name | Description | Downloads
|
20
|
+
--------------|-------------|----------|----------
|
21
|
+
<% @plugins.each do |current| %>
|
22
|
+
<%= current.linked_title %> | <%= current.info %> | <%= current.downloads %>
|
23
|
+
|
24
|
+
<% end %>
|
data/lib/fastlane.rb
CHANGED
@@ -18,18 +18,25 @@ require 'fastlane/one_off'
|
|
18
18
|
require 'fastlane/command_line_handler'
|
19
19
|
require 'fastlane/documentation/docs_generator'
|
20
20
|
require 'fastlane/other_action'
|
21
|
+
require 'fastlane/plugins/plugins'
|
21
22
|
|
22
23
|
module Fastlane
|
23
24
|
Helper = FastlaneCore::Helper # you gotta love Ruby: Helper.* should use the Helper class contained in FastlaneCore
|
24
25
|
UI = FastlaneCore::UI
|
25
26
|
|
26
|
-
|
27
|
-
|
28
|
-
|
27
|
+
class << self
|
28
|
+
def load_actions
|
29
|
+
Fastlane::Actions.load_default_actions
|
30
|
+
Fastlane::Actions.load_helpers
|
29
31
|
|
30
|
-
|
31
|
-
|
32
|
-
|
32
|
+
if Fastlane::FastlaneFolder.path
|
33
|
+
actions_path = File.join(Fastlane::FastlaneFolder.path, 'actions')
|
34
|
+
Fastlane::Actions.load_external_actions(actions_path) if File.directory?(actions_path)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def plugin_manager
|
39
|
+
@plugin_manager ||= Fastlane::PluginManager.new
|
33
40
|
end
|
34
41
|
end
|
35
42
|
end
|
@@ -1,8 +1,19 @@
|
|
1
1
|
module Fastlane
|
2
2
|
class ActionCollector < FastlaneCore::ToolCollector
|
3
|
+
# Is this an official fastlane action, that is bundled with fastlane?
|
3
4
|
def is_official?(name)
|
4
5
|
return true if name == :lane_switch
|
5
|
-
Actions.get_all_official_actions.include?
|
6
|
+
Actions.get_all_official_actions.include?(name)
|
7
|
+
end
|
8
|
+
|
9
|
+
def name_to_track(name)
|
10
|
+
return name if is_official?(name)
|
11
|
+
|
12
|
+
Fastlane.plugin_manager.plugin_references.each do |plugin_name, value|
|
13
|
+
return "#{plugin_name}/#{name}" if value[:actions].include?(name)
|
14
|
+
end
|
15
|
+
|
16
|
+
return nil
|
6
17
|
end
|
7
18
|
|
8
19
|
def show_message
|
@@ -15,7 +26,29 @@ module Fastlane
|
|
15
26
|
end
|
16
27
|
|
17
28
|
def determine_version(name)
|
18
|
-
|
29
|
+
self.class.determine_version(name)
|
30
|
+
end
|
31
|
+
|
32
|
+
# e.g.
|
33
|
+
# :gym
|
34
|
+
# :xcversion
|
35
|
+
# "fastlane-plugin-my_plugin/xcversion"
|
36
|
+
def self.determine_version(name)
|
37
|
+
result = super(name)
|
38
|
+
return result if result
|
39
|
+
|
40
|
+
if name.to_s.include?(PluginManager.plugin_prefix)
|
41
|
+
# That's an action from a plugin, we need to fetch its version number
|
42
|
+
begin
|
43
|
+
plugin_name = name.split("/").first.gsub(PluginManager.plugin_prefix, '')
|
44
|
+
return Fastlane.const_get(plugin_name.fastlane_class)::VERSION
|
45
|
+
rescue => ex
|
46
|
+
UI.verbose(ex)
|
47
|
+
return "undefined"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
return Fastlane::VERSION # that's the case for all built-in actions
|
19
52
|
end
|
20
53
|
end
|
21
54
|
end
|
@@ -8,8 +8,13 @@ module Fastlane
|
|
8
8
|
include Commander::Methods
|
9
9
|
|
10
10
|
def self.start
|
11
|
+
# since at this point we haven't yet loaded commander
|
12
|
+
# however we do want to log verbose information in the PluginManager
|
13
|
+
$verbose = true if ARGV.include?("--verbose")
|
14
|
+
|
11
15
|
FastlaneCore::UpdateChecker.start_looking_for_update('fastlane')
|
12
16
|
Fastlane.load_actions
|
17
|
+
Fastlane.plugin_manager.load_plugins
|
13
18
|
self.new.run
|
14
19
|
ensure
|
15
20
|
FastlaneCore::UpdateChecker.show_update_status('fastlane', Fastlane::VERSION)
|
@@ -170,8 +175,63 @@ module Fastlane
|
|
170
175
|
end
|
171
176
|
end
|
172
177
|
|
173
|
-
|
178
|
+
#####################################################
|
179
|
+
# @!group Plugins
|
180
|
+
#####################################################
|
181
|
+
|
182
|
+
command :new_plugin do |c|
|
183
|
+
c.syntax = 'fastlane new_plugin [plugin_name]'
|
184
|
+
c.description = 'Create a new plugin that can be used with fastlane'
|
185
|
+
|
186
|
+
c.action do |args, options|
|
187
|
+
PluginGenerator.new.generate(args.shift)
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
command :add_plugin do |c|
|
192
|
+
c.syntax = 'fastlane add_plugin [plugin_name]'
|
193
|
+
c.description = 'Add a new plugin to your fastlane setup'
|
194
|
+
|
195
|
+
c.action do |args, options|
|
196
|
+
args << UI.input("Enter the name of the plugin to install: ") if args.empty?
|
197
|
+
args.each do |plugin_name|
|
198
|
+
Fastlane.plugin_manager.add_dependency(plugin_name)
|
199
|
+
end
|
200
|
+
|
201
|
+
UI.important("Make sure to commit your Gemfile, Gemfile.lock and #{PluginManager::PLUGINFILE_NAME} to version control")
|
202
|
+
Fastlane.plugin_manager.install_dependencies!
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
command :install_plugins do |c|
|
207
|
+
c.syntax = 'fastlane install_plugins'
|
208
|
+
c.description = 'Install all plugins for this project'
|
174
209
|
|
210
|
+
c.action do |args, options|
|
211
|
+
Fastlane.plugin_manager.install_dependencies!
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
command :update_plugins do |c|
|
216
|
+
c.syntax = 'fastlane update_plugins'
|
217
|
+
c.description = 'Update all plugin dependencies'
|
218
|
+
|
219
|
+
c.action do |args, options|
|
220
|
+
Fastlane.plugin_manager.update_dependencies!
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
command :search_plugins do |c|
|
225
|
+
c.syntax = 'fastlane search_plugins [search_query]'
|
226
|
+
c.description = 'Search for plugins, search query is optional'
|
227
|
+
|
228
|
+
c.action do |args, options|
|
229
|
+
search_query = args.last
|
230
|
+
PluginSearch.print_plugins(search_query: search_query)
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
default_command :trigger
|
175
235
|
run!
|
176
236
|
end
|
177
237
|
|
data/lib/fastlane/lane.rb
CHANGED
@@ -55,7 +55,7 @@ module Fastlane
|
|
55
55
|
end
|
56
56
|
|
57
57
|
def black_list
|
58
|
-
%w(run init new_action lanes list docs action actions help)
|
58
|
+
%w(run init new_action lanes list docs action actions enable_auto_complete new_plugin add_plugin install_plugins update_plugins search_plugins help)
|
59
59
|
end
|
60
60
|
|
61
61
|
def gray_list
|
@@ -44,10 +44,14 @@ module Fastlane
|
|
44
44
|
e = nil
|
45
45
|
begin
|
46
46
|
ff.runner.execute(lane, platform, parameters)
|
47
|
-
rescue => ex
|
47
|
+
rescue Exception => ex # rubocop:disable Lint/RescueException
|
48
|
+
# We also catch Exception, since the implemented action might send a SystemExit signal
|
49
|
+
# (or similar). We still want to catch that, since we want properly finish running fastlane
|
50
|
+
# Tested with `xcake`, which throws a `Xcake::Informative` object
|
51
|
+
|
48
52
|
UI.important 'Variable Dump:'.yellow
|
49
53
|
UI.message Actions.lane_context
|
50
|
-
UI.error ex.to_s
|
54
|
+
UI.error ex.to_s if ex.kind_of?(StandardError) # we don't want to print things like 'system exit'
|
51
55
|
e = ex
|
52
56
|
end
|
53
57
|
|
data/lib/fastlane/one_off.rb
CHANGED
@@ -29,7 +29,13 @@ module Fastlane
|
|
29
29
|
begin
|
30
30
|
class_ref = Fastlane::Actions.const_get(class_name)
|
31
31
|
rescue NameError
|
32
|
-
|
32
|
+
if Fastlane::Actions.formerly_bundled_actions.include?(action)
|
33
|
+
# This was a formerly bundled action which is now a plugin.
|
34
|
+
UI.verbose(caller.join("\n"))
|
35
|
+
UI.user_error!("The action '#{action}' is no longer bundled with fastlane. You can install it using `fastlane add_plugin #{action}`")
|
36
|
+
else
|
37
|
+
UI.user_error!("Action '#{action}' not available, run `fastlane actions` to get a full list")
|
38
|
+
end
|
33
39
|
end
|
34
40
|
|
35
41
|
r = Runner.new
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module Fastlane
|
2
|
+
# Use the RubyGems API to get all fastlane plugins
|
3
|
+
class PluginFetcher
|
4
|
+
require 'fastlane_core'
|
5
|
+
require 'fastlane/plugins/plugin_manager'
|
6
|
+
|
7
|
+
# Returns an array of FastlanePlugin objects
|
8
|
+
def self.fetch_gems(search_query: nil)
|
9
|
+
require 'json'
|
10
|
+
require 'open-uri'
|
11
|
+
url = "https://rubygems.org/api/v1/search.json?query=#{PluginManager.plugin_prefix}"
|
12
|
+
results = JSON.parse(open(url).read)
|
13
|
+
|
14
|
+
plugins = results.collect do |current|
|
15
|
+
FastlanePlugin.new(current)
|
16
|
+
end
|
17
|
+
|
18
|
+
return plugins if search_query.to_s.length == 0
|
19
|
+
|
20
|
+
plugins.keep_if do |current|
|
21
|
+
current.full_name.include?(search_query)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.update_md_file!
|
26
|
+
@plugins = fetch_gems
|
27
|
+
|
28
|
+
lib_path = FastlaneCore::Helper.gem_path('fastlane')
|
29
|
+
template_path = File.join(lib_path, "lib/assets/AvailablePlugins.md.erb")
|
30
|
+
md = ERB.new(File.read(template_path), nil, '<>').result(binding) # http://www.rrn.dk/rubys-erb-templating-system
|
31
|
+
|
32
|
+
puts md
|
33
|
+
output_path = "docs/AvailablePlugins.md"
|
34
|
+
File.write(output_path, md)
|
35
|
+
FastlaneCore::UI.success("Successfully written plugin file to '#{output_path}'")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
class FastlanePlugin
|
40
|
+
attr_accessor :full_name
|
41
|
+
attr_accessor :name
|
42
|
+
attr_accessor :downloads
|
43
|
+
attr_accessor :info
|
44
|
+
attr_accessor :homepage
|
45
|
+
|
46
|
+
def initialize(hash)
|
47
|
+
self.full_name = hash["name"]
|
48
|
+
self.name = self.full_name.gsub(PluginManager.plugin_prefix, '')
|
49
|
+
self.downloads = hash["downloads"]
|
50
|
+
self.info = hash["info"]
|
51
|
+
self.homepage = hash["homepage_uri"]
|
52
|
+
end
|
53
|
+
|
54
|
+
def linked_title
|
55
|
+
return "`#{name}`" if homepage.to_s.length == 0
|
56
|
+
return "[#{name}](#{homepage})"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module Fastlane
|
2
|
+
# Generates a sample plugin by traversing a template directory structure
|
3
|
+
# and reproducing it in a destination location. At the same time, it runs
|
4
|
+
# variable replacements on directory names, file names, and runs ERB
|
5
|
+
# templating on file contents whose names end with '.erb'.
|
6
|
+
#
|
7
|
+
# Directory and file name variable replacements are defined like: %gem_name%
|
8
|
+
# The text between the percent signs will be used to invoke an accessor
|
9
|
+
# method on the PluginInfo object to get the replacement value.
|
10
|
+
class PluginGenerator
|
11
|
+
def initialize(ui: PluginGeneratorUI.new,
|
12
|
+
info_collector: PluginInfoCollector.new(ui),
|
13
|
+
template_root: File.join(File.dirname(__FILE__), 'template'),
|
14
|
+
dest_root: FileUtils.pwd)
|
15
|
+
@ui = ui
|
16
|
+
@info_collector = info_collector
|
17
|
+
@template_root = template_root
|
18
|
+
@dest_root = dest_root
|
19
|
+
end
|
20
|
+
|
21
|
+
# entry point
|
22
|
+
def generate(plugin_name = nil)
|
23
|
+
plugin_info = @info_collector.collect_info(plugin_name)
|
24
|
+
|
25
|
+
# Traverse all the files and directories in the template root,
|
26
|
+
# handling each in turn
|
27
|
+
Find.find(@template_root) do |template_path|
|
28
|
+
handle_template_path(template_path, plugin_info)
|
29
|
+
end
|
30
|
+
|
31
|
+
@ui.success "\nYour plugin was successfully generated at #{plugin_info.gem_name}/ 🚀"
|
32
|
+
@ui.success "\nTo get started with using this plugin, run"
|
33
|
+
@ui.message "\n fastlane add_plugin #{plugin_info.plugin_name}\n"
|
34
|
+
@ui.success "\nfrom a fastlane-enabled app project directory and provide the following as the path:"
|
35
|
+
@ui.message "\n #{File.expand_path(plugin_info.gem_name)}\n\n"
|
36
|
+
end
|
37
|
+
|
38
|
+
def handle_template_path(template_path, plugin_info)
|
39
|
+
dest_path = derive_dest_path(template_path, plugin_info)
|
40
|
+
|
41
|
+
if File.directory?(template_path)
|
42
|
+
FileUtils.mkdir_p(dest_path)
|
43
|
+
else
|
44
|
+
copy_file(template_path, dest_path, plugin_info)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def derive_dest_path(template_path, plugin_info)
|
49
|
+
relative_template_path = template_path.gsub(@template_root, '')
|
50
|
+
replaced_path = replace_path_variables(relative_template_path, plugin_info)
|
51
|
+
|
52
|
+
File.join(@dest_root, plugin_info.gem_name, replaced_path)
|
53
|
+
end
|
54
|
+
|
55
|
+
def copy_file(template_path, dest_path, plugin_info)
|
56
|
+
contents = File.read(template_path)
|
57
|
+
|
58
|
+
if dest_path.end_with?('.erb')
|
59
|
+
contents = ERB.new(contents).result(plugin_info.get_binding)
|
60
|
+
dest_path = dest_path[0...-4] # Remove the .erb suffix
|
61
|
+
end
|
62
|
+
|
63
|
+
File.write(dest_path, contents)
|
64
|
+
end
|
65
|
+
|
66
|
+
# Path variables can be defined like: %gem_name%
|
67
|
+
#
|
68
|
+
# The text between the percent signs will be used to invoke an accessor
|
69
|
+
# method on the PluginInfo object to be the replacement value.
|
70
|
+
def replace_path_variables(template_path, plugin_info)
|
71
|
+
path = template_path.dup
|
72
|
+
|
73
|
+
loop do
|
74
|
+
replacement_variable_regexp = /%([\w\-]*)%/
|
75
|
+
match = replacement_variable_regexp.match(path)
|
76
|
+
|
77
|
+
break unless match
|
78
|
+
|
79
|
+
replacement_value = plugin_info.send(match[1].to_sym)
|
80
|
+
path.gsub!(replacement_variable_regexp, replacement_value)
|
81
|
+
end
|
82
|
+
|
83
|
+
path
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Fastlane
|
2
|
+
class PluginInfo
|
3
|
+
attr_reader :plugin_name
|
4
|
+
attr_reader :author
|
5
|
+
attr_reader :gem_name
|
6
|
+
attr_reader :email
|
7
|
+
attr_reader :summary
|
8
|
+
|
9
|
+
def initialize(plugin_name, author, email, summary)
|
10
|
+
@plugin_name = plugin_name
|
11
|
+
@author = author
|
12
|
+
@email = email
|
13
|
+
@summary = summary
|
14
|
+
end
|
15
|
+
|
16
|
+
def gem_name
|
17
|
+
"#{Fastlane::PluginManager::FASTLANE_PLUGIN_PREFIX}#{plugin_name}"
|
18
|
+
end
|
19
|
+
|
20
|
+
def require_path
|
21
|
+
gem_name.tr('-', '/')
|
22
|
+
end
|
23
|
+
|
24
|
+
def actions_path
|
25
|
+
File.join(require_path, 'actions')
|
26
|
+
end
|
27
|
+
|
28
|
+
def helper_path
|
29
|
+
File.join(require_path, 'helper')
|
30
|
+
end
|
31
|
+
|
32
|
+
# Used to expose a local binding for use in ERB templating
|
33
|
+
#
|
34
|
+
# rubocop:disable Style/AccessorMethodName
|
35
|
+
def get_binding
|
36
|
+
binding
|
37
|
+
end
|
38
|
+
# rubocop:enable Style/AccessorMethodName
|
39
|
+
|
40
|
+
def ==(other)
|
41
|
+
@plugin_name == other.plugin_name &&
|
42
|
+
@author == other.author &&
|
43
|
+
@email == other.email &&
|
44
|
+
@summary == other.summary
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|