<commit_before>require 'erb'
require 'facets/file/atomic_write'
require 'find'
require 'fileutils'
require 'xezat'
require 'xezat/commands'
require 'xezat/cygchangelog'
require 'xezat/cygclasses'
require 'xezat/detectors'
require 'xezat/refine/linguist/file_blob'
require 'xezat/packages'
require 'xezat/variables'

module Xezat
  # ファイルのパーミッションが適切でない場合に投げられる例外
  class FilePermissionError < StandardError
  end

  # cygport の他のコマンドが終わっておらずに呼び出すべき状態ではない場合に投げられる例外
  class IllegalStateError < StandardError
  end

  module Command
    # README を生成または更新する
    class Bump
      def initialize(program)
        program.command(:bump) do |c|
          c.syntax 'bump cygport'
          c.description 'update CYGWIN-PATCHES/README'
          c.action do |args, options|
            execute(c, args, options)
          end
        end
      end

      CommandManager::register(:bump, self)

      def execute(c, args, options)
        cygport = args.shift
        raise ArgumentError, 'wrong number of arguments (0 for 1)' unless cygport
        c.logger.info "ignore extra arguments: #{args.to_s}" unless args.empty?

        variables = VariableManager::get_default_variables(cygport)
        packages = PackageManager::get_installed_packages()
        readme_file = File::expand_path(File::join(variables[:C], 'README'))

        info = {}
        info[:src_uri] = get_src_uri(variables)
        info[:runtimes] = get_runtime_packages(cygport)
        info[:developments] = get_development_packages(variables, packages)
        info[:files] = get_files(variables)
        info[:changelog] = get_changelog(variables, options, readme_file)

        File::atomic_write(readme_file) do |f|
          f.write(get_embedded_contents(variables, info))
        end
      end

      # changelog を取得する
      def get_changelog(variables, options, readme_file)
        current_version = variables[:PVR].intern
        if FileTest::exist?(readme_file)
          raise FilePermissionError, "Cannot read #{readme_file}" unless FileTest::readable?(readme_file)
          raise FilePermissionError, "Cannot write #{readme_file}" unless FileTest::writable?(readme_file)
          changelog = Cygchangelog.new(File::read(readme_file))
          options['message'] ||= 'Version bump.'
          changelog[current_version] = options['message'] unless changelog.key?(current_version)
        else
          changelog = Cygchangelog.new
          changelog[current_version] = 'Initial release by fd0 <https://github.com/fd00/>'
        end
        changelog
      end

      # vcs に対応した SRC_URI を取得する
      def get_src_uri(variables, cygclass_manager = CygclassManager.new)
        cygclass_manager.vcs.each do |vcs|
          src_uri_key = "#{vcs.to_s.upcase}_URI".intern
          return variables[src_uri_key].split if variables.key?(src_uri_key)
        end
        variables[:SRC_URI].split
      end

      # package が依存している runtime のリストを取得する
      def get_runtime_packages(cygport)
        command = ['bash', File.expand_path(File.join(DATA_DIR, 'invoke_cygport_dep.sh')), cygport]
        result, error, status = Open3.capture3(command.join(' '))
        raise CygportProcessError, error unless status.success?
        result.split($/).map! do |runtime|
          runtime.lstrip
        end
      end

      # package を build するために必要な development package のリストを取得する
      def get_development_packages(variables, packages)
        compilers = get_compilers(variables)
        tools = get_tools(variables)
        development_packages = (compilers + tools + [:cygport]).uniq.sort
        development_packages.map! do |package|
          packages[package] || ''
        end
      end

      # package を build するために必要な compiler package のリストを取得する
      def get_compilers(variables)

        # ファイルの内容からプログラミング言語を特定する
        languages = []
        Find::find(variables[:S]) do |path|
          unless FileTest::directory?(path)
            language = Xezat::Refine::Linguist::FileBlob.new(path).language
            unless language.nil?
              name = language.name
              if name == 'Objective-C' # Objective-C は誤検知があるため suffix で再確認
                next unless path.end_with?('.m')
              end
              if name == 'C++' # C++ は誤検知があるため suffix で再確認
                name = 'C' if path.end_with?('.h')
              end
              languages << name
            end
          end
        end

        # 言語から対応する compiler package を取得する
        compiler_file = File.expand_path(File.join(DATA_DIR, 'compilers.json'))
        compiler_candidates = JSON.parse(File::read(compiler_file))<commit_msg>Added workaround for github-linguist (ruby detection)<commit_after>require 'erb'
require 'facets/file/atomic_write'
require 'find'
require 'fileutils'
require 'xezat'
require 'xezat/commands'
require 'xezat/cygchangelog'
require 'xezat/cygclasses'
require 'xezat/detectors'
require 'xezat/refine/linguist/file_blob'
require 'xezat/packages'
require 'xezat/variables'

module Xezat
  # ファイルのパーミッションが適切でない場合に投げられる例外
  class FilePermissionError < StandardError
  end

  # cygport の他のコマンドが終わっておらずに呼び出すべき状態ではない場合に投げられる例外
  class IllegalStateError < StandardError
  end

  module Command
    # README を生成または更新する
    class Bump
      def initialize(program)
        program.command(:bump) do |c|
          c.syntax 'bump cygport'
          c.description 'update CYGWIN-PATCHES/README'
          c.action do |args, options|
            execute(c, args, options)
          end
        end
      end

      CommandManager::register(:bump, self)

      def execute(c, args, options)
        cygport = args.shift
        raise ArgumentError, 'wrong number of arguments (0 for 1)' unless cygport
        c.logger.info "ignore extra arguments: #{args.to_s}" unless args.empty?

        variables = VariableManager::get_default_variables(cygport)
        packages = PackageManager::get_installed_packages()
        readme_file = File::expand_path(File::join(variables[:C], 'README'))

        info = {}
        info[:src_uri] = get_src_uri(variables)
        info[:runtimes] = get_runtime_packages(cygport)
        info[:developments] = get_development_packages(variables, packages)
        info[:files] = get_files(variables)
        info[:changelog] = get_changelog(variables, options, readme_file)

        File::atomic_write(readme_file) do |f|
          f.write(get_embedded_contents(variables, info))
        end
      end

      # changelog を取得する
      def get_changelog(variables, options, readme_file)
        current_version = variables[:PVR].intern
        if FileTest::exist?(readme_file)
          raise FilePermissionError, "Cannot read #{readme_file}" unless FileTest::readable?(readme_file)
          raise FilePermissionError, "Cannot write #{readme_file}" unless FileTest::writable?(readme_file)
          changelog = Cygchangelog.new(File::read(readme_file))
          options['message'] ||= 'Version bump.'
          changelog[current_version] = options['message'] unless changelog.key?(current_version)
        else
          changelog = Cygchangelog.new
          changelog[current_version] = 'Initial release by fd0 <https://github.com/fd00/>'
        end
        changelog
      end

      # vcs に対応した SRC_URI を取得する
      def get_src_uri(variables, cygclass_manager = CygclassManager.new)
        cygclass_manager.vcs.each do |vcs|
          src_uri_key = "#{vcs.to_s.upcase}_URI".intern
          return variables[src_uri_key].split if variables.key?(src_uri_key)
        end
        variables[:SRC_URI].split
      end

      # package が依存している runtime のリストを取得する
      def get_runtime_packages(cygport)
        command = ['bash', File.expand_path(File.join(DATA_DIR, 'invoke_cygport_dep.sh')), cygport]
        result, error, status = Open3.capture3(command.join(' '))
        raise CygportProcessError, error unless status.success?
        result.split($/).map! do |runtime|
          runtime.lstrip
        end
      end

      # package を build するために必要な development package のリストを取得する
      def get_development_packages(variables, packages)
        compilers = get_compilers(variables)
        tools = get_tools(variables)
        development_packages = (compilers + tools + [:cygport]).uniq.sort
        development_packages.map! do |package|
          packages[package] || ''
        end
      end

      # package を build するために必要な compiler package のリストを取得する
      def get_compilers(variables)

        # ファイルの内容からプログラミング言語を特定する
        languages = []
        Find::find(variables[:S]) do |path|
          unless FileTest::directory?(path)
            language = Xezat::Refine::Linguist::FileBlob.new(path).language
            unless language.nil?
              name = language.name
              if name == 'Objective-C' # Objective-C は誤検知があるため suffix で再確認
                next unless path.end_with?('.m')
              end
              if name == 'Ruby' # Ruby は誤検知があるため suffix で再確認
                next unless path.end_with?('.rb')
              end
              if name == 'C++' # C++ は誤検知があるため suffix で再確認
                name = 'C' if path.end_with?('.h')
              end
              languages << name
            end
          end
        end

        # 言語から対応する compiler package を取得する
        compiler_file = File.expand_path(File.join(DATA_DIR, 'compilers.json'))
        compiler_candidates = JSON.parse(File::read(compiler_file))
{'fraction_non_alphanumeric': 0.09654656260023523, 'fraction_numerical': 0.0014968459317865924, 'mean_word_length': 2.685579196217494, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 5, 'https://': 2, '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': '6405683', 'n_tokens_mistral': 3126, 'n_tokens_neox': 3049, 'n_words': 603}