aboutsummaryrefslogtreecommitdiffstats
path: root/Library/Homebrew/test/helper/integration_command_test_case.rb
blob: 2f137e14a3c0e575c8c4c74abaa7df08601044df (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
require "bundler"
require "testing_env"
require "fileutils"
require "pathname"
require "formula"

class IntegrationCommandTestCase < Homebrew::TestCase
  def setup
    @cmd_id_index = 0 # Assign unique IDs to invocations of `cmd_output`.
    (HOMEBREW_PREFIX/"bin").mkpath
    FileUtils.touch HOMEBREW_PREFIX/"bin/brew"
  end

  def teardown
    coretap = CoreTap.new
    paths_to_delete = [
      HOMEBREW_LINKED_KEGS,
      HOMEBREW_PINNED_KEGS,
      HOMEBREW_CELLAR.children,
      HOMEBREW_CACHE.children,
      HOMEBREW_LOCK_DIR.children,
      HOMEBREW_LOGS.children,
      HOMEBREW_TEMP.children,
      HOMEBREW_PREFIX/"bin",
      HOMEBREW_PREFIX/"share",
      HOMEBREW_PREFIX/"opt",
      HOMEBREW_PREFIX/"Caskroom",
      HOMEBREW_LIBRARY/"Taps/caskroom",
      HOMEBREW_LIBRARY/"Taps/homebrew/homebrew-bundle",
      HOMEBREW_LIBRARY/"Taps/homebrew/homebrew-foo",
      HOMEBREW_LIBRARY/"Taps/homebrew/homebrew-services",
      HOMEBREW_LIBRARY/"Taps/homebrew/homebrew-shallow",
      HOMEBREW_REPOSITORY/".git",
      coretap.path/".git",
      coretap.alias_dir,
      coretap.formula_dir.children,
      coretap.path/"formula_renames.json",
    ].flatten
    FileUtils.rm_rf paths_to_delete
  end

  def needs_test_cmd_taps
    return if ENV["HOMEBREW_TEST_OFFICIAL_CMD_TAPS"]
    skip "HOMEBREW_TEST_OFFICIAL_CMD_TAPS is not set"
  end

  def needs_macos
    skip "Not on MacOS" unless OS.mac?
  end

  def cmd_id_from_args(args)
    args_pretty = args.join(" ").gsub(TEST_TMPDIR, "@TMPDIR@")
    test_pretty = "#{self.class.name}\##{name}.#{@cmd_id_index += 1}"
    "[#{test_pretty}] brew #{args_pretty}"
  end

  def cmd_output(*args)
    # 1.8-compatible way of writing def cmd_output(*args, **env)
    env = args.last.is_a?(Hash) ? args.pop : {}
    cmd_args = %W[
      -W0
      -I#{HOMEBREW_LIBRARY_PATH}/test/lib
      -rconfig
    ]
    if ENV["HOMEBREW_TESTS_COVERAGE"]
      # This is needed only because we currently use a patched version of
      # simplecov, and gems installed through git are not available without
      # requiring bundler/setup first. See also the comment in test/Gemfile.
      # Remove this line when we'll switch back to a stable simplecov release.
      cmd_args << "-rbundler/setup"
      cmd_args << "-rsimplecov"
    end
    cmd_args << "-rintegration_mocks"
    cmd_args << (HOMEBREW_LIBRARY_PATH/"brew.rb").resolved_path.to_s
    cmd_args += args
    developer = ENV["HOMEBREW_DEVELOPER"]
    Bundler.with_original_env do
      ENV["HOMEBREW_BREW_FILE"] = HOMEBREW_PREFIX/"bin/brew"
      ENV["HOMEBREW_INTEGRATION_TEST"] = cmd_id_from_args(args)
      ENV["HOMEBREW_TEST_TMPDIR"] = TEST_TMPDIR
      ENV["HOMEBREW_DEVELOPER"] = developer
      env.each_pair do |k, v|
        ENV[k] = v
      end

      read, write = IO.pipe
      begin
        pid = fork do
          read.close
          $stdout.reopen(write)
          $stderr.reopen(write)
          write.close
          exec RUBY_PATH, *cmd_args
        end
        write.close
        read.read.chomp
      ensure
        Process.wait(pid)
        read.close
      end
    end
  end

  def cmd(*args)
    output = cmd_output(*args)
    status = $?.exitstatus
    puts "\n'brew #{args.join " "}' output: #{output}" if status.nonzero?
    assert_equal 0, status
    output
  end

  def cmd_fail(*args)
    output = cmd_output(*args)
    status = $?.exitstatus
    $stderr.puts "\n'brew #{args.join " "}'" if status.zero?
    refute_equal 0, status
    output
  end

  def setup_test_formula(name, content = nil)
    formula_path = CoreTap.new.formula_dir/"#{name}.rb"

    case name
    when /^testball/
      content = <<-EOS.undent
        desc "Some test"
        homepage "https://example.com/#{name}"
        url "file://#{File.expand_path("../..", __FILE__)}/tarballs/testball-0.1.tbz"
        sha256 "#{TESTBALL_SHA256}"

        option "with-foo", "Build with foo"

        def install
          (prefix/"foo"/"test").write("test") if build.with? "foo"
          prefix.install Dir["*"]
          (buildpath/"test.c").write \
            "#include <stdio.h>\\nint main(){return printf(\\"test\\");}"
          bin.mkpath
          system ENV.cc, "test.c", "-o", bin/"test"
        end

        #{content}

        # something here
      EOS
    when "foo"
      content = <<-EOS.undent
        url "https://example.com/#{name}-1.0"
      EOS
    when "bar"
      content = <<-EOS.undent
        url "https://example.com/#{name}-1.0"
        depends_on "foo"
      EOS
    end

    formula_path.write <<-EOS.undent
      class #{Formulary.class_s(name)} < Formula
        #{content}
      end
    EOS

    formula_path
  end

  def setup_remote_tap(name)
    tap = Tap.fetch name
    tap.install(full_clone: false, quiet: true) unless tap.installed?
    tap
  end

  def install_and_rename_coretap_formula(old_name, new_name)
    core_tap = CoreTap.new
    core_tap.path.cd do
      shutup do
        system "git", "init"
        system "git", "add", "--all"
        system "git", "commit", "-m",
          "#{old_name.capitalize} has not yet been renamed"
      end
    end

    cmd("install", old_name)
    (core_tap.path/"Formula/#{old_name}.rb").unlink
    formula_renames = core_tap.path/"formula_renames.json"
    formula_renames.write Utils::JSON.dump(old_name => new_name)

    core_tap.path.cd do
      shutup do
        system "git", "add", "--all"
        system "git", "commit", "-m",
          "#{old_name.capitalize} has been renamed to #{new_name.capitalize}"
      end
    end
  end

  def testball
    "#{File.expand_path("../..", __FILE__)}/testball.rb"
  end
end