Merge pull request #315 from TouchInstinct/feature/support_inheritance_in_xcconfig_options
support inheritance in xcconfig options
This commit is contained in:
commit
76ac52accf
|
|
@ -0,0 +1,132 @@
|
|||
require 'json'
|
||||
require 'mustache'
|
||||
require 'yaml'
|
||||
|
||||
require_relative '../fastlane/touchlane/lib/touchlane/configuration_type'
|
||||
|
||||
class String
|
||||
def in_current_dir
|
||||
"#{__dir__}/#{self}"
|
||||
end
|
||||
end
|
||||
|
||||
class ConfigRenderer
|
||||
class XCConfigKeys
|
||||
DEVELOPMENT_TEAM = "DEVELOPMENT_TEAM"
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "PRODUCT_BUNDLE_IDENTIFIER"
|
||||
CODE_SIGN_STYLE = "CODE_SIGN_STYLE"
|
||||
end
|
||||
|
||||
INHERITED_PREFIX = "$(inherited)"
|
||||
|
||||
private_constant :INHERITED_PREFIX
|
||||
|
||||
def initialize(configurations_file_path, build_parameters_path, configs_folder_name)
|
||||
@configurations_file_path = configurations_file_path
|
||||
@build_parameters_path = build_parameters_path
|
||||
@configs_folder_name = configs_folder_name
|
||||
end
|
||||
|
||||
def render_xconfigs
|
||||
temp_configs_data_file_path = "configs_data.json".in_current_dir
|
||||
generator_path = "build_options_helper/helper.py".in_current_dir
|
||||
template_path = "target_xcconfig.mustache".in_current_dir
|
||||
|
||||
# Create config directory if needed
|
||||
Dir.mkdir(@configs_folder_name) unless Dir.exist?(@configs_folder_name)
|
||||
|
||||
# Call python script and generate configs to config file
|
||||
system("python #{generator_path} -bp #{@build_parameters_path} -o #{__dir__} -r ios_build_settings -p ios")
|
||||
|
||||
# Open settings, configurations and template files
|
||||
target_xcconfig_tempate = File.read(template_path)
|
||||
$configurations = YAML.load(File.open(@configurations_file_path))
|
||||
$config_types = $configurations["types"]
|
||||
|
||||
targets = $configurations["targets"]
|
||||
|
||||
# Run through all target in project
|
||||
targets.each do |target_name, target|
|
||||
|
||||
# Need open everytime, because script make some changes only for this target
|
||||
configs = JSON.load(File.open(temp_configs_data_file_path))
|
||||
|
||||
# Run through all configs
|
||||
configs.each do |config|
|
||||
|
||||
# Take default values
|
||||
distribution_type = Touchlane::ConfigurationType.from_account_type(config["account_type"]).type
|
||||
properties = target[distribution_type]
|
||||
|
||||
# Add properties from settings file
|
||||
properties.each do |key, value|
|
||||
if config["xcconfig_options"].any? { |option| key == option["key"] }
|
||||
config["xcconfig_options"].map! { |option| key == option["key"] ? merge_config_data(key, option["value"], value) : option }
|
||||
else
|
||||
config["xcconfig_options"].append(config_option(key, value))
|
||||
end
|
||||
end
|
||||
|
||||
# Add missing properties if needed
|
||||
config["xcconfig_options"].concat(generate_missing_properties(target_name, properties, distribution_type))
|
||||
|
||||
# Create settings pack
|
||||
config_data = {
|
||||
"target_name": target_name,
|
||||
"abstract_targets_prefix": target["abstract_targets_prefix"],
|
||||
"configuration": config
|
||||
}
|
||||
|
||||
# Create file for every setting in loop
|
||||
File.open(@configs_folder_name + "/" + target_name + config["name"] + ".xcconfig", 'w') { |file|
|
||||
file.puts(Mustache.render(target_xcconfig_tempate, config_data))
|
||||
}
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# Remove config file, it's trash
|
||||
File.delete(temp_configs_data_file_path) if File.exist?(temp_configs_data_file_path)
|
||||
end
|
||||
|
||||
# Make tuple of key and value become mustache template element
|
||||
def config_option(key, value)
|
||||
return { "key" => key, "value" => value }
|
||||
end
|
||||
|
||||
def merge_config_data(key, config_value, settings_value)
|
||||
if settings_value.start_with?(INHERITED_PREFIX)
|
||||
new_value = settings_value.split(INHERITED_PREFIX).last
|
||||
return config_option(key, config_value + new_value)
|
||||
else
|
||||
return config_option(key, settings_value)
|
||||
end
|
||||
end
|
||||
|
||||
# Fetch development team from build configuration
|
||||
def fetch_development_team(development_team_key, distribution_type)
|
||||
current_config = $config_types[distribution_type]
|
||||
team_value = current_config["team_id"]
|
||||
return config_option(development_team_key, team_value)
|
||||
end
|
||||
|
||||
# Generate missing properties if needed
|
||||
def generate_missing_properties(target_name, properties, distribution_type)
|
||||
result = []
|
||||
|
||||
# Bundle_id_key should be among the properties (required by fastlane)
|
||||
unless properties.key?(XCConfigKeys::PRODUCT_BUNDLE_IDENTIFIER)
|
||||
raise "#{target_name}: Could not find #{XCConfigKeys::PRODUCT_BUNDLE_IDENTIFIER} for #{distribution_type}"
|
||||
end
|
||||
|
||||
unless properties.key?(XCConfigKeys::DEVELOPMENT_TEAM)
|
||||
result.append(fetch_development_team(XCConfigKeys::DEVELOPMENT_TEAM, distribution_type))
|
||||
end
|
||||
|
||||
unless properties.key?(XCConfigKeys::CODE_SIGN_STYLE)
|
||||
result.append(config_option(XCConfigKeys::CODE_SIGN_STYLE, "Manual"))
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
end
|
||||
|
|
@ -5,10 +5,12 @@ targets:
|
|||
PRODUCT_BUNDLE_IDENTIFIER: "ru.touchin.testproject"
|
||||
PROVISIONING_PROFILE_SPECIFIER: "TestProjectDev"
|
||||
CODE_SIGN_ENTITLEMENTS: "TestProject/Standard.entitlements"
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS: "$(inherited) DEBUG_MENU"
|
||||
enterprise:
|
||||
PRODUCT_BUNDLE_IDENTIFIER: "com.touchin.testproject"
|
||||
PROVISIONING_PROFILE_SPECIFIER: "TestProjectEnterprise"
|
||||
CODE_SIGN_ENTITLEMENTS: "TestProject/Enterprise.entitlements"
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS: "$(inherited) DEBUG_MENU"
|
||||
appstore:
|
||||
PRODUCT_BUNDLE_IDENTIFIER: "ru.customer.domain"
|
||||
PROVISIONING_PROFILE_SPECIFIER: "TestProjectAppStore"
|
||||
|
|
@ -16,13 +18,13 @@ targets:
|
|||
|
||||
types:
|
||||
development:
|
||||
apple_id: "apple@touchin.ru"
|
||||
apple_id: "iosdev@touchin.ru"
|
||||
team_id: "**********"
|
||||
itc_team_id: "**********"
|
||||
enterprise:
|
||||
apple_id: "enterpriseapple@touchin.ru"
|
||||
team_id: "**********"
|
||||
appstore:
|
||||
apple_id: "apple@touchin.ru"
|
||||
apple_id: "iosdev@touchin.ru"
|
||||
team_id: "**********"
|
||||
itc_team_id: "**********"
|
||||
|
|
@ -1,7 +1,4 @@
|
|||
require 'json'
|
||||
require 'mustache'
|
||||
require 'yaml'
|
||||
|
||||
require_relative "config_renderer"
|
||||
#
|
||||
# Usage: render_xcconfigs.rb <configurations.yaml> <build_parameters.yaml> [<ouptut folder>]
|
||||
#
|
||||
|
|
@ -10,122 +7,9 @@ require 'yaml'
|
|||
# It is recommended to remove old .xcconfig files before running this script.
|
||||
#
|
||||
|
||||
class String
|
||||
def in_current_dir
|
||||
"#{__dir__}/#{self}"
|
||||
end
|
||||
end
|
||||
|
||||
# Input files paths
|
||||
configurations_file_path = ARGV[0]
|
||||
temp_configs_data_file_path = "configs_data.json".in_current_dir
|
||||
generator_path = "build_options_helper/helper.py".in_current_dir
|
||||
template_path = "target_xcconfig.mustache".in_current_dir
|
||||
build_parameters_path = ARGV[1]
|
||||
configs_folder_name = ARGV[2] || "TargetConfigurations"
|
||||
|
||||
# Create config directory if needed
|
||||
Dir.mkdir(configs_folder_name) unless Dir.exist?(configs_folder_name)
|
||||
|
||||
# Call python script and generate configs to config file
|
||||
system("python #{generator_path} -bp #{build_parameters_path} -o #{__dir__} -r ios_build_settings -p ios")
|
||||
|
||||
# Open settings, configurations and template files
|
||||
target_xcconfig_tempate = File.read(template_path)
|
||||
$configurations = YAML.load(File.open(configurations_file_path))
|
||||
$config_types = $configurations["types"]
|
||||
|
||||
# Set global property
|
||||
targets = $configurations["targets"]
|
||||
|
||||
# Make tuple of key and value become mustache template element
|
||||
def config_option(key, value)
|
||||
return { "key" => key, "value" => value }
|
||||
end
|
||||
|
||||
# Maps lane prefix to distribution type
|
||||
def distribution_type_of(account_type)
|
||||
case account_type
|
||||
when "Standard"
|
||||
"development"
|
||||
when "Enterprise"
|
||||
"enterprise"
|
||||
when "AppStore"
|
||||
"appstore"
|
||||
else
|
||||
raise "Error: Unsupported distribution type #{account_type}"
|
||||
end
|
||||
end
|
||||
|
||||
# Fetch development team from build configuration
|
||||
def fetch_development_team(development_team_key, distribution_type)
|
||||
current_config = $config_types[distribution_type]
|
||||
team_value = current_config["team_id"]
|
||||
return config_option(development_team_key, team_value)
|
||||
end
|
||||
|
||||
# Generate missing properties if needed
|
||||
def generate_missing_properties(target_name, properties, distribution_type)
|
||||
result = []
|
||||
development_team_key = "DEVELOPMENT_TEAM"
|
||||
bundle_id_key = "PRODUCT_BUNDLE_IDENTIFIER"
|
||||
code_sign_style_key = "CODE_SIGN_STYLE"
|
||||
|
||||
# Bundle_id_key should be among the properties (required by fastlane)
|
||||
unless properties.key?(bundle_id_key)
|
||||
raise "#{target_name}: Could not find #{bundle_id_key} for #{distribution_type}"
|
||||
end
|
||||
|
||||
unless properties.key?(development_team_key)
|
||||
result.append(fetch_development_team(development_team_key, distribution_type))
|
||||
end
|
||||
|
||||
unless properties.key?(code_sign_style_key)
|
||||
result.append(config_option(code_sign_style_key, "Manual"))
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
# Run through all target in project
|
||||
targets.each do |target_name, target|
|
||||
|
||||
# Need open everytime, because script make some changes only for this target
|
||||
configs = JSON.load(File.open(temp_configs_data_file_path))
|
||||
|
||||
# Run through all configs
|
||||
configs.each do |config|
|
||||
|
||||
# Take default values
|
||||
distribution_type = distribution_type_of(config["account_type"])
|
||||
properties = target[distribution_type]
|
||||
|
||||
# Add properties from settings file
|
||||
properties.each do |key, value|
|
||||
if config["xcconfig_options"].any? { |option| key == option["key"] }
|
||||
config["xcconfig_options"].map! { |option| key == option["key"] ? config_option(key, value) : option }
|
||||
else
|
||||
config["xcconfig_options"].append(config_option(key, value))
|
||||
end
|
||||
end
|
||||
|
||||
# Add missing properties if needed
|
||||
config["xcconfig_options"].concat(generate_missing_properties(target_name, properties, distribution_type))
|
||||
|
||||
# Create settings pack
|
||||
config_data = {
|
||||
"target_name": target_name,
|
||||
"abstract_targets_prefix": target["abstract_targets_prefix"],
|
||||
"configuration": config
|
||||
}
|
||||
|
||||
# Create file for every setting in loop
|
||||
File.open(configs_folder_name + "/" + target_name + config["name"] + ".xcconfig", 'w') { |file|
|
||||
file.puts(Mustache.render(target_xcconfig_tempate, config_data))
|
||||
}
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# Remove config file, it's trash
|
||||
File.delete(temp_configs_data_file_path) if File.exist?(temp_configs_data_file_path)
|
||||
ConfigRenderer.new(configurations_file_path, build_parameters_path, configs_folder_name).render_xconfigs()
|
||||
|
|
|
|||
|
|
@ -57,6 +57,20 @@ module Touchlane
|
|||
new(type)
|
||||
end
|
||||
|
||||
def self.from_account_type(account_type)
|
||||
case account_type
|
||||
when DEVELOPMENT_PREFIX
|
||||
from_type(DEVELOPMENT)
|
||||
when ENTERPRISE_PREFIX
|
||||
from_type(ENTERPRISE)
|
||||
when APP_STORE_PREFIX
|
||||
from_type(APP_STORE)
|
||||
else
|
||||
raise "Unable to map #{account_type} to #{ConfigurationType.class}."
|
||||
+ "Available account types: #{DEVELOPMENT_PREFIX}, #{ENTERPRISE_PREFIX}, #{APP_STORE_PREFIX}"
|
||||
end
|
||||
end
|
||||
|
||||
def to_options
|
||||
{
|
||||
:type => @type,
|
||||
|
|
|
|||
Loading…
Reference in New Issue