<commit_before>require "tmpdir"
require "bundler"
require "rubinjam/version"

module Rubinjam
  class << self
    def pack(dir)
      Dir.chdir(dir) do
        binaries = Dir["bin/*"]
        raise "No binary found in ./bin" if binaries.size == 0
        raise "Can only pack exactly 1 binary, found #{binaries.join(",")} in ./bin" unless binaries.size == 1
        content = environment + File.read(binaries.first)
        [File.basename(binaries.first), content]
      end
    end

    def pack_gem(gem, version=nil)
      require "shellwords"
      require "rubygems/package"

      Dir.mktmpdir do |dir|
        Dir.chdir(dir) do
          # fetch
          command = "gem fetch #{Shellwords.escape(gem)}"
          command << " -v" << version if version
          IO.popen(command).read

          # load spec
          gem_ball = Dir["*.gem"].first
          spec = Gem::Package.new(gem_ball).spec.to_ruby
          IO.popen("gem unpack #{gem_ball}").read

          # bundle
          Dir.chdir(gem_ball.sub(".gem", "")) do
            File.open("#{gem}.gemspec", "w") { |f| f.write spec }
            Rubinjam.pack(Dir.pwd)
          end
        end
      end
    end

    private

    def libraries
      libs_from_paths(["lib"]).merge(gem_libraries)
    end

    def gem_libraries
      return {} unless gemspec = Dir["*.gemspec"].first
      return {} unless File.read(gemspec) =~ /add_(runtime_)?dependency/

      Dir.mktmpdir do |dir|
        sh "cp -R . #{dir}/"
        Dir.chdir(dir) do
          write gemspec, File.read(gemspec).gsub(/.*add_development_dependency.*/, "")
          write "Gemfile", <<-RUBY.gsub(/^            /, "")
            source "https://rubygems.org"
            gemspec
          RUBY
          sh("rm -f Gemfile.lock")
          bundle = "bundle install --quiet --path bundle"
          sh("#{bundle} --local || #{bundle}")
          paths = sh("bundle exec ruby -e 'puts $LOAD_PATH'").split("\n")
          paths = paths.grep(%r{/gems/}).reject { |r| r =~ %r{/gems/bundler-\d} }
          libs_from_paths(paths)
        end
      end
    end

    def libs_from_paths(paths)
      paths.select { |p| File.directory?(p) }.inject({}) do |all, path|
        Dir.chdir path do
          all.merge!(Hash[Dir["**/*.rb"].map { |f| [f.sub(/\.rb$/, ""), File.read(f)] }])
        end
      end
    end

    def sh(command, options={})
      result = Bundler.with_clean_env { `#{command} 2>/dev/null` }
      raise "#{options[:fail] ? "SUCCESS" : "FAIL"} #{command}\n#{result}" if $?.success? == !!options[:fail]
      result
    end

    def write(file, content)
      FileUtils.mkdir_p(File.dirname(file))
      File.open(file, "w") { |f| f.write content }
    end

    def environment
      <<-RUBY.gsub(/^        /, "")<commit_msg>heroku runs in deployment mode ...<commit_after>require "tmpdir"
require "bundler"
require "rubinjam/version"

module Rubinjam
  class << self
    def pack(dir)
      Dir.chdir(dir) do
        binaries = Dir["bin/*"]
        raise "No binary found in ./bin" if binaries.size == 0
        raise "Can only pack exactly 1 binary, found #{binaries.join(",")} in ./bin" unless binaries.size == 1
        content = environment + File.read(binaries.first)
        [File.basename(binaries.first), content]
      end
    end

    def pack_gem(gem, version=nil)
      require "shellwords"
      require "rubygems/package"

      Dir.mktmpdir do |dir|
        Dir.chdir(dir) do
          # fetch
          command = "gem fetch #{Shellwords.escape(gem)}"
          command << " -v" << version if version
          sh(command)

          # load spec
          gem_ball = Dir["*.gem"].first
          spec = Gem::Package.new(gem_ball).spec.to_ruby
          sh("gem unpack #{gem_ball}")

          # bundle
          Dir.chdir(gem_ball.sub(".gem", "")) do
            File.open("#{gem}.gemspec", "w") { |f| f.write spec }
            Rubinjam.pack(Dir.pwd)
          end
        end
      end
    end

    private

    def libraries
      libs_from_paths(["lib"]).merge(gem_libraries)
    end

    def gem_libraries
      return {} unless gemspec = Dir["*.gemspec"].first
      return {} unless File.read(gemspec) =~ /add_(runtime_)?dependency/

      Dir.mktmpdir do |dir|
        sh "cp -R . #{dir}/"
        Dir.chdir(dir) do
          write gemspec, File.read(gemspec).gsub(/.*add_development_dependency.*/, "")
          write "Gemfile", <<-RUBY.gsub(/^            /, "")
            source "https://rubygems.org"
            gemspec
          RUBY

          sh("rm -f Gemfile.lock")
          sh("BUNDLE_IGNORE_CONFIG=1 bundle install --quiet --path bundle") # heroku has a --deployment config -> ignore it
          paths = sh("bundle exec ruby -e 'puts $LOAD_PATH'").split("\n")
          paths = paths.grep(%r{/gems/}).reject { |r| r =~ %r{/gems/bundler-\d} }
          libs_from_paths(paths)
        end
      end
    end

    def libs_from_paths(paths)
      paths.select { |p| File.directory?(p) }.inject({}) do |all, path|
        Dir.chdir path do
          all.merge!(Hash[Dir["**/*.rb"].map { |f| [f.sub(/\.rb$/, ""), File.read(f)] }])
        end
      end
    end

    def sh(command, options={})
      result = Bundler.with_clean_env { `#{command} 2>/dev/null` }
      raise "#{options[:fail] ? "SUCCESS" : "FAIL"} #{command}\n#{result}" if $?.success? == !!options[:fail]
      result
    end

    def write(file, content)
      FileUtils.mkdir_p(File.dirname(file))
      File.open(file, "w") { |f| f.write content }
    end

    def environment
      <<-RUBY.gsub(/^        /, "")
{'fraction_non_alphanumeric': 0.1586616297895305, 'fraction_numerical': 0.0016189962223421479, 'mean_word_length': 2.023382272974443, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 6, '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': '3573410', 'n_tokens_mistral': 1864, 'n_tokens_neox': 1792, 'n_words': 413}