diff --git a/CHANGELOG.md b/CHANGELOG.md index 0598e2b..9a299bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Added +- `cb uri` command now accepts `--database` and `--port`. + ### Changed - `cb login` now presents a login url for use with headless environments or where a default browser is not available diff --git a/spec/cb/cluster_uri_spec.cr b/spec/cb/cluster_uri_spec.cr index aace432..01d1f83 100644 --- a/spec/cb/cluster_uri_spec.cr +++ b/spec/cb/cluster_uri_spec.cr @@ -42,5 +42,23 @@ Spectator.describe CB::ClusterURI do expect(&.output.to_s).to eq expected end + + it "output with different database and port" do + action.cluster_id = cluster.id + action.database = "test" + action.port = 5431 + action.role = "user" + + expect(client).to receive(:get_account).and_return(account) + expect(client).to receive(:get_role).and_return(role) + + action.call + + expected = <<-EXPECTED + postgres://u_mijrfkkuqvhernzfqcbqf7b6me:secret@example.com:5431/test + EXPECTED + + expect(&.output.to_s).to eq expected + end end end diff --git a/spec/cb/completion_spec.cr b/spec/cb/completion_spec.cr index 51bef11..ac98830 100644 --- a/spec/cb/completion_spec.cr +++ b/spec/cb/completion_spec.cr @@ -760,10 +760,18 @@ Spectator.describe CB::Completion do expect(result).to eq expected_cluster_suggestion result = parse("cb uri abc ") + expect(result).to have_option "--database" + expect(result).to have_option "--port" expect(result).to have_option "--role" result = parse("cb uri abc --role ") expect(result).to eq CB::Role::VALID_CLUSTER_ROLES.to_a + + result = parse("cb uri abc --port ") + expect(result).to eq [] of String + + result = parse("cb uri abc --database ") + expect(result).to eq [] of String end it "completes team" do diff --git a/src/cb/cluster_uri.cr b/src/cb/cluster_uri.cr index 5d7be9a..fbd56de 100644 --- a/src/cb/cluster_uri.cr +++ b/src/cb/cluster_uri.cr @@ -3,6 +3,8 @@ require "./action" class CB::ClusterURI < CB::APIAction cluster_identifier_setter cluster_id role_setter role + i32_setter port + property database : String? def validate check_required_args do |missing| @@ -19,19 +21,24 @@ class CB::ClusterURI < CB::APIAction # Fetch the role. role = client.get_role(@cluster_id[:cluster], @role.to_s) + uri = role.uri + raise Error.new "There is no URI available for this cluster." unless uri + + uri.port = port if port + uri.path = database.to_s if database # Redact the password from the result. Redaction is handled by coloring the # foreground and background the same color. This benfits the user by not # allowing their password to be inadvertently exposed in a TTY session. But # it still allows for it to be copied and pasted without requiring any # special action from the user. - uri = role.uri.to_s + redacted_uri = uri.to_s unless role.password.nil? pw = role.password - uri = uri.gsub(pw, pw.colorize.black.on_black.to_s) if pw + redacted_uri = redacted_uri.gsub(pw, pw.colorize.black.on_black.to_s) if pw end - output << uri + output << redacted_uri rescue e : Client::Error msg = "unknown client error." case diff --git a/src/cb/completion.cr b/src/cb/completion.cr index 02d88bd..ffff1b7 100644 --- a/src/cb/completion.cr +++ b/src/cb/completion.cr @@ -1136,11 +1136,16 @@ class CB::Completion def uri return cluster_suggestions if @args.size == 2 + suggest_none if last_arg? "--database" + suggest_none if last_arg? "--port" + if last_arg? "--role" return Role::VALID_CLUSTER_ROLES.to_a end suggest = [] of String + suggest << "--database\tdatabase name" unless has_full_flag? :database + suggest << "--port\tport number" unless has_full_flag? :port suggest << "--role\trole name" unless has_full_flag? :role suggest end diff --git a/src/cli.cr b/src/cli.cr index 5893f9b..678bbff 100755 --- a/src/cli.cr +++ b/src/cli.cr @@ -111,6 +111,8 @@ op = OptionParser.new do |parser| parser.banner = "cb uri [--role]" uri = set_action ClusterURI + parser.on("--database DATABASE", "") { |arg| uri.database = arg } + parser.on("--port PORT", "Port number (default: 5432)") { |arg| uri.port = arg } parser.on("--role NAME", "Role name (default: default)") { |arg| uri.role = CB::Role.new arg } positional_args uri.cluster_id end