fastlane 1.8.0 → 1.9.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/custom_action_template.rb +6 -0
- data/lib/fastlane.rb +1 -0
- data/lib/fastlane/actions/actions_helper.rb +13 -12
- data/lib/fastlane/actions/ensure_git_branch.rb +1 -2
- data/lib/fastlane/actions/get_github_release.rb +112 -0
- data/lib/fastlane/actions/git_branch.rb +41 -0
- data/lib/fastlane/{lane_context.rb → actions/lane_context.rb} +0 -0
- data/lib/fastlane/actions/prompt.rb +58 -0
- data/lib/fastlane/actions/puts.rb +25 -0
- data/lib/fastlane/actions/slack.rb +16 -2
- data/lib/fastlane/docs_generator.rb +4 -4
- data/lib/fastlane/fast_file.rb +39 -93
- data/lib/fastlane/fastlane_folder.rb +7 -5
- data/lib/fastlane/lane.rb +33 -0
- data/lib/fastlane/lane_list.rb +6 -10
- data/lib/fastlane/lane_manager.rb +1 -1
- data/lib/fastlane/runner.rb +134 -44
- data/lib/fastlane/version.rb +1 -1
- metadata +8 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: beef52022ff1b725c056cb6d6b76940e08a80e47
|
4
|
+
data.tar.gz: 7d3ae10b2bd5e238fb9476d14ea3133f53c3fb04
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0cd216d8caabb4f7cbfe99e0d9adf6bba9269fd75f0561939c4f7e0675c9b6bc156f9ec54de1533f3f2d1ef2f17567721799654ffbe2af178dd4e4fb7f086b59
|
7
|
+
data.tar.gz: f882d73eb82fc32a530ae6538060c3c9895fe5b222fcbab700253a8dd9e1f1145ade69dc74b0b11453dffc4942640669e520b9fefd4b2ab98d977b163e71dbd8
|
@@ -24,6 +24,12 @@ module Fastlane
|
|
24
24
|
"A short description with <= 80 characters of what this action does"
|
25
25
|
end
|
26
26
|
|
27
|
+
def self.details
|
28
|
+
# Optional:
|
29
|
+
# this is your change to provide a more detailed description of this action
|
30
|
+
"You can use this action to do cool things..."
|
31
|
+
end
|
32
|
+
|
27
33
|
def self.available_options
|
28
34
|
# Define all options your action supports.
|
29
35
|
|
data/lib/fastlane.rb
CHANGED
@@ -8,10 +8,7 @@ module Fastlane
|
|
8
8
|
ENVIRONMENT = :ENVIRONMENT
|
9
9
|
end
|
10
10
|
|
11
|
-
|
12
|
-
@executed_actions ||= []
|
13
|
-
end
|
14
|
-
|
11
|
+
# Helper Methods
|
15
12
|
def self.git_author
|
16
13
|
s = `git log --name-status HEAD^..HEAD`
|
17
14
|
s = s.match(/Author:.*<(.*)>/)[1]
|
@@ -27,6 +24,18 @@ module Fastlane
|
|
27
24
|
nil
|
28
25
|
end
|
29
26
|
|
27
|
+
# Returns the current git branch - can be replaced using the environment variable `GIT_BRANCH`
|
28
|
+
def self.git_branch
|
29
|
+
return ENV['GIT_BRANCH'] if ENV['GIT_BRANCH'].to_s.length > 0 # set by Jenkins
|
30
|
+
s = `git rev-parse --abbrev-ref HEAD`
|
31
|
+
return s.to_s.strip if s.to_s.length > 0
|
32
|
+
nil
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
def self.executed_actions
|
37
|
+
@executed_actions ||= []
|
38
|
+
end
|
30
39
|
|
31
40
|
# The shared hash can be accessed by any action and contains information like the screenshots path or beta URL
|
32
41
|
def self.lane_context
|
@@ -109,14 +118,6 @@ module Fastlane
|
|
109
118
|
Encoding.default_internal = previous_encoding.last
|
110
119
|
end
|
111
120
|
|
112
|
-
# Returns the current git branch - can be replaced using the environment variable `GIT_BRANCH`
|
113
|
-
def self.git_branch
|
114
|
-
return ENV['GIT_BRANCH'] if ENV['GIT_BRANCH'].to_s.length > 0 # set by Jenkins
|
115
|
-
s = `git rev-parse --abbrev-ref HEAD`
|
116
|
-
return s.to_s.strip if s.to_s.length > 0
|
117
|
-
nil
|
118
|
-
end
|
119
|
-
|
120
121
|
# returns a list of official integrations
|
121
122
|
def self.get_all_official_actions
|
122
123
|
Dir[File.expand_path '*.rb', File.dirname(__FILE__)].collect do |file|
|
@@ -7,9 +7,8 @@ module Fastlane
|
|
7
7
|
class EnsureGitBranchAction < Action
|
8
8
|
def self.run(params)
|
9
9
|
branch = params[:branch]
|
10
|
-
|
11
10
|
if Actions.git_branch != branch
|
12
|
-
raise "Git is not on the `#{branch}` branch
|
11
|
+
raise "Git is not on the `#{branch}` branch, but on `#{Actions.git_branch}`! Please ensure the repo is checked out to the correct branch.".red
|
13
12
|
else
|
14
13
|
Helper.log.info "Git branch is `#{branch}`, all good! 💪".green
|
15
14
|
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
module Fastlane
|
2
|
+
module Actions
|
3
|
+
module SharedValues
|
4
|
+
GET_GITHUB_RELEASE_INFO = :GET_GITHUB_RELEASE_INFO
|
5
|
+
end
|
6
|
+
|
7
|
+
class GetGithubReleaseAction < Action
|
8
|
+
def self.run(params)
|
9
|
+
Helper.log.info "Verifying release on GitHub (#{params[:url]}: #{params[:version]})"
|
10
|
+
require 'excon'
|
11
|
+
result = JSON.parse(Excon.get("https://api.github.com/repos/#{params[:url]}/releases").body)
|
12
|
+
result.each do |current|
|
13
|
+
if current['tag_name'] == params[:version]
|
14
|
+
# Found it
|
15
|
+
if current['body'].to_s.length > 0
|
16
|
+
Actions.lane_context[SharedValues::GET_GITHUB_RELEASE_INFO] = current
|
17
|
+
Helper.log.info "Version is already live on GitHub.com 🚁"
|
18
|
+
return current
|
19
|
+
else
|
20
|
+
raise "No release notes found for #{params[:version]}"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
Helper.log.error "Couldn't find GitHub release #{params[:version]}".yellow
|
26
|
+
return nil
|
27
|
+
end
|
28
|
+
|
29
|
+
#####################################################
|
30
|
+
# @!group Documentation
|
31
|
+
#####################################################
|
32
|
+
|
33
|
+
def self.description
|
34
|
+
"This will verify if a given release version is avialable on GitHub"
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.details
|
38
|
+
sample = '
|
39
|
+
{"url"=>"https://api.github.com/repos/KrauseFx/fastlane/releases/1537713",
|
40
|
+
"assets_url"=>"https://api.github.com/repos/KrauseFx/fastlane/releases/1537713/assets",
|
41
|
+
"upload_url"=>"https://uploads.github.com/repos/KrauseFx/fastlane/releases/1537713/assets{?name}",
|
42
|
+
"html_url"=>"https://github.com/KrauseFx/fastlane/releases/tag/1.8.0",
|
43
|
+
"id"=>1537713,
|
44
|
+
"tag_name"=>"1.8.0",
|
45
|
+
"target_commitish"=>"master",
|
46
|
+
"name"=>"1.8.0 Switch Lanes & Pass Parameters",
|
47
|
+
"draft"=>false,
|
48
|
+
"author"=>
|
49
|
+
{"login"=>"KrauseFx",
|
50
|
+
"id"=>869950,
|
51
|
+
"avatar_url"=>"https://avatars.githubusercontent.com/u/869950?v=3",
|
52
|
+
"gravatar_id"=>"",
|
53
|
+
"url"=>"https://api.github.com/users/KrauseFx",
|
54
|
+
"html_url"=>"https://github.com/KrauseFx",
|
55
|
+
"followers_url"=>"https://api.github.com/users/KrauseFx/followers",
|
56
|
+
"following_url"=>"https://api.github.com/users/KrauseFx/following{/other_user}",
|
57
|
+
"gists_url"=>"https://api.github.com/users/KrauseFx/gists{/gist_id}",
|
58
|
+
"starred_url"=>"https://api.github.com/users/KrauseFx/starred{/owner}{/repo}",
|
59
|
+
"subscriptions_url"=>"https://api.github.com/users/KrauseFx/subscriptions",
|
60
|
+
"organizations_url"=>"https://api.github.com/users/KrauseFx/orgs",
|
61
|
+
"repos_url"=>"https://api.github.com/users/KrauseFx/repos",
|
62
|
+
"events_url"=>"https://api.github.com/users/KrauseFx/events{/privacy}",
|
63
|
+
"received_events_url"=>"https://api.github.com/users/KrauseFx/received_events",
|
64
|
+
"type"=>"User",
|
65
|
+
"site_admin"=>false},
|
66
|
+
"prerelease"=>false,
|
67
|
+
"created_at"=>"2015-07-14T23:33:01Z",
|
68
|
+
"published_at"=>"2015-07-14T23:44:10Z",
|
69
|
+
"assets"=>[],
|
70
|
+
"tarball_url"=>"https://api.github.com/repos/KrauseFx/fastlane/tarball/1.8.0",
|
71
|
+
"zipball_url"=>"https://api.github.com/repos/KrauseFx/fastlane/zipball/1.8.0",
|
72
|
+
"body"=>
|
73
|
+
"This is one of the biggest updates of `fastlane` yet"
|
74
|
+
}'
|
75
|
+
|
76
|
+
[
|
77
|
+
"This will return all information about a release. For example:",
|
78
|
+
sample
|
79
|
+
].join("\n")
|
80
|
+
end
|
81
|
+
|
82
|
+
def self.output
|
83
|
+
[
|
84
|
+
['GET_GITHUB_RELEASE_INFO', 'Contains all the information about this release']
|
85
|
+
]
|
86
|
+
end
|
87
|
+
|
88
|
+
def self.available_options
|
89
|
+
[
|
90
|
+
FastlaneCore::ConfigItem.new(key: :url,
|
91
|
+
env_name: "FL_GET_GITHUB_RELEASE_URL",
|
92
|
+
description: "The path to your repo, e.g. 'KrauseFx/fastlane'",
|
93
|
+
verify_block: Proc.new do |value|
|
94
|
+
raise "Please only pass the path, e.g. 'KrauseFx/fastlane'".red if value.include?"github.com"
|
95
|
+
raise "Please only pass the path, e.g. 'KrauseFx/fastlane'".red if value.split('/').count != 2
|
96
|
+
end),
|
97
|
+
FastlaneCore::ConfigItem.new(key: :version,
|
98
|
+
env_name: "FL_GET_GITHUB_RELEASE_VERSION",
|
99
|
+
description: "The version tag of the release to check")
|
100
|
+
]
|
101
|
+
end
|
102
|
+
|
103
|
+
def self.authors
|
104
|
+
["KrauseFx"]
|
105
|
+
end
|
106
|
+
|
107
|
+
def self.is_supported?(platform)
|
108
|
+
true
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Fastlane
|
2
|
+
module Actions
|
3
|
+
module SharedValues
|
4
|
+
|
5
|
+
end
|
6
|
+
|
7
|
+
class GitBranchAction < Action
|
8
|
+
def self.run(params)
|
9
|
+
ENV['GIT_BRANCH'] or `git symbolic-ref HEAD --short 2>/dev/null`.strip
|
10
|
+
end
|
11
|
+
|
12
|
+
#####################################################
|
13
|
+
# @!group Documentation
|
14
|
+
#####################################################
|
15
|
+
|
16
|
+
def self.description
|
17
|
+
"Returns the name of the current git branch"
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.details
|
21
|
+
"If no branch could be found, this action will return nil"
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.available_options
|
25
|
+
[]
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.output
|
29
|
+
[]
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.authors
|
33
|
+
["KrauseFx"]
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.is_supported?(platform)
|
37
|
+
true
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
File without changes
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Fastlane
|
2
|
+
module Actions
|
3
|
+
class PromptAction < Action
|
4
|
+
def self.run(params)
|
5
|
+
params[:text] += " (y/n)" if params[:boolean]
|
6
|
+
Helper.log.info params[:text]
|
7
|
+
|
8
|
+
user_input = params[:ci_input] if Helper.is_ci?
|
9
|
+
user_input ||= STDIN.gets.chomp.strip
|
10
|
+
|
11
|
+
user_input = (user_input.downcase == 'y') if params[:boolean]
|
12
|
+
|
13
|
+
return user_input
|
14
|
+
end
|
15
|
+
|
16
|
+
#####################################################
|
17
|
+
# @!group Documentation
|
18
|
+
#####################################################
|
19
|
+
|
20
|
+
def self.description
|
21
|
+
"Ask the user for a value or for confirmation"
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.details
|
25
|
+
[
|
26
|
+
"You can use `prompt` to ask the user for a value or to just let the user confirm the next step",
|
27
|
+
"When this is executed on a CI service, the passed `ci_input` value will be returned"
|
28
|
+
].join("\n")
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.available_options
|
32
|
+
[
|
33
|
+
FastlaneCore::ConfigItem.new(key: :text,
|
34
|
+
description: "The text that will be displayed to the user"),
|
35
|
+
FastlaneCore::ConfigItem.new(key: :ci_input,
|
36
|
+
description: "The default text that will be used when being executed on a CI service",
|
37
|
+
default_value: ''),
|
38
|
+
FastlaneCore::ConfigItem.new(key: :boolean,
|
39
|
+
description: "Is that a boolean question (yes/no)? This will add (y/n) at the end",
|
40
|
+
default_value: false,
|
41
|
+
is_string: false)
|
42
|
+
]
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.output
|
46
|
+
[]
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.authors
|
50
|
+
["KrauseFx"]
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.is_supported?(platform)
|
54
|
+
true
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Fastlane
|
2
|
+
module Actions
|
3
|
+
class PutsAction < Action
|
4
|
+
def self.run(params)
|
5
|
+
Helper.log.info params.join(' ')
|
6
|
+
end
|
7
|
+
|
8
|
+
#####################################################
|
9
|
+
# @!group Documentation
|
10
|
+
#####################################################
|
11
|
+
|
12
|
+
def self.description
|
13
|
+
"Prints out the given text"
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.authors
|
17
|
+
["KrauseFx"]
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.is_supported?(platform)
|
21
|
+
true
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -82,6 +82,11 @@ module Fastlane
|
|
82
82
|
description: "Remove some of the default payloads. More information about the available payloads on GitHub",
|
83
83
|
optional: true,
|
84
84
|
is_string: false),
|
85
|
+
FastlaneCore::ConfigItem.new(key: :attachment_properties,
|
86
|
+
env_name: "FL_SLACK_ATTACHMENT_PROPERTIES",
|
87
|
+
description: "Merge additional properties in the slack attachment, see https://api.slack.com/docs/attachments",
|
88
|
+
default_value: {},
|
89
|
+
is_string: false),
|
85
90
|
FastlaneCore::ConfigItem.new(key: :success,
|
86
91
|
env_name: "FL_SLACK_SUCCESS",
|
87
92
|
description: "Was this build successful? (true/false)",
|
@@ -128,7 +133,7 @@ module Fastlane
|
|
128
133
|
# test_result
|
129
134
|
if should_add_payload[:test_result]
|
130
135
|
slack_attachment[:fields] << {
|
131
|
-
title: '
|
136
|
+
title: 'Result',
|
132
137
|
value: (options[:success] ? 'Success' : 'Error'),
|
133
138
|
short: true
|
134
139
|
}
|
@@ -165,7 +170,16 @@ module Fastlane
|
|
165
170
|
}
|
166
171
|
end
|
167
172
|
|
168
|
-
|
173
|
+
# merge additional properties
|
174
|
+
deep_merge(slack_attachment, options[:attachment_properties])
|
175
|
+
end
|
176
|
+
|
177
|
+
# Adapted from http://stackoverflow.com/a/30225093/158525
|
178
|
+
def self.deep_merge(a, b)
|
179
|
+
merger = proc { |key, v1, v2| Hash === v1 && Hash === v2 ?
|
180
|
+
v1.merge(v2, &merger) : Array === v1 && Array === v2 ?
|
181
|
+
v1 | v2 : [:undefined, nil, :nil].include?(v2) ? v1 : v2 }
|
182
|
+
a.merge(b, &merger)
|
169
183
|
end
|
170
184
|
end
|
171
185
|
end
|
@@ -11,17 +11,17 @@ module Fastlane
|
|
11
11
|
|
12
12
|
output << "# Available Actions"
|
13
13
|
|
14
|
-
all_keys = ff.runner.
|
14
|
+
all_keys = ff.runner.lanes.keys.reject(&:nil?)
|
15
15
|
all_keys.unshift(nil) # because we want root elements on top. always! They have key nil
|
16
16
|
|
17
17
|
all_keys.each do |platform|
|
18
18
|
output << "## #{formatted_platform(platform)}" if platform
|
19
19
|
|
20
|
-
value = ff.runner.
|
20
|
+
value = ff.runner.lanes[platform]
|
21
21
|
|
22
22
|
if value
|
23
|
-
value.each do |
|
24
|
-
output << render(platform,
|
23
|
+
value.each do |lane_name, lane|
|
24
|
+
output << render(platform, lane_name, lane.description.join("\n\n"))
|
25
25
|
end
|
26
26
|
|
27
27
|
output << ""
|
data/lib/fastlane/fast_file.rb
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
module Fastlane
|
2
2
|
class FastFile
|
3
|
+
# Stores all relevant information from the currently running process
|
3
4
|
attr_accessor :runner
|
4
5
|
|
6
|
+
# the platform in which we're currently in when parsing the Fastfile
|
7
|
+
# This is used to identify the platform in which the lane is in
|
8
|
+
attr_accessor :current_platform
|
9
|
+
|
5
10
|
SharedValues = Fastlane::Actions::SharedValues
|
6
11
|
|
7
12
|
# @return The runner which can be executed to trigger the given actions
|
@@ -34,10 +39,10 @@ module Fastlane
|
|
34
39
|
def lane(lane_name, &block)
|
35
40
|
raise "You have to pass a block using 'do' for lane '#{lane_name}'. Make sure you read the docs on GitHub.".red unless block
|
36
41
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
42
|
+
self.runner.add_lane(Lane.new(platform: self.current_platform,
|
43
|
+
block: block,
|
44
|
+
description: desc_collection,
|
45
|
+
name: lane_name))
|
41
46
|
|
42
47
|
@desc_collection = nil # reset the collected description again for the next lane
|
43
48
|
end
|
@@ -46,11 +51,11 @@ module Fastlane
|
|
46
51
|
def platform(platform_name, &block)
|
47
52
|
SupportedPlatforms.verify!platform_name
|
48
53
|
|
49
|
-
|
54
|
+
self.current_platform = platform_name
|
50
55
|
|
51
56
|
block.call
|
52
57
|
|
53
|
-
|
58
|
+
self.current_platform = nil
|
54
59
|
end
|
55
60
|
|
56
61
|
# Is executed before each test run
|
@@ -68,61 +73,6 @@ module Fastlane
|
|
68
73
|
@runner.set_error(@current_platform, block)
|
69
74
|
end
|
70
75
|
|
71
|
-
def try_switch_to_lane(new_lane, parameters)
|
72
|
-
current_platform = Actions.lane_context[Actions::SharedValues::PLATFORM_NAME]
|
73
|
-
block = @runner.blocks.fetch(current_platform, {}).fetch(new_lane, nil)
|
74
|
-
platform_nil = (block == nil) # used for the output
|
75
|
-
block ||= @runner.blocks.fetch(nil, {}).fetch(new_lane, nil) # fallback to general lane for multiple platforms
|
76
|
-
if block
|
77
|
-
pretty = [new_lane]
|
78
|
-
pretty = [current_platform, new_lane] unless platform_nil
|
79
|
-
Helper.log.info "Cruising over to lane '#{pretty.join(' ')}' 🚖".green
|
80
|
-
collector.did_launch_action(:lane_switch)
|
81
|
-
result = block.call(parameters.first || {}) # to always pass a hash
|
82
|
-
original_lane = Actions.lane_context[Actions::SharedValues::LANE_NAME]
|
83
|
-
Helper.log.info "Cruising back to lane '#{original_lane}' 🚘".green
|
84
|
-
return result
|
85
|
-
else
|
86
|
-
# No action and no lane, raising an exception now
|
87
|
-
raise "Could not find action or lane '#{new_lane}'. Check out the README for more details: https://github.com/KrauseFx/fastlane".red
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
def execute_action(method_sym, class_ref, arguments)
|
92
|
-
collector.did_launch_action(method_sym)
|
93
|
-
|
94
|
-
step_name = class_ref.step_text rescue nil
|
95
|
-
step_name = method_sym.to_s unless step_name
|
96
|
-
|
97
|
-
verify_supported_os(method_sym, class_ref)
|
98
|
-
|
99
|
-
Helper.log_alert("Step: " + step_name)
|
100
|
-
|
101
|
-
begin
|
102
|
-
Dir.chdir('..') do # go up from the fastlane folder, to the project folder
|
103
|
-
Actions.execute_action(method_sym) do
|
104
|
-
# arguments is an array by default, containing an hash with the actual parameters
|
105
|
-
# Since we usually just need the passed hash, we'll just use the first object if there is only one
|
106
|
-
if arguments.count == 0
|
107
|
-
arguments = ConfigurationHelper.parse(class_ref, {}) # no parameters => empty hash
|
108
|
-
elsif arguments.count == 1 and arguments.first.kind_of?Hash
|
109
|
-
arguments = ConfigurationHelper.parse(class_ref, arguments.first) # Correct configuration passed
|
110
|
-
elsif not class_ref.available_options
|
111
|
-
# This action does not use the new action format
|
112
|
-
# Just passing the arguments to this method
|
113
|
-
else
|
114
|
-
raise "You have to pass the options for '#{method_sym}' in a different way. Please check out the current documentation on GitHub!".red
|
115
|
-
end
|
116
|
-
|
117
|
-
class_ref.run(arguments)
|
118
|
-
end
|
119
|
-
end
|
120
|
-
rescue => ex
|
121
|
-
collector.did_raise_error(method_sym)
|
122
|
-
raise ex
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
76
|
# Is used to look if the method is implemented as an action
|
127
77
|
def method_missing(method_sym, *arguments, &_block)
|
128
78
|
# First, check if there is a predefined method in the actions folder
|
@@ -132,14 +82,14 @@ module Fastlane
|
|
132
82
|
class_ref = Fastlane::Actions.const_get(class_name)
|
133
83
|
if class_ref && class_ref.respond_to?(:run)
|
134
84
|
# Action is available, now execute it
|
135
|
-
return execute_action(method_sym, class_ref, arguments)
|
85
|
+
return self.runner.execute_action(method_sym, class_ref, arguments)
|
136
86
|
else
|
137
87
|
raise "Action '#{method_sym}' of class '#{class_name}' was found, but has no `run` method.".red
|
138
88
|
end
|
139
89
|
rescue NameError => ex
|
140
90
|
# Action not found
|
141
91
|
# Is there a lane under this name?
|
142
|
-
return try_switch_to_lane(method_sym, arguments)
|
92
|
+
return self.runner.try_switch_to_lane(method_sym, arguments)
|
143
93
|
end
|
144
94
|
end
|
145
95
|
|
@@ -147,21 +97,16 @@ module Fastlane
|
|
147
97
|
# @!group Other things
|
148
98
|
#####################################################
|
149
99
|
|
150
|
-
|
151
|
-
|
152
|
-
# Overwrite this, since there is already a 'say' method defined in the Ruby standard library
|
153
|
-
value ||= yield
|
154
|
-
Actions.execute_action('say') do
|
155
|
-
Fastlane::Actions::SayAction.run([value])
|
156
|
-
end
|
100
|
+
def collector
|
101
|
+
runner.collector
|
157
102
|
end
|
158
103
|
|
159
104
|
# Is the given key a platform block or a lane?
|
160
105
|
def is_platform_block?(key)
|
161
106
|
raise 'No key given'.red unless key
|
162
107
|
|
163
|
-
return false if (self.runner.
|
164
|
-
return true if self.runner.
|
108
|
+
return false if (self.runner.lanes[nil][key.to_sym] rescue false)
|
109
|
+
return true if self.runner.lanes[key.to_sym].kind_of?Hash
|
165
110
|
|
166
111
|
raise "Could not find '#{key}'. Available lanes: #{self.runner.available_lanes.join(', ')}".red
|
167
112
|
end
|
@@ -179,34 +124,35 @@ module Fastlane
|
|
179
124
|
end
|
180
125
|
end
|
181
126
|
|
182
|
-
def
|
183
|
-
|
184
|
-
if Actions.lane_context[Actions::SharedValues::PLATFORM_NAME]
|
185
|
-
# This value is filled in based on the executed platform block. Might be nil when lane is in root of Fastfile
|
186
|
-
platform = Actions.lane_context[Actions::SharedValues::PLATFORM_NAME]
|
187
|
-
|
188
|
-
unless class_ref.is_supported?(platform)
|
189
|
-
raise "Action '#{name}' doesn't support required operating system '#{platform}'.".red
|
190
|
-
end
|
191
|
-
end
|
192
|
-
end
|
127
|
+
def desc(string)
|
128
|
+
desc_collection << string
|
193
129
|
end
|
194
130
|
|
195
|
-
|
196
|
-
|
197
|
-
collector.did_finish
|
131
|
+
def desc_collection
|
132
|
+
@desc_collection ||= []
|
198
133
|
end
|
199
134
|
|
200
|
-
|
201
|
-
|
202
|
-
|
135
|
+
#####################################################
|
136
|
+
# @!group Overwriting Ruby methods
|
137
|
+
#####################################################
|
203
138
|
|
204
|
-
|
205
|
-
|
139
|
+
# Speak out loud
|
140
|
+
def say(value)
|
141
|
+
# Overwrite this, since there is already a 'say' method defined in the Ruby standard library
|
142
|
+
value ||= yield
|
143
|
+
Actions.execute_action('say') do
|
144
|
+
collector.did_launch_action(:say)
|
145
|
+
Fastlane::Actions::SayAction.run([value])
|
146
|
+
end
|
206
147
|
end
|
207
148
|
|
208
|
-
def
|
209
|
-
|
149
|
+
def puts(value)
|
150
|
+
# Overwrite this, since there is already a 'puts' method defined in the Ruby standard library
|
151
|
+
value ||= yield
|
152
|
+
Actions.execute_action('puts') do
|
153
|
+
collector.did_launch_action(:pus)
|
154
|
+
Fastlane::Actions::PutsAction.run([value])
|
155
|
+
end
|
210
156
|
end
|
211
157
|
end
|
212
158
|
end
|
@@ -4,11 +4,13 @@ module Fastlane
|
|
4
4
|
|
5
5
|
# Path to the fastlane folder containing the Fastfile and other configuration files
|
6
6
|
def self.path
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
7
|
+
value ||= "./#{FOLDER_NAME}/" if File.directory?("./#{FOLDER_NAME}/")
|
8
|
+
value ||= "./.#{FOLDER_NAME}/" if File.directory?("./.#{FOLDER_NAME}/") # hidden folder
|
9
|
+
value ||= "./" if File.basename(Dir.getwd) == FOLDER_NAME && File.exist?('Fastfile') # inside the folder
|
10
|
+
value ||= "./" if File.basename(Dir.getwd) == ".#{FOLDER_NAME}" && File.exist?('Fastfile') # inside the folder and hidden
|
11
|
+
|
12
|
+
value = nil if Helper.is_test? # this is required, as the tests would use the ./fastlane folder otherwise
|
13
|
+
return value
|
12
14
|
end
|
13
15
|
|
14
16
|
# Does a fastlane configuration already exist?
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Fastlane
|
2
|
+
# Represents a lane
|
3
|
+
class Lane
|
4
|
+
attr_accessor :platform
|
5
|
+
|
6
|
+
attr_accessor :name
|
7
|
+
|
8
|
+
# @return (Array) An array containing the description of this lane
|
9
|
+
# Each item of the array is one line
|
10
|
+
attr_accessor :description
|
11
|
+
|
12
|
+
attr_accessor :block
|
13
|
+
|
14
|
+
def initialize(platform: nil, name: nil, description: nil, block: nil)
|
15
|
+
raise "description must be an array" unless description.kind_of?Array
|
16
|
+
|
17
|
+
self.platform = platform
|
18
|
+
self.name = name
|
19
|
+
self.description = description
|
20
|
+
self.block = block
|
21
|
+
end
|
22
|
+
|
23
|
+
# Execute this lane
|
24
|
+
def call(parameters)
|
25
|
+
block.call(parameters || {})
|
26
|
+
end
|
27
|
+
|
28
|
+
# @return [String] The lane + name of the lane. If there is no platform, it will only be the lane name
|
29
|
+
def pretty_name
|
30
|
+
[platform, name].reject(&:nil?).join(' ')
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/fastlane/lane_list.rb
CHANGED
@@ -12,25 +12,21 @@ module Fastlane
|
|
12
12
|
ff = Fastlane::FastFile.new(path)
|
13
13
|
output = ""
|
14
14
|
|
15
|
-
all_keys = ff.runner.
|
15
|
+
all_keys = ff.runner.lanes.keys.reject(&:nil?)
|
16
16
|
all_keys.unshift(nil) # because we want root elements on top. always! They have key nil
|
17
17
|
|
18
18
|
all_keys.each do |platform|
|
19
|
-
next if (ff.runner.
|
19
|
+
next if (ff.runner.lanes[platform] || []).count == 0
|
20
20
|
plat_text = platform
|
21
21
|
plat_text = "general" if platform.to_s.empty?
|
22
22
|
output += "\n--------- #{plat_text}---------\n".yellow
|
23
23
|
|
24
|
-
value = ff.runner.
|
24
|
+
value = ff.runner.lanes[platform]
|
25
25
|
|
26
26
|
if value
|
27
|
-
value.each do |
|
28
|
-
|
29
|
-
|
30
|
-
lane_text += lane.to_s + "\n"
|
31
|
-
|
32
|
-
output += lane_text.green
|
33
|
-
output += description.gsub("\n\n", "\n") + "\n\n" if description.to_s.length > 0
|
27
|
+
value.each do |lane_name, lane|
|
28
|
+
output += "----- fastlane #{lane.pretty_name}".green
|
29
|
+
output += "\n" + lane.description.join("\n") + "\n\n" if lane.description.count > 0
|
34
30
|
end
|
35
31
|
end
|
36
32
|
end
|
@@ -50,7 +50,7 @@ module Fastlane
|
|
50
50
|
|
51
51
|
# All the finishing up that needs to be done
|
52
52
|
def self.finish_fastlane(ff, duration, error)
|
53
|
-
ff.did_finish
|
53
|
+
ff.runner.did_finish
|
54
54
|
|
55
55
|
# Finished with all the lanes
|
56
56
|
Fastlane::JUnitGenerator.generate(Fastlane::Actions.executed_actions)
|
data/lib/fastlane/runner.rb
CHANGED
@@ -1,48 +1,56 @@
|
|
1
1
|
module Fastlane
|
2
2
|
class Runner
|
3
|
+
# Symbol for the current lane
|
4
|
+
attr_accessor :current_lane
|
3
5
|
|
4
|
-
#
|
6
|
+
# Symbol for the current platform
|
7
|
+
attr_accessor :current_platform
|
8
|
+
|
9
|
+
# @return [Hash] All the lanes available, first the platform, then the lane
|
10
|
+
attr_accessor :lanes
|
11
|
+
|
12
|
+
def full_lane_name
|
13
|
+
[current_platform, current_lane].reject(&:nil?).join(' ')
|
14
|
+
end
|
15
|
+
|
16
|
+
# This will take care of executing **one** lane. That's when the user triggers a lane from the CLI for example
|
17
|
+
# This method is **not** executed when switching a lane
|
5
18
|
# @param lane_name The name of the lane to execute
|
6
19
|
# @param platform The name of the platform to execute
|
7
20
|
# @param parameters [Hash] The parameters passed from the command line to the lane
|
8
21
|
def execute(lane, platform = nil, parameters = nil)
|
9
22
|
raise "No lane given" unless lane
|
10
23
|
|
11
|
-
|
12
|
-
|
13
|
-
ENV["FASTLANE_PLATFORM_NAME"] = platform.to_s
|
14
|
-
else
|
15
|
-
ENV["FASTLANE_PLATFORM_NAME"] = nil
|
16
|
-
end
|
17
|
-
|
18
|
-
lane = lane.to_sym
|
19
|
-
platform = platform.to_sym if platform # might be nil, which is okay => root element
|
24
|
+
self.current_lane = lane.to_sym
|
25
|
+
self.current_platform = (platform ? platform.to_sym : nil)
|
20
26
|
|
21
|
-
|
27
|
+
ENV["FASTLANE_LANE_NAME"] = current_lane.to_s
|
28
|
+
ENV["FASTLANE_PLATFORM_NAME"] = (current_platform ? current_platform.to_s : nil)
|
29
|
+
|
30
|
+
Actions.lane_context[Actions::SharedValues::PLATFORM_NAME] = current_platform
|
31
|
+
Actions.lane_context[Actions::SharedValues::LANE_NAME] = full_lane_name
|
22
32
|
|
23
|
-
full_lane_name = [platform, lane].reject(&:nil?).join(' ')
|
24
33
|
Helper.log.info "Driving the lane '#{full_lane_name}' 🚀".green
|
25
|
-
Actions.lane_context[Actions::SharedValues::LANE_NAME] = full_lane_name
|
26
34
|
|
27
35
|
return_val = nil
|
28
36
|
|
29
37
|
path_to_use = Fastlane::FastlaneFolder.path || Dir.pwd
|
30
38
|
Dir.chdir(path_to_use) do # the file is located in the fastlane folder
|
31
39
|
|
32
|
-
unless (
|
40
|
+
unless (lanes[current_platform][current_lane] rescue nil)
|
33
41
|
raise "Could not find lane '#{full_lane_name}'. Available lanes: #{available_lanes.join(', ')}".red
|
34
42
|
end
|
35
43
|
|
36
44
|
# Call the platform specific before_all block and then the general one
|
37
|
-
before_all_blocks[
|
38
|
-
before_all_blocks[nil].call(
|
45
|
+
before_all_blocks[current_platform].call(current_lane) if (before_all_blocks[current_platform] and current_platform)
|
46
|
+
before_all_blocks[nil].call(current_lane) if before_all_blocks[nil]
|
39
47
|
|
40
|
-
return_val =
|
48
|
+
return_val = lanes[current_platform][current_lane].call(parameters || {}) # by default no parameters
|
41
49
|
|
42
50
|
# `after_all` is only called if no exception was raised before
|
43
51
|
# Call the platform specific before_all block and then the general one
|
44
|
-
after_all_blocks[
|
45
|
-
after_all_blocks[nil].call(
|
52
|
+
after_all_blocks[current_platform].call(current_lane) if (after_all_blocks[current_platform] and current_platform)
|
53
|
+
after_all_blocks[nil].call(current_lane) if (after_all_blocks[nil])
|
46
54
|
end
|
47
55
|
|
48
56
|
return return_val
|
@@ -51,26 +59,126 @@ module Fastlane
|
|
51
59
|
# Provide error block exception without colour code
|
52
60
|
error_ex = ex.exception(ex.message.gsub(/\033\[\d+m/, ''))
|
53
61
|
|
54
|
-
error_blocks[
|
55
|
-
error_blocks[nil].call(
|
62
|
+
error_blocks[current_platform].call(current_lane, error_ex) if (error_blocks[current_platform] and current_platform)
|
63
|
+
error_blocks[nil].call(current_lane, error_ex) if error_blocks[nil]
|
56
64
|
end
|
57
65
|
raise ex
|
58
66
|
end
|
59
67
|
|
60
68
|
# @param filter_platform: Filter, to only show the lanes of a given platform
|
69
|
+
# @return an array of lanes (platform lane_name) to print them out to the user
|
61
70
|
def available_lanes(filter_platform = nil)
|
62
71
|
all = []
|
63
|
-
|
72
|
+
lanes.each do |platform, platform_lanes|
|
64
73
|
next if (filter_platform and filter_platform.to_s != platform.to_s) # skip actions that don't match
|
65
74
|
|
66
|
-
|
75
|
+
platform_lanes.each do |lane_name, lane|
|
67
76
|
all << [platform, lane_name].reject(&:nil?).join(' ')
|
68
77
|
end
|
69
78
|
end
|
70
79
|
all
|
71
80
|
end
|
72
81
|
|
73
|
-
#
|
82
|
+
#
|
83
|
+
# All the methods that are usually called on execution
|
84
|
+
#
|
85
|
+
|
86
|
+
def try_switch_to_lane(new_lane, parameters)
|
87
|
+
block = lanes.fetch(current_platform, {}).fetch(new_lane, nil)
|
88
|
+
block ||= lanes.fetch(nil, {}).fetch(new_lane, nil) # fallback to general lane for multiple platforms
|
89
|
+
if block
|
90
|
+
original_full = full_lane_name
|
91
|
+
original_lane = current_lane
|
92
|
+
|
93
|
+
raise "Parameters for a lane must always be a hash".red unless (parameters.first || {}).kind_of?Hash
|
94
|
+
|
95
|
+
pretty = [new_lane]
|
96
|
+
pretty = [current_platform, new_lane] if current_platform
|
97
|
+
Helper.log.info "Cruising over to lane '#{pretty.join(' ')}' 🚖".green
|
98
|
+
|
99
|
+
# Actually switch lane now
|
100
|
+
current_lane = new_lane
|
101
|
+
collector.did_launch_action(:lane_switch)
|
102
|
+
result = block.call(parameters.first || {}) # to always pass a hash
|
103
|
+
current_lane = original_lane
|
104
|
+
|
105
|
+
Helper.log.info "Cruising back to lane '#{original_full}' 🚘".green
|
106
|
+
return result
|
107
|
+
else
|
108
|
+
# No action and no lane, raising an exception now
|
109
|
+
raise "Could not find action or lane '#{new_lane}'. Check out the README for more details: https://github.com/KrauseFx/fastlane".red
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def execute_action(method_sym, class_ref, arguments)
|
114
|
+
collector.did_launch_action(method_sym)
|
115
|
+
|
116
|
+
step_name = class_ref.step_text rescue nil
|
117
|
+
step_name = method_sym.to_s unless step_name
|
118
|
+
|
119
|
+
verify_supported_os(method_sym, class_ref)
|
120
|
+
|
121
|
+
Helper.log_alert("Step: " + step_name)
|
122
|
+
|
123
|
+
begin
|
124
|
+
Dir.chdir('..') do # go up from the fastlane folder, to the project folder
|
125
|
+
Actions.execute_action(method_sym) do
|
126
|
+
# arguments is an array by default, containing an hash with the actual parameters
|
127
|
+
# Since we usually just need the passed hash, we'll just use the first object if there is only one
|
128
|
+
if arguments.count == 0
|
129
|
+
arguments = ConfigurationHelper.parse(class_ref, {}) # no parameters => empty hash
|
130
|
+
elsif arguments.count == 1 and arguments.first.kind_of?Hash
|
131
|
+
arguments = ConfigurationHelper.parse(class_ref, arguments.first) # Correct configuration passed
|
132
|
+
elsif not class_ref.available_options
|
133
|
+
# This action does not use the new action format
|
134
|
+
# Just passing the arguments to this method
|
135
|
+
else
|
136
|
+
raise "You have to pass the options for '#{method_sym}' in a different way. Please check out the current documentation on GitHub!".red
|
137
|
+
end
|
138
|
+
|
139
|
+
class_ref.run(arguments)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
rescue => ex
|
143
|
+
collector.did_raise_error(method_sym)
|
144
|
+
raise ex
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def verify_supported_os(name, class_ref)
|
149
|
+
if class_ref.respond_to?(:is_supported?)
|
150
|
+
if Actions.lane_context[Actions::SharedValues::PLATFORM_NAME]
|
151
|
+
# This value is filled in based on the executed platform block. Might be nil when lane is in root of Fastfile
|
152
|
+
platform = Actions.lane_context[Actions::SharedValues::PLATFORM_NAME]
|
153
|
+
|
154
|
+
unless class_ref.is_supported?(platform)
|
155
|
+
raise "Action '#{name}' doesn't support required operating system '#{platform}'.".red
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
def collector
|
162
|
+
@collector ||= ActionCollector.new
|
163
|
+
end
|
164
|
+
|
165
|
+
# Fastfile was finished executing
|
166
|
+
def did_finish
|
167
|
+
collector.did_finish
|
168
|
+
end
|
169
|
+
|
170
|
+
# Called internally to setup the runner object
|
171
|
+
#
|
172
|
+
|
173
|
+
# @param lane [Lane] A lane object
|
174
|
+
def add_lane(lane)
|
175
|
+
lanes[lane.platform] ||= {}
|
176
|
+
|
177
|
+
raise "Lane '#{lane.name}' was defined multiple times!".red if lanes[lane.platform][lane.name]
|
178
|
+
|
179
|
+
lanes[lane.platform][lane.name] = lane
|
180
|
+
end
|
181
|
+
|
74
182
|
def set_before_all(platform, block)
|
75
183
|
before_all_blocks[platform] = block
|
76
184
|
end
|
@@ -83,22 +191,8 @@ module Fastlane
|
|
83
191
|
error_blocks[platform] = block
|
84
192
|
end
|
85
193
|
|
86
|
-
|
87
|
-
|
88
|
-
# @param block: The block of the lane
|
89
|
-
# @param desc: Description of this action
|
90
|
-
def set_block(lane, platform, block, desc = nil)
|
91
|
-
blocks[platform] ||= {}
|
92
|
-
description_blocks[platform] ||= {}
|
93
|
-
|
94
|
-
raise "Lane '#{lane}' was defined multiple times!".red if blocks[platform][lane]
|
95
|
-
|
96
|
-
blocks[platform][lane] = block
|
97
|
-
description_blocks[platform][lane] = desc
|
98
|
-
end
|
99
|
-
|
100
|
-
def blocks
|
101
|
-
@blocks ||= {}
|
194
|
+
def lanes
|
195
|
+
@lanes ||= {}
|
102
196
|
end
|
103
197
|
|
104
198
|
def before_all_blocks
|
@@ -112,9 +206,5 @@ module Fastlane
|
|
112
206
|
def error_blocks
|
113
207
|
@error_blocks ||= {}
|
114
208
|
end
|
115
|
-
|
116
|
-
def description_blocks
|
117
|
-
@description_blocks ||= {}
|
118
|
-
end
|
119
209
|
end
|
120
210
|
end
|
data/lib/fastlane/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fastlane
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Felix Krause
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-07-
|
11
|
+
date: 2015-07-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|
@@ -430,6 +430,8 @@ files:
|
|
430
430
|
- lib/fastlane/actions/fastlane_version.rb
|
431
431
|
- lib/fastlane/actions/frameit.rb
|
432
432
|
- lib/fastlane/actions/gcovr.rb
|
433
|
+
- lib/fastlane/actions/get_github_release.rb
|
434
|
+
- lib/fastlane/actions/git_branch.rb
|
433
435
|
- lib/fastlane/actions/hg_add_tag.rb
|
434
436
|
- lib/fastlane/actions/hg_commit_version_bump.rb
|
435
437
|
- lib/fastlane/actions/hg_ensure_clean_status.rb
|
@@ -442,6 +444,7 @@ files:
|
|
442
444
|
- lib/fastlane/actions/install_carthage.rb
|
443
445
|
- lib/fastlane/actions/install_cocapods.rb
|
444
446
|
- lib/fastlane/actions/ipa.rb
|
447
|
+
- lib/fastlane/actions/lane_context.rb
|
445
448
|
- lib/fastlane/actions/lcov.rb
|
446
449
|
- lib/fastlane/actions/mailgun.rb
|
447
450
|
- lib/fastlane/actions/notify.rb
|
@@ -449,7 +452,9 @@ files:
|
|
449
452
|
- lib/fastlane/actions/opt_out_usage.rb
|
450
453
|
- lib/fastlane/actions/pem.rb
|
451
454
|
- lib/fastlane/actions/produce.rb
|
455
|
+
- lib/fastlane/actions/prompt.rb
|
452
456
|
- lib/fastlane/actions/push_to_git_remote.rb
|
457
|
+
- lib/fastlane/actions/puts.rb
|
453
458
|
- lib/fastlane/actions/register_devices.rb
|
454
459
|
- lib/fastlane/actions/reset_git_repo.rb
|
455
460
|
- lib/fastlane/actions/resign.rb
|
@@ -483,7 +488,7 @@ files:
|
|
483
488
|
- lib/fastlane/fast_file.rb
|
484
489
|
- lib/fastlane/fastlane_folder.rb
|
485
490
|
- lib/fastlane/junit_generator.rb
|
486
|
-
- lib/fastlane/
|
491
|
+
- lib/fastlane/lane.rb
|
487
492
|
- lib/fastlane/lane_list.rb
|
488
493
|
- lib/fastlane/lane_manager.rb
|
489
494
|
- lib/fastlane/new_action.rb
|