# frozen_string_literal: true

require_relative "spec/support/rubygems_ext"

desc "Run specs"
task :spec do
  sh("bin/rspec")
end

namespace :dev do
  desc "Ensure dev dependencies are installed"
  task :deps do
    Spec::Rubygems.dev_setup
  end
end

namespace :spec do
  desc "Ensure spec dependencies are installed"
  task :deps => "dev:deps" do
    Spec::Rubygems.install_test_deps
  end

  desc "Ensure spec dependencies for running in parallel are installed"
  task :parallel_deps => "dev:deps" do
    Spec::Rubygems.install_parallel_test_deps
  end

  desc "Run all specs"
  task :all => %w[spec:regular spec:realworld spec:sudo]

  desc "Run the regular spec suite"
  task :regular do
    sh("bin/parallel_rspec")
  end

  desc "Run the real-world spec suite"
  task :realworld do
    sh("BUNDLER_SPEC_PRE_RECORDED=1 bin/rspec --tag realworld")
  end

  namespace :realworld do
    desc "Re-record cassettes for the realworld specs"
    task :record do
      sh("rm -rf spec/support/artifice/vcr_cassettes && bin/rspec --tag realworld")
    end
  end

  desc "Run the spec suite with the sudo tests"
  task :sudo do
    require "open3"
    output, status = Open3.capture2e("sudo", "cp", "/etc/sudoers", "tmp/old_sudoers")
    raise "Couldn't read sudoers file: #{output}" unless status.success?

    begin
      output, status = Open3.capture2e("sudo sed -i '/secure_path/d' /etc/sudoers")
      raise "Couldn't configure sudo to preserve path: #{output}" unless status.success?

      raise "Couldn't configure sudo correctly to preserve path" unless `ruby -v` == `sudo -E ruby -v`

      sh("sudo -E --preserve-env=RUBYOPT bin/rspec --tag sudo")
    ensure
      system("sudo", "cp", "tmp/old_sudoers", "/etc/sudoers")
      system("sudo", "chown", "-R", ENV["USER"], "tmp")
    end
  end
end

desc "Check RVM integration"
task :check_rvm_integration do
  # The rubygems-bundler gem is installed by RVM by default and it could easily
  # break when we change bundler. Make sure that binstubs still run with it
  # installed.
  sh("gem install rubygems-bundler rake && RUBYOPT=-Ilib rake -T")
end

namespace :man do
  if RUBY_ENGINE == "jruby"
    task(:build) {}
  else
    begin
      Spec::Rubygems.gem_require("ronn")
    rescue Gem::LoadError => e
      desc "Build the man pages"
      task(:build) { abort "We couldn't activate ronn (#{e.requirement}). Try `gem install ronn:'#{e.requirement}'` to be able to build the help pages" }

      desc "Verify man pages are in sync"
      task(:check) { abort "We couldn't activate ronn (#{e.requirement}). Try `gem install ronn:'#{e.requirement}'` to be able to build the help pages" }
    else
      directory "man"

      index = Dir["man/*.ronn"].map do |source|
        ronn = "man/#{File.basename(source)}"
        roff = "man/#{File.basename(source, ".ronn")}"

        file roff => ["man", ronn] do
          sh "bin/ronn --warnings --roff --pipe --date #{Time.now.strftime("%Y-%m-%d")} #{ronn} > #{roff}"
        end

        task :build_all_pages => roff

        [ronn, File.basename(roff)]
      end

      file "index.txt" do
        index.map! do |(ronn, roff)|
          [File.read(ronn).split(" ").first, roff]
        end
        index = index.sort_by(&:first)
        justification = index.map {|(n, _f)| n.length }.max + 4
        File.open("man/index.txt", "w") do |f|
          index.each do |name, filename|
            f << name.ljust(justification) << filename << "\n"
          end
        end
      end
      task :build_all_pages => "index.txt"

      desc "Remove all built man pages"
      task :clean do
        leftovers = Dir["man/*"].reject do |f|
          File.extname(f) == ".ronn"
        end
        rm leftovers if leftovers.any?
      end

      desc "Build the man pages"
      task :build => ["man:clean", "man:build_all_pages"]

      desc "Verify man pages are in sync"
      task :check => :build do
        sh("git diff --quiet --ignore-all-space man") do |outcome, _|
          if outcome
            puts
            puts "Manpages are in sync!"
            puts
          else
            sh("GIT_PAGER=cat git diff --ignore-all-space man")

            puts
            puts "Man pages are out of sync. Above you can see the diff that got generated from rebuilding them. Please review and commit the results."
            puts

            exit(1)
          end
        end
      end
    end
  end
end

load "task/automatiek.rake"

desc "Vendor a specific version of molinillo"
Automatiek::RakeTask.new("molinillo") do |lib|
  lib.download = { :github => "https://github.com/CocoaPods/Molinillo" }
  lib.namespace = "Molinillo"
  lib.prefix = "Bundler"
  lib.vendor_lib = "lib/bundler/vendor/molinillo"
end

desc "Vendor a specific version of thor"
Automatiek::RakeTask.new("thor") do |lib|
  lib.version = "v1.0.1"
  lib.download = { :github => "https://github.com/erikhuda/thor" }
  lib.namespace = "Thor"
  lib.prefix = "Bundler"
  lib.vendor_lib = "lib/bundler/vendor/thor"
end

desc "Vendor a specific version of fileutils"
Automatiek::RakeTask.new("fileutils") do |lib|
  lib.version = "v1.4.1"
  lib.download = { :github => "https://github.com/ruby/fileutils" }
  lib.namespace = "FileUtils"
  lib.prefix = "Bundler"
  lib.vendor_lib = "lib/bundler/vendor/fileutils"
end

# We currently include the following changes over the official version:
# * Avoid requiring the optional `net-http-pipeline` dependency, so that its version can be selected by end users.
# * We also include changes to require the vendored dependencies `uri` and `connection_pool` relatively.
# * Avoid autoloading `OpenSSL` since it causes problems on jruby.
desc "Vendor a specific version of net-http-persistent"
Automatiek::RakeTask.new("net-http-persistent") do |lib|
  lib.version = "v4.0.0"
  lib.download = { :github => "https://github.com/drbrain/net-http-persistent" }
  lib.namespace = "Net::HTTP::Persistent"
  lib.prefix = "Bundler::Persistent"
  lib.vendor_lib = "lib/bundler/vendor/net-http-persistent"

  lib.dependency("connection_pool") do |sublib|
    sublib.version = "v2.2.2"
    sublib.download = { :github => "https://github.com/mperham/connection_pool" }
    sublib.namespace = "ConnectionPool"
    sublib.prefix = "Bundler"
    sublib.vendor_lib = "lib/bundler/vendor/connection_pool"
  end

  # We currently include changes over the official version to require internal paths
  # relatively.
  lib.dependency("uri") do |sublib|
    sublib.version = "v0.10.0"
    sublib.download = { :github => "https://github.com/ruby/uri" }
    sublib.namespace = "URI"
    sublib.prefix = "Bundler"
    sublib.vendor_lib = "lib/bundler/vendor/uri"
  end
end

task :override_version do
  next unless version = ENV["BUNDLER_SPEC_SUB_VERSION"]
  Spec::Path.replace_version_file(version)
end

task :default => :spec

load "task/bundler_3.rake"
load "task/release.rake"
