Skip to content

Commit

Permalink
Merge pull request #1330 from Homebrew/vscode-uid
Browse files Browse the repository at this point in the history
vscode_extension_installer: use UID for installs
  • Loading branch information
MikeMcQuaid authored Apr 1, 2024
2 parents 77f4db8 + d7e6189 commit 2935b4d
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 1 deletion.
28 changes: 27 additions & 1 deletion lib/bundle/vscode_extension_installer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,39 @@ def preinstall(name, no_upgrade: false, verbose: false)
true
end

def exchange_uid(&block)
euid = Process.euid
uid = Process.uid
return yield if euid == uid

old_euid = euid
process_reexchangeable = Process::UID.re_exchangeable?
if process_reexchangeable
Process::UID.re_exchange
else
Process::Sys.seteuid(uid)
end

return_value = with_env("HOME" => Etc.getpwuid(Process.uid).dir, &block)

if process_reexchangeable
Process::UID.re_exchange
else
Process::Sys.seteuid(old_euid)
end

return_value
end

def install(name, preinstall: true, no_upgrade: false, verbose: false, force: false)
return true unless preinstall
return true if extension_installed?(name)

puts "Installing #{name} VSCode extension. It is not currently installed." if verbose

return false unless Bundle.system "code", "--install-extension", name, verbose: verbose
return false unless exchange_uid do
Bundle.system("code", "--install-extension", name, verbose:)
end

installed_extensions << name

Expand Down
21 changes: 21 additions & 0 deletions spec/bundle/vscode_extension_installer_spec.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# frozen_string_literal: true

require "spec_helper"
require "extend/kernel"

describe Bundle::VscodeExtensionInstaller do
context "when VSCode is not installed" do
Expand Down Expand Up @@ -48,6 +49,26 @@
expect(described_class.preinstall("foo")).to be(true)
expect(described_class.install("foo")).to be(true)
end

it "installs extension when euid != uid and Process::UID.re_exchangeable? returns true" do
expect(Process).to receive(:euid).and_return(1).once
expect(Process::UID).to receive(:re_exchangeable?).and_return(true).once
expect(Process::UID).to receive(:re_exchange).twice

expect(Bundle).to receive(:system).with("code", "--install-extension", "foo", verbose: false).and_return(true)
expect(described_class.preinstall("foo")).to be(true)
expect(described_class.install("foo")).to be(true)
end

it "installs extension when euid != uid and Process::UID.re_exchangeable? returns false" do
expect(Process).to receive(:euid).and_return(1).once
expect(Process::UID).to receive(:re_exchangeable?).and_return(false).once
expect(Process::Sys).to receive(:seteuid).twice

expect(Bundle).to receive(:system).with("code", "--install-extension", "foo", verbose: false).and_return(true)
expect(described_class.preinstall("foo")).to be(true)
expect(described_class.install("foo")).to be(true)
end
end
end
end
7 changes: 7 additions & 0 deletions spec/stub/extend/kernel.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

module Kernel
def with_env(_hash)
yield if block_given?
end
end

0 comments on commit 2935b4d

Please sign in to comment.