class Gym::PackageCommandGeneratorXcode7

Responsible for building the fully working xcodebuild command

Constants

DEFAULT_EXPORT_METHOD

Public Class Methods

app_thinning_path() click to toggle source

The path to the app-thinning plist file

# File gym/lib/gym/generators/package_command_generator_xcode7.rb, line 131
def app_thinning_path
  Gym.cache[:app_thinning] ||= File.join(temporary_output_path, "app-thinning.plist")
end
app_thinning_size_report_path() click to toggle source

The path to the App Thinning Size Report file

# File gym/lib/gym/generators/package_command_generator_xcode7.rb, line 136
def app_thinning_size_report_path
  Gym.cache[:app_thinning_size_report] ||= File.join(temporary_output_path, "App Thinning Size Report.txt")
end
apps_path() click to toggle source

The path to the Apps folder

# File gym/lib/gym/generators/package_command_generator_xcode7.rb, line 141
def apps_path
  Gym.cache[:apps_path] ||= File.join(temporary_output_path, "Apps")
end
appstore_info_path() click to toggle source
# File gym/lib/gym/generators/package_command_generator_xcode7.rb, line 150
def appstore_info_path
  Gym.cache[:appstore_info_path] ||= File.join(temporary_output_path, "AppStoreInfo.plist")
end
asset_packs_path() click to toggle source

The path to the Apps folder

# File gym/lib/gym/generators/package_command_generator_xcode7.rb, line 146
def asset_packs_path
  Gym.cache[:asset_packs_path] ||= File.join(temporary_output_path, "OnDemandResources")
end
binary_path() click to toggle source
# File gym/lib/gym/generators/package_command_generator_xcode7.rb, line 85
def binary_path
  path = Gym.cache[:binary_path]
  return path if path

  path = Dir[File.join(temporary_output_path, "*.pkg")].last
  app_path = Dir[File.join(temporary_output_path, "*.app")].last
  # We need to process generic PKG or APP
  if path
    # Try to find PKG file in the output directory, used when app thinning was not set
    Gym.cache[:binary_path] = File.join(temporary_output_path, "#{Gym.config[:output_name]}.pkg")
    FileUtils.mv(path, Gym.cache[:binary_path]) unless File.expand_path(path).casecmp(File.expand_path(Gym.cache[:binary_path]).downcase).zero?
  elsif Dir.exist?(apps_path)
    # Try to find "generic" PKG file inside "Apps" folder, used when app thinning was set
    files = Dir[File.join(apps_path, "*.pkg")]
    # Generic PKG file doesn't have suffix so its name is the shortest
    path = files.min_by(&:length)
    Gym.cache[:binary_path] = File.join(temporary_output_path, "#{Gym.config[:output_name]}.pkg")
    FileUtils.cp(path, Gym.cache[:binary_path]) unless File.expand_path(path).casecmp(File.expand_path(Gym.cache[:binary_path]).downcase).zero?
  elsif app_path
    # Try to find .app file in the output directory. This is used when macOS is set and .app is being generated.
    Gym.cache[:binary_path] = File.join(temporary_output_path, "#{Gym.config[:output_name]}.app")
    FileUtils.mv(app_path, Gym.cache[:binary_path]) unless File.expand_path(app_path).casecmp(File.expand_path(Gym.cache[:binary_path]).downcase).zero?
  else
    ErrorHandler.handle_empty_pkg unless path
  end

  Gym.cache[:binary_path]
end
config_path() click to toggle source

The path the config file we use to sign our app

# File gym/lib/gym/generators/package_command_generator_xcode7.rb, line 120
def config_path
  Gym.cache[:config_path] ||= "#{Tempfile.new('gym_config').path}.plist"
  return Gym.cache[:config_path]
end
dsym_path() click to toggle source

The path the the dsym file for this app. Might be nil

# File gym/lib/gym/generators/package_command_generator_xcode7.rb, line 115
def dsym_path
  Dir[BuildCommandGenerator.archive_path + "/**/*.app.dSYM"].last
end
generate() click to toggle source
# File gym/lib/gym/generators/package_command_generator_xcode7.rb, line 22
def generate
  parts = ["/usr/bin/xcrun #{wrap_xcodebuild.shellescape} -exportArchive"]
  parts += options
  parts += pipe

  File.write(config_path, config_content) # overwrite everytime. Could be optimized

  parts
end
ipa_path() click to toggle source
# File gym/lib/gym/generators/package_command_generator_xcode7.rb, line 61
def ipa_path
  path = Gym.cache[:ipa_path]
  return path if path

  path = Dir[File.join(temporary_output_path, "*.ipa")].last
  # We need to process generic IPA
  if path
    # Try to find IPA file in the output directory, used when app thinning was not set
    Gym.cache[:ipa_path] = File.join(temporary_output_path, "#{Gym.config[:output_name]}.ipa")
    FileUtils.mv(path, Gym.cache[:ipa_path]) unless File.expand_path(path).casecmp?(File.expand_path(Gym.cache[:ipa_path]).downcase)
  elsif Dir.exist?(apps_path)
    # Try to find "generic" IPA file inside "Apps" folder, used when app thinning was set
    files = Dir[File.join(apps_path, "*.ipa")]
    # Generic IPA file doesn't have suffix so its name is the shortest
    path = files.min_by(&:length)
    Gym.cache[:ipa_path] = File.join(temporary_output_path, "#{Gym.config[:output_name]}.ipa")
    FileUtils.cp(path, Gym.cache[:ipa_path]) unless File.expand_path(path).casecmp?(File.expand_path(Gym.cache[:ipa_path]).downcase)
  else
    ErrorHandler.handle_empty_ipa unless path
  end

  Gym.cache[:ipa_path]
end
manifest_path() click to toggle source

The path to the manifest plist file

# File gym/lib/gym/generators/package_command_generator_xcode7.rb, line 126
def manifest_path
  Gym.cache[:manifest_path] ||= File.join(temporary_output_path, "manifest.plist")
end
options() click to toggle source
# File gym/lib/gym/generators/package_command_generator_xcode7.rb, line 32
def options
  config = Gym.config

  options = []
  options << "-exportOptionsPlist '#{config_path}'"
  options << "-archivePath #{BuildCommandGenerator.archive_path.shellescape}"
  options << "-exportPath '#{temporary_output_path}'"
  options << "-toolchain '#{config[:toolchain]}'" if config[:toolchain]
  options << config[:export_xcargs] if config[:export_xcargs]
  options << config[:xcargs] if config[:xcargs]

  options
end
pipe() click to toggle source
# File gym/lib/gym/generators/package_command_generator_xcode7.rb, line 46
def pipe
  [""]
end
temporary_output_path() click to toggle source

We export the ipa into this directory, as we can't specify the ipa file directly

# File gym/lib/gym/generators/package_command_generator_xcode7.rb, line 51
def temporary_output_path
  Gym.cache[:temporary_output_path] ||= Dir.mktmpdir('gym_output')
end
wrap_xcodebuild() click to toggle source

Wrap xcodebuild to work-around ipatool dependency to system ruby

# File gym/lib/gym/generators/package_command_generator_xcode7.rb, line 56
def wrap_xcodebuild
  require 'fileutils'
  @wrapped_xcodebuild_path ||= File.join(Gym::ROOT, "lib/assets/wrap_xcodebuild/xcbuild-safe.sh")
end

Private Class Methods

config_content() click to toggle source
# File gym/lib/gym/generators/package_command_generator_xcode7.rb, line 188
def config_content
  hash = read_export_options

  # Overrides export options if needed
  hash[:method] = Gym.config[:export_method]
  if Gym.config[:export_method] == 'app-store'
    hash[:uploadSymbols] = (Gym.config[:include_symbols] ? true : false) unless Gym.config[:include_symbols].nil?
    hash[:uploadBitcode] = (Gym.config[:include_bitcode] ? true : false) unless Gym.config[:include_bitcode].nil?
  end

  # xcodebuild will not use provisioning profiles
  # if we don't specify signingStyle as manual
  if Helper.xcode_at_least?("9.0") && hash[:provisioningProfiles]
    hash[:signingStyle] = 'manual'
  end

  if Gym.config[:installer_cert_name] && (Gym.project.mac? || Gym.building_mac_catalyst_for_mac?)
    hash[:installerSigningCertificate] = Gym.config[:installer_cert_name]
  end

  hash[:teamID] = Gym.config[:export_team_id] if Gym.config[:export_team_id]

  UI.important("Generated plist file with the following values:")
  UI.command_output("-----------------------------------------")
  UI.command_output(JSON.pretty_generate(hash))
  UI.command_output("-----------------------------------------")
  if FastlaneCore::Globals.verbose?
    UI.message("This results in the following plist file:")
    UI.command_output("-----------------------------------------")
    UI.command_output(hash.to_plist)
    UI.command_output("-----------------------------------------")
  end

  hash.to_plist
end
normalize_export_options(hash) click to toggle source
# File gym/lib/gym/generators/package_command_generator_xcode7.rb, line 156
def normalize_export_options(hash)
  # Normalize some values
  hash[:onDemandResourcesAssetPacksBaseURL] = Addressable::URI.encode(hash[:onDemandResourcesAssetPacksBaseURL]) if hash[:onDemandResourcesAssetPacksBaseURL]
  if hash[:manifest]
    hash[:manifest][:appURL] = Addressable::URI.encode(hash[:manifest][:appURL]) if hash[:manifest][:appURL]
    hash[:manifest][:displayImageURL] = Addressable::URI.encode(hash[:manifest][:displayImageURL]) if hash[:manifest][:displayImageURL]
    hash[:manifest][:fullSizeImageURL] = Addressable::URI.encode(hash[:manifest][:fullSizeImageURL]) if hash[:manifest][:fullSizeImageURL]
    hash[:manifest][:assetPackManifestURL] = Addressable::URI.encode(hash[:manifest][:assetPackManifestURL]) if hash[:manifest][:assetPackManifestURL]
  end
  hash
end
read_export_options() click to toggle source
# File gym/lib/gym/generators/package_command_generator_xcode7.rb, line 168
def read_export_options
  # Reads export options
  if Gym.config[:export_options]
    hash = normalize_export_options(Gym.config[:export_options])

    # Saves configuration for later use
    Gym.config[:export_method] ||= hash[:method] || DEFAULT_EXPORT_METHOD
    Gym.config[:include_symbols] = hash[:uploadSymbols] if Gym.config[:include_symbols].nil?
    Gym.config[:include_bitcode] = hash[:uploadBitcode] if Gym.config[:include_bitcode].nil?
    Gym.config[:export_team_id] ||= hash[:teamID]
  else
    hash = {}
    # Sets default values
    Gym.config[:export_method] ||= DEFAULT_EXPORT_METHOD
    Gym.config[:include_symbols] = true if Gym.config[:include_symbols].nil?
    Gym.config[:include_bitcode] = false if Gym.config[:include_bitcode].nil?
  end
  hash
end
signing_style() click to toggle source
# File gym/lib/gym/generators/package_command_generator_xcode7.rb, line 224
def signing_style
  projects = Gym.project.project_paths
  project = projects.first
  xcodeproj = Xcodeproj::Project.open(project)
  xcodeproj.root_object.attributes["TargetAttributes"].each do |target, sett|
    return sett["ProvisioningStyle"].to_s.downcase
  end
rescue => e
  UI.verbose(e.to_s)
  UI.error("Unable to read provisioning style from .pbxproj file.")
  return "automatic"
end