diff --git a/plugins/commands/port/command.rb b/plugins/commands/port/command.rb index 76dfd6e17..af35def4b 100644 --- a/plugins/commands/port/command.rb +++ b/plugins/commands/port/command.rb @@ -12,13 +12,16 @@ module VagrantPlugins end def execute + options = {} + opts = OptionParser.new do |o| o.banner = "Usage: vagrant port [options] [name]" o.separator "" o.separator "Options:" o.separator "" - o.on("--guest", "Output the host port that maps to the given guest port") do + o.on("--guest PORT", "Output the host port that maps to the given guest port") do |port| + options[:guest] = port end o.on("--machine-readable", "Display machine-readable output") @@ -46,14 +49,40 @@ module VagrantPlugins return 0 end - @env.ui.info(I18n.t("port_command.details")) - @env.ui.info("") - ports.each do |guest, host| - @env.ui.info("#{guest.to_s.rjust(6)} (guest) => #{host} (host)") - @env.ui.machine("forwarded_port", guest, host, target: vm.name.to_s) + if present?(options[:guest]) + return print_single(vm, ports, options[:guest]) + else + return print_all(vm, ports) end end + end + private + + # Print all the guest <=> host port mappings. + # @return [0] the exit code + def print_all(vm, ports) + @env.ui.info(I18n.t("port_command.details")) + @env.ui.info("") + ports.each do |host, guest| + @env.ui.info("#{guest.to_s.rjust(6)} (guest) => #{host} (host)") + @env.ui.machine("forwarded_port", guest, host, target: vm.name.to_s) + end + return 0 + end + + # Print the host mapping that matches the given guest target. + # @return [0,1] the exit code + def print_single(vm, ports, target) + map = ports.find { |_, guest| "#{guest}" == "#{target}" } + if !present?(map) + @env.ui.error(I18n.t("port_command.no_matching_port", + port: target, + )) + return 1 + end + + @env.ui.info("#{map[0]}") return 0 end end diff --git a/plugins/commands/port/locales/en.yml b/plugins/commands/port/locales/en.yml index 8bcfdf1c7..ba1389db7 100644 --- a/plugins/commands/port/locales/en.yml +++ b/plugins/commands/port/locales/en.yml @@ -14,3 +14,7 @@ en: most likely a limitation of the provider and not a bug in Vagrant. If you believe this is a bug in Vagrant, please search existing issues before opening a new one. + no_matching_port: |- + The guest is not currently mapping port %{port} to the host machine. Is + the port configured in the Vagrantfile? You may need to run `vagrant reload` + if changes were made to the port configuration in the Vagrantfile. diff --git a/test/unit/plugins/commands/port/command_test.rb b/test/unit/plugins/commands/port/command_test.rb index 5ec4027de..ac3da72a0 100644 --- a/test/unit/plugins/commands/port/command_test.rb +++ b/test/unit/plugins/commands/port/command_test.rb @@ -16,9 +16,7 @@ describe VagrantPlugins::CommandPort::Command do iso_env.create_vagrant_env end - let(:argv) { [] } - let(:pushes) { {} } - let(:state) { double(:state, id: :running) } + let(:state) { double(:state, id: :running) } let(:machine) { env.machine(env.machine_names[0], :dummy) } @@ -27,7 +25,7 @@ describe VagrantPlugins::CommandPort::Command do I18n.reload! end - subject { described_class.new(argv, env) } + subject { described_class.new([], env) } before do allow(machine).to receive(:state).and_return(state) @@ -46,7 +44,7 @@ describe VagrantPlugins::CommandPort::Command do end EOH - subject = described_class.new(argv, iso_env.create_vagrant_env) + subject = described_class.new([], iso_env.create_vagrant_env) expect { subject.execute }.to raise_error(Vagrant::Errors::ConfigInvalid) { |err| expect(err.message).to include("The following settings shouldn't exist: bad") @@ -96,8 +94,56 @@ describe VagrantPlugins::CommandPort::Command do expect(subject.execute).to eq(0) expect(output).to include("forwarded ports for the machine") - expect(output).to include("2222 (guest) => 22 (host)") - expect(output).to include("1111 (guest) => 11 (host)") + expect(output).to include("22 (guest) => 2222 (host)") + expect(output).to include("11 (guest) => 1111 (host)") + end + + it "prints the matching host port when --guest is given" do + argv = ["--guest", "22"] + subject = described_class.new(argv, env) + + allow(machine.provider).to receive(:capability?).and_return(true) + allow(machine.provider).to receive(:capability).with(:forwarded_ports) + .and_return([[2222,22]]) + + output = "" + allow(env.ui).to receive(:info) do |data| + output << data + end + + expect(subject.execute).to eq(0) + + expect(output).to eq("2222") + end + + it "returns an error with no port is mapped to the --guest option" do + argv = ["--guest", "80"] + subject = described_class.new(argv, env) + + allow(machine.provider).to receive(:capability?).and_return(true) + allow(machine.provider).to receive(:capability).with(:forwarded_ports) + .and_return([[2222,22]]) + + output = "" + allow(env.ui).to receive(:error) do |data| + output << data + end + + expect(subject.execute).to_not eq(0) + + expect(output).to include("not currently mapping port 80") end end end + + + + + + + + + + + +