# 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

  desc "Ensure dev dependencies are installed, and make sure no lockifle changes are generated"
  task :frozen_deps => :deps do
    Spec::Rubygems.check_source_control_changes(
      :success_message => "Development dependencies were installed and the lockfile is in sync",
      :error_message => "Development dependencies were installed but the lockfile is out of sync. Commit the updated lockfile and try again"
    )
  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, [:specs] => [] do |_t, opts|
    require_relative "spec/support/sudo"
    Spec::Sudo.write_safe_config

    begin
      sh("sudo GIT_CONFIG_GLOBAL=#{Spec::Path.tmp("gitconfig")} PATH=#{ENV["PATH"]} RUBYOPT=#{ENV["RUBYOPT"]} bin/rspec --tag sudo #{opts[:specs]}")
    ensure
      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

desc "Check RubyGems integration"
task :check_rubygems_integration do
  # Bundler monkeypatches RubyGems in some ways that could potentially break gem
  # activation. Run a non trivial binstub activation, with two different
  # versions of a dependent gem installed.
  sh("gem install reline:0.3.0 reline:0.3.1 irb && ruby -Ilib -rbundler -S irb --version")
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
      Spec::Rubygems.check_source_control_changes(
        :success_message => "Man pages are in sync",
        :error_message => "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."
      )
    end
  end
end

load "../util/automatiek.rake"

# We currently ship Molinillo master branch as of
# https://github.com/CocoaPods/Molinillo/commit/b4a510349e6893486b9eb44a71734c05a8034256
# plus the following patches:
# * Require `tsort` relatively to use our vendored version.
# * Allow full customization of Molinillo's conflict error message
#   (https://github.com/CocoaPods/Molinillo/pull/164).
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"
  lib.license_path = "LICENSE"

  lib.dependency("tsort") do |sublib|
    sublib.version = "master"
    sublib.download = { :github => "https://github.com/ruby/tsort" }
    sublib.namespace = "TSort"
    sublib.prefix = "Bundler"
    sublib.vendor_lib = "lib/bundler/vendor/tsort"
    sublib.license_path = "LICENSE.txt"
  end
end

desc "Vendor a specific version of thor"
Automatiek::RakeTask.new("thor") do |lib|
  lib.version = "v1.2.1"
  lib.download = { :github => "https://github.com/erikhuda/thor" }
  lib.namespace = "Thor"
  lib.prefix = "Bundler"
  lib.vendor_lib = "lib/bundler/vendor/thor"
  lib.license_path = "LICENSE.md"
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.license_path = nil # There is no license file in the Repo

  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"
    sublib.license_path = "LICENSE.txt"
  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.license_path = "README.rdoc"

  # We currently include the official version as of
  # https://github.com/mperham/connection_pool/commit/813c271e41be0714334834d6517ce68ca1357fc0.
  lib.dependency("connection_pool") do |sublib|
    sublib.version = "master"
    sublib.download = { :github => "https://github.com/mperham/connection_pool" }
    sublib.namespace = "ConnectionPool"
    sublib.prefix = "Bundler"
    sublib.vendor_lib = "lib/bundler/vendor/connection_pool"
    sublib.license_path = "LICENSE"
  end

  lib.dependency("uri") do |sublib|
    sublib.version = "v0.10.1"
    sublib.download = { :github => "https://github.com/ruby/uri" }
    sublib.namespace = "URI"
    sublib.prefix = "Bundler"
    sublib.vendor_lib = "lib/bundler/vendor/uri"
    sublib.license_path = "LICENSE.txt"
  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"
