diff --git a/xcode/config_generator/render_xcconfigs.rb b/xcode/config_generator/render_xcconfigs.rb index 47f1495..dd041d8 100755 --- a/xcode/config_generator/render_xcconfigs.rb +++ b/xcode/config_generator/render_xcconfigs.rb @@ -2,7 +2,7 @@ require 'json' require 'mustache' require 'yaml' -# Usage: render_xcconfigs.rb +# Usage: render_xcconfigs.rb # # Result: Adds .xcconfig files to $configs_folder_name directory. # Files are only being added and changed, not removed! @@ -11,9 +11,6 @@ require 'yaml' # Constants $configs_folder_name = "TargetConfigurations" -$standard_bundle_prefix = "ru.touchin." -$enterprise_bundle_prefix = "com.touchin." -$bundle_id_key = "PRODUCT_BUNDLE_IDENTIFIER" class String def in_current_dir @@ -21,135 +18,134 @@ class String end end -custom_settings_path = ARGV[0] -configurations_yaml_file = ARGV[1] -temp_configs_data_file = "configs_data.json".in_current_dir +# Input files paths +configurations_file_path = ARGV[0] +temp_configs_data_file_path = "configs_data.json".in_current_dir +generator_path = "gen_configurations.py".in_current_dir +template_path = "target_xcconfig.mustache".in_current_dir -# create config directory if needed +# 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 #{"gen_configurations.py".in_current_dir} > #{temp_configs_data_file}") +# Call python script and generate configs to config file +system("python #{generator_path} > #{temp_configs_data_file_path}") +# 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"] -# open settings, configurations and template files -settings = JSON.load(File.open(custom_settings_path)) -target_xcconfig_tempate = File.read("target_xcconfig.mustache".in_current_dir) -$configurations = YAML.load(File.open(configurations_yaml_file)) +# Set global property +targets = $configurations["targets"] -# set global property -targets = settings["targets"] - -# make tuple of key and value become mustache template element +# Make tuple of key and value become mustache template element def config_option(key, value) return { "key" => key, "value" => value } end -# return empty array or generated dev team hash -def generate_development_team(development_team_key, account_type) - current_config = case account_type - when "Standard" - $configurations["development"] - when "Enterprise" - $configurations["enterprise"] - when "AppStore" - $configurations["appstore"] - else - raise "Error: Unsupported distribution type #{account_type}" - 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 -# return empty array or generated provisioning profile hash -def generate_provisioning_profile(provisioning_key, bundle_id, account_type) - if account_type == "AppStore" - app_store_profiile = "match AppStore " + bundle_id - return config_option(provisioning_key, app_store_profiile) - else - return config_option(provisioning_key, bundle_id) - end +# Return empty array or generated provisioning profile hash +def generate_provisioning_profile(provisioning_key, bundle_id, distribution_type) + case distribution_type + when "appstore" + app_store_profile = "match AppStore " + bundle_id + config_option(provisioning_key, app_store_profile) + else + config_option(provisioning_key, bundle_id) + end end -def generate_bundle_id(target_name, account_type) - bundle_id_prefix = account_type == "Standard" ? $standard_bundle_prefix : $enterprise_bundle_prefix - bundle_id = bundle_id_prefix + target_name - return config_option($bundle_id_key, bundle_id) -end - -def generate_google_service_info_plist_path(google_service_info_plist_key, target_name, account_type) +def generate_google_service_info_plist_path(google_service_info_plist_key, target_name, distribution_type) google_service_info_plist_path = target_name + "/Resources/" - if account_type == "AppStore" - google_service_info_plist_path += "AppStore-GoogleService-Info.plist" - elsif account_type == "Enterprise" - google_service_info_plist_path += "Enterprise-GoogleService-Info.plist" - else - google_service_info_plist_path += "Standard-GoogleService-Info.plist" - end + path_suffix = case distribution_type + when "development" + "Standard-GoogleService-Info.plist" + when "enterprise" + "Enterprise-GoogleService-Info.plist" + else + "AppStore-GoogleService-Info.plist" + end - return config_option(google_service_info_plist_key, google_service_info_plist_path) + return config_option(google_service_info_plist_key, google_service_info_plist_path + path_suffix) end -# generate missing properties if needed -def generate_missing_properties(target_name, properties, account_type) +# Generate missing properties if needed +def generate_missing_properties(target_name, properties, distribution_type) result = [] development_team_key = "DEVELOPMENT_TEAM" provisioning_key = "PROVISIONING_PROFILE_SPECIFIER" google_service_info_plist_key = "GOOGLE_SERVICE_INFO_PLIST_PATH" + bundle_id_key = "PRODUCT_BUNDLE_IDENTIFIER" - unless properties.key?($bundle_id_key) - bundle_id_config = generate_bundle_id(target_name, account_type) - bundle_id = bundle_id_config["value"] - result.append(bundle_id_config) - else - bundle_id = properties[$bundle_id_key] + # 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(generate_development_team(development_team_key, account_type)) + result.append(fetch_development_team(development_team_key, distribution_type)) end unless properties.key?(provisioning_key) - result.append(generate_provisioning_profile(provisioning_key, bundle_id, account_type)) + result.append(generate_provisioning_profile(provisioning_key, bundle_id, distribution_type)) end unless properties.key?(google_service_info_plist_key) - result.append(generate_google_service_info_plist_path(google_service_info_plist_key, target_name, account_type)) + result.append(generate_google_service_info_plist_path(google_service_info_plist_key, target_name, distribution_type)) end return result end -# run through all target in project -targets.each do |target| +# 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))["configurations"] + # Need open everytime, because script make some changes only for this target + configs = JSON.load(File.open(temp_configs_data_file_path))["configurations"] - # run through all configs + # Run through all configs configs.each do |config| + + # Take default values + distribution_type = distribution_type_of(config["account_type"]) + properties = target[distribution_type] - # take default values - account_type = config["account_type"] - target_name = target.keys.first - properties = target[target_name][account_type] - - # add properties from settings file + # Add properties from settings file properties.each do |key, value| config["xcconfig_options"].append(config_option(key, value)) end - # add missing properties if needed - config["xcconfig_options"].concat(generate_missing_properties(target_name, properties, account_type)) + # Add missing properties if needed + config["xcconfig_options"].concat(generate_missing_properties(target_name, properties, distribution_type)) - # create settings pack + # Create settings pack config_data = { "target_name": target_name, "configuration": config } - # create file for every setting in loop + # 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)) } @@ -157,5 +153,5 @@ targets.each do |target| end -# remove config file, it's trash -File.delete(temp_configs_data_file) if File.exist?(temp_configs_data_file) +# Remove config file, it's trash +File.delete(temp_configs_data_file_path) if File.exist?(temp_configs_data_file_path) diff --git a/xcode/fastlane/touchlane/lib/configuration.rb b/xcode/fastlane/touchlane/lib/configuration.rb index a12c764..02cc4d3 100644 --- a/xcode/fastlane/touchlane/lib/configuration.rb +++ b/xcode/fastlane/touchlane/lib/configuration.rb @@ -13,18 +13,19 @@ module Touchlane attr_reader :type, :app_identifier, :apple_id, :team_id, :itc_team_id def self.from_file(path, type) - hash_of_types = load_hash_of_types_from_file(path) - attrs_hash = hash_of_types[type] + configuration_hash = load_configuration_from_file(path) + attrs_hash = configuration_hash["types"][type] + identifiers = get_app_identifiers_from_configuration_hash(configuration_hash, type) unless attrs_hash raise "There is no configuration with type #{type}. Available types: #{attrs_hash.keys}" else config_type = Touchlane::ConfigurationType.from_type(type) - new(config_type, attrs_hash["app_identifier"], attrs_hash["apple_id"], attrs_hash["team_id"], attrs_hash["itc_team_id"]) + new(config_type, identifiers, attrs_hash["apple_id"], attrs_hash["team_id"], attrs_hash["itc_team_id"]) end end - def self.load_hash_of_types_from_file(path) + def self.load_configuration_from_file(path) unless File.exists? path raise "Unable to load configurations from file at #{path}" else @@ -32,7 +33,14 @@ module Touchlane end end - private_class_method :new, :load_hash_of_types_from_file + def self.get_app_identifiers_from_configuration_hash(configuration_hash, type) + identifier_key = "PRODUCT_BUNDLE_IDENTIFIER" + configuration_hash["targets"].collect do |target, types| + types[type][identifier_key] or raise "#{target}: There is no #{identifier_key} field in #{type}" + end + end + + private_class_method :new, :load_configuration_from_file, :get_app_identifiers_from_configuration_hash def to_options {