<commit_before>module Fastlane
  module Actions
    class IncrementBuildNumberInXcodeprojAction < Action
      def self.run(params)
        unless params[:xcodeproj]
          if Helper.test?
            params[:xcodeproj] = "/tmp/fastlane/tests/fastlane/xcodeproj/versioning_fixture_project.xcodeproj"
          else
            params[:xcodeproj] = Dir["*.xcodeproj"][0] unless params[:xcodeproj]
          end
        end

        if params[:build_number]
          next_build_number = params[:build_number]
        else
          current_build_number = GetBuildNumberFromXcodeprojAction.run(params)
          build_array = current_build_number.split(".").map(&:to_i)
          build_array[-1] = build_array[-1] + 1
          next_build_number = build_array.join(".")
        end

        if params[:target]
          set_build_number_using_target(params, next_build_number)
        elsif params[:build_configuration_name] && params[:scheme]
          set_build_number_using_scheme(params, next_build_number)
        else
          set_all_xcodeproj_build_numbers(params, next_build_number)
        end
        Actions.lane_context[SharedValues::BUILD_NUMBER] = next_build_number
        next_build_number
      end

      def self.set_all_xcodeproj_build_numbers(params, next_build_number)
        project = Xcodeproj::Project.open(params[:xcodeproj])
        configs = project.objects.select { |obj| select_build_configuration_predicate(nil, obj) }
        configs.each do |config|
          config.build_settings["CURRENT_PROJECT_VERSION"] = next_build_number
        end
        project.save
      end

      private_class_method
      def self.select_build_configuration_predicate(name, configuration)
        is_build_valid_configuration = configuration.isa == "XCBuildConfiguration" && !configuration.build_settings["PRODUCT_BUNDLE_IDENTIFIER"].nil?
        is_build_valid_configuration &&= configuration.name == name unless name.nil?
        return is_build_valid_configuration
      end

      def self.set_build_number_using_target(params, next_build_number)
        project = Xcodeproj::Project.open(params[:xcodeproj])
        if params[:target]
          target = project.targets.detect { |t| t.name == params[:target] }
        else
          # firstly we are trying to find modern application target
          target = project.targets.detect do |t|
            t.kind_of?(Xcodeproj::Project::Object::PBXNativeTarget) &&
              t.product_type == 'com.apple.product-type.application'
          end
          target = project.targets[0] if target.nil?
        end

        target.build_configurations.each do |config|
          UI.message "updating #{config.name} to build #{next_build_number}"
          config.build_settings["CURRENT_PROJECT_VERSION"] = next_build_number
        end unless target.nil?

        project.save
      end

      def self.set_build_number_using_scheme(params, next_build_number)
        config = { project: params[:xcodeproj], scheme: params[:scheme], configuration: params[:build_configuration_name] }
        project = FastlaneCore::Project.new(config)
        project.select_scheme

        project.build_settings["CURRENT_PROJECT_VERSION"] = next_build_number
        project.save
      end

      #####################################################
      # @!group Documentation
      #####################################################

      def self.description
        "Increment build number in xcodeproj"<commit_msg>Fix cincrement_build_number_in_xcodeproj crashing when including scheme and build configuration<commit_after>module Fastlane
  module Actions
    class IncrementBuildNumberInXcodeprojAction < Action
      def self.run(params)
        unless params[:xcodeproj]
          if Helper.test?
            params[:xcodeproj] = "/tmp/fastlane/tests/fastlane/xcodeproj/versioning_fixture_project.xcodeproj"
          else
            params[:xcodeproj] = Dir["*.xcodeproj"][0] unless params[:xcodeproj]
          end
        end

        if params[:build_number]
          next_build_number = params[:build_number]
        else
          current_build_number = GetBuildNumberFromXcodeprojAction.run(params)
          build_array = current_build_number.split(".").map(&:to_i)
          build_array[-1] = build_array[-1] + 1
          next_build_number = build_array.join(".")
        end

        if params[:target]
          set_build_number_using_target(params, next_build_number)
        elsif params[:build_configuration_name] && params[:scheme]
          set_build_number_using_scheme(params, next_build_number)
        else
          set_all_xcodeproj_build_numbers(params, next_build_number)
        end
        Actions.lane_context[SharedValues::BUILD_NUMBER] = next_build_number
        next_build_number
      end

      def self.set_all_xcodeproj_build_numbers(params, next_build_number)
        project = Xcodeproj::Project.open(params[:xcodeproj])
        configs = project.objects.select { |obj| select_build_configuration_predicate(nil, obj) }
        configs.each do |config|
          config.build_settings["CURRENT_PROJECT_VERSION"] = next_build_number
        end
        project.save
      end

      private_class_method
      def self.select_build_configuration_predicate(name, configuration)
        is_build_valid_configuration = configuration.isa == "XCBuildConfiguration" && !configuration.build_settings["PRODUCT_BUNDLE_IDENTIFIER"].nil?
        is_build_valid_configuration &&= configuration.name == name unless name.nil?
        return is_build_valid_configuration
      end

      def self.set_build_number_using_target(params, next_build_number)
        project = Xcodeproj::Project.open(params[:xcodeproj])
        if params[:target]
          target = project.targets.detect { |t| t.name == params[:target] }
        else
          # firstly we are trying to find modern application target
          target = project.targets.detect do |t|
            t.kind_of?(Xcodeproj::Project::Object::PBXNativeTarget) &&
              t.product_type == 'com.apple.product-type.application'
          end
          target = project.targets[0] if target.nil?
        end

        target.build_configurations.each do |config|
          UI.message "updating #{config.name} to build #{next_build_number}"
          config.build_settings["CURRENT_PROJECT_VERSION"] = next_build_number
        end unless target.nil?

        project.save
      end

      def self.set_build_number_using_scheme(params, next_build_number)
        project = Xcodeproj::Project.open(params[:xcodeproj])
        configs = project.objects.select { |obj| select_build_configuration_predicate(nil, obj) }
        configs.each do |config|
            if config.to_s === params[:build_configuration_name]
                config.build_settings["CURRENT_PROJECT_VERSION"] = next_build_number
            end
        end
        
        project.save
      end

      #####################################################
      # @!group Documentation
      #####################################################

      def self.description
        "Increment build number in xcodeproj"
{'fraction_non_alphanumeric': 0.11182645206438069, 'fraction_numerical': 0.0013995801259622112, 'mean_word_length': 2.97, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6990187', 'n_tokens_mistral': 2015, 'n_tokens_neox': 2006, 'n_words': 342}