pgchief 0.5.3 → 0.5.4
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 +4 -4
- data/.rubocop.yml +5 -31
- data/.rubocop_todo.yml +39 -0
- data/CHANGELOG.md +12 -0
- data/README.md +33 -6
- data/Rakefile +8 -8
- data/config/pgchief.toml +6 -1
- data/exe/pgchief +1 -1
- data/lib/pgchief/cli.rb +33 -5
- data/lib/pgchief/command/config_create.rb +2 -2
- data/lib/pgchief/command/database_backup.rb +3 -3
- data/lib/pgchief/command/database_privileges_grant.rb +1 -1
- data/lib/pgchief/command/database_restore.rb +3 -3
- data/lib/pgchief/command/retrieve_connection_string.rb +1 -1
- data/lib/pgchief/command/s3_upload.rb +3 -3
- data/lib/pgchief/command/store_connection_string.rb +1 -1
- data/lib/pgchief/command/user_create.rb +1 -1
- data/lib/pgchief/command/user_drop.rb +1 -1
- data/lib/pgchief/config/s3.rb +1 -1
- data/lib/pgchief/config.rb +16 -8
- data/lib/pgchief/connection_string.rb +5 -5
- data/lib/pgchief/database/backups.rb +1 -1
- data/lib/pgchief/database.rb +4 -4
- data/lib/pgchief/prompt/backup_database.rb +1 -1
- data/lib/pgchief/prompt/base.rb +3 -3
- data/lib/pgchief/prompt/create_database.rb +1 -1
- data/lib/pgchief/prompt/create_user.rb +2 -2
- data/lib/pgchief/prompt/database_management.rb +7 -7
- data/lib/pgchief/prompt/drop_database.rb +1 -1
- data/lib/pgchief/prompt/drop_user.rb +1 -1
- data/lib/pgchief/prompt/grant_database_privileges.rb +2 -2
- data/lib/pgchief/prompt/restore_database.rb +9 -4
- data/lib/pgchief/prompt/start.rb +5 -5
- data/lib/pgchief/prompt/user_management.rb +7 -7
- data/lib/pgchief/prompt/view_database_connection_string.rb +3 -3
- data/lib/pgchief/user.rb +3 -3
- data/lib/pgchief/version.rb +1 -1
- data/lib/pgchief.rb +39 -39
- metadata +4 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e11f487141ba0fab474322adf299d2d97676b2af3e26d14a77dce8d1ee2d1f5d
|
4
|
+
data.tar.gz: 45419f8a0f286c9fb415190be6793572b11fb8528999041b432ec69c706121cd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0aec7a349ff2fa06ec5c3030276953eca2a89fde24df5cf360ba9b5fea29a6ecddc1b13b5b2578983fe16068a94127bcfb9a2b3be3aa8b9dd2dbdfe5f3a761da
|
7
|
+
data.tar.gz: 210b49ddaf86e5515772b24a1da0f03666b44146ae874a638f748d538043fcaf633b4e7865b11094867a71da587ca70be757fe1c2b6b96c924d55f8735b3835a
|
data/.rubocop.yml
CHANGED
@@ -1,34 +1,8 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
inherit_from: .rubocop_todo.yml
|
2
|
+
|
3
|
+
plugins:
|
4
|
+
- rubocop-rake
|
5
|
+
- rubocop-rspec
|
5
6
|
|
6
7
|
AllCops:
|
7
|
-
TargetRubyVersion: 3.0
|
8
8
|
NewCops: enable
|
9
|
-
|
10
|
-
Style/StringLiterals:
|
11
|
-
EnforcedStyle: double_quotes
|
12
|
-
|
13
|
-
Style/StringLiteralsInInterpolation:
|
14
|
-
EnforcedStyle: double_quotes
|
15
|
-
|
16
|
-
Metrics/BlockLength:
|
17
|
-
Exclude:
|
18
|
-
- 'spec/**/*'
|
19
|
-
- '*.gemspec'
|
20
|
-
|
21
|
-
Lint/MixedRegexpCaptureTypes:
|
22
|
-
Enabled: false
|
23
|
-
|
24
|
-
RSpec/MultipleExpectations:
|
25
|
-
Max: 5
|
26
|
-
|
27
|
-
RSpec/ExampleLength:
|
28
|
-
Max: 20
|
29
|
-
|
30
|
-
Lint/MissingSuper:
|
31
|
-
Enabled: false
|
32
|
-
|
33
|
-
Metrics/ParameterLists:
|
34
|
-
Enabled: false
|
data/.rubocop_todo.yml
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# This configuration was generated by
|
2
|
+
# `rubocop --auto-gen-config`
|
3
|
+
# on 2025-03-25 01:44:14 UTC using RuboCop version 1.74.0.
|
4
|
+
# The point is for the user to remove these configuration records
|
5
|
+
# one by one as the offenses are removed from the code base.
|
6
|
+
# Note that changes in the inspected code, or installation of new
|
7
|
+
# versions of RuboCop, may require this file to be generated again.
|
8
|
+
|
9
|
+
# Offense count: 2
|
10
|
+
# Configuration parameters: AllowedParentClasses.
|
11
|
+
Lint/MissingSuper:
|
12
|
+
Exclude:
|
13
|
+
- 'lib/pgchief/command/database_privileges_grant.rb'
|
14
|
+
- 'lib/pgchief/command/retrieve_connection_string.rb'
|
15
|
+
|
16
|
+
# Offense count: 2
|
17
|
+
Lint/MixedRegexpCaptureTypes:
|
18
|
+
Exclude:
|
19
|
+
- 'lib/pgchief/config/s3.rb'
|
20
|
+
- 'lib/pgchief/connection_string.rb'
|
21
|
+
|
22
|
+
# Offense count: 1
|
23
|
+
# Configuration parameters: CountKeywordArgs, MaxOptionalParameters.
|
24
|
+
Metrics/ParameterLists:
|
25
|
+
Max: 6
|
26
|
+
|
27
|
+
# Offense count: 12
|
28
|
+
# Configuration parameters: CountAsOne.
|
29
|
+
RSpec/ExampleLength:
|
30
|
+
Max: 9
|
31
|
+
|
32
|
+
# Offense count: 15
|
33
|
+
RSpec/MultipleExpectations:
|
34
|
+
Max: 5
|
35
|
+
|
36
|
+
# Offense count: 4
|
37
|
+
# Configuration parameters: AllowSubject.
|
38
|
+
RSpec/MultipleMemoizedHelpers:
|
39
|
+
Max: 6
|
data/CHANGELOG.md
CHANGED
@@ -13,6 +13,18 @@ and this project will try its best to adhere to [Semantic Versioning](https://se
|
|
13
13
|
|
14
14
|
### Fixes
|
15
15
|
|
16
|
+
## [0.5.4]
|
17
|
+
|
18
|
+
### Additions
|
19
|
+
|
20
|
+
* Improve CLI usability with --version and --help flags.
|
21
|
+
* Adds --remote-backup and --remote-restore CLI options.
|
22
|
+
* Modifies DatabaseRestore and prompt flows to conditionally operate on remote backups.
|
23
|
+
|
24
|
+
### Changes
|
25
|
+
|
26
|
+
* Updates the config loader to respect CLI flags and TOML values for remote_backup and remote_restore.
|
27
|
+
|
16
28
|
## [0.5.3]
|
17
29
|
|
18
30
|
### Additions
|
data/README.md
CHANGED
@@ -38,8 +38,23 @@ pgchief --init
|
|
38
38
|
# export DATABASE_URL=postgresql://postgres:password@postgres.local:5432
|
39
39
|
|
40
40
|
pgchief
|
41
|
+
|
42
|
+
# Full usage:
|
43
|
+
|
44
|
+
$ pgchief --help
|
45
|
+
Options:
|
46
|
+
-h, --help Print usage
|
47
|
+
-i, --init Initialize the TOML configuration file
|
48
|
+
--remote-backup Backup a database to a remote location
|
49
|
+
--remote-restore Restore a database from a remote backup
|
50
|
+
-v, --version Show the version
|
41
51
|
```
|
42
52
|
|
53
|
+
> [!Note]
|
54
|
+
> Prompts accept both `↑` and `↓` arrows, as well as `j` and `k`.
|
55
|
+
> Pressing the `esc` key at any point amidst a prompt will exit out of the
|
56
|
+
> program.
|
57
|
+
|
43
58
|
## Config
|
44
59
|
|
45
60
|
Format of `~/.config/pgchief/config.toml`
|
@@ -53,14 +68,26 @@ backup_dir = "~/.pgchief/backups"
|
|
53
68
|
|
54
69
|
# ** OPTIONAL **
|
55
70
|
|
56
|
-
# Location of
|
57
|
-
# credentials_file = "~/.pgchief/credentials"
|
58
|
-
|
71
|
+
# Location of saved database connection strings
|
72
|
+
# credentials_file = "~/.config/pgchief/credentials"
|
73
|
+
|
74
|
+
# S3 config
|
75
|
+
# ---------
|
76
|
+
# s3_key = ""
|
77
|
+
# s3_secret = ""
|
78
|
+
# s3_region = "us-east-1"
|
79
|
+
# s3_objects_path = "s3://bucket-name/database-backups/"
|
59
80
|
|
60
|
-
|
81
|
+
# Backup and restore from remote locations?
|
82
|
+
# remote_restore = false # default: false
|
83
|
+
# remote_backup = false # default: false
|
84
|
+
```
|
61
85
|
|
62
|
-
|
63
|
-
|
86
|
+
> [!IMPORTANT]
|
87
|
+
> Backup files must be named starting with `[Database Name]-` in order for the
|
88
|
+
> file(s) to be found for restoration. Eg: A database named
|
89
|
+
> `project_production` that has backups named `project_production-20250325.tar`
|
90
|
+
> will be picked up and given the option to restore.
|
64
91
|
|
65
92
|
## Development of the gem
|
66
93
|
|
data/Rakefile
CHANGED
@@ -1,19 +1,19 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require 'bundler/gem_tasks'
|
4
|
+
require 'rspec/core/rake_task'
|
5
5
|
|
6
6
|
RSpec::Core::RakeTask.new(:spec)
|
7
7
|
|
8
8
|
# Set up Rubocop tasks
|
9
|
-
require
|
9
|
+
require 'rubocop/rake_task'
|
10
10
|
RuboCop::RakeTask.new(:rubocop) do |t|
|
11
11
|
t.options = [
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
12
|
+
'--autocorrect-all',
|
13
|
+
'--cache=true',
|
14
|
+
'--display-cop-names',
|
15
|
+
'--display-time',
|
16
|
+
'--parallel'
|
17
17
|
]
|
18
18
|
end
|
19
19
|
|
data/config/pgchief.toml
CHANGED
@@ -9,8 +9,13 @@ backup_dir = "~/.config/pgchief/backups"
|
|
9
9
|
# Location of saved database connection strings
|
10
10
|
# credentials_file = "~/.config/pgchief/credentials"
|
11
11
|
|
12
|
-
# S3 config
|
12
|
+
# S3 config
|
13
|
+
# ---------
|
13
14
|
# s3_key = ""
|
14
15
|
# s3_secret = ""
|
15
16
|
# s3_region = "us-east-1"
|
16
17
|
# s3_objects_path = "s3://bucket-name/database-backups/"
|
18
|
+
|
19
|
+
# Backup and restore from remote locations?
|
20
|
+
# remote_restore = false # default: false
|
21
|
+
# remote_backup = false # default: false
|
data/exe/pgchief
CHANGED
data/lib/pgchief/cli.rb
CHANGED
@@ -5,17 +5,45 @@ module Pgchief
|
|
5
5
|
class Cli
|
6
6
|
include TTY::Option
|
7
7
|
|
8
|
+
banner 'Usage: pgchief [OPTIONS]'
|
9
|
+
|
8
10
|
option :init do
|
9
|
-
short
|
10
|
-
long
|
11
|
-
desc
|
11
|
+
short '-i'
|
12
|
+
long '--init'
|
13
|
+
desc 'Initialize the TOML configuration file'
|
14
|
+
end
|
15
|
+
|
16
|
+
option :version do
|
17
|
+
short '-v'
|
18
|
+
long '--version'
|
19
|
+
desc 'Show the version'
|
20
|
+
end
|
21
|
+
|
22
|
+
option :'remote-restore' do
|
23
|
+
long '--remote-restore'
|
24
|
+
desc 'Restore a database from a remote backup'
|
25
|
+
end
|
26
|
+
|
27
|
+
option :'remote-backup' do
|
28
|
+
long '--remote-backup'
|
29
|
+
desc 'Backup a database to a remote location'
|
30
|
+
end
|
31
|
+
|
32
|
+
flag :help do
|
33
|
+
short '-h'
|
34
|
+
long '--help'
|
35
|
+
desc 'Print usage'
|
12
36
|
end
|
13
37
|
|
14
38
|
def run
|
15
|
-
if params[:
|
39
|
+
if params[:help]
|
40
|
+
print help
|
41
|
+
elsif params[:init]
|
16
42
|
Pgchief::Command::ConfigCreate.call
|
43
|
+
elsif params[:version]
|
44
|
+
puts Pgchief::VERSION
|
17
45
|
else
|
18
|
-
Pgchief::Prompt::Start.call
|
46
|
+
Pgchief::Prompt::Start.call(params)
|
19
47
|
end
|
20
48
|
end
|
21
49
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require 'fileutils'
|
4
4
|
|
5
5
|
module Pgchief
|
6
6
|
module Command
|
@@ -13,7 +13,7 @@ module Pgchief
|
|
13
13
|
def call(dir: "#{Dir.home}/.config/pgchief")
|
14
14
|
return if File.exist?("#{dir}/config.toml")
|
15
15
|
|
16
|
-
template = File.join(__dir__,
|
16
|
+
template = File.join(__dir__, '..', '..', '..', 'config', 'pgchief.toml')
|
17
17
|
FileUtils.mkdir_p(dir)
|
18
18
|
FileUtils.cp(template, "#{dir}/config.toml")
|
19
19
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require 'forwardable'
|
4
4
|
|
5
5
|
module Pgchief
|
6
6
|
module Command
|
@@ -39,7 +39,7 @@ module Pgchief
|
|
39
39
|
end
|
40
40
|
|
41
41
|
def check_backup!
|
42
|
-
raise Pgchief::Errors::BackupError,
|
42
|
+
raise Pgchief::Errors::BackupError, 'Backup file has 0 bytes' unless File.size?(local_location)
|
43
43
|
end
|
44
44
|
|
45
45
|
def db_exists?
|
@@ -53,7 +53,7 @@ module Pgchief
|
|
53
53
|
|
54
54
|
def local_location
|
55
55
|
@local_location ||= begin
|
56
|
-
timestamp = Time.now.strftime(
|
56
|
+
timestamp = Time.now.strftime('%Y%m%d%H%M%S')
|
57
57
|
"#{Pgchief::Config.backup_dir}#{database}-#{timestamp}.dump"
|
58
58
|
end
|
59
59
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require 'forwardable'
|
4
4
|
|
5
5
|
module Pgchief
|
6
6
|
module Command
|
@@ -17,7 +17,7 @@ module Pgchief
|
|
17
17
|
@filename = params.last
|
18
18
|
raise Pgchief::Errors::DatabaseMissingError unless db_exists?
|
19
19
|
|
20
|
-
download! if
|
20
|
+
download! if Pgchief::Config.remote_restore
|
21
21
|
restore!
|
22
22
|
|
23
23
|
"Database '#{database}' restored from #{filename}"
|
@@ -38,7 +38,7 @@ module Pgchief
|
|
38
38
|
end
|
39
39
|
|
40
40
|
def restore!
|
41
|
-
`pg_restore --clean --no-owner --dbname=#{Pgchief::Config.pgurl}/#{database} #{local_location}`
|
41
|
+
`pg_restore --clean --if-exists --no-owner --dbname=#{Pgchief::Config.pgurl}/#{database} #{local_location}`
|
42
42
|
end
|
43
43
|
|
44
44
|
def db_exists?
|
@@ -15,9 +15,9 @@ module Pgchief
|
|
15
15
|
s3.client.put_object(
|
16
16
|
bucket: s3.bucket,
|
17
17
|
key: "#{s3.path}#{file_name}",
|
18
|
-
body: File.open(local_location,
|
19
|
-
acl:
|
20
|
-
content_type:
|
18
|
+
body: File.open(local_location, 'rb'),
|
19
|
+
acl: 'private',
|
20
|
+
content_type: 'application/octet-stream'
|
21
21
|
)
|
22
22
|
end
|
23
23
|
|
data/lib/pgchief/config/s3.rb
CHANGED
data/lib/pgchief/config.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require 'toml-rb'
|
4
4
|
|
5
5
|
module Pgchief
|
6
6
|
# Class to store configuration settings
|
@@ -9,7 +9,9 @@ module Pgchief
|
|
9
9
|
attr_accessor \
|
10
10
|
:s3_key,
|
11
11
|
:s3_secret,
|
12
|
-
:s3_region
|
12
|
+
:s3_region,
|
13
|
+
:remote_restore,
|
14
|
+
:remote_backup
|
13
15
|
|
14
16
|
attr_writer :pgurl
|
15
17
|
|
@@ -18,7 +20,7 @@ module Pgchief
|
|
18
20
|
:backup_dir,
|
19
21
|
:credentials_file
|
20
22
|
|
21
|
-
def load_config!(toml_file = "#{Dir.home}/.config/pgchief/config.toml") # rubocop:disable Metrics/AbcSize
|
23
|
+
def load_config!(params, toml_file = "#{Dir.home}/.config/pgchief/config.toml") # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
22
24
|
config = TomlRB.load_file(toml_file, symbolize_keys: true)
|
23
25
|
self.backup_dir = config[:backup_dir]
|
24
26
|
self.credentials_file = config[:credentials_file]
|
@@ -27,6 +29,12 @@ module Pgchief
|
|
27
29
|
self.s3_secret = config[:s3_secret]
|
28
30
|
self.s3_region = config[:s3_region]
|
29
31
|
self.s3_objects_path = config[:s3_objects_path] || config[:s3_path_prefix]
|
32
|
+
self.remote_restore = params[:'remote-restore'] == true ||
|
33
|
+
params[:'local-restore'] == false ||
|
34
|
+
config[:remote_restore]
|
35
|
+
self.remote_backup = params[:'remote-backup'] == true ||
|
36
|
+
params[:'local-backup'] == false ||
|
37
|
+
config[:remote_backup]
|
30
38
|
rescue Errno::ENOENT
|
31
39
|
puts config_missing_error(toml_file)
|
32
40
|
end
|
@@ -36,19 +44,19 @@ module Pgchief
|
|
36
44
|
end
|
37
45
|
|
38
46
|
def pgurl
|
39
|
-
ENV.fetch(
|
47
|
+
ENV.fetch('DATABASE_URL', @pgurl)
|
40
48
|
end
|
41
49
|
|
42
50
|
def backup_dir=(value)
|
43
|
-
@backup_dir = value ? "#{value.chomp(
|
51
|
+
@backup_dir = value ? "#{value.chomp('/')}/".gsub('~', Dir.home) : '/tmp/'
|
44
52
|
end
|
45
53
|
|
46
54
|
def s3_objects_path=(value)
|
47
|
-
@s3_objects_path = value ? "#{value.chomp(
|
55
|
+
@s3_objects_path = value ? "#{value.chomp('/')}/" : nil
|
48
56
|
end
|
49
57
|
|
50
58
|
def credentials_file=(value)
|
51
|
-
@credentials_file = value&.gsub(
|
59
|
+
@credentials_file = value&.gsub('~', Dir.home)
|
52
60
|
end
|
53
61
|
|
54
62
|
def set_up_file_structure!
|
@@ -62,7 +70,7 @@ module Pgchief
|
|
62
70
|
|
63
71
|
def config_missing_error(toml_file)
|
64
72
|
"You must create a config file at #{toml_file}.\n" \
|
65
|
-
|
73
|
+
'run `pgchief --init` to create it.'
|
66
74
|
end
|
67
75
|
end
|
68
76
|
end
|
@@ -9,7 +9,7 @@ module Pgchief
|
|
9
9
|
:?(?<password>[^@]*)?
|
10
10
|
@?(?<host>[^:]*)?
|
11
11
|
:?(?<port>\d+)?
|
12
|
-
/?(?<database>[
|
12
|
+
/?(?<database>[^?]*)?
|
13
13
|
\z}
|
14
14
|
|
15
15
|
attr_reader :database_url
|
@@ -39,19 +39,19 @@ module Pgchief
|
|
39
39
|
end
|
40
40
|
|
41
41
|
def username
|
42
|
-
@username || (
|
42
|
+
@username || ('' if matched[:host].empty? && !matched[:username].empty?) || matched[:username] || ''
|
43
43
|
end
|
44
44
|
|
45
45
|
def password
|
46
|
-
@password || matched[:password] ||
|
46
|
+
@password || matched[:password] || ''
|
47
47
|
end
|
48
48
|
|
49
49
|
def port
|
50
|
-
@port || matched[:port] ||
|
50
|
+
@port || matched[:port] || '5432'
|
51
51
|
end
|
52
52
|
|
53
53
|
def database
|
54
|
-
@database || matched[:database] ||
|
54
|
+
@database || matched[:database] || ''
|
55
55
|
end
|
56
56
|
|
57
57
|
private
|
data/lib/pgchief/database.rb
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require 'pg'
|
4
4
|
|
5
5
|
module Pgchief
|
6
6
|
# Database information and operations
|
7
7
|
class Database
|
8
8
|
def self.all
|
9
9
|
conn = PG.connect(Pgchief::Config.pgurl)
|
10
|
-
result = conn.exec(
|
10
|
+
result = conn.exec('SELECT datname FROM pg_database WHERE datistemplate = false')
|
11
11
|
result
|
12
|
-
.map { |row| row[
|
13
|
-
.reject { |name| name ==
|
12
|
+
.map { |row| row['datname'] }
|
13
|
+
.reject { |name| name == 'postgres' }
|
14
14
|
ensure
|
15
15
|
conn.close
|
16
16
|
end
|
@@ -5,7 +5,7 @@ module Pgchief
|
|
5
5
|
# Class to prompt for which database to backup
|
6
6
|
class BackupDatabase < Base
|
7
7
|
def call
|
8
|
-
database = prompt.select(
|
8
|
+
database = prompt.select('Which database needs backing up?', Pgchief::Database.all)
|
9
9
|
result = Pgchief::Command::DatabaseBackup.call(database)
|
10
10
|
|
11
11
|
prompt.say result
|
data/lib/pgchief/prompt/base.rb
CHANGED
@@ -20,7 +20,7 @@ module Pgchief
|
|
20
20
|
|
21
21
|
def klassify(scope, words)
|
22
22
|
Object.const_get([
|
23
|
-
|
23
|
+
'Pgchief', '::', scope.capitalize, '::',
|
24
24
|
words.split.map(&:capitalize)
|
25
25
|
].flatten.join)
|
26
26
|
end
|
@@ -33,8 +33,8 @@ module Pgchief
|
|
33
33
|
def prompt
|
34
34
|
@prompt ||= TTY::Prompt.new.tap do |p|
|
35
35
|
p.on(:keypress) do |event|
|
36
|
-
p.trigger(:keydown) if event.value ==
|
37
|
-
p.trigger(:keyup) if event.value ==
|
36
|
+
p.trigger(:keydown) if event.value == 'j'
|
37
|
+
p.trigger(:keyup) if event.value == 'k'
|
38
38
|
end
|
39
39
|
|
40
40
|
p.on(:keyescape) do
|
@@ -5,7 +5,7 @@ module Pgchief
|
|
5
5
|
# Class to ask for database name, in order to create it
|
6
6
|
class CreateDatabase < Base
|
7
7
|
def call
|
8
|
-
database = prompt.ask(
|
8
|
+
database = prompt.ask('Database name:')
|
9
9
|
result = Pgchief::Command::DatabaseCreate.call(database)
|
10
10
|
|
11
11
|
prompt.say result
|
@@ -5,8 +5,8 @@ module Pgchief
|
|
5
5
|
# Class to prompt for user creation details
|
6
6
|
class CreateUser < Base
|
7
7
|
def call
|
8
|
-
username = prompt.ask(
|
9
|
-
password = prompt.mask(
|
8
|
+
username = prompt.ask('Username:')
|
9
|
+
password = prompt.mask('Password:')
|
10
10
|
result = Pgchief::Command::UserCreate.call(username, password)
|
11
11
|
|
12
12
|
prompt.say result
|
@@ -6,14 +6,14 @@ module Pgchief
|
|
6
6
|
class DatabaseManagement < Base
|
7
7
|
def call
|
8
8
|
prompt = TTY::Prompt.new
|
9
|
-
result = prompt.select(
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
9
|
+
result = prompt.select('Database management', [
|
10
|
+
'Create database',
|
11
|
+
'Drop database',
|
12
|
+
'Database List',
|
13
|
+
'Backup database',
|
14
|
+
'Restore database'
|
15
15
|
])
|
16
|
-
scope = result ==
|
16
|
+
scope = result == 'Database List' ? 'command' : 'prompt'
|
17
17
|
|
18
18
|
klassify(scope, result).call
|
19
19
|
end
|
@@ -5,7 +5,7 @@ module Pgchief
|
|
5
5
|
# Class to prompt for which database to drop
|
6
6
|
class DropDatabase < Base
|
7
7
|
def call
|
8
|
-
database = prompt.select(
|
8
|
+
database = prompt.select('Which database needs to be dropped?', Pgchief::Database.all)
|
9
9
|
result = Pgchief::Command::DatabaseDrop.call(database)
|
10
10
|
|
11
11
|
prompt.say result
|
@@ -5,7 +5,7 @@ module Pgchief
|
|
5
5
|
# Class to prompt for which user to drop
|
6
6
|
class DropUser < Base
|
7
7
|
def call
|
8
|
-
user = prompt.select(
|
8
|
+
user = prompt.select('Which user needs to be deleted?', Pgchief::User.all)
|
9
9
|
result = Pgchief::Command::UserDrop.call(user)
|
10
10
|
|
11
11
|
prompt.say result
|
@@ -15,11 +15,11 @@ module Pgchief
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def select_user
|
18
|
-
prompt.select(
|
18
|
+
prompt.select('Select user to update:', Pgchief::User.all)
|
19
19
|
end
|
20
20
|
|
21
21
|
def ask_for_password
|
22
|
-
prompt.mask(
|
22
|
+
prompt.mask('Password:')
|
23
23
|
end
|
24
24
|
end
|
25
25
|
end
|
@@ -5,11 +5,16 @@ module Pgchief
|
|
5
5
|
# Class to prompt for which database to restore
|
6
6
|
class RestoreDatabase < Base
|
7
7
|
def call
|
8
|
-
database
|
9
|
-
|
10
|
-
result = Pgchief::Command::DatabaseRestore.call(database, local_file)
|
8
|
+
database = prompt.select('Which database needs restoring?', Pgchief::Database.all)
|
9
|
+
backups = Pgchief::Database.backups_for(database, remote: Pgchief::Config.remote_restore)
|
11
10
|
|
12
|
-
|
11
|
+
if backups.empty?
|
12
|
+
prompt.warn "No backup files found for database '#{database}'"
|
13
|
+
else
|
14
|
+
local_file = prompt.select('Which backup file do you want to restore?', backups)
|
15
|
+
result = Pgchief::Command::DatabaseRestore.call(database, local_file)
|
16
|
+
prompt.say result
|
17
|
+
end
|
13
18
|
end
|
14
19
|
end
|
15
20
|
end
|
data/lib/pgchief/prompt/start.rb
CHANGED
@@ -8,20 +8,20 @@ module Pgchief
|
|
8
8
|
manage_config!
|
9
9
|
|
10
10
|
result = prompt.select(
|
11
|
-
|
11
|
+
'Welcome! How can I help?',
|
12
12
|
[
|
13
|
-
|
14
|
-
|
13
|
+
'Database management',
|
14
|
+
'User management'
|
15
15
|
]
|
16
16
|
)
|
17
17
|
|
18
|
-
klassify(
|
18
|
+
klassify('prompt', result).call
|
19
19
|
end
|
20
20
|
|
21
21
|
private
|
22
22
|
|
23
23
|
def manage_config!
|
24
|
-
Pgchief::Config.load_config!
|
24
|
+
Pgchief::Config.load_config!(params.first)
|
25
25
|
Pgchief::Config.set_up_file_structure!
|
26
26
|
end
|
27
27
|
end
|
@@ -5,15 +5,15 @@ module Pgchief
|
|
5
5
|
# Class to manage users
|
6
6
|
class UserManagement < Base
|
7
7
|
def call
|
8
|
-
result = prompt.select(
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
8
|
+
result = prompt.select('User management', [
|
9
|
+
'Create user',
|
10
|
+
'Drop user',
|
11
|
+
'User list',
|
12
|
+
'Grant database privileges',
|
13
|
+
'View database connection string'
|
14
14
|
])
|
15
15
|
|
16
|
-
scope = result ==
|
16
|
+
scope = result == 'User list' ? 'command' : 'prompt'
|
17
17
|
klassify(scope, result).call
|
18
18
|
end
|
19
19
|
end
|
@@ -6,15 +6,15 @@ module Pgchief
|
|
6
6
|
class ViewDatabaseConnectionString < Base
|
7
7
|
def call
|
8
8
|
username = params.first || select_user
|
9
|
-
database = prompt.select("Database you're connecting to:", Pgchief::Database.all + [
|
10
|
-
database = nil if database ==
|
9
|
+
database = prompt.select("Database you're connecting to:", Pgchief::Database.all + ['None'])
|
10
|
+
database = nil if database == 'None'
|
11
11
|
result = Pgchief::Command::RetrieveConnectionString.call(username, database)
|
12
12
|
|
13
13
|
prompt.say result
|
14
14
|
end
|
15
15
|
|
16
16
|
def select_user
|
17
|
-
prompt.select(
|
17
|
+
prompt.select('Select user to update:', Pgchief::User.all)
|
18
18
|
end
|
19
19
|
end
|
20
20
|
end
|
data/lib/pgchief/user.rb
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require 'pg'
|
4
4
|
|
5
5
|
module Pgchief
|
6
6
|
# Database information and operations
|
7
7
|
class User
|
8
8
|
def self.all
|
9
9
|
conn = PG.connect(Pgchief::Config.pgurl)
|
10
|
-
result = conn.exec(
|
10
|
+
result = conn.exec('SELECT usename FROM pg_user')
|
11
11
|
|
12
|
-
result.map { |row| row[
|
12
|
+
result.map { |row| row['usename'] }.reject { |name| name == 'postgres' }
|
13
13
|
ensure
|
14
14
|
conn.close
|
15
15
|
end
|
data/lib/pgchief/version.rb
CHANGED
data/lib/pgchief.rb
CHANGED
@@ -1,47 +1,47 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
3
|
+
require 'pg'
|
4
|
+
require 'tty-prompt'
|
5
|
+
require 'tty-option'
|
6
|
+
require 'aws-sdk-s3'
|
7
7
|
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
11
|
-
require
|
12
|
-
require
|
13
|
-
require
|
14
|
-
require
|
15
|
-
require
|
8
|
+
require 'pgchief/cli'
|
9
|
+
require 'pgchief/config'
|
10
|
+
require 'pgchief/config/s3'
|
11
|
+
require 'pgchief/connection_string'
|
12
|
+
require 'pgchief/version'
|
13
|
+
require 'pgchief/database'
|
14
|
+
require 'pgchief/database/backups'
|
15
|
+
require 'pgchief/user'
|
16
16
|
|
17
|
-
require
|
18
|
-
require
|
19
|
-
require
|
20
|
-
require
|
21
|
-
require
|
22
|
-
require
|
23
|
-
require
|
24
|
-
require
|
25
|
-
require
|
26
|
-
require
|
27
|
-
require
|
28
|
-
require
|
17
|
+
require 'pgchief/prompt/base'
|
18
|
+
require 'pgchief/prompt/backup_database'
|
19
|
+
require 'pgchief/prompt/create_database'
|
20
|
+
require 'pgchief/prompt/create_user'
|
21
|
+
require 'pgchief/prompt/database_management'
|
22
|
+
require 'pgchief/prompt/drop_database'
|
23
|
+
require 'pgchief/prompt/drop_user'
|
24
|
+
require 'pgchief/prompt/grant_database_privileges'
|
25
|
+
require 'pgchief/prompt/restore_database'
|
26
|
+
require 'pgchief/prompt/start'
|
27
|
+
require 'pgchief/prompt/user_management'
|
28
|
+
require 'pgchief/prompt/view_database_connection_string'
|
29
29
|
|
30
|
-
require
|
31
|
-
require
|
32
|
-
require
|
33
|
-
require
|
34
|
-
require
|
35
|
-
require
|
36
|
-
require
|
37
|
-
require
|
38
|
-
require
|
39
|
-
require
|
40
|
-
require
|
41
|
-
require
|
42
|
-
require
|
43
|
-
require
|
44
|
-
require
|
30
|
+
require 'pgchief/command'
|
31
|
+
require 'pgchief/command/base'
|
32
|
+
require 'pgchief/command/config_create'
|
33
|
+
require 'pgchief/command/database_backup'
|
34
|
+
require 'pgchief/command/database_create'
|
35
|
+
require 'pgchief/command/database_drop'
|
36
|
+
require 'pgchief/command/database_list'
|
37
|
+
require 'pgchief/command/database_privileges_grant'
|
38
|
+
require 'pgchief/command/database_restore'
|
39
|
+
require 'pgchief/command/retrieve_connection_string'
|
40
|
+
require 'pgchief/command/s3_upload'
|
41
|
+
require 'pgchief/command/store_connection_string'
|
42
|
+
require 'pgchief/command/user_create'
|
43
|
+
require 'pgchief/command/user_drop'
|
44
|
+
require 'pgchief/command/user_list'
|
45
45
|
|
46
46
|
module Pgchief
|
47
47
|
class Error < StandardError; end
|
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pgchief
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joel Oliveira
|
8
|
-
autorequire:
|
9
8
|
bindir: exe
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 2025-03-25 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: aws-sdk-s3
|
@@ -80,7 +79,6 @@ dependencies:
|
|
80
79
|
- - ">="
|
81
80
|
- !ruby/object:Gem::Version
|
82
81
|
version: '0'
|
83
|
-
description:
|
84
82
|
email:
|
85
83
|
- joel.oliveira@gmail.com
|
86
84
|
executables:
|
@@ -91,6 +89,7 @@ files:
|
|
91
89
|
- ".env.sample"
|
92
90
|
- ".rspec"
|
93
91
|
- ".rubocop.yml"
|
92
|
+
- ".rubocop_todo.yml"
|
94
93
|
- CHANGELOG.md
|
95
94
|
- CODE_OF_CONDUCT.md
|
96
95
|
- LICENSE.txt
|
@@ -145,7 +144,6 @@ metadata:
|
|
145
144
|
source_code_uri: https://github.com/jayroh/pgchief
|
146
145
|
changelog_uri: https://github.com/jayroh/pgchief/blob/main/CHANGELOG.md
|
147
146
|
rubygems_mfa_required: 'true'
|
148
|
-
post_install_message:
|
149
147
|
rdoc_options: []
|
150
148
|
require_paths:
|
151
149
|
- lib
|
@@ -160,8 +158,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
160
158
|
- !ruby/object:Gem::Version
|
161
159
|
version: '0'
|
162
160
|
requirements: []
|
163
|
-
rubygems_version: 3.
|
164
|
-
signing_key:
|
161
|
+
rubygems_version: 3.6.2
|
165
162
|
specification_version: 4
|
166
163
|
summary: A simple ruby script to manage postgresql databases and users
|
167
164
|
test_files: []
|