port_of_call 0.1.0.alpha1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.rspec +3 -0
- data/CHANGELOG.md +35 -0
- data/LICENSE.txt +31 -0
- data/README.md +86 -0
- data/RELEASE_NOTES.md +62 -0
- data/Rakefile +8 -0
- data/examples/basic_usage.rb +40 -0
- data/examples/rails_example.rb +58 -0
- data/exe/port_of_call +7 -0
- data/lib/generators/port_of_call/install_generator.rb +21 -0
- data/lib/generators/port_of_call/templates/README.md +27 -0
- data/lib/generators/port_of_call/templates/initializer.rb +22 -0
- data/lib/port_of_call/cli.rb +138 -0
- data/lib/port_of_call/configuration.rb +46 -0
- data/lib/port_of_call/port_calculator.rb +119 -0
- data/lib/port_of_call/railtie.rb +48 -0
- data/lib/port_of_call/version.rb +7 -0
- data/lib/port_of_call.rb +116 -0
- data/lib/tasks/port_of_call.rake +112 -0
- data/sig/port_of_call.rbs +4 -0
- metadata +138 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: c5f861789c53684db6036135fcb5eb0057c90ea56c95aedd7fabd4cc85c9c0b2
|
4
|
+
data.tar.gz: 0eab14311169be6984ed29ac0a531b0c0ac0f1da8a403dc7af2561a098969267
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 984c62a2c7dec18962070b1dd51b7a0149a21f4caa57c39a42832e5e460671f4ccc55a82445158102d26eb29a27a27f98a99ab7270ec1af9ac5fd900c71427cd
|
7
|
+
data.tar.gz: fcf8f557fa7763042ef1f0aae10f416d101d83413f9d9c5ec869266e217d3931b31dc7dc33afad5ef3cbfbc7f0bb107f9fb2943ae740945dd418a8f3fc59a878
|
data/.rspec
ADDED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
All notable changes to this project will be documented in this file.
|
4
|
+
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
7
|
+
|
8
|
+
## [0.1.0.alpha1] - 2025-03-25
|
9
|
+
|
10
|
+
### Added
|
11
|
+
- Initial pre-release of Port of Call gem
|
12
|
+
- Core port calculation functionality
|
13
|
+
- Project name extraction from git or directory
|
14
|
+
- Deterministic SHA256 hashing algorithm
|
15
|
+
- Configurable port range mapping
|
16
|
+
- Rails integration via Railtie
|
17
|
+
- Automatic port assignment for Rails server
|
18
|
+
- Generator for configuration initializer
|
19
|
+
- Command-line interface
|
20
|
+
- Server command for starting Rails
|
21
|
+
- Port command for displaying calculated port
|
22
|
+
- Set command for setting default port
|
23
|
+
- Version and help commands
|
24
|
+
- Rake tasks for common operations
|
25
|
+
- port_of_call:port to show calculated port
|
26
|
+
- port_of_call:start to start server
|
27
|
+
- port_of_call:install to generate initializer
|
28
|
+
- port_of_call:set_default to update development.rb
|
29
|
+
- port_of_call:check to verify port availability
|
30
|
+
- port_of_call:info to display configuration
|
31
|
+
- Configuration options
|
32
|
+
- Custom port range
|
33
|
+
- Base port setting
|
34
|
+
- Project name override
|
35
|
+
- Reserved ports list
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2025 Jonathan P. Berger and contributors
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
22
|
+
|
23
|
+
ADDITIONAL DISCLAIMER:
|
24
|
+
This software is provided for educational and informational purposes only.
|
25
|
+
The author(s) of this software take no responsibility for any conflicts, errors,
|
26
|
+
or system issues that may arise from using this software. Users are advised
|
27
|
+
to thoroughly test this software in a controlled environment before deploying
|
28
|
+
it in production settings. Port conflicts, networking issues, or any other
|
29
|
+
problems that may occur when using this software are solely the responsibility
|
30
|
+
of the user. By using this software, you agree to hold the author(s) harmless
|
31
|
+
from any liability.
|
data/README.md
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
⛵️ Why use Port of Call?
|
2
|
+
=============================
|
3
|
+
Do you have multiple Rails apps running on your machine? Tired of conflicts on port 3000? I was, so I vibe-coded this gem.
|
4
|
+
|
5
|
+
Port of Call automatically assigns deterministic port numbers to each Rails application based on its name.
|
6
|
+
|
7
|
+
⛵️⛵️ Who's Port of Call for?
|
8
|
+
=============================
|
9
|
+
Rails developers who tend to work on multiple applications simultaneously
|
10
|
+
|
11
|
+
⛵️⛵️⛵️ What exactly does Port of Call do?
|
12
|
+
=============================
|
13
|
+
Port of Call deterministically assigns port numbers to Rails applications:
|
14
|
+
|
15
|
+
1. It extracts your application's name from Git or directory name
|
16
|
+
2. It creates a hash of the name using SHA256
|
17
|
+
3. It maps this hash to a port number within your configured range (default: 3000-3999)
|
18
|
+
4. It automatically sets this port when you start your Rails server
|
19
|
+
|
20
|
+
The same app always gets the same port on any machine, avoiding conflicts!
|
21
|
+
|
22
|
+
⛵️⛵️⛵️⛵️ How do I use it?
|
23
|
+
=============================
|
24
|
+
1. Install the gem:
|
25
|
+
```ruby
|
26
|
+
# In your Gemfile
|
27
|
+
gem 'port_of_call'
|
28
|
+
```
|
29
|
+
|
30
|
+
2. Bundle install:
|
31
|
+
```bash
|
32
|
+
$ bundle install
|
33
|
+
```
|
34
|
+
|
35
|
+
3. Generate the initializer (optional):
|
36
|
+
```bash
|
37
|
+
$ rails generate port_of_call:install
|
38
|
+
```
|
39
|
+
|
40
|
+
4. Run your server as usual:
|
41
|
+
```bash
|
42
|
+
$ rails server
|
43
|
+
```
|
44
|
+
|
45
|
+
CLI Commands:
|
46
|
+
- `port_of_call server` - Start Rails server with calculated port
|
47
|
+
- `port_of_call port` - Show the calculated port
|
48
|
+
- `port_of_call set` - Set as default port in development.rb
|
49
|
+
- `port_of_call -v` - Show version information
|
50
|
+
- `port_of_call -h` - Show help
|
51
|
+
|
52
|
+
Rake Tasks:
|
53
|
+
- `rake port_of_call` - Show calculated port
|
54
|
+
- `rake port_of_call:start` - Start Rails server
|
55
|
+
- `rake poc` - Shorthand for starting the server
|
56
|
+
|
57
|
+
⛵️⛵️⛵️⛵️⛵️ Extras
|
58
|
+
=============================
|
59
|
+
Configuration:
|
60
|
+
```ruby
|
61
|
+
# In config/initializers/port_of_call.rb
|
62
|
+
PortOfCall.configure do |config|
|
63
|
+
# Change port range (default: 3000..3999)
|
64
|
+
config.port_range = 4000..4999
|
65
|
+
|
66
|
+
# Set custom project name
|
67
|
+
config.project_name = "my_unique_app_name"
|
68
|
+
|
69
|
+
# Avoid specific ports
|
70
|
+
config.reserved_ports = [4567, 5000]
|
71
|
+
end
|
72
|
+
```
|
73
|
+
|
74
|
+
Troubleshooting:
|
75
|
+
- If your port is already in use, Port of Call will warn you
|
76
|
+
- To check port availability: `rake port_of_call:check`
|
77
|
+
- For detailed info: `rake port_of_call:info`
|
78
|
+
|
79
|
+
GitHub: [github.com/jonathanpberger/port-of-call](https://github.com/jonathanpberger/port-of-call)
|
80
|
+
|
81
|
+
License: MIT with additional [disclaimer](LICENSE.txt)
|
82
|
+
```
|
83
|
+
|
84
|
+
## Development
|
85
|
+
|
86
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt.
|
data/RELEASE_NOTES.md
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
# Port of Call 0.1.0 Release Notes
|
2
|
+
|
3
|
+
We're excited to announce the initial release of Port of Call!
|
4
|
+
|
5
|
+
Port of Call is a Ruby gem that assigns each Rails application a consistent, deterministic port number based on the application's name or repository. This solves the common conflict of multiple Rails apps all defaulting to port 3000.
|
6
|
+
|
7
|
+
## Features
|
8
|
+
|
9
|
+
### Automatic Port Assignment
|
10
|
+
- Simply install the gem, and your Rails server will use a unique port based on your project name
|
11
|
+
- No configuration required - it just works!
|
12
|
+
|
13
|
+
### Deterministic Ports
|
14
|
+
- Same project always gets the same port on any machine
|
15
|
+
- Consistent development experience across your team
|
16
|
+
|
17
|
+
### Multiple Interface Options
|
18
|
+
- Command-line interface with intuitive commands
|
19
|
+
- Rake tasks for easy integration
|
20
|
+
- Ruby API for programmatic use
|
21
|
+
|
22
|
+
### Customization
|
23
|
+
- Configurable port range
|
24
|
+
- Custom project name option
|
25
|
+
- Reserved ports list
|
26
|
+
|
27
|
+
## Installation
|
28
|
+
|
29
|
+
Add this line to your application's Gemfile:
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
gem 'port_of_call'
|
33
|
+
```
|
34
|
+
|
35
|
+
And then execute:
|
36
|
+
|
37
|
+
```bash
|
38
|
+
$ bundle install
|
39
|
+
$ rails generate port_of_call:install # Optional
|
40
|
+
```
|
41
|
+
|
42
|
+
## Usage
|
43
|
+
|
44
|
+
Start your Rails server as usual:
|
45
|
+
|
46
|
+
```bash
|
47
|
+
$ rails server
|
48
|
+
```
|
49
|
+
|
50
|
+
You should see output indicating the port that Port of Call has assigned.
|
51
|
+
|
52
|
+
## Documentation
|
53
|
+
|
54
|
+
For detailed usage instructions, see the [README](README.md).
|
55
|
+
|
56
|
+
## Feedback
|
57
|
+
|
58
|
+
We welcome feedback, bug reports, and feature requests! Please submit issues on GitHub.
|
59
|
+
|
60
|
+
---
|
61
|
+
|
62
|
+
Thank you for using Port of Call!
|
data/Rakefile
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# This is an example of how to use Port of Call programmatically
|
4
|
+
|
5
|
+
require "port_of_call"
|
6
|
+
|
7
|
+
# Get the calculated port for the current project
|
8
|
+
puts "Project name: #{PortOfCall.project_name}"
|
9
|
+
puts "Calculated port: #{PortOfCall.calculate_port}"
|
10
|
+
|
11
|
+
# Check if the port is available
|
12
|
+
port = PortOfCall.calculate_port
|
13
|
+
if PortOfCall.port_in_use?(port)
|
14
|
+
puts "Port #{port} is already in use by another process"
|
15
|
+
else
|
16
|
+
puts "Port #{port} is available"
|
17
|
+
end
|
18
|
+
|
19
|
+
# Configure Port of Call
|
20
|
+
PortOfCall.configure do |config|
|
21
|
+
# Use a different port range
|
22
|
+
config.port_range = 4000..4999
|
23
|
+
|
24
|
+
# Set a different base port
|
25
|
+
config.base_port = 4000
|
26
|
+
|
27
|
+
# Set a custom project name
|
28
|
+
config.project_name = "my_custom_project"
|
29
|
+
|
30
|
+
# Reserve specific ports
|
31
|
+
config.reserved_ports = [4000, 4001, 4002]
|
32
|
+
end
|
33
|
+
|
34
|
+
# Get the new calculated port after configuration
|
35
|
+
puts "New project name: #{PortOfCall.project_name}"
|
36
|
+
puts "New calculated port: #{PortOfCall.calculate_port}"
|
37
|
+
|
38
|
+
# Get server options hash (useful for Rails server)
|
39
|
+
options = PortOfCall.server_options
|
40
|
+
puts "Server options: #{options.inspect}"
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# This file demonstrates how to use Port of Call in a Rails application
|
4
|
+
|
5
|
+
# In your Gemfile:
|
6
|
+
# -----------------
|
7
|
+
# gem 'port_of_call'
|
8
|
+
|
9
|
+
|
10
|
+
# In config/initializers/port_of_call.rb:
|
11
|
+
# ----------------------------------------
|
12
|
+
# PortOfCall.configure do |config|
|
13
|
+
# # The port range to use (default: 3000..3999)
|
14
|
+
# config.port_range = 3000..3999
|
15
|
+
#
|
16
|
+
# # The base port to start from (default: 3000)
|
17
|
+
# config.base_port = 3000
|
18
|
+
#
|
19
|
+
# # Optional: manually set a project name (default: nil, auto-detected)
|
20
|
+
# # config.project_name = "my_custom_app_name"
|
21
|
+
#
|
22
|
+
# # Optional: ports to avoid (default: [])
|
23
|
+
# # config.reserved_ports = [3333, 4567]
|
24
|
+
# end
|
25
|
+
|
26
|
+
|
27
|
+
# In your terminal:
|
28
|
+
# -----------------
|
29
|
+
# Show the calculated port:
|
30
|
+
# $ rake port_of_call
|
31
|
+
#
|
32
|
+
# Start the server with the calculated port:
|
33
|
+
# $ rails server
|
34
|
+
#
|
35
|
+
# Or use the CLI:
|
36
|
+
# $ port_of_call server # Start the server
|
37
|
+
# $ port_of_call port # Show the port
|
38
|
+
# $ port_of_call set # Set as default port
|
39
|
+
#
|
40
|
+
# Use the shortcut task:
|
41
|
+
# $ rake poc # Start the server
|
42
|
+
|
43
|
+
|
44
|
+
# In your Ruby code:
|
45
|
+
# ------------------
|
46
|
+
# # Get the calculated port:
|
47
|
+
# port = PortOfCall.calculate_port
|
48
|
+
#
|
49
|
+
# # Get the project name:
|
50
|
+
# name = PortOfCall.project_name
|
51
|
+
#
|
52
|
+
# # Check if the port is available:
|
53
|
+
# if PortOfCall.port_in_use?(port)
|
54
|
+
# puts "Port #{port} is in use"
|
55
|
+
# end
|
56
|
+
#
|
57
|
+
# # Get server options for Rails:
|
58
|
+
# options = PortOfCall.server_options # Returns { Port: calculated_port }
|
data/exe/port_of_call
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rails/generators"
|
4
|
+
|
5
|
+
module PortOfCall
|
6
|
+
module Generators
|
7
|
+
class InstallGenerator < Rails::Generators::Base
|
8
|
+
source_root File.expand_path("templates", __dir__)
|
9
|
+
|
10
|
+
desc "Creates a Port of Call initializer for your application"
|
11
|
+
|
12
|
+
def copy_initializer
|
13
|
+
template "initializer.rb", "config/initializers/port_of_call.rb"
|
14
|
+
end
|
15
|
+
|
16
|
+
def show_readme
|
17
|
+
readme "README.md" if behavior == :invoke
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# Port of Call
|
2
|
+
|
3
|
+
## Next Steps
|
4
|
+
|
5
|
+
Port of Call has been installed and configured. Your Rails server will now
|
6
|
+
automatically use a unique, deterministic port based on your project name.
|
7
|
+
|
8
|
+
### Usage
|
9
|
+
|
10
|
+
To start your Rails server with the calculated port:
|
11
|
+
|
12
|
+
```bash
|
13
|
+
$ rails server
|
14
|
+
```
|
15
|
+
|
16
|
+
To see the calculated port:
|
17
|
+
|
18
|
+
```bash
|
19
|
+
$ rake port_of_call
|
20
|
+
```
|
21
|
+
|
22
|
+
### Configuration
|
23
|
+
|
24
|
+
Your configuration file is at `config/initializers/port_of_call.rb`.
|
25
|
+
You can edit this file to customize the behavior of Port of Call.
|
26
|
+
|
27
|
+
For more information, see: https://github.com/jpb/port-of-claude
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Port of Call Configuration
|
4
|
+
#
|
5
|
+
# This initializer configures the Port of Call gem, which automatically
|
6
|
+
# assigns a unique, deterministic port to your Rails application.
|
7
|
+
#
|
8
|
+
# For more information, see: https://github.com/jpb/port-of-claude
|
9
|
+
|
10
|
+
PortOfCall.configure do |config|
|
11
|
+
# The port range to use (default: 3000..3999)
|
12
|
+
# config.port_range = 3000..3999
|
13
|
+
|
14
|
+
# The base port to start from (default: 3000)
|
15
|
+
# config.base_port = 3000
|
16
|
+
|
17
|
+
# Manually set a project name (default: nil, auto-detected)
|
18
|
+
# config.project_name = "my_custom_app_name"
|
19
|
+
|
20
|
+
# Reserved ports to avoid (default: [])
|
21
|
+
# config.reserved_ports = [3333, 4567]
|
22
|
+
end
|
@@ -0,0 +1,138 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module PortOfCall
|
4
|
+
# Command Line Interface for Port of Call
|
5
|
+
#
|
6
|
+
# Provides command-line functionality for interacting with Port of Call.
|
7
|
+
# Available commands:
|
8
|
+
# - server: Start Rails server with calculated port
|
9
|
+
# - port: Show the calculated port
|
10
|
+
# - set: Set port as default in development.rb
|
11
|
+
# - version: Show version information
|
12
|
+
# - help: Display usage information
|
13
|
+
class CLI
|
14
|
+
# Start the CLI with the given arguments
|
15
|
+
# @param args [Array<String>] command-line arguments
|
16
|
+
# @return [void]
|
17
|
+
def self.start(args)
|
18
|
+
new.start(args)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Route to the appropriate command
|
22
|
+
# @param args [Array<String>] command-line arguments
|
23
|
+
# @return [void]
|
24
|
+
def start(args)
|
25
|
+
command = args.shift || "server"
|
26
|
+
|
27
|
+
case command
|
28
|
+
when "server", "s"
|
29
|
+
start_server(args)
|
30
|
+
when "port", "p"
|
31
|
+
show_port
|
32
|
+
when "set"
|
33
|
+
set_default_port
|
34
|
+
when "version", "--version", "-v"
|
35
|
+
show_version
|
36
|
+
when "help", "--help", "-h"
|
37
|
+
show_help
|
38
|
+
else
|
39
|
+
puts "Unknown command: #{command}"
|
40
|
+
show_help
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
# Start the Rails server with the calculated port
|
47
|
+
# @param args [Array<String>] additional arguments for the server
|
48
|
+
# @return [void]
|
49
|
+
def start_server(args)
|
50
|
+
# Get the calculated port
|
51
|
+
port = PortOfCall.calculate_port
|
52
|
+
project_name = PortOfCall.project_name
|
53
|
+
|
54
|
+
# Check if the port is already in use
|
55
|
+
if PortOfCall.port_in_use?(port)
|
56
|
+
puts "WARNING: Port #{port} is already in use by another process!"
|
57
|
+
exit 1
|
58
|
+
end
|
59
|
+
|
60
|
+
# Construct server command
|
61
|
+
if defined?(Rails) && defined?(Rails::Server)
|
62
|
+
puts "Port of Call - Starting Rails server for #{project_name} on port #{port}"
|
63
|
+
|
64
|
+
# Add -p option if not already specified
|
65
|
+
unless args.include?("-p") || args.include?("--port")
|
66
|
+
args.unshift("-p", port.to_s)
|
67
|
+
end
|
68
|
+
|
69
|
+
# Start server
|
70
|
+
Rails::Server.new(args).tap do |server|
|
71
|
+
# Set port in server options
|
72
|
+
server.options[:Port] = port if server.options[:Port].nil?
|
73
|
+
|
74
|
+
# Start server
|
75
|
+
server.start
|
76
|
+
end
|
77
|
+
else
|
78
|
+
# Fallback when not running in a Rails context
|
79
|
+
puts "Port of Call - Rails environment not detected"
|
80
|
+
puts "Calculated port for #{project_name}: #{port}"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# Show the calculated port
|
85
|
+
# @return [void]
|
86
|
+
def show_port
|
87
|
+
port = PortOfCall.calculate_port
|
88
|
+
project_name = PortOfCall.project_name
|
89
|
+
|
90
|
+
puts "Port of Call - Calculated port for #{project_name}: #{port}"
|
91
|
+
|
92
|
+
# Check if the port is already in use
|
93
|
+
if PortOfCall.port_in_use?(port)
|
94
|
+
puts "WARNING: Port #{port} is already in use by another process!"
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
# Set the calculated port as the default in development.rb
|
99
|
+
# @return [void]
|
100
|
+
def set_default_port
|
101
|
+
if defined?(Rails) && defined?(Rails.root)
|
102
|
+
# Use rake task for this
|
103
|
+
system("rake", "port_of_call:set_default")
|
104
|
+
else
|
105
|
+
puts "ERROR: Rails environment not detected"
|
106
|
+
exit 1
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
# Show version information
|
111
|
+
# @return [void]
|
112
|
+
def show_version
|
113
|
+
puts "Port of Call v#{PortOfCall::VERSION}"
|
114
|
+
end
|
115
|
+
|
116
|
+
# Show help information
|
117
|
+
# @return [void]
|
118
|
+
def show_help
|
119
|
+
puts <<~HELP
|
120
|
+
Port of Call v#{PortOfCall::VERSION} - Deterministic port assignment for Rails applications
|
121
|
+
|
122
|
+
Usage: port_of_call [COMMAND] [OPTIONS]
|
123
|
+
|
124
|
+
Commands:
|
125
|
+
server, s Start the Rails server with the calculated port (default)
|
126
|
+
port, p Show the calculated port for this application
|
127
|
+
set Set the calculated port as the default in development.rb
|
128
|
+
version, -v Display version information
|
129
|
+
help, -h Show this help message
|
130
|
+
|
131
|
+
Examples:
|
132
|
+
port_of_call # Start the Rails server with the calculated port
|
133
|
+
port_of_call port # Show the calculated port
|
134
|
+
port_of_call set # Set the calculated port as the default
|
135
|
+
HELP
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module PortOfCall
|
4
|
+
# Configuration class for Port of Call settings
|
5
|
+
#
|
6
|
+
# @attr [Range] port_range The range of port numbers to use
|
7
|
+
# @attr [Integer] base_port The base port number
|
8
|
+
# @attr [String, nil] custom_project_name Optional custom project name to override auto-detection
|
9
|
+
# @attr [Array<Integer>] reserved_ports List of ports to avoid using
|
10
|
+
class Configuration
|
11
|
+
attr_accessor :port_range, :base_port, :custom_project_name, :reserved_ports
|
12
|
+
|
13
|
+
# Initialize a new configuration with default values
|
14
|
+
def initialize
|
15
|
+
@port_range = 3000..3999
|
16
|
+
@base_port = 3000
|
17
|
+
@custom_project_name = nil
|
18
|
+
@reserved_ports = []
|
19
|
+
end
|
20
|
+
|
21
|
+
# Get the custom project name
|
22
|
+
# @return [String, nil] the custom project name or nil if not set
|
23
|
+
def project_name
|
24
|
+
@custom_project_name
|
25
|
+
end
|
26
|
+
|
27
|
+
# Set a custom project name
|
28
|
+
# @param name [String] the project name to use
|
29
|
+
def project_name=(name)
|
30
|
+
@custom_project_name = name
|
31
|
+
end
|
32
|
+
|
33
|
+
# Calculate the size of the port range
|
34
|
+
# @return [Integer] the number of ports in the range
|
35
|
+
def port_range_size
|
36
|
+
@port_range.end - @port_range.begin + 1
|
37
|
+
end
|
38
|
+
|
39
|
+
# Check if a port is available within the configuration constraints
|
40
|
+
# @param port [Integer] the port to check
|
41
|
+
# @return [Boolean] true if the port is in range and not reserved
|
42
|
+
def available_port?(port)
|
43
|
+
port_range.include?(port) && !reserved_ports.include?(port)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "digest"
|
4
|
+
|
5
|
+
module PortOfCall
|
6
|
+
# Calculates deterministic port numbers based on project name
|
7
|
+
#
|
8
|
+
# This class is responsible for:
|
9
|
+
# 1. Extracting the project name from various sources
|
10
|
+
# 2. Hashing the project name consistently
|
11
|
+
# 3. Mapping the hash to a port number within the configured range
|
12
|
+
class PortCalculator
|
13
|
+
# @return [Configuration] the configuration instance
|
14
|
+
attr_reader :config
|
15
|
+
|
16
|
+
# Initialize a new calculator with the given configuration
|
17
|
+
# @param config [Configuration] the configuration instance
|
18
|
+
def initialize(config)
|
19
|
+
@config = config
|
20
|
+
end
|
21
|
+
|
22
|
+
# Calculate a deterministic port number for the current project
|
23
|
+
# @return [Integer] the calculated port number
|
24
|
+
def calculate
|
25
|
+
project_name = extract_project_name
|
26
|
+
hash_value = hash_project_name(project_name)
|
27
|
+
port_from_hash(hash_value)
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
# Extract the project name using various methods
|
33
|
+
# @return [String] the project name
|
34
|
+
def extract_project_name
|
35
|
+
# Use custom project name if set
|
36
|
+
return config.project_name if config.project_name
|
37
|
+
|
38
|
+
# Try multiple methods to determine the project name
|
39
|
+
git_name || directory_name || fallback_name
|
40
|
+
end
|
41
|
+
|
42
|
+
# Try to get the project name from git
|
43
|
+
# @return [String, nil] the project name from git, or nil if not available
|
44
|
+
def git_name
|
45
|
+
return nil unless File.exist?(File.join(root_path, '.git'))
|
46
|
+
|
47
|
+
# Try to get name from git remote origin URL
|
48
|
+
remote_url = `cd #{root_path} && git config --get remote.origin.url 2>/dev/null`.strip
|
49
|
+
return extract_git_repo_name(remote_url) unless remote_url.empty?
|
50
|
+
|
51
|
+
# Fallback to git directory name
|
52
|
+
nil
|
53
|
+
end
|
54
|
+
|
55
|
+
# Extract repository name from git URL
|
56
|
+
# @param url [String] the git remote URL
|
57
|
+
# @return [String, nil] the repository name, or nil if not parseable
|
58
|
+
def extract_git_repo_name(url)
|
59
|
+
return nil if url.nil? || url.empty?
|
60
|
+
|
61
|
+
# Match various git URL formats:
|
62
|
+
# - https://github.com/user/repo.git
|
63
|
+
# - git@github.com:user/repo.git
|
64
|
+
# - git://github.com/user/repo
|
65
|
+
if url =~ %r{/([^/]+?)(\.git)?$} || url =~ %r{:([^/]+?)(\.git)?$}
|
66
|
+
return $1
|
67
|
+
end
|
68
|
+
|
69
|
+
nil
|
70
|
+
end
|
71
|
+
|
72
|
+
# Get the project name from the directory name
|
73
|
+
# @return [String] the directory name
|
74
|
+
def directory_name
|
75
|
+
# Use base name of the root directory
|
76
|
+
File.basename(root_path)
|
77
|
+
end
|
78
|
+
|
79
|
+
# Fallback project name to use if all else fails
|
80
|
+
# @return [String] the fallback name
|
81
|
+
def fallback_name
|
82
|
+
# Fallback name in case all else fails
|
83
|
+
"rails_app"
|
84
|
+
end
|
85
|
+
|
86
|
+
# Hash the project name to an integer consistently
|
87
|
+
# @param name [String] the project name
|
88
|
+
# @return [Integer] a hash value
|
89
|
+
def hash_project_name(name)
|
90
|
+
# Use SHA256 for consistent hashing across platforms
|
91
|
+
# Take the first 8 hex chars (32 bits) and convert to integer
|
92
|
+
Digest::SHA256.hexdigest(name)[0, 8].to_i(16)
|
93
|
+
end
|
94
|
+
|
95
|
+
# Map a hash value to a port number within the configured range
|
96
|
+
# @param hash_value [Integer] the hash value
|
97
|
+
# @return [Integer] a port number
|
98
|
+
def port_from_hash(hash_value)
|
99
|
+
# Get the size of the port range
|
100
|
+
range_size = config.port_range.size
|
101
|
+
|
102
|
+
# Calculate offset based on hash value
|
103
|
+
offset = hash_value % range_size
|
104
|
+
|
105
|
+
# Apply offset to base port
|
106
|
+
config.base_port + offset
|
107
|
+
end
|
108
|
+
|
109
|
+
# Get the root path of the application
|
110
|
+
# @return [String] the root path
|
111
|
+
def root_path
|
112
|
+
if defined?(Rails) && Rails.respond_to?(:root)
|
113
|
+
Rails.root.to_s
|
114
|
+
else
|
115
|
+
Dir.pwd
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module PortOfCall
|
4
|
+
class Railtie < Rails::Railtie
|
5
|
+
# Load rake tasks
|
6
|
+
rake_tasks do
|
7
|
+
load File.expand_path("../tasks/port_of_call.rake", __dir__)
|
8
|
+
end
|
9
|
+
|
10
|
+
# Override the server default port
|
11
|
+
initializer "port_of_call.set_default_port" do |app|
|
12
|
+
# Only override if no port is explicitly specified
|
13
|
+
if !ENV["PORT"] && !ENV["RAILS_PORT"]
|
14
|
+
port = PortOfCall.calculate_port
|
15
|
+
|
16
|
+
# Set the port in the application configuration if available
|
17
|
+
if app.config.respond_to?(:server_timing) && app.config.server_timing.respond_to?(:set)
|
18
|
+
app.config.server_timing.set(Port: port)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Hook into Rails command
|
22
|
+
if defined?(Rails::Command) && Rails::Command.respond_to?(:invoke)
|
23
|
+
Rails::Command.singleton_class.prepend(PortCommandExtension)
|
24
|
+
end
|
25
|
+
|
26
|
+
# Store the port for other components to use
|
27
|
+
ENV["PORT"] = port.to_s
|
28
|
+
|
29
|
+
Rails.logger.info "Port of Call: Assigned port #{port} to #{PortOfCall.project_name}" if Rails.logger
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# Hook into Rails Server command
|
34
|
+
module PortCommandExtension
|
35
|
+
def invoke(command_name, *args)
|
36
|
+
if command_name == "server" && args.last.is_a?(Hash) && !args.last.key?(:Port)
|
37
|
+
args.last[:Port] = PortOfCall.calculate_port
|
38
|
+
end
|
39
|
+
super
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Generate initializer
|
44
|
+
generators do
|
45
|
+
require_relative "../generators/port_of_call/install_generator"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/lib/port_of_call.rb
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "socket"
|
4
|
+
require_relative "port_of_call/version"
|
5
|
+
require_relative "port_of_call/configuration"
|
6
|
+
require_relative "port_of_call/port_calculator"
|
7
|
+
require_relative "port_of_call/railtie" if defined?(Rails)
|
8
|
+
require_relative "port_of_call/cli"
|
9
|
+
|
10
|
+
# Port of Call is a Ruby gem that assigns each Rails application a consistent,
|
11
|
+
# deterministic port number based on the application's name or repository.
|
12
|
+
# This solves the common conflict of multiple Rails apps all defaulting to port 3000.
|
13
|
+
#
|
14
|
+
# @example Basic usage with Rails
|
15
|
+
# # In Gemfile
|
16
|
+
# gem 'port_of_call'
|
17
|
+
#
|
18
|
+
# # Your Rails server will automatically use a unique port
|
19
|
+
# # based on your project name
|
20
|
+
#
|
21
|
+
# @example Configuration via initializer
|
22
|
+
# # In config/initializers/port_of_call.rb
|
23
|
+
# PortOfCall.configure do |config|
|
24
|
+
# config.port_range = 3000..3999
|
25
|
+
# config.base_port = 3000
|
26
|
+
# # config.project_name = "custom_name" # Optional
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
# @example Ruby API usage
|
30
|
+
# require 'port_of_call'
|
31
|
+
#
|
32
|
+
# # Get the calculated port for the current project
|
33
|
+
# port = PortOfCall.calculate_port
|
34
|
+
#
|
35
|
+
# # Check if the port is available
|
36
|
+
# if PortOfCall.port_in_use?(port)
|
37
|
+
# puts "Port #{port} is already in use!"
|
38
|
+
# end
|
39
|
+
module PortOfCall
|
40
|
+
# Standard error class for Port of Call exceptions
|
41
|
+
class Error < StandardError; end
|
42
|
+
|
43
|
+
class << self
|
44
|
+
attr_writer :configuration
|
45
|
+
|
46
|
+
# Returns the current configuration
|
47
|
+
# @return [Configuration] the current configuration
|
48
|
+
def configuration
|
49
|
+
@configuration ||= Configuration.new
|
50
|
+
end
|
51
|
+
|
52
|
+
# Configures the gem with the given block
|
53
|
+
# @yield [config] The configuration object
|
54
|
+
# @example
|
55
|
+
# PortOfCall.configure do |config|
|
56
|
+
# config.port_range = 4000..4999
|
57
|
+
# config.base_port = 4000
|
58
|
+
# end
|
59
|
+
def configure
|
60
|
+
yield(configuration)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Resets the configuration to defaults
|
64
|
+
# @return [Configuration] the new configuration object
|
65
|
+
def reset
|
66
|
+
@configuration = Configuration.new
|
67
|
+
end
|
68
|
+
|
69
|
+
# Calculates the port for the current project
|
70
|
+
# @return [Integer] the calculated port number
|
71
|
+
def calculate_port
|
72
|
+
calculator.calculate
|
73
|
+
end
|
74
|
+
|
75
|
+
# Returns the detected or configured project name
|
76
|
+
# @return [String] the project name
|
77
|
+
def project_name
|
78
|
+
calculator.send(:extract_project_name)
|
79
|
+
end
|
80
|
+
|
81
|
+
# Checks if the calculated port is available
|
82
|
+
# @return [Boolean] true if the port is available, false if in use
|
83
|
+
def available?
|
84
|
+
port = calculate_port
|
85
|
+
!port_in_use?(port)
|
86
|
+
end
|
87
|
+
|
88
|
+
# Checks if a specific port is in use by another process
|
89
|
+
# @param port [Integer] the port to check
|
90
|
+
# @return [Boolean] true if the port is in use, false if available
|
91
|
+
def port_in_use?(port)
|
92
|
+
# Check if the port is already in use by another process
|
93
|
+
begin
|
94
|
+
socket = TCPServer.new('127.0.0.1', port)
|
95
|
+
socket.close
|
96
|
+
false
|
97
|
+
rescue Errno::EADDRINUSE
|
98
|
+
true
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# Returns options hash for Rails server
|
103
|
+
# @return [Hash] options with the Port key set
|
104
|
+
def server_options
|
105
|
+
{ Port: calculate_port }
|
106
|
+
end
|
107
|
+
|
108
|
+
private
|
109
|
+
|
110
|
+
# Returns the port calculator instance
|
111
|
+
# @return [PortCalculator] the port calculator
|
112
|
+
def calculator
|
113
|
+
@calculator ||= PortCalculator.new(configuration)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
namespace :port_of_call do
|
4
|
+
desc "Print the calculated port for this Rails application"
|
5
|
+
task :port => :environment do
|
6
|
+
port = PortOfCall.calculate_port
|
7
|
+
project_name = PortOfCall.project_name
|
8
|
+
puts "Port of Call - Calculated port for #{project_name}: #{port}"
|
9
|
+
|
10
|
+
# Check if the port is already in use
|
11
|
+
if PortOfCall.port_in_use?(port)
|
12
|
+
puts "WARNING: Port #{port} is already in use by another process!"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
desc "Start the Rails server with the calculated port"
|
17
|
+
task :start => :environment do
|
18
|
+
port = PortOfCall.calculate_port
|
19
|
+
project_name = PortOfCall.project_name
|
20
|
+
|
21
|
+
puts "Port of Call - Starting Rails server for #{project_name} on port #{port}"
|
22
|
+
|
23
|
+
# Check if the port is already in use
|
24
|
+
if PortOfCall.port_in_use?(port)
|
25
|
+
puts "WARNING: Port #{port} is already in use by another process!"
|
26
|
+
exit 1
|
27
|
+
end
|
28
|
+
|
29
|
+
# Start the Rails server with the calculated port
|
30
|
+
system("rails", "server", "-p", port.to_s)
|
31
|
+
end
|
32
|
+
|
33
|
+
desc "Generate an initializer for Port of Call"
|
34
|
+
task :install => :environment do
|
35
|
+
puts "Generating Port of Call initializer..."
|
36
|
+
system("rails", "generate", "port_of_call:install")
|
37
|
+
end
|
38
|
+
|
39
|
+
desc "Set the calculated port as the default for this Rails application"
|
40
|
+
task :set_default => :environment do
|
41
|
+
port = PortOfCall.calculate_port
|
42
|
+
project_name = PortOfCall.project_name
|
43
|
+
|
44
|
+
# Get Rails development.rb config file
|
45
|
+
config_file = Rails.root.join("config", "environments", "development.rb")
|
46
|
+
|
47
|
+
if File.exist?(config_file)
|
48
|
+
content = File.read(config_file)
|
49
|
+
|
50
|
+
if content.include?("config.port = ")
|
51
|
+
# Update existing port setting
|
52
|
+
updated_content = content.gsub(/config\.port\s*=\s*\d+/, "config.port = #{port}")
|
53
|
+
else
|
54
|
+
# Add new port setting at the end of the config block
|
55
|
+
updated_content = content.gsub(/(Rails\.application\.configure do.*?)(\nend)/m, "\\1\n # Port of Call - Assigned port\n config.port = #{port}\n\\2")
|
56
|
+
end
|
57
|
+
|
58
|
+
# Write updated content back to the file
|
59
|
+
File.write(config_file, updated_content)
|
60
|
+
|
61
|
+
puts "Port of Call - Set default port for #{project_name} to #{port} in #{config_file}"
|
62
|
+
else
|
63
|
+
puts "ERROR: Could not find development.rb config file"
|
64
|
+
exit 1
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
desc "Check if the calculated port is available"
|
69
|
+
task :check => :environment do
|
70
|
+
port = PortOfCall.calculate_port
|
71
|
+
project_name = PortOfCall.project_name
|
72
|
+
|
73
|
+
puts "Port of Call - Checking port #{port} for #{project_name}..."
|
74
|
+
|
75
|
+
if PortOfCall.port_in_use?(port)
|
76
|
+
puts "WARNING: Port #{port} is already in use by another process!"
|
77
|
+
exit 1
|
78
|
+
else
|
79
|
+
puts "Port #{port} is available."
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
desc "Show configuration information for Port of Call"
|
84
|
+
task :info => :environment do
|
85
|
+
port = PortOfCall.calculate_port
|
86
|
+
project_name = PortOfCall.project_name
|
87
|
+
config = PortOfCall.configuration
|
88
|
+
|
89
|
+
puts "Port of Call - Configuration Information"
|
90
|
+
puts "---------------------------------------"
|
91
|
+
puts "Project name: #{project_name}"
|
92
|
+
puts "Calculated port: #{port}"
|
93
|
+
puts "Port range: #{config.port_range}"
|
94
|
+
puts "Base port: #{config.base_port}"
|
95
|
+
puts "Custom name: #{config.custom_project_name || 'Not set'}"
|
96
|
+
puts "Reserved ports: #{config.reserved_ports.empty? ? 'None' : config.reserved_ports.join(', ')}"
|
97
|
+
puts "---------------------------------------"
|
98
|
+
|
99
|
+
if PortOfCall.port_in_use?(port)
|
100
|
+
puts "WARNING: Port #{port} is already in use by another process!"
|
101
|
+
else
|
102
|
+
puts "Port #{port} is available."
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
# Add shortcut tasks at the top level
|
108
|
+
desc "Print the calculated port for this Rails application"
|
109
|
+
task :port_of_call => "port_of_call:port"
|
110
|
+
|
111
|
+
desc "Start the Rails server with the calculated port"
|
112
|
+
task :poc => "port_of_call:start"
|
metadata
ADDED
@@ -0,0 +1,138 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: port_of_call
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0.alpha1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- JPB
|
8
|
+
bindir: exe
|
9
|
+
cert_chain: []
|
10
|
+
date: 2025-03-26 00:00:00.000000000 Z
|
11
|
+
dependencies:
|
12
|
+
- !ruby/object:Gem::Dependency
|
13
|
+
name: rails
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
15
|
+
requirements:
|
16
|
+
- - ">="
|
17
|
+
- !ruby/object:Gem::Version
|
18
|
+
version: '6.0'
|
19
|
+
type: :runtime
|
20
|
+
prerelease: false
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
22
|
+
requirements:
|
23
|
+
- - ">="
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
version: '6.0'
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: rspec
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
29
|
+
requirements:
|
30
|
+
- - "~>"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '3.0'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '3.0'
|
40
|
+
- !ruby/object:Gem::Dependency
|
41
|
+
name: rake
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - "~>"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '13.0'
|
47
|
+
type: :development
|
48
|
+
prerelease: false
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '13.0'
|
54
|
+
- !ruby/object:Gem::Dependency
|
55
|
+
name: yard
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0.9'
|
61
|
+
type: :development
|
62
|
+
prerelease: false
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - "~>"
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0.9'
|
68
|
+
- !ruby/object:Gem::Dependency
|
69
|
+
name: rubocop
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - "~>"
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '1.21'
|
75
|
+
type: :development
|
76
|
+
prerelease: false
|
77
|
+
version_requirements: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - "~>"
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '1.21'
|
82
|
+
description: Port of Call assigns each Rails application a consistent, deterministic
|
83
|
+
port number based on the application's name or repository. This solves the common
|
84
|
+
conflict of multiple Rails apps all defaulting to port 3000.
|
85
|
+
email:
|
86
|
+
- jonathanpberger@gmail.com
|
87
|
+
executables:
|
88
|
+
- port_of_call
|
89
|
+
extensions: []
|
90
|
+
extra_rdoc_files: []
|
91
|
+
files:
|
92
|
+
- ".rspec"
|
93
|
+
- CHANGELOG.md
|
94
|
+
- LICENSE.txt
|
95
|
+
- README.md
|
96
|
+
- RELEASE_NOTES.md
|
97
|
+
- Rakefile
|
98
|
+
- examples/basic_usage.rb
|
99
|
+
- examples/rails_example.rb
|
100
|
+
- exe/port_of_call
|
101
|
+
- lib/generators/port_of_call/install_generator.rb
|
102
|
+
- lib/generators/port_of_call/templates/README.md
|
103
|
+
- lib/generators/port_of_call/templates/initializer.rb
|
104
|
+
- lib/port_of_call.rb
|
105
|
+
- lib/port_of_call/cli.rb
|
106
|
+
- lib/port_of_call/configuration.rb
|
107
|
+
- lib/port_of_call/port_calculator.rb
|
108
|
+
- lib/port_of_call/railtie.rb
|
109
|
+
- lib/port_of_call/version.rb
|
110
|
+
- lib/tasks/port_of_call.rake
|
111
|
+
- sig/port_of_call.rbs
|
112
|
+
homepage: https://github.com/jonathanpberger/port-of-call
|
113
|
+
licenses:
|
114
|
+
- MIT
|
115
|
+
metadata:
|
116
|
+
homepage_uri: https://github.com/jonathanpberger/port-of-call
|
117
|
+
source_code_uri: https://github.com/jonathanpberger/port-of-call
|
118
|
+
changelog_uri: https://github.com/jonathanpberger/port-of-call/blob/main/CHANGELOG.md
|
119
|
+
rubygems_mfa_required: 'true'
|
120
|
+
documentation_uri: https://github.com/jonathanpberger/port-of-call/blob/main/README.md
|
121
|
+
rdoc_options: []
|
122
|
+
require_paths:
|
123
|
+
- lib
|
124
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
125
|
+
requirements:
|
126
|
+
- - ">="
|
127
|
+
- !ruby/object:Gem::Version
|
128
|
+
version: 3.0.0
|
129
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
130
|
+
requirements:
|
131
|
+
- - ">="
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '0'
|
134
|
+
requirements: []
|
135
|
+
rubygems_version: 3.6.6
|
136
|
+
specification_version: 4
|
137
|
+
summary: Deterministic port assignment for Rails applications
|
138
|
+
test_files: []
|