module Nixenvironment class BuildEnvVarsLoader def self.save_last_build_vars(config_settings) executable_name = config_settings[EXECUTABLE_NAME_KEY] watchkit_app_executable = executable_name + WATCHKIT_APP_SUFFIX_WITH_EXT watchkit_extension_executable = executable_name + WATCHKIT_EXTENSION_SUFFIX_WITH_EXT widget_executable = executable_name + WIDGET_SUFFIX_WITH_EXT app_product = File.join(config_settings[BUILT_PRODUCTS_DIR_KEY], executable_name) + APP_EXT watchkit_extension_relative_product = config_settings[RESIGNED_WATCHKIT_EXTENSION_BUNDLE_ID_KEY].nil? ? nil : File.join(IOS_PLUGINS_FOLDER_NAME, watchkit_extension_executable) watchkit_app_relative_product = config_settings[RESIGNED_WATCHKIT_APP_BUNDLE_ID_KEY].nil? ? nil : File.join(watchkit_extension_relative_product, watchkit_app_executable) widget_relative_product = config_settings[RESIGNED_WIDGET_BUNDLE_ID_KEY].nil? ? nil : File.join(IOS_PLUGINS_FOLDER_NAME, widget_executable) resigned_watchkit_extension_entitlements_path = config_settings[RESIGNED_WATCHKIT_EXTENSION_ENTITLEMENTS_PATH_KEY].nil? ? nil : @config_settings[RESIGNED_WATCHKIT_EXTENSION_ENTITLEMENTS_PATH_KEY] resigned_widget_entitlements_path = config_settings[RESIGNED_WIDGET_ENTITLEMENTS_PATH_KEY].nil? ? nil : @config_settings[RESIGNED_WIDGET_ENTITLEMENTS_PATH_KEY] embedded_profile = File.join(app_product, config_settings[EMBEDDED_PROFILE_NAME_KEY]) system(" echo \"#!/bin/sh\ #{AUTOGENERATED_FILES_HEADER} PROJECT='#{config_settings[PROJECT_KEY]}' BUILT_PRODUCTS_DIR='#{config_settings[BUILT_PRODUCTS_DIR_KEY]}' OBJECTS_NORMAL_DIR='#{config_settings[OBJECT_FILE_DIR_NORMAL_KEY]}' EXECUTABLE_NAME='#{config_settings[EXECUTABLE_NAME_KEY]}' APP_PRODUCT='#{app_product}' WATCHKIT_APP_RELATIVE_PRODUCT='#{watchkit_app_relative_product}' WATCHKIT_EXTENSION_RELATIVE_PRODUCT='#{watchkit_extension_relative_product}' WIDGET_RELATIVE_PRODUCT='#{widget_relative_product}' APP_DSYM='#{app_product + DSYM_EXT}' EMBEDDED_PROFILE='#{embedded_profile}' TARGET_NAME='#{config_settings[TARGET_NAME_KEY]}' CONFIGURATION='#{config_settings[CONFIGURATION_KEY]}' SDK_NAME='#{config_settings[SDK_NAME_KEY]}' RESIGNED_BUNDLE_ID='#{config_settings[RESIGNED_BUNDLE_ID_KEY]}' RESIGNED_WATCHKIT_APP_BUNDLE_ID='#{config_settings[RESIGNED_WATCHKIT_APP_BUNDLE_ID_KEY]}' RESIGNED_WATCHKIT_EXTENSION_BUNDLE_ID='#{config_settings[RESIGNED_WATCHKIT_EXTENSION_BUNDLE_ID_KEY]}' RESIGNED_WIDGET_BUNDLE_ID='#{config_settings[RESIGNED_WIDGET_BUNDLE_ID_KEY]}' RESIGNED_BUNDLE_NAME='#{config_settings[RESIGNED_BUNDLE_NAME_KEY]}' RESIGNED_ENTITLEMENTS_PATH='#{config_settings[RESIGNED_ENTITLEMENTS_PATH_KEY]}' RESIGNED_WATCHKIT_EXTENSION_ENTITLEMENTS_PATH='#{resigned_watchkit_extension_entitlements_path}' RESIGNED_WIDGET_ENTITLEMENTS_PATH='#{resigned_widget_entitlements_path}'\" > #{AUTOGENERATED_LAST_BUILD_VARS} ") end def self.save_last_revision(revision, monotonic_revision, working_copy_is_clean) system(" echo \"#!/bin/sh\ #{AUTOGENERATED_FILES_HEADER} REVISION='#{revision}' MONOTONIC_REVISION='#{monotonic_revision}' WORKING_COPY_IS_CLEAN='#{working_copy_is_clean}'\" > #{AUTOGENERATED_LAST_REVISION} ") end def self.load build_env_vars = load_last_revision.merge(load_last_build_vars) app_product_path = build_env_vars[APP_PRODUCT_KEY] embedded_profile = build_env_vars['EMBEDDED_PROFILE'] monotonic_revision = build_env_vars['MONOTONIC_REVISION'] sdk = build_env_vars[SDK_NAME_KEY] info_plist_relative_path = nil if sdk.include?('iphoneos') embedded_profile_exist = embedded_profile.present? && File.exist?(embedded_profile) embedded_profile_name = embedded_profile_exist ? %x[ /usr/libexec/PlistBuddy -c 'Print :Name' /dev/stdin <<< $(security cms -D -i '#{embedded_profile}') ].strip : 'SIMULATOR' info_plist_relative_path = 'Info.plist' elsif sdk.include?('macos') info_plist_relative_path = 'Contents/Info.plist' end info_plist_path = File.join(app_product_path, info_plist_relative_path) info_plist = Plist.from_file(info_plist_path) current_app_version = info_plist['CFBundleShortVersionString'] build_env_vars[EMBEDDED_PROFILE_NAME_KEY] = embedded_profile_name build_env_vars[CURRENT_APP_VERSION_KEY] = current_app_version build_env_vars[CURRENT_BUILD_VERSION_KEY] = monotonic_revision puts puts "#{EMBEDDED_PROFILE_NAME_KEY} = #{embedded_profile_name}" # TODO: find out why it's blank!!! puts "#{CURRENT_APP_VERSION_KEY} = #{current_app_version}" puts "#{CURRENT_BUILD_VERSION_KEY} = #{monotonic_revision}" puts build_env_vars end def self.load_last_revision load_internal(AUTOGENERATED_LAST_REVISION, false) end def self.load_last_build_vars load_internal(AUTOGENERATED_LAST_BUILD_VARS, false) end def self.working_copy_is_clean? working_copy_is_clean = load_last_revision['WORKING_COPY_IS_CLEAN'] == '1' if working_copy_is_clean puts 'Working copy is clean. Continuing ...' else puts 'error: working copy must not have local modifications.' puts 'You must add following files and folders to .gitignore:' Git.status(:porcelain => true) end working_copy_is_clean end def self.load_internal(file, print_log = true) raise "error: file '#{file}' must exist!" unless File.exist?(file) build_env_vars = {} vars_list = File.read(file).lines.reject(&:empty?) if vars_list.present? puts if print_log vars_to_strip = Hash[vars_list.map { |it| it.split('=', 2) }] vars_to_strip.each do |key, value| if key.present? && !key.include?(AUTOGENERATED_FILES_HEADER) stripped_key = key.strip stripped_value = value ? value.tr("'", '').strip : 'unknown' puts "#{stripped_key} = #{stripped_value}" if print_log build_env_vars[stripped_key] = stripped_value end end puts if print_log end build_env_vars end private_class_method :load_internal end end