module Fastlane module Actions class CarthageAction < Action # rubocop:disable Metrics/PerceivedComplexity def self.run(params) validate(params) cmd = [params[:executable]] command_name = params[:command] cmd << command_name if command_name == "archive" && params[:frameworks].count > 0 cmd.concat(params[:frameworks]) # "update", "build" and "bootstrap" are the only commands that support "--derived-data" parameter elsif ["update", "build", "bootstrap"].include?(command_name) cmd.concat(params[:dependencies]) if params[:dependencies].count > 0 cmd << "--derived-data #{params[:derived_data].shellescape}" if params[:derived_data] end cmd << "--output #{params[:output]}" if params[:output] cmd << "--use-ssh" if params[:use_ssh] cmd << "--use-submodules" if params[:use_submodules] cmd << "--use-netrc" if params[:use_netrc] cmd << "--no-use-binaries" if params[:use_binaries] == false cmd << "--no-checkout" if params[:no_checkout] == true cmd << "--no-build" if params[:no_build] == true cmd << "--no-skip-current" if params[:no_skip_current] == true cmd << "--verbose" if params[:verbose] == true cmd << "--platform #{params[:platform]}" if params[:platform] cmd << "--configuration #{params[:configuration]}" if params[:configuration] cmd << "--toolchain #{params[:toolchain]}" if params[:toolchain] cmd << "--project-directory #{params[:project_directory]}" if params[:project_directory] cmd << "--cache-builds" if params[:cache_builds] cmd << "--new-resolver" if params[:new_resolver] cmd << "--log-path #{params[:log_path]}" if params[:log_path] cmd << "--use-xcframeworks" if params[:use_xcframeworks] cmd << "--archive" if params[:archive] Actions.sh(cmd.join(' ')) end # rubocop:enable Metrics/PerceivedComplexity def self.validate(params) command_name = params[:command] if command_name != "archive" && params[:frameworks].count > 0 UI.user_error!("Frameworks option is available only for 'archive' command.") end if command_name != "archive" && params[:output] UI.user_error!("Output option is available only for 'archive' command.") end if params[:log_path] && !%w(build bootstrap update).include?(command_name) UI.user_error!("Log path option is available only for 'build', 'bootstrap', and 'update' command.") end if params[:use_xcframeworks] && !%w(build bootstrap update).include?(command_name) UI.user_error!("Use XCFrameworks option is available only for 'build', 'bootstrap', and 'update' command.") end if command_name != "build" && params[:archive] UI.user_error!("Archive option is available only for 'build' command.") end end def self.description "Runs `carthage` for your project" end def self.available_commands %w(build bootstrap update archive) end def self.available_platforms %w(all iOS Mac tvOS watchOS) end def self.available_options [ FastlaneCore::ConfigItem.new(key: :command, env_name: "FL_CARTHAGE_COMMAND", description: "Carthage command (one of: #{available_commands.join(', ')})", default_value: 'bootstrap', verify_block: proc do |value| UI.user_error!("Please pass a valid command. Use one of the following: #{available_commands.join(', ')}") unless available_commands.include?(value) end), FastlaneCore::ConfigItem.new(key: :dependencies, description: "Carthage dependencies to update, build or bootstrap", default_value: [], is_string: false, type: Array), FastlaneCore::ConfigItem.new(key: :use_ssh, env_name: "FL_CARTHAGE_USE_SSH", description: "Use SSH for downloading GitHub repositories", is_string: false, type: Boolean, optional: true), FastlaneCore::ConfigItem.new(key: :use_submodules, env_name: "FL_CARTHAGE_USE_SUBMODULES", description: "Add dependencies as Git submodules", is_string: false, type: Boolean, optional: true), FastlaneCore::ConfigItem.new(key: :use_netrc, env_name: "FL_CARTHAGE_USE_NETRC", description: "Use .netrc for downloading frameworks", is_string: false, type: Boolean, optional: true), FastlaneCore::ConfigItem.new(key: :use_binaries, env_name: "FL_CARTHAGE_USE_BINARIES", description: "Check out dependency repositories even when prebuilt frameworks exist", is_string: false, type: Boolean, optional: true), FastlaneCore::ConfigItem.new(key: :no_checkout, env_name: "FL_CARTHAGE_NO_CHECKOUT", description: "When bootstrapping Carthage do not checkout", is_string: false, type: Boolean, optional: true), FastlaneCore::ConfigItem.new(key: :no_build, env_name: "FL_CARTHAGE_NO_BUILD", description: "When bootstrapping Carthage do not build", is_string: false, type: Boolean, optional: true), FastlaneCore::ConfigItem.new(key: :no_skip_current, env_name: "FL_CARTHAGE_NO_SKIP_CURRENT", description: "Don't skip building the Carthage project (in addition to its dependencies)", is_string: false, type: Boolean, optional: true), FastlaneCore::ConfigItem.new(key: :derived_data, env_name: "FL_CARTHAGE_DERIVED_DATA", description: "Use derived data folder at path", optional: true), FastlaneCore::ConfigItem.new(key: :verbose, env_name: "FL_CARTHAGE_VERBOSE", description: "Print xcodebuild output inline", is_string: false, type: Boolean, optional: true), FastlaneCore::ConfigItem.new(key: :platform, env_name: "FL_CARTHAGE_PLATFORM", description: "Define which platform to build for", optional: true, verify_block: proc do |value| value.split(',').each do |platform| UI.user_error!("Please pass a valid platform. Use one of the following: #{available_platforms.join(', ')}") unless available_platforms.map(&:downcase).include?(platform.downcase) end end), FastlaneCore::ConfigItem.new(key: :cache_builds, env_name: "FL_CARTHAGE_CACHE_BUILDS", description: "By default Carthage will rebuild a dependency regardless of whether it's the same resolved version as before. Passing the --cache-builds will cause carthage to avoid rebuilding a dependency if it can", is_string: false, default_value: false), FastlaneCore::ConfigItem.new(key: :frameworks, description: "Framework name or names to archive, could be applied only along with the archive command", default_value: [], is_string: false, type: Array), FastlaneCore::ConfigItem.new(key: :output, description: "Output name for the archive, could be applied only along with the archive command. Use following format *.framework.zip", is_string: true, optional: true, verify_block: proc do |value| UI.user_error!("Please pass a valid string for output. Use following format *.framework.zip") unless value.end_with?("framework.zip") end), FastlaneCore::ConfigItem.new(key: :configuration, env_name: "FL_CARTHAGE_CONFIGURATION", description: "Define which build configuration to use when building", optional: true, verify_block: proc do |value| if value.chomp(' ').empty? UI.user_error!("Please pass a valid build configuration. You can review the list of configurations for this project using the command: xcodebuild -list") end end), FastlaneCore::ConfigItem.new(key: :toolchain, env_name: "FL_CARTHAGE_TOOLCHAIN", description: "Define which xcodebuild toolchain to use when building", optional: true), FastlaneCore::ConfigItem.new(key: :project_directory, env_name: "FL_CARTHAGE_PROJECT_DIRECTORY", description: "Define the directory containing the Carthage project", optional: true), FastlaneCore::ConfigItem.new(key: :new_resolver, env_name: "FL_CARTHAGE_NEW_RESOLVER", description: "Use new resolver when resolving dependency graph", is_string: false, optional: true, type: Boolean), FastlaneCore::ConfigItem.new(key: :log_path, env_name: "FL_CARTHAGE_LOG_PATH", description: "Path to the xcode build output", optional: true), FastlaneCore::ConfigItem.new(key: :use_xcframeworks, env_name: "FL_CARTHAGE_USE_XCFRAMEWORKS", description: "Create xcframework bundles instead of one framework per platform (requires Xcode 12+)", type: Boolean, is_string: false, default_value: false), FastlaneCore::ConfigItem.new(key: :archive, env_name: "FL_CARTHAGE_ARCHIVE", description: "Archive built frameworks from the current project", is_string: false, type: Boolean, default_value: false), FastlaneCore::ConfigItem.new(key: :executable, env_name: "FL_CARTHAGE_EXECUTABLE", description: "Path to the `carthage` executable on your machine", default_value: 'carthage') ] end def self.example_code [ 'carthage', 'carthage( frameworks: ["MyFramework1", "MyFramework2"], # Specify which frameworks to archive (only for the archive command) output: "MyFrameworkBundle.framework.zip", # Specify the output archive name (only for the archive command) command: "bootstrap", # One of: build, bootstrap, update, archive. (default: bootstrap) dependencies: ["Alamofire", "Notice"], # Specify which dependencies to update or build (only for update, build and bootstrap commands) use_ssh: false, # Use SSH for downloading GitHub repositories. use_submodules: false, # Add dependencies as Git submodules. use_binaries: true, # Check out dependency repositories even when prebuilt frameworks exist no_build: false, # When bootstrapping Carthage do not build no_skip_current: false, # Don\'t skip building the current project (only for frameworks) verbose: false, # Print xcodebuild output inline platform: "all", # Define which platform to build for (one of ‘all’, ‘Mac’, ‘iOS’, ‘watchOS’, ‘tvOS‘, or comma-separated values of the formers except for ‘all’) configuration: "Release", # Build configuration to use when building cache_builds: true, # By default Carthage will rebuild a dependency regardless of whether its the same resolved version as before. toolchain: "com.apple.dt.toolchain.Swift_2_3", # Specify the xcodebuild toolchain new_resolver: false, # Use the new resolver to resolve depdendency graph log_path: "carthage.log" # Path to the xcode build output )' ] end def self.category :building end def self.is_supported?(platform) [:ios, :mac].include?(platform) end def self.authors ["bassrock", "petester42", "jschmid", "JaviSoto", "uny", "phatblat", "bfcrampton", "antondomashnev", "gbrhaz"] end end end end