Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
locport (1.2.1)
locport (1.3.0)
thor (~> 1.3)

GEM
Expand Down
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,22 @@ locport list

If any conflicts are detected, they will be displayed and program exits with error code 1.

### Looking up a port by address

```sh
locport port ADDRESS
```

Examples:

```sh
locport port alpha.localhost
locport port http://alpha.localhost
```

Lookup compares addresses after removing a leading `http://` prefix from both sides.
If no address is found, command exits with code 1 and produces empty output.

### Adding existing projects to the index

```sh
Expand Down
8 changes: 8 additions & 0 deletions lib/locport.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,14 @@ def add(host = "#{File.basename(Dir.pwd)}.localhost")
say "added ✓", :green
end

desc "port ADDRESS", "Print the indexed port for an address"
def port(address)
found_port = indexer.port_for_address(address)
return say(found_port) if found_port

exit 1
end

desc "list", "List indexed projects, hosts and ports"
def list
indexer.projects.each do |dir, addresses|
Expand Down
12 changes: 12 additions & 0 deletions lib/locport/indexer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,14 @@ def append_address_to_dotfile(address, dir: Dir.pwd)
save
end

def port_for_address(value)
normalized_value = normalize_http_address(value)

addresses.find do |address|
normalize_http_address(address.host) == normalized_value
end&.port
end

def storage_path
File.join storage_dir, DATA_FILE
end
Expand Down Expand Up @@ -174,5 +182,9 @@ def find_unused_port
return port unless @addresses.any? { |address| address.port == port } || port_listening?(port)
end
end

def normalize_http_address(value)
value.to_s.delete_prefix("http://")
end
end
end
2 changes: 1 addition & 1 deletion locport.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Gem::Specification.new do |spec|
spec.name = "locport"
spec.version = "1.2.1"
spec.version = "1.3.0"
spec.summary = "localhost port management"
spec.description = "Overview of localhost ports used across projects. Prevent conflicts."
spec.authors = ["Robert Starsi"]
Expand Down
13 changes: 13 additions & 0 deletions test/locport/indexer_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,19 @@ def test_port_open
refute @indexer.port_listening?(port)
end

def test_port_for_address
@indexer.index(@projects_path, recursive: true)
@indexer.load_projects

assert_equal 30000, @indexer.port_for_address("http://alpha.localhost")
assert_equal 30000, @indexer.port_for_address("alpha.localhost")
assert_equal 30001, @indexer.port_for_address("http://conflict.localhost")
assert_equal 30001, @indexer.port_for_address("conflict.localhost")
assert_nil @indexer.port_for_address("http://alpha.localhost/foo")
assert_nil @indexer.port_for_address("missing.localhost")
assert_nil @indexer.port_for_address(nil)
end

def test_create_address_without_conflicts
dir = Dir.mktmpdir

Expand Down
38 changes: 38 additions & 0 deletions test/locport_main_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,42 @@ class LocportMainTest < Minitest::Test
def test_default_task_is_list
assert_equal "list", Locport::Main.default_task
end

def test_port_prints_port_when_found
indexer = Minitest::Mock.new
indexer.expect :port_for_address, 30000, ["https://alpha.localhost/foo"]
main = build_main(indexer)

out, err = capture_io do
main.port("https://alpha.localhost/foo")
end

assert_equal "30000\n", out
assert_empty err
indexer.verify
end

def test_port_exits_with_non_zero_and_empty_output_when_not_found
indexer = Minitest::Mock.new
indexer.expect :port_for_address, nil, ["https://missing.localhost"]
main = build_main(indexer)

out, err = capture_io do
error = assert_raises(SystemExit) do
main.port("https://missing.localhost")
end
assert_equal 1, error.status
end

assert_empty out
assert_empty err
indexer.verify
end

private
def build_main(indexer)
main = Locport::Main.new
main.define_singleton_method(:indexer) { indexer }
main
end
end