| 
									
										
										
										
											2019-04-19 15:38:03 +09:00
										 |  |  | # frozen_string_literal: true | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-17 18:35:26 +01:00
										 |  |  | require "utils/shell" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-18 15:11:11 -08:00
										 |  |  | RSpec.describe Utils::Shell do | 
					
						
							| 
									
										
										
										
											2017-04-22 16:28:07 +01:00
										 |  |  |   describe "::profile" do | 
					
						
							| 
									
										
										
										
											2020-05-11 21:26:45 -07:00
										 |  |  |     it "returns ~/.profile by default" do | 
					
						
							| 
									
										
										
										
											2017-02-17 18:35:26 +01:00
										 |  |  |       ENV["SHELL"] = "/bin/another_shell" | 
					
						
							| 
									
										
										
										
											2021-01-11 12:28:07 -08:00
										 |  |  |       expect(described_class.profile).to eq("~/.profile") | 
					
						
							| 
									
										
										
										
											2017-02-17 18:35:26 +01:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-11 21:26:45 -07:00
										 |  |  |     it "returns ~/.profile for sh" do | 
					
						
							| 
									
										
										
										
											2018-10-20 08:53:19 +02:00
										 |  |  |       ENV["SHELL"] = "/bin/sh" | 
					
						
							| 
									
										
										
										
											2021-01-11 12:28:07 -08:00
										 |  |  |       expect(described_class.profile).to eq("~/.profile") | 
					
						
							| 
									
										
										
										
											2018-10-20 08:53:19 +02:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-11 21:26:45 -07:00
										 |  |  |     it "returns ~/.profile for Bash" do | 
					
						
							| 
									
										
										
										
											2017-02-17 18:35:26 +01:00
										 |  |  |       ENV["SHELL"] = "/bin/bash" | 
					
						
							| 
									
										
										
										
											2021-01-11 12:28:07 -08:00
										 |  |  |       expect(described_class.profile).to eq("~/.profile") | 
					
						
							| 
									
										
										
										
											2017-02-17 18:35:26 +01:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-06 12:03:01 -04:00
										 |  |  |     it "returns /tmp/.zshrc for Zsh if ZDOTDIR is /tmp" do | 
					
						
							|  |  |  |       ENV["SHELL"] = "/bin/zsh" | 
					
						
							| 
									
										
										
										
											2024-06-12 16:24:45 +02:00
										 |  |  |       ENV["HOMEBREW_ZDOTDIR"] = "/tmp" | 
					
						
							| 
									
										
										
										
											2021-01-11 12:28:07 -08:00
										 |  |  |       expect(described_class.profile).to eq("/tmp/.zshrc") | 
					
						
							| 
									
										
										
										
											2019-10-06 12:03:01 -04:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-17 18:35:26 +01:00
										 |  |  |     it "returns ~/.zshrc for Zsh" do | 
					
						
							|  |  |  |       ENV["SHELL"] = "/bin/zsh" | 
					
						
							| 
									
										
										
										
											2024-06-12 16:24:45 +02:00
										 |  |  |       ENV["HOMEBREW_ZDOTDIR"] = nil | 
					
						
							| 
									
										
										
										
											2021-01-11 12:28:07 -08:00
										 |  |  |       expect(described_class.profile).to eq("~/.zshrc") | 
					
						
							| 
									
										
										
										
											2017-02-17 18:35:26 +01:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it "returns ~/.kshrc for Ksh" do | 
					
						
							|  |  |  |       ENV["SHELL"] = "/bin/ksh" | 
					
						
							| 
									
										
										
										
											2021-01-11 12:28:07 -08:00
										 |  |  |       expect(described_class.profile).to eq("~/.kshrc") | 
					
						
							| 
									
										
										
										
											2017-02-17 18:35:26 +01:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2025-03-02 18:17:38 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     it "returns ~/.config/powershell/Microsoft.PowerShell_profile.ps1 for PowerShell" do | 
					
						
							|  |  |  |       ENV["SHELL"] = "/usr/bin/pwsh" | 
					
						
							|  |  |  |       expect(described_class.profile).to eq("~/.config/powershell/Microsoft.PowerShell_profile.ps1") | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2017-02-17 18:35:26 +01:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-22 16:28:07 +01:00
										 |  |  |   describe "::from_path" do | 
					
						
							| 
									
										
										
										
											2017-02-17 18:35:26 +01:00
										 |  |  |     it "supports a raw command name" do | 
					
						
							| 
									
										
										
										
											2021-01-11 12:28:07 -08:00
										 |  |  |       expect(described_class.from_path("bash")).to eq(:bash) | 
					
						
							| 
									
										
										
										
											2017-02-17 18:35:26 +01:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it "supports full paths" do | 
					
						
							| 
									
										
										
										
											2021-01-11 12:28:07 -08:00
										 |  |  |       expect(described_class.from_path("/bin/bash")).to eq(:bash) | 
					
						
							| 
									
										
										
										
											2017-02-17 18:35:26 +01:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it "supports versions" do | 
					
						
							| 
									
										
										
										
											2021-01-11 12:28:07 -08:00
										 |  |  |       expect(described_class.from_path("zsh-5.2")).to eq(:zsh) | 
					
						
							| 
									
										
										
										
											2017-02-17 18:35:26 +01:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it "strips newlines" do | 
					
						
							| 
									
										
										
										
											2021-01-11 12:28:07 -08:00
										 |  |  |       expect(described_class.from_path("zsh-5.2\n")).to eq(:zsh) | 
					
						
							| 
									
										
										
										
											2017-02-17 18:35:26 +01:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it "returns nil when input is invalid" do | 
					
						
							| 
									
										
										
										
											2022-03-01 00:01:13 +00:00
										 |  |  |       expect(described_class.from_path("")).to be_nil | 
					
						
							|  |  |  |       expect(described_class.from_path("@@@@@@")).to be_nil | 
					
						
							|  |  |  |       expect(described_class.from_path("invalid_shell-4.2")).to be_nil | 
					
						
							| 
									
										
										
										
											2017-02-17 18:35:26 +01:00
										 |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   specify "::sh_quote" do | 
					
						
							| 
									
										
										
										
											2021-01-11 12:28:07 -08:00
										 |  |  |     expect(described_class.send(:sh_quote, "")).to eq("''") | 
					
						
							|  |  |  |     expect(described_class.send(:sh_quote, "\\")).to eq("\\\\") | 
					
						
							|  |  |  |     expect(described_class.send(:sh_quote, "\n")).to eq("'\n'") | 
					
						
							|  |  |  |     expect(described_class.send(:sh_quote, "$")).to eq("\\$") | 
					
						
							|  |  |  |     expect(described_class.send(:sh_quote, "word")).to eq("word") | 
					
						
							| 
									
										
										
										
											2017-02-17 18:35:26 +01:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   specify "::csh_quote" do | 
					
						
							| 
									
										
										
										
											2021-01-11 12:28:07 -08:00
										 |  |  |     expect(described_class.send(:csh_quote, "")).to eq("''") | 
					
						
							|  |  |  |     expect(described_class.send(:csh_quote, "\\")).to eq("\\\\") | 
					
						
							| 
									
										
										
										
											2024-04-26 20:55:51 +02:00
										 |  |  |     # NOTE: This test is different than for `sh`. | 
					
						
							| 
									
										
										
										
											2021-01-11 12:28:07 -08:00
										 |  |  |     expect(described_class.send(:csh_quote, "\n")).to eq("'\\\n'") | 
					
						
							|  |  |  |     expect(described_class.send(:csh_quote, "$")).to eq("\\$") | 
					
						
							|  |  |  |     expect(described_class.send(:csh_quote, "word")).to eq("word") | 
					
						
							| 
									
										
										
										
											2017-02-17 18:35:26 +01:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-22 16:28:07 +01:00
										 |  |  |   describe "::prepend_path_in_profile" do | 
					
						
							| 
									
										
										
										
											2017-02-17 18:35:26 +01:00
										 |  |  |     let(:path) { "/my/path" } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-29 17:31:11 -04:00
										 |  |  |     it "supports tcsh" do | 
					
						
							| 
									
										
										
										
											2017-02-17 18:35:26 +01:00
										 |  |  |       ENV["SHELL"] = "/bin/tcsh" | 
					
						
							| 
									
										
										
										
											2021-01-11 12:28:07 -08:00
										 |  |  |       expect(described_class.prepend_path_in_profile(path)) | 
					
						
							| 
									
										
										
										
											2023-02-28 15:02:06 +00:00
										 |  |  |         .to eq("echo 'setenv PATH #{path}:$PATH' >> #{described_class.profile}") | 
					
						
							| 
									
										
										
										
											2017-02-17 18:35:26 +01:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it "supports Bash" do | 
					
						
							|  |  |  |       ENV["SHELL"] = "/bin/bash" | 
					
						
							| 
									
										
										
										
											2021-01-11 12:28:07 -08:00
										 |  |  |       expect(described_class.prepend_path_in_profile(path)) | 
					
						
							| 
									
										
										
										
											2023-02-28 15:02:06 +00:00
										 |  |  |         .to eq("echo 'export PATH=\"#{path}:$PATH\"' >> #{described_class.profile}") | 
					
						
							| 
									
										
										
										
											2017-02-17 18:35:26 +01:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-29 17:31:11 -04:00
										 |  |  |     it "supports fish" do | 
					
						
							| 
									
										
										
										
											2017-02-17 18:35:26 +01:00
										 |  |  |       ENV["SHELL"] = "/usr/local/bin/fish" | 
					
						
							| 
									
										
										
										
											2018-05-12 11:47:12 -05:00
										 |  |  |       ENV["fish_user_paths"] = "/some/path" | 
					
						
							| 
									
										
										
										
											2021-01-11 12:28:07 -08:00
										 |  |  |       expect(described_class.prepend_path_in_profile(path)) | 
					
						
							| 
									
										
										
										
											2022-02-05 16:29:09 +01:00
										 |  |  |         .to eq("fish_add_path #{path}") | 
					
						
							| 
									
										
										
										
											2017-02-17 18:35:26 +01:00
										 |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2025-03-24 13:37:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   describe "::shell_with_prompt" do | 
					
						
							| 
									
										
										
										
											2025-06-05 15:43:34 +01:00
										 |  |  |     let(:home) { HOMEBREW_TEMP } | 
					
						
							|  |  |  |     let(:notice) { "" } | 
					
						
							|  |  |  |     let(:prompt) { "test" } | 
					
						
							|  |  |  |     let(:path) { "/some/path" } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-24 13:37:25 +00:00
										 |  |  |     it "returns zsh-specific prompt configuration" do | 
					
						
							| 
									
										
										
										
											2025-06-05 15:43:34 +01:00
										 |  |  |       preferred_path = "/bin/zsh" | 
					
						
							|  |  |  |       ENV["SHELL"] = preferred_path | 
					
						
							|  |  |  |       ENV["PATH"] = path | 
					
						
							|  |  |  |       zdotdir = "#{HOMEBREW_TEMP}/brew-zsh-prompt-#{Process.euid}" | 
					
						
							|  |  |  |       expect(described_class.shell_with_prompt(prompt, preferred_path:, notice:, home:)).to eq \ | 
					
						
							|  |  |  |         "BREW_PROMPT_PATH=\"#{path}\" BREW_PROMPT_TYPE=\"#{prompt}\" ZDOTDIR=\"#{zdotdir}\" #{preferred_path}" | 
					
						
							| 
									
										
										
										
											2025-03-24 13:37:25 +00:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-05 15:43:34 +01:00
										 |  |  |     it "returns bash-specific prompt configuration" do | 
					
						
							|  |  |  |       preferred_path = "/bin/bash" | 
					
						
							| 
									
										
										
										
											2025-03-24 13:37:25 +00:00
										 |  |  |       ENV["SHELL"] = "/bin/bash" | 
					
						
							| 
									
										
										
										
											2025-06-05 15:43:34 +01:00
										 |  |  |       ENV["PATH"] = path | 
					
						
							|  |  |  |       rcfile = "#{HOMEBREW_LIBRARY_PATH}/utils/bash/brew-sh-prompt-bashrc.bash" | 
					
						
							|  |  |  |       expect(described_class.shell_with_prompt(prompt, preferred_path:, notice:, home:)).to eq \ | 
					
						
							|  |  |  |         "BREW_PROMPT_PATH=\"#{path}\" BREW_PROMPT_TYPE=\"#{prompt}\" #{preferred_path} --rcfile \"#{rcfile}\"" | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it "returns generic shell prompt configuration" do | 
					
						
							|  |  |  |       preferred_path = "/bin/dash" | 
					
						
							|  |  |  |       ENV["SHELL"] = preferred_path | 
					
						
							|  |  |  |       expect(described_class.shell_with_prompt(prompt, preferred_path:, notice:, home:)).to eq \ | 
					
						
							|  |  |  |         "PS1=\"\\[\\033[1;32m\\]#{prompt} \\[\\033[1;31m\\]\\w \\[\\033[1;34m\\]$\\[\\033[0m\\] \" #{preferred_path}" | 
					
						
							| 
									
										
										
										
											2025-03-24 13:37:25 +00:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it "outputs notice when provided" do | 
					
						
							|  |  |  |       notice = "Test Notice" | 
					
						
							|  |  |  |       expect { described_class.shell_with_prompt("test", preferred_path: "/bin/bash", notice: notice) } | 
					
						
							|  |  |  |         .to output("#{notice}\n").to_stdout | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2017-02-17 18:35:26 +01:00
										 |  |  | end |