From b6ef418a07aa88abddfac2e32eea08f83964e604 Mon Sep 17 00:00:00 2001 From: Sergey Kopytov Date: Thu, 12 Sep 2019 22:35:27 +0300 Subject: [PATCH 1/4] add configs generator script --- xcode/config_generator/Readme.md | 3 + xcode/config_generator/gen_configurations.py | 94 ++++++++++++++++++ xcode/config_generator/render_xcconfigs.rb | 98 +++++++++++++++++++ xcode/config_generator/settings.json | 25 +++++ .../config_generator/target_xcconfig.mustache | 7 ++ 5 files changed, 227 insertions(+) create mode 100644 xcode/config_generator/Readme.md create mode 100644 xcode/config_generator/gen_configurations.py create mode 100644 xcode/config_generator/render_xcconfigs.rb create mode 100644 xcode/config_generator/settings.json create mode 100644 xcode/config_generator/target_xcconfig.mustache diff --git a/xcode/config_generator/Readme.md b/xcode/config_generator/Readme.md new file mode 100644 index 0000000..77fe832 --- /dev/null +++ b/xcode/config_generator/Readme.md @@ -0,0 +1,3 @@ +# Генератор конфигурационных файлов в формате `.xcconfig` + + здесь должна быть инструкция или ссылка на нее \ No newline at end of file diff --git a/xcode/config_generator/gen_configurations.py b/xcode/config_generator/gen_configurations.py new file mode 100644 index 0000000..22845ed --- /dev/null +++ b/xcode/config_generator/gen_configurations.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from __future__ import unicode_literals # python 2/3 support + +from itertools import chain +import json + +distribution_options = ["Enterprise", "Standard"] +server_type_options = ["Mock", "Touchin", "Customer"] +server_environment_options = ["Dev", "Test", "Stage", "Prod"] +ssl_pinning_options = ["WithSSLPinning", "WithoutSSLPinning"] +build_type_options = ["Debug", "Release"] + +all_options = [ + distribution_options, + server_type_options, + server_environment_options, + ssl_pinning_options, + build_type_options +] + +def combine_string_with_options(all_options, string="", applied_options=[]): + if len(all_options) == 0: + yield string, applied_options + return + + for current_option in chain.from_iterable(all_options[:1]): + for result_tuple in combine_string_with_options(all_options[1:], string + current_option, applied_options + [current_option]): + yield result_tuple + + yield ("AppStoreRelease", ['AppStore', 'Customer', 'Prod', 'WithSSLPinning', 'Release']) + +def make_config_dict(args): + config_name, applied_options = args + + if "Enterprise" in applied_options: + account_type = "Enterprise" + elif "Standard" in applied_options: + account_type = "Standard" + else: + account_type = "AppStore" + + if "Debug" in applied_options: + build_type = "debug" + elif "AppStore" in applied_options: + build_type = "appstore" + else: + build_type = "release" + + return { + "name": config_name, + "build_type": build_type, + "account_type": account_type, + "xcconfig_options": [ + { + "key": "SWIFT_ACTIVE_COMPILATION_CONDITIONS", + "value": " ".join(map(lambda option: option.upper(), applied_options)) + }, + { + "key": "DEBUG_INFORMATION_FORMAT", + "value": "dwarf" if "Debug" in applied_options else "dwarf-with-dsym" + }, + { + "key": "VALIDATE_PRODUCT", + "value": "NO" if "Debug" in applied_options else "YES" + }, + { + "key": "ENABLE_TESTABILITY", + "value": "YES" if "Debug" in applied_options else "NO" + }, + { + "key": "CODE_SIGN_IDENTITY", + "value": "iPhone Developer" if account_type == "Standard" else "iPhone Distribution" + }, + { + "key": "GCC_OPTIMIZATION_LEVEL", + "value": "0" if "Debug" in applied_options else "s" + }, + { + "key": "SWIFT_OPTIMIZATION_LEVEL", + "value": "-Onone" if "Debug" in applied_options else "-O" + }, + { + "key": "SWIFT_COMPILATION_MODE", + "value": "singlefile" if "Debug" in applied_options else "wholemodule" + } + ] + } + + +config_dicts = map(make_config_dict, combine_string_with_options(all_options)) + +print(json.dumps({"configurations": config_dicts}, indent=4)) diff --git a/xcode/config_generator/render_xcconfigs.rb b/xcode/config_generator/render_xcconfigs.rb new file mode 100644 index 0000000..750a2e7 --- /dev/null +++ b/xcode/config_generator/render_xcconfigs.rb @@ -0,0 +1,98 @@ +require 'json' +require 'mustache' + + +# create config files if needed +system("touch configs_data.json") unless File.exist?("configs_data") +system("mkdir TargetConfigurations") unless Dir.exist?("TargetConfigurations") + +# call python script and generate configs to config file +system("python gen_configurations.py > configs_data.json") + + +# open settings + template file +settings = JSON.load(File.open("settings.json")) +target_xcconfig_tempate = File.read("target_xcconfig.mustache") + + +# set global property +targets = settings["targets"] + +# 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 development_team_if_needed(properties, account_type) + development_team_key = "DEVELOPMENT_TEAM" + if properties.key?(development_team_key) + return [] + end + + team_value = account_type == "Standard" ? "D4HA43V467" : "228J5MMU7S" + return [config_option(development_team_key, team_value)] +end + +# return empty array or generated provisioning profile hash +def provisioning_profile_if_needed(properties, account_type) + provisioning_key = "PROVISIONING_PROFILE_SPECIFIER" + if properties.key?(provisioning_key) + return [] + end + + bundle_id = properties["PRODUCT_BUNDLE_IDENTIFIER"] + 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 +end + +# generate missing properties if needed +def generate_missing_properties(properties, account_type) + result = [] + result.concat(development_team_if_needed(properties, account_type)) + result.concat(provisioning_profile_if_needed(properties, account_type)) + return result +end + +# run through all target in project +targets.each do |target| + + # need open everytime, because script make some changes only for this target + configs = JSON.load(File.open("configs_data.json"))["configurations"] + + # run through all configs + configs.each do |config| + + # take default values + account_type = config["account_type"] + target_name = target.keys.first + properties = target[target_name][account_type] + + # 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(properties, account_type)) + + # create settings pack + config_data = { + "target_name": target_name, + "configuration": config + } + + # create file for every setting in loop + File.open("TargetConfigurations/" + target_name + config["name"] + ".xcconfig", 'w') { |file| + file.puts(Mustache.render(target_xcconfig_tempate, config_data)) + } + end + +end + +# remove config file, it's trash +system("rm configs_data.json") if File.exist?("configs_data.json") diff --git a/xcode/config_generator/settings.json b/xcode/config_generator/settings.json new file mode 100644 index 0000000..d70867d --- /dev/null +++ b/xcode/config_generator/settings.json @@ -0,0 +1,25 @@ +{ + "targets": [ + { + "target_name": { + "Standard": { + "PROVISIONING_PROFILE_SPECIFIER": "", + "PRODUCT_BUNDLE_IDENTIFIER": "", + "CODE_SIGN_ENTITLEMENTS": "" + }, + + "Enterprise": { + "PROVISIONING_PROFILE_SPECIFIER": "", + "PRODUCT_BUNDLE_IDENTIFIER": "", + "CODE_SIGN_ENTITLEMENTS": "" + }, + + "AppStore": { + "DEVELOPMENT_TEAM": "", + "PRODUCT_BUNDLE_IDENTIFIER": "", + "CODE_SIGN_ENTITLEMENTS": "" + } + } + } + ] +} diff --git a/xcode/config_generator/target_xcconfig.mustache b/xcode/config_generator/target_xcconfig.mustache new file mode 100644 index 0000000..7e5477a --- /dev/null +++ b/xcode/config_generator/target_xcconfig.mustache @@ -0,0 +1,7 @@ +#include "Pods/Target Support Files/Pods-{{target_name}}/Pods-{{target_name}}.{{configuration.build_type}}.xcconfig" + +{{#configuration.xcconfig_options}} +{{key}} = {{value}} +{{/configuration.xcconfig_options}} + +CODE_SIGN_STYLE = Manual \ No newline at end of file From 20d4e506983a61a483c81035236513cd541c7104 Mon Sep 17 00:00:00 2001 From: Sergey Kopytov Date: Fri, 13 Sep 2019 14:15:48 +0300 Subject: [PATCH 2/4] refactor --- xcode/config_generator/Readme.md | 3 --- xcode/config_generator/render_xcconfigs.rb | 14 +++++++++----- xcode/config_generator/settings.json | 2 +- 3 files changed, 10 insertions(+), 9 deletions(-) delete mode 100644 xcode/config_generator/Readme.md diff --git a/xcode/config_generator/Readme.md b/xcode/config_generator/Readme.md deleted file mode 100644 index 77fe832..0000000 --- a/xcode/config_generator/Readme.md +++ /dev/null @@ -1,3 +0,0 @@ -# Генератор конфигурационных файлов в формате `.xcconfig` - - здесь должна быть инструкция или ссылка на нее \ No newline at end of file diff --git a/xcode/config_generator/render_xcconfigs.rb b/xcode/config_generator/render_xcconfigs.rb index 750a2e7..a3eecb5 100644 --- a/xcode/config_generator/render_xcconfigs.rb +++ b/xcode/config_generator/render_xcconfigs.rb @@ -1,10 +1,14 @@ require 'json' require 'mustache' +# Constants +configs_folder_name = "TargetConfigurations" +standard_dev_team = "D4HA43V467" +enterprise_dev_team = "228J5MMU7S" # create config files if needed -system("touch configs_data.json") unless File.exist?("configs_data") -system("mkdir TargetConfigurations") unless Dir.exist?("TargetConfigurations") +File.new("configs_data.json", 'a') +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 > configs_data.json") @@ -30,7 +34,7 @@ def development_team_if_needed(properties, account_type) return [] end - team_value = account_type == "Standard" ? "D4HA43V467" : "228J5MMU7S" + team_value = account_type == "Standard" ? standard_dev_team : enterprise_dev_team return [config_option(development_team_key, team_value)] end @@ -87,7 +91,7 @@ targets.each do |target| } # create file for every setting in loop - File.open("TargetConfigurations/" + target_name + config["name"] + ".xcconfig", 'w') { |file| + File.open(configs_folder_name + "/" + target_name + config["name"] + ".xcconfig", 'w') { |file| file.puts(Mustache.render(target_xcconfig_tempate, config_data)) } end @@ -95,4 +99,4 @@ targets.each do |target| end # remove config file, it's trash -system("rm configs_data.json") if File.exist?("configs_data.json") +File.delete("configs_data.json") if File.exist?("configs_data.json") diff --git a/xcode/config_generator/settings.json b/xcode/config_generator/settings.json index d70867d..a190324 100644 --- a/xcode/config_generator/settings.json +++ b/xcode/config_generator/settings.json @@ -1,7 +1,7 @@ { "targets": [ { - "target_name": { + "YOUR_TARGET_NAME": { "Standard": { "PROVISIONING_PROFILE_SPECIFIER": "", "PRODUCT_BUNDLE_IDENTIFIER": "", From dea34e68e7bae8fb96eef44a4fc2541e74f5c093 Mon Sep 17 00:00:00 2001 From: Sergey Kopytov Date: Fri, 13 Sep 2019 14:29:05 +0300 Subject: [PATCH 3/4] refactor generators functions --- xcode/config_generator/render_xcconfigs.rb | 32 ++++++++++------------ 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/xcode/config_generator/render_xcconfigs.rb b/xcode/config_generator/render_xcconfigs.rb index a3eecb5..081051d 100644 --- a/xcode/config_generator/render_xcconfigs.rb +++ b/xcode/config_generator/render_xcconfigs.rb @@ -28,37 +28,35 @@ def config_option(key, value) end # return empty array or generated dev team hash -def development_team_if_needed(properties, account_type) - development_team_key = "DEVELOPMENT_TEAM" - if properties.key?(development_team_key) - return [] - end - +def generate_development_team(account_type) team_value = account_type == "Standard" ? standard_dev_team : enterprise_dev_team - return [config_option(development_team_key, team_value)] + return config_option(development_team_key, team_value) end # return empty array or generated provisioning profile hash -def provisioning_profile_if_needed(properties, account_type) - provisioning_key = "PROVISIONING_PROFILE_SPECIFIER" - if properties.key?(provisioning_key) - return [] - end - - bundle_id = properties["PRODUCT_BUNDLE_IDENTIFIER"] +def generate_provisioning_profile(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)] + return config_option(provisioning_key, bundle_id) end end # generate missing properties if needed def generate_missing_properties(properties, account_type) result = [] - result.concat(development_team_if_needed(properties, account_type)) - result.concat(provisioning_profile_if_needed(properties, account_type)) + development_team_key = "DEVELOPMENT_TEAM" + provisioning_key = "PROVISIONING_PROFILE_SPECIFIER" + + unless properties.key?(development_team_key) + result.append(generate_development_team(account_type)) + end + + unless properties.key?(provisioning_key) + result.append(generate_provisioning_profile(properties["PRODUCT_BUNDLE_IDENTIFIER"], account_type)) + end + return result end From 1a381bad79d39664c8182560ed97ef2576510816 Mon Sep 17 00:00:00 2001 From: Sergey Kopytov Date: Mon, 16 Sep 2019 13:59:09 +0300 Subject: [PATCH 4/4] refactor --- .../{settings.json => custom_settings.json} | 0 xcode/config_generator/render_xcconfigs.rb | 25 +++++++++---------- 2 files changed, 12 insertions(+), 13 deletions(-) rename xcode/config_generator/{settings.json => custom_settings.json} (100%) diff --git a/xcode/config_generator/settings.json b/xcode/config_generator/custom_settings.json similarity index 100% rename from xcode/config_generator/settings.json rename to xcode/config_generator/custom_settings.json diff --git a/xcode/config_generator/render_xcconfigs.rb b/xcode/config_generator/render_xcconfigs.rb index 081051d..b4ad9b7 100644 --- a/xcode/config_generator/render_xcconfigs.rb +++ b/xcode/config_generator/render_xcconfigs.rb @@ -2,20 +2,19 @@ require 'json' require 'mustache' # Constants -configs_folder_name = "TargetConfigurations" -standard_dev_team = "D4HA43V467" -enterprise_dev_team = "228J5MMU7S" +$configs_folder_name = "TargetConfigurations" +$standard_dev_team = "D4HA43V467" +$enterprise_dev_team = "228J5MMU7S" -# create config files if needed -File.new("configs_data.json", 'a') -Dir.mkdir(configs_folder_name) unless Dir.exist?(configs_folder_name) +# 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 > configs_data.json") # open settings + template file -settings = JSON.load(File.open("settings.json")) +settings = JSON.load(File.open("custom_settings.json")) target_xcconfig_tempate = File.read("target_xcconfig.mustache") @@ -28,13 +27,13 @@ def config_option(key, value) end # return empty array or generated dev team hash -def generate_development_team(account_type) - team_value = account_type == "Standard" ? standard_dev_team : enterprise_dev_team +def generate_development_team(development_team_key, account_type) + team_value = account_type == "Standard" ? $standard_dev_team : $enterprise_dev_team return config_option(development_team_key, team_value) end # return empty array or generated provisioning profile hash -def generate_provisioning_profile(bundle_id, account_type) +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)] @@ -50,11 +49,11 @@ def generate_missing_properties(properties, account_type) provisioning_key = "PROVISIONING_PROFILE_SPECIFIER" unless properties.key?(development_team_key) - result.append(generate_development_team(account_type)) + result.append(generate_development_team(development_team_key, account_type)) end unless properties.key?(provisioning_key) - result.append(generate_provisioning_profile(properties["PRODUCT_BUNDLE_IDENTIFIER"], account_type)) + result.append(generate_provisioning_profile(provisioning_key, properties["PRODUCT_BUNDLE_IDENTIFIER"], account_type)) end return result @@ -89,7 +88,7 @@ targets.each do |target| } # create file for every setting in loop - File.open(configs_folder_name + "/" + target_name + config["name"] + ".xcconfig", 'w') { |file| + File.open($configs_folder_name + "/" + target_name + config["name"] + ".xcconfig", 'w') { |file| file.puts(Mustache.render(target_xcconfig_tempate, config_data)) } end