# 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", "sh", "-c", "sed -e'/secure_path/d' /etc/sudoers > /etc/sudoers.bak && mv /etc/sudoers.bak /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
    index = Dir["lib/bundler/man/*.ronn"].map do |ronn|
      roff = "#{File.dirname(ronn)}/#{File.basename(ronn, ".ronn")}"

      file roff => ronn do
        date = ENV["MAN_PAGES_DATE"] || Time.now.strftime("%Y-%m-%d")
        sh "bin/ronn --warnings --roff --pipe --date #{date} #{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("lib/bundler/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 "Make sure ronn is installed"
    task :check_ronn do
      begin
        Spec::Rubygems.gem_require("ronn")
      rescue Gem::LoadError => e
        abort("We couldn't activate ronn (#{e.requirement}). Try `gem install ronn:'#{e.requirement}'` to be able to build the help pages")
      end
    end

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

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

    desc "Sets target date for building man pages to the one currently present"
    task :set_current_date do
      require "date"
      ENV["MAN_PAGES_DATE"] = Date.parse(File.readlines("lib/bundler/man/bundle-add.1")[3].split('"')[5]).strftime("%Y-%m-%d")
    end

    desc "Verify man pages are in sync"
    task :check => [:check_ronn, :set_current_date, :build] do
      require "open3"

      output, status = Open3.capture2e("git status --porcelain")

      if status.success? && output.empty?
        puts
        puts "Man pages are in sync"
        puts
      else
        sh("git status --porcelain")

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

        exit(1)
      end
    end
  end
end

load "../util/automatiek.rake"

# We currently ship Molinillo master branch as of
# https://github.com/CocoaPods/Molinillo/commit/7cc27a355e861bdf593e2cde7bf1bca3daae4303
desc "Vendor a specific version of molinillo"
Automatiek::RakeTask.new("molinillo") do |lib|
  lib.version = "master"
  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.1.0"
  lib.download = { :github => "https://github.com/erikhuda/thor" }
  lib.namespace = "Thor"
  lib.prefix = "Bundler"
  lib.vendor_lib = "lib/bundler/vendor/thor"
end

# We currently include the official version as of
# https://github.com/ruby/tmpdir/commit/c79bc7adf66a39617d0d6bae21085adc77c02b0e
# with the following changes on top:
# * require fileutils relatively to use our vendored version.
# * Inherit from `Dir` so that code assuming we're inside the
#   `Dir` class still works. Also change the `systmpdir` class variable to an
#   instance variable since otherwise inheriting from dir doesn't work.
# * Remove a "block variable shadowing outer variable" warning on older rubies
#   that was breaking some specs.
desc "Vendor a specific version of tmpdir"
Automatiek::RakeTask.new("tmpdir") do |lib|
  lib.version = "master"
  lib.download = { :github => "https://github.com/ruby/tmpdir" }
  lib.namespace = "Dir"
  lib.prefix = "Bundler"
  lib.vendor_lib = "lib/bundler/vendor/tmpdir"

  lib.dependency("fileutils") do |sublib|
    sublib.version = "v1.4.1"
    sublib.download = { :github => "https://github.com/ruby/fileutils" }
    sublib.namespace = "FileUtils"
    sublib.prefix = "Bundler"
    sublib.vendor_lib = "lib/bundler/vendor/fileutils"
  end
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.
# * Workaround for incorrect `Process.getrlimit` on JRuby + Windows.
# * We also include changes to require the vendored dependencies `uri` and `connection_pool` relatively.
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"
