Class: Fastlane::Setup
- Inherits:
-
Object
- Object
- Fastlane::Setup
- Defined in:
- fastlane/lib/fastlane/setup/setup.rb
Direct Known Subclasses
Instance Attribute Summary collapse
-
#appfile_content ⇒ Object
Appfile.
-
#fastfile_content ⇒ Object
The current content of the generated Fastfile.
-
#had_multiple_projects_to_choose_from ⇒ Object
remember if there were multiple projects if so, we set it as part of the Fastfile.
-
#is_swift_fastfile ⇒ Object
Is the current ‘setup` using a swift based configuration file.
-
#lane_to_mention ⇒ Object
This is the lane that we tell the user to run to try the new fastlane setup This needs to be setup by each setup.
-
#platform ⇒ Object
:ios or :android.
-
#preferred_setup_method ⇒ Object
Used for :manual sometimes.
-
#project_path ⇒ Object
Path to the xcodeproj or xcworkspace.
-
#user ⇒ Object
For iOS projects that’s the Apple ID email.
Class Method Summary collapse
-
.setup_swift_support ⇒ Object
rubocop:enable Metrics/BlockNesting.
-
.start(user: nil, is_swift_fastfile: false) ⇒ Object
Start the setup process rubocop:disable Metrics/BlockNesting.
Instance Method Summary collapse
-
#add_or_update_gemfile(update_gemfile_if_needed: false) ⇒ Object
This method is responsible for ensuring there is a working Gemfile, and that ‘fastlane` is defined as a dependency while also having `rubygems` as a gem source.
-
#append_lane(lane) ⇒ Object
Append a lane to the current Fastfile template we’re generating.
-
#append_team(team) ⇒ Object
Append a team to the Appfile.
- #appfile_template_content ⇒ Object
- #continue_with_enter ⇒ Object
- #ensure_gemfile_valid!(update_gemfile_if_needed: false) ⇒ Object
- #explain_concepts ⇒ Object
- #fastfile_template_content ⇒ Object
- #finish_up ⇒ Object
-
#gemfile_exists? ⇒ Boolean
Gemfile related code:.
- #gemfile_path ⇒ Object
-
#initialize(is_swift_fastfile: nil, user: nil, project_path: nil, had_multiple_projects_to_choose_from: nil, preferred_setup_method: nil) ⇒ Setup
constructor
A new instance of Setup.
- #setup_gemfile! ⇒ Object
- #show_analytics_note ⇒ Object
- #suggest_next_steps ⇒ Object
-
#welcome_to_fastlane ⇒ Object
Helpers.
- #write_fastfile! ⇒ Object
Constructor Details
#initialize(is_swift_fastfile: nil, user: nil, project_path: nil, had_multiple_projects_to_choose_from: nil, preferred_setup_method: nil) ⇒ Setup
Returns a new instance of Setup.
152 153 154 155 156 157 158 |
# File 'fastlane/lib/fastlane/setup/setup.rb', line 152 def initialize(is_swift_fastfile: nil, user: nil, project_path: nil, had_multiple_projects_to_choose_from: nil, preferred_setup_method: nil) self.is_swift_fastfile = is_swift_fastfile self.user = user self.project_path = project_path self.had_multiple_projects_to_choose_from = had_multiple_projects_to_choose_from self.preferred_setup_method = preferred_setup_method end |
Instance Attribute Details
#appfile_content ⇒ Object
Appfile
25 26 27 |
# File 'fastlane/lib/fastlane/setup/setup.rb', line 25 def appfile_content @appfile_content end |
#fastfile_content ⇒ Object
The current content of the generated Fastfile
22 23 24 |
# File 'fastlane/lib/fastlane/setup/setup.rb', line 22 def fastfile_content @fastfile_content end |
#had_multiple_projects_to_choose_from ⇒ Object
remember if there were multiple projects if so, we set it as part of the Fastfile
19 20 21 |
# File 'fastlane/lib/fastlane/setup/setup.rb', line 19 def had_multiple_projects_to_choose_from @had_multiple_projects_to_choose_from end |
#is_swift_fastfile ⇒ Object
Is the current ‘setup` using a swift based configuration file
6 7 8 |
# File 'fastlane/lib/fastlane/setup/setup.rb', line 6 def is_swift_fastfile @is_swift_fastfile end |
#lane_to_mention ⇒ Object
This is the lane that we tell the user to run to try the new fastlane setup This needs to be setup by each setup
32 33 34 |
# File 'fastlane/lib/fastlane/setup/setup.rb', line 32 def lane_to_mention @lane_to_mention end |
#platform ⇒ Object
:ios or :android
9 10 11 |
# File 'fastlane/lib/fastlane/setup/setup.rb', line 9 def platform @platform end |
#preferred_setup_method ⇒ Object
Used for :manual sometimes
15 16 17 |
# File 'fastlane/lib/fastlane/setup/setup.rb', line 15 def preferred_setup_method @preferred_setup_method end |
#project_path ⇒ Object
Path to the xcodeproj or xcworkspace
12 13 14 |
# File 'fastlane/lib/fastlane/setup/setup.rb', line 12 def project_path @project_path end |
#user ⇒ Object
For iOS projects that’s the Apple ID email
28 29 30 |
# File 'fastlane/lib/fastlane/setup/setup.rb', line 28 def user @user end |
Class Method Details
.setup_swift_support ⇒ Object
rubocop:enable Metrics/BlockNesting
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
# File 'fastlane/lib/fastlane/setup/setup.rb', line 134 def self.setup_swift_support runner_source_resources = "#{Fastlane::ROOT}/swift/." destination_path = File.('swift', FastlaneCore::FastlaneFolder.path) # Return eearly if already setup return if File.exist?(destination_path) # Show message if Fastfile.swift exists but missing Swift classes and Xcode project if FastlaneCore::FastlaneFolder.swift? UI.important("Restoring Swift classes and FastlaneSwiftRunner.xcodeproj...") end FileUtils.cp_r(runner_source_resources, destination_path) UI.success("Copied Swift fastlane runner project to '#{destination_path}'.") Fastlane::SwiftLaneManager.first_time_setup end |
.start(user: nil, is_swift_fastfile: false) ⇒ Object
Start the setup process rubocop:disable Metrics/BlockNesting
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'fastlane/lib/fastlane/setup/setup.rb', line 36 def self.start(user: nil, is_swift_fastfile: false) if FastlaneCore::FastlaneFolder.setup? && !Helper.test? # If Fastfile.swift exists, but the swift sources folder does not, rebuild it setup_swift_support if is_swift_fastfile require 'fastlane/lane_list' Fastlane::LaneList.output(FastlaneCore::FastlaneFolder.fastfile_path) UI.important("------------------") UI.important("fastlane is already set up at path `#{FastlaneCore::FastlaneFolder.path}`, see the available lanes above") UI.("") setup_ios = self.new setup_ios.add_or_update_gemfile(update_gemfile_if_needed: false) setup_ios.suggest_next_steps return end # this is used by e.g. configuration.rb to not show warnings when running produce ENV["FASTLANE_ONBOARDING_IN_PROCESS"] = 1.to_s spinner = TTY::Spinner.new("[:spinner] Looking for iOS and Android projects in current directory...", format: :dots) spinner.auto_spin ios_projects = Dir["**/*.xcodeproj"] + Dir["**/*.xcworkspace"] ios_projects.delete_if do |path| Gem.path.any? { |gem_path| File.(path).start_with?(gem_path) } end ios_projects.delete_if { |path| path.match("fastlane/swift/FastlaneSwiftRunner/FastlaneSwiftRunner.xcodeproj") } android_projects = Dir["**/*.gradle"] + Dir["**/*.gradle.kts"] spinner.success FastlaneCore::FastlaneFolder.create_folder! # Currently we prefer iOS app projects, as the `init` process is # more intelligent and does more things. The user can easily add # the `:android` platform to the resulting Fastfile if ios_projects.count > 0 current_directory = ios_projects.find_all do |current_project_path| current_project_path.split(File::Separator).count == 1 end chosen_project = nil had_multiple_projects_to_choose_from = false if current_directory.count == 1 chosen_project = current_directory.first elsif current_directory.count > 1 if current_directory.count == 2 # This is a common case (e.g. with CocoaPods), where the project has an xcodeproj and an xcworkspace file extensions = [File.extname(current_directory[0]), File.extname(current_directory[1])] if extensions.sort == [".xcodeproj", ".xcworkspace"].sort # Yep, that's this kind of setup chosen_project = current_directory.find { |d| d.end_with?(".xcworkspace") } end end chosen_project ||= UI.select("Multiple iOS projects found in current directory", current_directory) had_multiple_projects_to_choose_from = true else UI.error("It looks like there is no iOS project in the current directory, though we did find one in a sub-directory") UI.error("Please `cd` into the directory of the intended Xcode project you wish to use.") UI.user_error!("Please `cd` into the directory of the intended Xcode project you wish to use and run `fastlane init` again") end if chosen_project == "Pods.xcodeproj" unless UI.confirm("Found '#{chosen_project}', which usually isn't normally what you want. Make sure to switch to the directory containing your intended Xcode project. Would you still like to continue with #{chosen_project}?") UI.user_error!("Make sure to `cd` into the directory containing the Xcode project you intend to use and then use `fastlane init` again") end end UI.("Detected an iOS/macOS project in the current directory: '#{chosen_project}'") SetupIos.new( is_swift_fastfile: is_swift_fastfile, user: user, project_path: chosen_project, had_multiple_projects_to_choose_from: had_multiple_projects_to_choose_from ).setup_ios elsif android_projects.count > 0 UI.("Detected an Android project in the current directory...") SetupAndroid.new.setup_android else UI.error("No iOS or Android projects were found in directory '#{Dir.pwd}'") UI.error("Make sure to `cd` into the directory containing your iOS or Android app") if UI.confirm("Alternatively, would you like to manually setup a fastlane config in the current directory instead?") SetupIos.new( is_swift_fastfile: is_swift_fastfile, user: user, project_path: chosen_project, had_multiple_projects_to_choose_from: had_multiple_projects_to_choose_from, preferred_setup_method: :ios_manual ).setup_ios else UI.user_error!("Make sure to `cd` into the directory containing your project and then use `fastlane init` again") end end end |
Instance Method Details
#add_or_update_gemfile(update_gemfile_if_needed: false) ⇒ Object
This method is responsible for ensuring there is a working Gemfile, and that ‘fastlane` is defined as a dependency while also having `rubygems` as a gem source
272 273 274 275 276 277 278 279 280 281 |
# File 'fastlane/lib/fastlane/setup/setup.rb', line 272 def add_or_update_gemfile(update_gemfile_if_needed: false) if gemfile_exists? ensure_gemfile_valid!(update_gemfile_if_needed: update_gemfile_if_needed) else if update_gemfile_if_needed || UI.confirm("It is recommended to run fastlane with a Gemfile set up, do you want fastlane to create one for you?") setup_gemfile! end end return gemfile_path end |
#append_lane(lane) ⇒ Object
Append a lane to the current Fastfile template we’re generating
168 169 170 171 172 173 174 175 176 177 178 179 |
# File 'fastlane/lib/fastlane/setup/setup.rb', line 168 def append_lane(lane) lane.compact! # remove nil values new_lines = "\n\n" if self.is_swift_fastfile new_lines = "" unless self.fastfile_content.include?("lane() {") # the first lane we don't want new lines self.fastfile_content.gsub!("[[LANES]]", "#{new_lines}\t#{lane.join("\n\t")}[[LANES]]") else new_lines = "" unless self.fastfile_content.include?("lane :") # the first lane we don't want new lines self.fastfile_content.gsub!("[[LANES]]", "#{new_lines} #{lane.join("\n ")}[[LANES]]") end end |
#append_team(team) ⇒ Object
Append a team to the Appfile
182 183 184 |
# File 'fastlane/lib/fastlane/setup/setup.rb', line 182 def append_team(team) self.appfile_content.gsub!("[[TEAMS]]", "#{team}\n[[TEAMS]]") end |
#appfile_template_content ⇒ Object
301 302 303 304 305 306 307 308 309 310 311 312 313 |
# File 'fastlane/lib/fastlane/setup/setup.rb', line 301 def appfile_template_content if self.platform == :ios if self.is_swift_fastfile path = "#{Fastlane::ROOT}/lib/assets/AppfileTemplate.swift" else path = "#{Fastlane::ROOT}/lib/assets/AppfileTemplate" end else path = "#{Fastlane::ROOT}/lib/assets/AppfileTemplateAndroid" end return File.read(path) end |
#continue_with_enter ⇒ Object
329 330 331 |
# File 'fastlane/lib/fastlane/setup/setup.rb', line 329 def continue_with_enter UI.input("Continue by pressing Enter ⏎") end |
#ensure_gemfile_valid!(update_gemfile_if_needed: false) ⇒ Object
245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 |
# File 'fastlane/lib/fastlane/setup/setup.rb', line 245 def ensure_gemfile_valid!(update_gemfile_if_needed: false) gemfile_content = File.read(gemfile_path) unless gemfile_content.include?("https://rubygems.org") UI.error("You have a local Gemfile, but RubyGems isn't defined as source") UI.error("Please update your Gemfile at path `#{gemfile_path}` to include") UI.important("") UI.important("source \"https://rubygems.org\"") UI.important("") UI.error("Update your Gemfile, and run `bundle update` afterwards") end unless gemfile_content.include?("fastlane") if update_gemfile_if_needed gemfile_content << "\n\ngem \"fastlane\"" UI.("Adding `fastlane` to your existing Gemfile at path '#{gemfile_path}'") File.write(gemfile_path, gemfile_content) else UI.error("You have a local Gemfile, but it doesn't include \"fastlane\" as a dependency") UI.error("Please add `gem \"fastlane\"` to your Gemfile") end end end |
#explain_concepts ⇒ Object
315 316 317 318 319 320 321 322 323 324 325 326 327 |
# File 'fastlane/lib/fastlane/setup/setup.rb', line 315 def explain_concepts UI.header("fastlane lanes") UI.("fastlane uses a " + "`Fastfile`".yellow + " to store the automation configuration") UI.("Within that, you'll see different " + "lanes".yellow + ".") UI.("Each is there to automate a different task, like screenshots, code signing, or pushing new releases") continue_with_enter UI.header("How to customize your Fastfile") UI.("Use a text editor of your choice to open the newly created Fastfile and take a look") UI.("You can now edit the available lanes and actions to customize the setup to fit your needs") UI.("To get a list of all the available actions, open " + "https://docs.fastlane.tools/actions".cyan) continue_with_enter end |
#fastfile_template_content ⇒ Object
291 292 293 294 295 296 297 298 299 |
# File 'fastlane/lib/fastlane/setup/setup.rb', line 291 def fastfile_template_content if self.is_swift_fastfile path = "#{Fastlane::ROOT}/lib/assets/DefaultFastfileTemplate.swift" else path = "#{Fastlane::ROOT}/lib/assets/DefaultFastfileTemplate" end return File.read(path) end |
#finish_up ⇒ Object
283 284 285 286 287 288 289 |
# File 'fastlane/lib/fastlane/setup/setup.rb', line 283 def finish_up write_fastfile! self.class.setup_swift_support if is_swift_fastfile show_analytics_note explain_concepts suggest_next_steps end |
#gemfile_exists? ⇒ Boolean
Gemfile related code:
219 220 221 |
# File 'fastlane/lib/fastlane/setup/setup.rb', line 219 def gemfile_exists? return File.exist?(gemfile_path) end |
#gemfile_path ⇒ Object
214 215 216 |
# File 'fastlane/lib/fastlane/setup/setup.rb', line 214 def gemfile_path "Gemfile" end |
#setup_gemfile! ⇒ Object
223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 |
# File 'fastlane/lib/fastlane/setup/setup.rb', line 223 def setup_gemfile! # No Gemfile yet gemfile_content = [] gemfile_content << "source \"https://rubygems.org\"" gemfile_content << "" gemfile_content << 'gem "fastlane"' gemfile_content << "" File.write(gemfile_path, gemfile_content.join("\n")) UI.("Installing dependencies for you...") FastlaneCore::CommandExecutor.execute( command: "bundle update", print_all: FastlaneCore::Globals.verbose?, print_command: true, error: proc do |error_output| UI.error("Something went wrong when running `bundle update` for you") UI.error("Please take a look at your Gemfile at path `#{gemfile_path}`") UI.error("and make sure you can run `bundle update` on your machine.") end ) end |
#show_analytics_note ⇒ Object
360 361 362 363 |
# File 'fastlane/lib/fastlane/setup/setup.rb', line 360 def show_analytics_note UI.("fastlane will collect the number of errors for each action to detect integration issues") UI.("No sensitive/private information will be uploaded, more information: " + "https://docs.fastlane.tools/#metrics".cyan) end |
#suggest_next_steps ⇒ Object
333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 |
# File 'fastlane/lib/fastlane/setup/setup.rb', line 333 def suggest_next_steps UI.header("Where to go from here?") if self.platform == :android UI.("📸 Learn more about how to automatically generate localized Google Play screenshots:") UI.("\t\thttps://docs.fastlane.tools/getting-started/android/screenshots/".cyan) UI.("👩✈️ Learn more about distribution to beta testing services:") UI.("\t\thttps://docs.fastlane.tools/getting-started/android/beta-deployment/".cyan) UI.("🚀 Learn more about how to automate the Google Play release process:") UI.("\t\thttps://docs.fastlane.tools/getting-started/android/release-deployment/".cyan) else UI.("📸 Learn more about how to automatically generate localized App Store screenshots:") UI.("\t\thttps://docs.fastlane.tools/getting-started/ios/screenshots/".cyan) UI.("👩✈️ Learn more about distribution to beta testing services:") UI.("\t\thttps://docs.fastlane.tools/getting-started/ios/beta-deployment/".cyan) UI.("🚀 Learn more about how to automate the App Store release process:") UI.("\t\thttps://docs.fastlane.tools/getting-started/ios/appstore-deployment/".cyan) UI.("👩⚕️ Learn more about how to setup code signing with fastlane") UI.("\t\thttps://docs.fastlane.tools/codesigning/getting-started/".cyan) end # we crash here, so that this never happens when a new setup method is added return if self.lane_to_mention.to_s.length == 0 UI.("") UI.("To try your new fastlane setup, just enter and run") UI.command("fastlane #{self.lane_to_mention}") end |
#welcome_to_fastlane ⇒ Object
Helpers
161 162 163 164 165 |
# File 'fastlane/lib/fastlane/setup/setup.rb', line 161 def welcome_to_fastlane UI.header("Welcome to fastlane 🚀") UI.("fastlane can help you with all kinds of automation for your mobile app") UI.("We recommend automating one task first, and then gradually automating more over time") end |
#write_fastfile! ⇒ Object
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 |
# File 'fastlane/lib/fastlane/setup/setup.rb', line 186 def write_fastfile! # Write the Fastfile fastfile_file_name = "Fastfile" fastfile_file_name += ".swift" if self.is_swift_fastfile fastfile_path = File.join(FastlaneCore::FastlaneFolder.path, fastfile_file_name) self.fastfile_content.gsub!("[[LANES]]", "") # since we always keep it until writing out File.write(fastfile_path, self.fastfile_content) # remove trailing spaces before platform ends appfile_file_name = "Appfile" appfile_file_name += ".swift" if self.is_swift_fastfile appfile_path = File.join(FastlaneCore::FastlaneFolder.path, appfile_file_name) self.appfile_content.gsub!("[[TEAMS]]", "") File.write(appfile_path, self.appfile_content) add_or_update_gemfile(update_gemfile_if_needed: true) UI.header("✅ Successfully generated fastlane configuration") UI.("Generated Fastfile at path `#{fastfile_path}`") UI.("Generated Appfile at path `#{appfile_path}`") UI.("Gemfile and Gemfile.lock at path `#{gemfile_path}`") UI.("Please check the newly generated configuration files into git along with your project") UI.("This way everyone in your team can benefit from your fastlane setup") continue_with_enter end |