<commit_before>require 'pathname'
require 'shellwords'

module Fastlane
  module Actions
    module SharedValues
      GRADLE_APK_OUTPUT_PATH = :GRADLE_APK_OUTPUT_PATH
      GRADLE_ALL_APK_OUTPUT_PATHS = :GRADLE_ALL_APK_OUTPUT_PATHS
      GRADLE_AAB_OUTPUT_PATH = :GRADLE_AAB_OUTPUT_PATH
      GRADLE_ALL_AAB_OUTPUT_PATHS = :GRADLE_ALL_AAB_OUTPUT_PATHS
      GRADLE_OUTPUT_JSON_OUTPUT_PATH = :GRADLE_OUTPUT_JSON_OUTPUT_PATH
      GRADLE_ALL_OUTPUT_JSON_OUTPUT_PATHS = :GRADLE_ALL_OUTPUT_JSON_OUTPUT_PATHS
      GRADLE_MAPPING_TXT_OUTPUT_PATH = :GRADLE_MAPPING_TXT_OUTPUT_PATH
      GRADLE_ALL_MAPPING_TXT_OUTPUT_PATHS = :GRADLE_ALL_MAPPING_TXT_OUTPUT_PATHS
      GRADLE_FLAVOR = :GRADLE_FLAVOR
      GRADLE_BUILD_TYPE = :GRADLE_BUILD_TYPE
    end

    class GradleAction < Action
      # rubocop:disable Metrics/PerceivedComplexity
      def self.run(params)
        task = params[:task]
        flavor = params[:flavor]
        build_type = params[:build_type]
        tasks = params[:tasks]

        gradle_task = gradle_task(task, flavor, build_type, tasks)

        UI.user_error!('Please pass a gradle task or tasks') if gradle_task.empty?

        project_dir = params[:project_dir]

        gradle_path_param = params[:gradle_path] || './gradlew'

        # Get the path to gradle, if it's an absolute path we take it as is, if it's relative we assume it's relative to the project_dir
        gradle_path = if Pathname.new(gradle_path_param).absolute?
                        File.expand_path(gradle_path_param)
                      else
                        File.expand_path(File.join(project_dir, gradle_path_param))
                      end

        # Ensure we ended up with a valid path to gradle
        UI.user_error!("Couldn't find gradlew at path '#{File.expand_path(gradle_path)}'") unless File.exist?(gradle_path)

        # Construct our flags
        flags = []
        flags << "-p #{project_dir.shellescape}"
        flags << params[:properties].map { |k, v| "-P#{k.to_s.shellescape}=#{v.to_s.shellescape}" }.join(' ') unless params[:properties].nil?
        flags << params[:system_properties].map { |k, v| "-D#{k.to_s.shellescape}=#{v.to_s.shellescape}" }.join(' ') unless params[:system_properties].nil?
        flags << params[:flags] unless params[:flags].nil?

        # Run the actual gradle task
        gradle = Helper::GradleHelper.new(gradle_path: gradle_path)

        # If these were set as properties, then we expose them back out as they might be useful to others
        Actions.lane_context[SharedValues::GRADLE_BUILD_TYPE] = build_type if build_type
        Actions.lane_context[SharedValues::GRADLE_FLAVOR] = flavor if flavor

        # We run the actual gradle task
        result = gradle.trigger(task: gradle_task,
                                serial: params[:serial],
                                flags: flags.join(' '),
                                print_command: params[:print_command],
                                print_command_output: params[:print_command_output])

        # If we didn't build, then we return now, as it makes no sense to search for apk's in a non-`assemble` or non-`build` scenario
        return result unless task =~ /\b(assemble)/ || task =~ /\b(bundle)/

        apk_search_path = File.join(project_dir, '**', 'build', 'outputs', 'apk', '**', '*.apk')
        aab_search_path = File.join(project_dir, '**', 'build', 'outputs', 'bundle', '**', '*.aab')
        output_json_search_path = File.join(project_dir, '**', 'build', 'outputs', 'apk', '**', 'output.json')
        mapping_txt_search_path = File.join(project_dir, '**', 'build', 'outputs', 'mapping', '**', 'mapping.txt')

        # Our apk/aab is now built, but there might actually be multiple ones that were built if a flavor was not specified in a multi-flavor project (e.g. `assembleRelease`)
        # However, we're not interested in unaligned apk's...
        new_apks = Dir[apk_search_path].reject { |path| path =~ /^.*-unaligned.apk$/i }
        new_apks = new_apks.map { |path| File.expand_path(path) }
        new_aabs = Dir[aab_search_path]
        new_aabs = new_aabs.map { |path| File.expand_path(path) }
        new_output_jsons = Dir[output_json_search_path]
        new_output_jsons = new_output_jsons.map { |path| File.expand_path(path) }
        new_mapping_txts = Dir[mapping_txt_search_path]
        new_mapping_txts = new_mapping_txts.map { |path| File.expand_path(path) }

        # We expose all of these new apks and aabs
        Actions.lane_context[SharedValues::GRADLE_ALL_APK_OUTPUT_PATHS] = new_apks
        Actions.lane_context[SharedValues::GRADLE_ALL_AAB_OUTPUT_PATHS] = new_aabs
        Actions.lane_context[SharedValues::GRADLE_ALL_OUTPUT_JSON_OUTPUT_PATHS] = new_output_jsons
        Actions.lane_context[SharedValues::GRADLE_ALL_MAPPING_TXT_OUTPUT_PATHS] = new_mapping_txts
<commit_msg>[action] gradle: Update for GRADLE_OUTPUT_JSON_OUTPUT_PATH and GRADLE… (#19038)<commit_after>require 'pathname'
require 'shellwords'

module Fastlane
  module Actions
    module SharedValues
      GRADLE_APK_OUTPUT_PATH = :GRADLE_APK_OUTPUT_PATH
      GRADLE_ALL_APK_OUTPUT_PATHS = :GRADLE_ALL_APK_OUTPUT_PATHS
      GRADLE_AAB_OUTPUT_PATH = :GRADLE_AAB_OUTPUT_PATH
      GRADLE_ALL_AAB_OUTPUT_PATHS = :GRADLE_ALL_AAB_OUTPUT_PATHS
      GRADLE_OUTPUT_JSON_OUTPUT_PATH = :GRADLE_OUTPUT_JSON_OUTPUT_PATH
      GRADLE_ALL_OUTPUT_JSON_OUTPUT_PATHS = :GRADLE_ALL_OUTPUT_JSON_OUTPUT_PATHS
      GRADLE_MAPPING_TXT_OUTPUT_PATH = :GRADLE_MAPPING_TXT_OUTPUT_PATH
      GRADLE_ALL_MAPPING_TXT_OUTPUT_PATHS = :GRADLE_ALL_MAPPING_TXT_OUTPUT_PATHS
      GRADLE_FLAVOR = :GRADLE_FLAVOR
      GRADLE_BUILD_TYPE = :GRADLE_BUILD_TYPE
    end

    class GradleAction < Action
      # rubocop:disable Metrics/PerceivedComplexity
      def self.run(params)
        task = params[:task]
        flavor = params[:flavor]
        build_type = params[:build_type]
        tasks = params[:tasks]

        gradle_task = gradle_task(task, flavor, build_type, tasks)

        UI.user_error!('Please pass a gradle task or tasks') if gradle_task.empty?

        project_dir = params[:project_dir]

        gradle_path_param = params[:gradle_path] || './gradlew'

        # Get the path to gradle, if it's an absolute path we take it as is, if it's relative we assume it's relative to the project_dir
        gradle_path = if Pathname.new(gradle_path_param).absolute?
                        File.expand_path(gradle_path_param)
                      else
                        File.expand_path(File.join(project_dir, gradle_path_param))
                      end

        # Ensure we ended up with a valid path to gradle
        UI.user_error!("Couldn't find gradlew at path '#{File.expand_path(gradle_path)}'") unless File.exist?(gradle_path)

        # Construct our flags
        flags = []
        flags << "-p #{project_dir.shellescape}"
        flags << params[:properties].map { |k, v| "-P#{k.to_s.shellescape}=#{v.to_s.shellescape}" }.join(' ') unless params[:properties].nil?
        flags << params[:system_properties].map { |k, v| "-D#{k.to_s.shellescape}=#{v.to_s.shellescape}" }.join(' ') unless params[:system_properties].nil?
        flags << params[:flags] unless params[:flags].nil?

        # Run the actual gradle task
        gradle = Helper::GradleHelper.new(gradle_path: gradle_path)

        # If these were set as properties, then we expose them back out as they might be useful to others
        Actions.lane_context[SharedValues::GRADLE_BUILD_TYPE] = build_type if build_type
        Actions.lane_context[SharedValues::GRADLE_FLAVOR] = flavor if flavor

        # We run the actual gradle task
        result = gradle.trigger(task: gradle_task,
                                serial: params[:serial],
                                flags: flags.join(' '),
                                print_command: params[:print_command],
                                print_command_output: params[:print_command_output])

        # If we didn't build, then we return now, as it makes no sense to search for apk's in a non-`assemble` or non-`build` scenario
        return result unless task =~ /\b(assemble)/ || task =~ /\b(bundle)/

        apk_search_path = File.join(project_dir, '**', 'build', 'outputs', 'apk', '**', '*.apk')
        aab_search_path = File.join(project_dir, '**', 'build', 'outputs', 'bundle', '**', '*.aab')
        output_json_search_path = File.join(project_dir, '**', 'build', 'outputs', 'apk', '**', 'output*.json') # output.json in Android Stuido 3 and output-metadata.json in Android Studio 4
        mapping_txt_search_path = File.join(project_dir, '**', 'build', 'outputs', 'mapping', '**', 'mapping.txt')

        # Our apk/aab is now built, but there might actually be multiple ones that were built if a flavor was not specified in a multi-flavor project (e.g. `assembleRelease`)
        # However, we're not interested in unaligned apk's...
        new_apks = Dir[apk_search_path].reject { |path| path =~ /^.*-unaligned.apk$/i }
        new_apks = new_apks.map { |path| File.expand_path(path) }
        new_aabs = Dir[aab_search_path]
        new_aabs = new_aabs.map { |path| File.expand_path(path) }
        new_output_jsons = Dir[output_json_search_path]
        new_output_jsons = new_output_jsons.map { |path| File.expand_path(path) }
        new_mapping_txts = Dir[mapping_txt_search_path]
        new_mapping_txts = new_mapping_txts.map { |path| File.expand_path(path) }

        # We expose all of these new apks and aabs
        Actions.lane_context[SharedValues::GRADLE_ALL_APK_OUTPUT_PATHS] = new_apks
        Actions.lane_context[SharedValues::GRADLE_ALL_AAB_OUTPUT_PATHS] = new_aabs
        Actions.lane_context[SharedValues::GRADLE_ALL_OUTPUT_JSON_OUTPUT_PATHS] = new_output_jsons
        Actions.lane_context[SharedValues::GRADLE_ALL_MAPPING_TXT_OUTPUT_PATHS] = new_mapping_txts

{'fraction_non_alphanumeric': 0.10335760517799353, 'fraction_numerical': 0.0007079288025889968, 'mean_word_length': 3.1498111624003355, 'pattern_counts': {'":': 0, '<': 21, '<?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': '7377334', 'n_tokens_mistral': 3266, 'n_tokens_neox': 3141, 'n_words': 672}