class XcodeUtils::Command::UITest::Install

Public Class Methods

new(argv) click to toggle source
Calls superclass method
# File lib/xcutils/uitest.rb, line 30
def initialize(argv)
  @project_name = argv.option('project-name', nil)
  @taget_config = argv.option('target-config', nil)
  @target_scheme = argv.option('target-scheme', nil)
  @uitest_name = 'UITestRunner'
  @project_path = "./#{@project_name}.xcodeproj"
  super
  @additional_args = argv.remainder!
end
options() click to toggle source
# File lib/xcutils/uitest.rb, line 22
def self.options
  [
    ['--project-name', 'The name of your xcode project'],
    ['--target-config', 'The name of build configuration to be copied to uitestrunner build configuration'],
    ['--target-scheme', 'The name of build scheme to be copied to uitestrunner build scheme'],
  ]
end

Public Instance Methods

add_files(direc, current_group, main_target) click to toggle source
# File lib/xcutils/uitest.rb, line 196
def add_files(direc, current_group, main_target)
  Dir.glob(direc) do |item|
      next if item == '.' or item == '.DS_Store'
              if File.directory?(item)
          group_name = File.basename(item)
          created_group = current_group.new_group(nil, group_name)
          add_files("#{item}/*", created_group, main_target)
      else
        i = current_group.new_file(File.basename(item))
        
        if item.include? ".swift" or item.include? ".m"
          main_target.add_file_references([i])
        end

        if item.include? ".storyboard" or item.include? ".xib"
          set_custom_module(item)
          main_target.add_resources([i])
        else
          main_target.add_resources([i])
        end
      end
  end
end
appended(string, other) click to toggle source
# File lib/xcutils/uitest.rb, line 190
def appended(string, other)
  return other if string == nil
  return string if string.include? other
  return string << " #{other}"
end
copy_template_files() click to toggle source
# File lib/xcutils/uitest.rb, line 166
def copy_template_files
  puts "Copy template files"
    
  @project.targets.each { |target|
    template_path = "./#{target.name}/#{@uitest_name}"

    if !Dir.exist?(template_path)
      puts "\tCopying template files into target #{target.name}"
      path = File.expand_path('../../../templates', __FILE__)
      FileUtils.copy_entry path, "./#{target.name}"
    else
      puts "\tSkip to copy template files. Files are already exsit".gray
    end

    target_group = @project.groups.select { |e| e.path == target.name }.first

    if target_group.groups.select { |e| e.path == @uitest_name }.first.nil?
      puts "\tAdding references for files and resources into target #{target.name}"
      template_group = target_group.new_group(nil, @uitest_name)
      add_files("#{template_path}/*", template_group, target)
    end
  }
end
generate_build_configurations() click to toggle source
# File lib/xcutils/uitest.rb, line 89
def generate_build_configurations
  puts "Generating build configurations"
    
  @project.targets.each { |target|
    target_config = target.build_configurations.select { |e| e.name == @taget_config }.first
    target_main_sb = nil
    
    target.build_configurations.each { |e|
      break if e.name == @uitest_name

      puts "\tConfigure build configuration #{e.name} in #{target.name}"

      path = e.build_settings['INFOPLIST_FILE']
      plist = Plist.parse_xml(path)
      plist_main_sb = plist['UIMainStoryboardFile']
      build_settings_main_sb = e.build_settings['MAIN_STORYBOARD_FILE']
      variable_name = '$(MAIN_STORYBOARD_FILE)'
      is_not_variable = plist_main_sb != variable_name

      e.build_settings['MAIN_STORYBOARD_FILE'] = is_not_variable ? plist_main_sb : (target_main_sb != nil ? target_main_sb : build_settings_main_sb)
      
      if target_main_sb.nil?
        target_main_sb = build_settings_main_sb
      end

      plist['UIMainStoryboardFile'] = variable_name
    
      if is_not_variable
        File.write(path, plist.to_plist)
      end

      file_names_string = e.build_settings['EXCLUDED_SOURCE_FILE_NAMES']
      file_names_string = appended(file_names_string, '$(SRCROOT)/$(PRODUCT_NAME)/UITestRunner/*')
      file_names_string = appended(file_names_string, '$(SRCROOT)/$(PRODUCT_NAME)/UITestRunner/**/*')
      e.build_settings['EXCLUDED_SOURCE_FILE_NAMES'] = file_names_string
    }
    
    test_config = target.build_configurations.select { |e| e.name == @uitest_name }.first

    if test_config.nil?
      puts "\tGenerating build configuration #{@uitest_name} into #{target.name}"
      new_config = @project.new(Xcodeproj::Project::Object::XCBuildConfiguration)
      new_config.name = @uitest_name
      new_config.base_configuration_reference = target_config.base_configuration_reference
      target.build_configurations << new_config
    else
      puts "\tConfigure build configuration #{@uitest_name} in #{target.name}"
      new_config = test_config
    end

    new_config.build_settings.update(target_config.build_settings)
    new_config.build_settings['MAIN_STORYBOARD_FILE'] = @uitest_name
    new_config.build_settings['EXCLUDED_SOURCE_FILE_NAMES'] = nil
  }
end
generate_project_configuration() click to toggle source
# File lib/xcutils/uitest.rb, line 73
def generate_project_configuration
  puts "Generating project configuration #{@uitest_name} into #{@project_name}"
    
  configuration_list = @project.root_object.build_configuration_list
    
  if configuration_list.build_settings(@uitest_name) != nil
    puts "\tSkip to generate project configuration for #{@uitest_name}. It is already installed in the project #{@project_name}".gray
    return
  end
    
  configuration = @project.new(Xcodeproj::Project::Object::XCBuildConfiguration)
  configuration.name = @uitest_name
  configuration.build_settings = configuration_list.build_settings(@taget_config)
  configuration_list.build_configurations << configuration
end
generate_scheme_files() click to toggle source
# File lib/xcutils/uitest.rb, line 145
def generate_scheme_files
  puts "Generating scheme files"
    
  @project.targets.each { |target|
    scheme_name = "#{target.name} #{@uitest_name}"
    
    if File.exist?(scheme_path(scheme_name))
      puts "\tSkip to generate. A scheme file is already exsit, #{scheme_name}".gray
      next
    end
    
    puts "\tGenerating scheme file #{scheme_path(scheme_name)}"

    FileUtils.copy_file(scheme_path(@target_scheme), scheme_path(scheme_name))
    
    scheme = Xcodeproj::XCScheme.new(scheme_path(scheme_name))
    scheme.launch_action.build_configuration = @uitest_name
    scheme.save_as(@project_path, scheme_name)
  }
end
open_project() click to toggle source
# File lib/xcutils/uitest.rb, line 64
def open_project
  puts "Open project #{@project_name}"

  if !Dir.exist?(@project_path)
    abort "😭 Abort to install. Project #{project_name} does not exist".red
  end
  @project = Xcodeproj::Project.open(@project_path)
end
run() click to toggle source
# File lib/xcutils/uitest.rb, line 47
def run
  puts "🤖 Run: project_name: #{@project_name}, target_config: #{@taget_config}, target_scheme: #{@target_scheme}".green
  open_project
  generate_project_configuration
  generate_build_configurations
  generate_scheme_files
  copy_template_files

  if !@project.nil?
    puts "Save project".green
    @project.save()
    puts "🤩 Finished".green
  else
    puts "😡 Aborted".red
  end
end
scheme_path(name) click to toggle source
# File lib/xcutils/uitest.rb, line 233
def scheme_path(name)
  return "#{@project_path}/xcshareddata/xcschemes/#{name}.xcscheme"
end
set_custom_module(item) click to toggle source
# File lib/xcutils/uitest.rb, line 220
def set_custom_module(item)
  doc = Nokogiri::XML(File.open(item))
  nodes = doc.xpath("//viewController")

  nodes.each { |e|
    e['customModule'] = @project_name
  }

  if nodes.count > 0
    File.write(item, doc.to_xml)
  end
end
validate!() click to toggle source
Calls superclass method
# File lib/xcutils/uitest.rb, line 40
def validate!
  super
  help! 'Argument --project-name is required.' unless @project_name
  help! 'Argument --target-config is required.' unless @taget_config
  help! 'Argument --target-scheme is required.' unless @target_scheme
end