class Fastlane::Actions::ReadXcconfigAction
Action to read and resolve values in Xcconfig files.
Public Class Methods
Plugin action available options.
# File lib/fastlane/plugin/xcconfig_actions/actions/read_xcconfig_action.rb, line 180 def self.available_options [ FastlaneCore::ConfigItem.new(key: :path, env_name: "XCCONFIG_ACTIONS_READ_PATH", description: "Path to xcconfig to read", optional: false, type: String, verify_block: proc do |value| UI.user_error!("Couldn't find xcconfig at path: '#{value}'") unless File.exist?(value) end), FastlaneCore::ConfigItem.new(key: :parent, env_name: "XCCONFIG_ACTIONS_READ_PARENT", description: "Parent xcconfig file to inherit build settings from.\nThis is the xcconfig you'd set on the project level in Xcode", optional: true, type: String, verify_block: proc do |value| UI.user_error!("Couldn't find parent xcconfig at path: '#{value}'") if value && !File.exist?(value) end), FastlaneCore::ConfigItem.new(key: :resolve, env_name: "XCCONFIG_ACTIONS_READ_RESOLVE", description: "Resolve variables in xcconfigs", default_value: true, type: Boolean), FastlaneCore::ConfigItem.new(key: :srcroot, env_name: "XCCONFIG_ACTIONS_READ_SRCROOT", description: "Value for SRCROOT build setting, default is current working directory", optional: true, type: String), FastlaneCore::ConfigItem.new(key: :target_name, env_name: "XCCONFIG_ACTIONS_READ_TARGET_NAME", description: "Value for TARGET_NAME build setting", optional: true, type: String), FastlaneCore::ConfigItem.new(key: :output_path, env_name: "XCCONFIG_ACTIONS_READ_OUTPUT_PATH", description: "Output path", optional: true, type: String) ] end
Plugin action category.
# File lib/fastlane/plugin/xcconfig_actions/actions/read_xcconfig_action.rb, line 175 def self.category :building end
Plugin action description.
# File lib/fastlane/plugin/xcconfig_actions/actions/read_xcconfig_action.rb, line 155 def self.description "Read and resolve contents of xcconfig file and return as JSON" end
Plugin action details.
# File lib/fastlane/plugin/xcconfig_actions/actions/read_xcconfig_action.rb, line 170 def self.details "" end
Check if platform is supported by the action. @param [Symbol] platform Platform to check. @return [Boolean] A Boolean indicating whether the platform is supported by the action.
# File lib/fastlane/plugin/xcconfig_actions/actions/read_xcconfig_action.rb, line 224 def self.is_supported?(platform) [:ios, :mac].include?(platform) end
Read xcconfig value as a hash.
@param [String] filename Xcconfig path. @return [Hash<String,String>] Dictionary of xcconfig values.
# File lib/fastlane/plugin/xcconfig_actions/actions/read_xcconfig_action.rb, line 71 def self.read_config(filename) # TODO: If filename starts with <DEVELOPER_DIR>, then need to resolve it first. return {} if filename.nil? || !File.exist?(filename) # Used to use Xcodeproj::Config.new(filename) here, but it just doesn't do the job, # e.g. it resolves $(inherited) incorrectly, allowing it to work within the scope of one file # without any parent config. xcconfig = Helper::XcconfigActionsHelper.read_xcconfig(filename) config = xcconfig[:config] includes = xcconfig[:includes] # Xcodeproj does not resolve overrides from included files, so do it manually. resolved_includes_config = includes.reduce({}) do |resolved_config, include_path| resolved_path = resolve_path(include_path, relative_to: filename) resolved_config.merge(read_config(resolved_path)) end config.merge(resolved_includes_config) end
Resolve config using parent information. @param [Hash] config Config to resolve. @param [Hash] parent Parent config. @param [String] srcroot Path to use for $(SRCROOT). @param [String] target_name Name to use for $(TARGET_NAME) @return [Hash] Resolved config.
# File lib/fastlane/plugin/xcconfig_actions/actions/read_xcconfig_action.rb, line 48 def self.resolve(config, parent, srcroot, target_name) parent_config = read_config(parent) parent_config["SRCROOT"] = srcroot parent_config["TARGET_NAME"] = target_name if target_name if Helper::XcconfigActionsHelper.command_exist?("xcodebuild") # Set value of XCODE_VERSION_MAJOR not available when reading xcconfigs directly. xcode_version = `xcodebuild -version | head -n1 | cut -d' ' -f2 | xargs`.strip xcode_version_major_padded = xcode_version.split(".").first.rjust(2, "0") + "00" parent_config["XCODE_VERSION_MAJOR"] = xcode_version_major_padded end resolved_parent_config = resolve_config(parent_config) resolved_config = resolve_config(config, parent: resolved_parent_config) resolved_parent_config.merge(resolved_config) end
Resolve xcconfig values using parent config.
@param [Hash<String,String>] config Current dictionary of values. @param [Hash<String,String>] parent Resolved parent xcconfig values.
@return [Hash<String,String>] Resolved xcconfig values.
# File lib/fastlane/plugin/xcconfig_actions/actions/read_xcconfig_action.rb, line 143 def self.resolve_config(config, parent: {}) config.each do |k, v| resolve_value(v, key: k, resolved: config, parent: parent) end config end
Expand given path in relation to another path.
Used to resolved '#include “relative/path.xcconfig”' includes.
@param [String] path Path to expand. @param [String] relative_to Parent path to expand in relation to.
@return [String] Expanded path.
# File lib/fastlane/plugin/xcconfig_actions/actions/read_xcconfig_action.rb, line 100 def self.resolve_path(path, relative_to:) # Absolute or special SDK paths need no resolving. return path if path.start_with?("/", "<") File.expand_path(File.join(File.dirname(relative_to), path)) end
Resolve xcconfig value, i.e. expand any of the $() variable references.
@param [String] value String value to resolve. @param [String] key Key under which this value is defined in xcconfig. This key will be used to pick up values from parent xcconfig. @param [Hash<String,String>] resolved Dictionary of already resolved values. @param [Hash<String,String>] parent Dictionary of parent xcconfig values.
@return [String] Resolved value.
# File lib/fastlane/plugin/xcconfig_actions/actions/read_xcconfig_action.rb, line 115 def self.resolve_value(value, key:, resolved: {}, parent: {}) matches = value.scan(/(\$\([^$\)]*\))/) mutable_value = value.dup # Prevent unwanted side-effect of input modification. matches.each do |group| group.each do |match| var_name = match.delete("$()") # If inherited, use value from parent config. var_value = if var_name == "inherited" parent[key] else resolved[var_name] || parent[var_name] end mutable_value.gsub!(match, var_value || "") resolved[key] = mutable_value end end # If there are still variables, keep resolving then. mutable_value.include?("$(") ? resolve_value(mutable_value, key: key, resolved: resolved, parent: parent) : mutable_value end
Plugin action return value.
# File lib/fastlane/plugin/xcconfig_actions/actions/read_xcconfig_action.rb, line 165 def self.return_value "Parse and resolved build settings from xcconfig represented as JSON" end
Run action. @param [Hash] params Action parameters. @return [Hash] Xcconfig dictionary.
# File lib/fastlane/plugin/xcconfig_actions/actions/read_xcconfig_action.rb, line 19 def self.run(params) path = params[:path] parent = params[:parent] srcroot = params[:srcroot] || Dir.pwd target_name = params[:target_name] config = read_config(path) config = resolve(config, parent, srcroot, target_name) if params[:resolve] Actions.lane_context[SharedValues::XCCONFIG_ACTIONS_BUILD_SETTINGS] = config if params[:output_path] File.open(params[:output_path], "w") { |f| f.puts(config.to_json) } else return config end end