pgchief 0.5.3 → 0.6.0
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 +17 -26
- data/.rubocop_todo.yml +39 -0
- data/CHANGELOG.md +33 -0
- data/README.md +55 -10
- data/Rakefile +8 -8
- data/config/pgchief.toml +6 -1
- data/exe/pgchief +1 -1
- data/lib/pgchief/cli.rb +54 -6
- data/lib/pgchief/command/config_create.rb +2 -2
- data/lib/pgchief/command/database_backup.rb +8 -4
- data/lib/pgchief/command/database_drop.rb +2 -2
- data/lib/pgchief/command/database_privileges_grant.rb +1 -1
- data/lib/pgchief/command/database_restore.rb +3 -3
- data/lib/pgchief/command/quick_backup.rb +15 -0
- data/lib/pgchief/command/quick_restore.rb +20 -0
- 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 +48 -15
- data/lib/pgchief/connection_string.rb +5 -5
- data/lib/pgchief/database/backups.rb +4 -4
- 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 +59 -44
- metadata +6 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 142a11a0be4792a8b0c428c25119c964fb899564db0f6ace3464fef0409017c6
|
4
|
+
data.tar.gz: d62cd7fd0b58525300e25065b3fff56b1e9bd157af9058f335c5436c88e0090f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c02ad41656562151ac067e33a8a61bf8c3c39a915d32b93eda8ed76df0b601bbc4b3bfd8ab5c9979492ae0bb3b543c1e806fbcc9dbfe6b5e9452111662415336
|
7
|
+
data.tar.gz: 9cc987456a024dd1abaa656b2a725152a3e16ec7f345ab8723e3d912bcae6b213b3329e383b73bf23491826f9b8f9769d1e36d67d5688d5ad53f1bc829b5a907
|
data/.rubocop.yml
CHANGED
@@ -1,34 +1,25 @@
|
|
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
9
|
|
10
|
-
Style/
|
11
|
-
EnforcedStyle: double_quotes
|
12
|
-
|
13
|
-
Style/StringLiteralsInInterpolation:
|
14
|
-
EnforcedStyle: double_quotes
|
15
|
-
|
16
|
-
Metrics/BlockLength:
|
10
|
+
Style/Documentation:
|
17
11
|
Exclude:
|
18
|
-
- '
|
19
|
-
- '
|
20
|
-
|
21
|
-
Lint/MixedRegexpCaptureTypes:
|
22
|
-
Enabled: false
|
12
|
+
- 'lib/pgchief.rb'
|
13
|
+
- 'spec/**/*.rb'
|
23
14
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
RSpec/ExampleLength:
|
28
|
-
Max: 20
|
15
|
+
Metrics/AbcSize:
|
16
|
+
Exclude:
|
17
|
+
- 'lib/pgchief/config.rb'
|
29
18
|
|
30
|
-
|
31
|
-
|
19
|
+
Metrics/MethodLength:
|
20
|
+
Exclude:
|
21
|
+
- 'lib/pgchief/config.rb'
|
32
22
|
|
33
|
-
Metrics/
|
34
|
-
|
23
|
+
Metrics/CyclomaticComplexity:
|
24
|
+
Exclude:
|
25
|
+
- 'lib/pgchief/config.rb'
|
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,39 @@ and this project will try its best to adhere to [Semantic Versioning](https://se
|
|
13
13
|
|
14
14
|
### Fixes
|
15
15
|
|
16
|
+
## [0.6.0]
|
17
|
+
|
18
|
+
### Additions
|
19
|
+
|
20
|
+
* Adds `--backup database_name` option to cli to quickly backup a provided database.
|
21
|
+
|
22
|
+
### Changes
|
23
|
+
|
24
|
+
* Update restore command to only act on objects `--if-exists` (if they exist)
|
25
|
+
* Allow for config to be set via ENV variables
|
26
|
+
* Don't raise error when a database doesn't exist when a drop is attempted - just notify
|
27
|
+
|
28
|
+
### Fixes
|
29
|
+
|
30
|
+
* Fix method signature in `Database::Backups` - `remote` should be a kwarg and should
|
31
|
+
pass it along as such.
|
32
|
+
* When backing up a database, we add the db name to the end of the pg connection string.
|
33
|
+
In cases where that DATABASE_URL already has the database name tacked on at the end,
|
34
|
+
make sure it's only there once.
|
35
|
+
|
36
|
+
## [0.5.4]
|
37
|
+
|
38
|
+
### Additions
|
39
|
+
|
40
|
+
* Improve CLI usability with `--version` and `--help` flags.
|
41
|
+
* Adds `--remote-backup` and `--remote-restore` CLI options.
|
42
|
+
* Modifies `DatabaseRestore` and prompt flows to conditionally operate on remote backups.
|
43
|
+
* Adds `--restore database_name` option to cli to quickly restore latest backup for a provided database.
|
44
|
+
|
45
|
+
### Changes
|
46
|
+
|
47
|
+
* Updates the config loader to respect CLI flags and TOML values for remote_backup and remote_restore.
|
48
|
+
|
16
49
|
## [0.5.3]
|
17
50
|
|
18
51
|
### Additions
|
data/README.md
CHANGED
@@ -24,7 +24,7 @@ below for the feature check-list and current progress.
|
|
24
24
|
## Usage
|
25
25
|
|
26
26
|
```sh
|
27
|
-
# System
|
27
|
+
# System dependencies `build-essential` and `libpq-dev` must be installed
|
28
28
|
gem install pgchief
|
29
29
|
|
30
30
|
# To initialize the config file at `~/.config/pgchief/config.toml`:
|
@@ -38,9 +38,26 @@ 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
|
+
-b, --backup string Quickly backup specific database. Pass name of db.
|
47
|
+
-h, --help Print usage.
|
48
|
+
-i, --init Initialize the TOML configuration file.
|
49
|
+
--remote-backup Backup a database to a remote location.
|
50
|
+
--remote-restore Restore a database from a remote backup.
|
51
|
+
-r, --restore string Quickly restore specific database. Pass name of db.
|
52
|
+
-v, --version Show the version.
|
41
53
|
```
|
42
54
|
|
43
|
-
|
55
|
+
> [!Note]
|
56
|
+
> Prompts accept both `↑` and `↓` arrows, as well as `j` and `k`.
|
57
|
+
> Pressing the `esc` key at any point amidst a prompt will exit out of the
|
58
|
+
> program.
|
59
|
+
|
60
|
+
## Config via File
|
44
61
|
|
45
62
|
Format of `~/.config/pgchief/config.toml`
|
46
63
|
|
@@ -53,14 +70,42 @@ backup_dir = "~/.pgchief/backups"
|
|
53
70
|
|
54
71
|
# ** OPTIONAL **
|
55
72
|
|
56
|
-
# Location of
|
57
|
-
# credentials_file = "~/.pgchief/credentials"
|
73
|
+
# Location of saved database connection strings
|
74
|
+
# credentials_file = "~/.config/pgchief/credentials"
|
75
|
+
|
76
|
+
# S3 config
|
77
|
+
# ---------
|
78
|
+
# s3_key = ""
|
79
|
+
# s3_secret = ""
|
80
|
+
# s3_region = "us-east-1"
|
81
|
+
# s3_objects_path = "s3://bucket-name/database-backups/"
|
82
|
+
|
83
|
+
# Backup and restore from remote locations?
|
84
|
+
# remote_restore = false # default: false
|
85
|
+
# remote_backup = false # default: false
|
58
86
|
```
|
59
87
|
|
60
|
-
|
88
|
+
### OR ... Config via Environment Variables
|
89
|
+
|
90
|
+
The following environment variables will be picked up in the absence of a config
|
91
|
+
file.
|
92
|
+
|
93
|
+
```env
|
94
|
+
# Required
|
95
|
+
DATABASE_URL
|
96
|
+
|
97
|
+
# Optional
|
98
|
+
AWS_ACCESS_KEY_ID or AWS_ACCESS_KEY
|
99
|
+
AWS_SECRET_ACCESS_KEY or AWS_SECRET_KEY
|
100
|
+
AWS_DEFAULT_REGION or AWS_REGION
|
101
|
+
S3_BACKUPS_PATH
|
102
|
+
```
|
61
103
|
|
62
|
-
|
63
|
-
|
104
|
+
> [!IMPORTANT]
|
105
|
+
> Backup files must be named starting with `[Database Name]-` in order for the
|
106
|
+
> file(s) to be found for restoration. Eg: A database named
|
107
|
+
> `project_production` that has backups named `project_production-20250325.tar`
|
108
|
+
> will be picked up and given the option to restore.
|
64
109
|
|
65
110
|
## Development of the gem
|
66
111
|
|
@@ -135,7 +180,7 @@ Give "rando-username" access to database(s):
|
|
135
180
|
* [x] Back up database to S3
|
136
181
|
* [x] Restore local database
|
137
182
|
* [x] Restore remote database @ S3
|
138
|
-
* [
|
139
|
-
* [
|
183
|
+
* [x] Quickly back up via command line option
|
184
|
+
* [x] Quickly restore via command line option
|
140
185
|
* [ ] Task for inclusion in a Rakefile
|
141
|
-
* [
|
186
|
+
* [x] Support environment variables in config
|
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,18 +5,66 @@ 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
|
+
option :restore do
|
33
|
+
short '-r'
|
34
|
+
long '--restore string'
|
35
|
+
arity 1
|
36
|
+
desc 'Quickly restore specific database. Pass name of db.'
|
37
|
+
end
|
38
|
+
|
39
|
+
option :backup do
|
40
|
+
short '-b'
|
41
|
+
long '--backup string'
|
42
|
+
arity 1
|
43
|
+
desc 'Quickly backup specific database. Pass name of db.'
|
44
|
+
end
|
45
|
+
|
46
|
+
flag :help do
|
47
|
+
short '-h'
|
48
|
+
long '--help'
|
49
|
+
desc 'Print usage.'
|
12
50
|
end
|
13
51
|
|
14
|
-
def run
|
15
|
-
if params[:
|
52
|
+
def run # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
53
|
+
if params[:help]
|
54
|
+
print help
|
55
|
+
elsif params[:init]
|
16
56
|
Pgchief::Command::ConfigCreate.call
|
57
|
+
elsif params[:version]
|
58
|
+
puts Pgchief::VERSION
|
59
|
+
elsif params[:restore]
|
60
|
+
puts Pgchief::Command::QuickRestore.call(params, params[:restore])
|
61
|
+
elsif params[:backup]
|
62
|
+
puts Pgchief::Command::QuickBackup.call(params, params[:backup])
|
17
63
|
else
|
18
|
-
Pgchief::Prompt::Start.call
|
64
|
+
Pgchief::Prompt::Start.call(params)
|
19
65
|
end
|
66
|
+
rescue Pgchief::Error => e
|
67
|
+
puts e.message
|
20
68
|
end
|
21
69
|
end
|
22
70
|
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
|
@@ -35,11 +35,15 @@ module Pgchief
|
|
35
35
|
private
|
36
36
|
|
37
37
|
def backup!
|
38
|
-
`
|
38
|
+
# if the provided `pgurl` already has a database at the tail
|
39
|
+
# end of the string, remove it. We'll explicitly add it below.
|
40
|
+
pgurl = Pgchief::Config.pgurl.gsub(%r{/[a-zA-Z\-_]*$}, '')
|
41
|
+
|
42
|
+
`pg_dump -Fc #{pgurl}/#{database} -f #{local_location}`
|
39
43
|
end
|
40
44
|
|
41
45
|
def check_backup!
|
42
|
-
raise Pgchief::Errors::BackupError,
|
46
|
+
raise Pgchief::Errors::BackupError, 'Backup file has 0 bytes' unless File.size?(local_location)
|
43
47
|
end
|
44
48
|
|
45
49
|
def db_exists?
|
@@ -53,7 +57,7 @@ module Pgchief
|
|
53
57
|
|
54
58
|
def local_location
|
55
59
|
@local_location ||= begin
|
56
|
-
timestamp = Time.now.strftime(
|
60
|
+
timestamp = Time.now.strftime('%Y%m%d%H%M%S')
|
57
61
|
"#{Pgchief::Config.backup_dir}#{database}-#{timestamp}.dump"
|
58
62
|
end
|
59
63
|
end
|
@@ -8,10 +8,10 @@ module Pgchief
|
|
8
8
|
|
9
9
|
def call
|
10
10
|
@database = params.first
|
11
|
-
raise Pgchief::Errors::DatabaseMissingError unless db_exists?
|
12
11
|
|
13
|
-
|
12
|
+
return "Database '#{database}' does not exist." unless db_exists?
|
14
13
|
|
14
|
+
conn.exec("DROP DATABASE #{database}")
|
15
15
|
"Database '#{database}' dropped successfully!"
|
16
16
|
rescue PG::Error => e
|
17
17
|
"Error: #{e.message}"
|
@@ -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?
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Pgchief
|
4
|
+
module Command
|
5
|
+
# Command object to quickly restore the latest backup for a database
|
6
|
+
class QuickBackup < Base
|
7
|
+
def call
|
8
|
+
database = params.last
|
9
|
+
Pgchief::Config.load_config!(params.first)
|
10
|
+
Pgchief::Config.set_up_file_structure!
|
11
|
+
Pgchief::Command::DatabaseBackup.call(database)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Pgchief
|
4
|
+
module Command
|
5
|
+
# Command object to quickly restore the latest backup for a database
|
6
|
+
class QuickRestore < Base
|
7
|
+
def call
|
8
|
+
database = params.last
|
9
|
+
Pgchief::Config.load_config!(params.first)
|
10
|
+
Pgchief::Config.set_up_file_structure!
|
11
|
+
|
12
|
+
filename = Pgchief::Database
|
13
|
+
.backups_for(database, remote: Pgchief::Config.remote_restore)
|
14
|
+
.first
|
15
|
+
|
16
|
+
Pgchief::Command::DatabaseRestore.call(database, filename)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -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,25 +1,37 @@
|
|
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
|
7
7
|
class Config
|
8
|
+
DEFAULT_CONFIG = "#{Dir.home}/.config/pgchief/config.toml".freeze
|
9
|
+
|
8
10
|
class << self
|
9
11
|
attr_accessor \
|
10
12
|
:s3_key,
|
11
13
|
:s3_secret,
|
12
|
-
:s3_region
|
14
|
+
:s3_region,
|
15
|
+
:remote_restore,
|
16
|
+
:remote_backup
|
13
17
|
|
14
18
|
attr_writer :pgurl
|
15
19
|
|
16
20
|
attr_reader \
|
17
21
|
:s3_objects_path,
|
18
22
|
:backup_dir,
|
19
|
-
:credentials_file
|
23
|
+
:credentials_file,
|
24
|
+
:toml_file
|
25
|
+
|
26
|
+
# explicitly define getter so that pgurl is always available if
|
27
|
+
# load_config! is not run.
|
28
|
+
def pgurl
|
29
|
+
ENV.fetch('DATABASE_URL', ENV.fetch('DB_URL', @pgurl))
|
30
|
+
end
|
20
31
|
|
21
|
-
def load_config!(toml_file =
|
22
|
-
|
32
|
+
def load_config!(params, toml_file = DEFAULT_CONFIG)
|
33
|
+
@toml_file = toml_file
|
34
|
+
config = toml_config || env_config
|
23
35
|
self.backup_dir = config[:backup_dir]
|
24
36
|
self.credentials_file = config[:credentials_file]
|
25
37
|
self.pgurl = config[:pgurl]
|
@@ -27,7 +39,13 @@ module Pgchief
|
|
27
39
|
self.s3_secret = config[:s3_secret]
|
28
40
|
self.s3_region = config[:s3_region]
|
29
41
|
self.s3_objects_path = config[:s3_objects_path] || config[:s3_path_prefix]
|
30
|
-
|
42
|
+
self.remote_restore = params[:'remote-restore'] == true ||
|
43
|
+
params[:'local-restore'] == false ||
|
44
|
+
config[:remote_restore]
|
45
|
+
self.remote_backup = params[:'remote-backup'] == true ||
|
46
|
+
params[:'local-backup'] == false ||
|
47
|
+
config[:remote_backup]
|
48
|
+
rescue Pgchief::Errors::ConfigMissingError
|
31
49
|
puts config_missing_error(toml_file)
|
32
50
|
end
|
33
51
|
|
@@ -35,20 +53,16 @@ module Pgchief
|
|
35
53
|
@s3 ||= Pgchief::Config::S3.new(self)
|
36
54
|
end
|
37
55
|
|
38
|
-
def pgurl
|
39
|
-
ENV.fetch("DATABASE_URL", @pgurl)
|
40
|
-
end
|
41
|
-
|
42
56
|
def backup_dir=(value)
|
43
|
-
@backup_dir = value ? "#{value.chomp(
|
57
|
+
@backup_dir = value ? "#{value.chomp('/')}/".gsub('~', Dir.home) : '/tmp/'
|
44
58
|
end
|
45
59
|
|
46
60
|
def s3_objects_path=(value)
|
47
|
-
@s3_objects_path = value ? "#{value.chomp(
|
61
|
+
@s3_objects_path = value ? "#{value.chomp('/')}/" : nil
|
48
62
|
end
|
49
63
|
|
50
64
|
def credentials_file=(value)
|
51
|
-
@credentials_file = value&.gsub(
|
65
|
+
@credentials_file = value&.gsub('~', Dir.home)
|
52
66
|
end
|
53
67
|
|
54
68
|
def set_up_file_structure!
|
@@ -60,9 +74,28 @@ module Pgchief
|
|
60
74
|
|
61
75
|
private
|
62
76
|
|
77
|
+
def toml_config
|
78
|
+
return unless File.exist?(toml_file.to_s)
|
79
|
+
|
80
|
+
TomlRB.load_file(toml_file, symbolize_keys: true)
|
81
|
+
end
|
82
|
+
|
83
|
+
def env_config
|
84
|
+
pgurl = ENV.fetch('DATABASE_URL', ENV.fetch('DB_URL', nil))
|
85
|
+
raise Pgchief::Errors::ConfigMissingError if pgurl.nil?
|
86
|
+
|
87
|
+
{
|
88
|
+
pgurl: pgurl,
|
89
|
+
s3_key: ENV.fetch('AWS_ACCESS_KEY_ID', ENV.fetch('AWS_ACCESS_KEY', nil)),
|
90
|
+
s3_secret: ENV.fetch('AWS_SECRET_ACCESS_KEY', ENV.fetch('AWS_SECRET_KEY', nil)),
|
91
|
+
s3_region: ENV.fetch('AWS_DEFAULT_REGION', ENV.fetch('AWS_REGION', nil)),
|
92
|
+
s3_objects_path: ENV.fetch('S3_BACKUPS_PATH', nil)
|
93
|
+
}
|
94
|
+
end
|
95
|
+
|
63
96
|
def config_missing_error(toml_file)
|
64
|
-
"You must create a config file at #{toml_file}.\n" \
|
65
|
-
|
97
|
+
"You must create a config file at #{toml_file || DEFAULT_CONFIG}.\n" \
|
98
|
+
'run `pgchief --init` to create it.'
|
66
99
|
end
|
67
100
|
end
|
68
101
|
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
|
@@ -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
|
class Database
|
@@ -10,13 +10,13 @@ module Pgchief
|
|
10
10
|
|
11
11
|
def_delegators :s3, :bucket, :path, :client
|
12
12
|
|
13
|
-
def self.for(database, remote)
|
14
|
-
new(database, remote).for
|
13
|
+
def self.for(database, remote:)
|
14
|
+
new(database, remote: remote).for
|
15
15
|
end
|
16
16
|
|
17
17
|
attr_reader :database, :remote
|
18
18
|
|
19
|
-
def initialize(database, remote)
|
19
|
+
def initialize(database, remote:)
|
20
20
|
@database = database
|
21
21
|
@remote = remote
|
22
22
|
end
|
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,55 +1,70 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
11
|
-
require
|
12
|
-
require
|
13
|
-
require
|
14
|
-
require
|
15
|
-
require
|
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
|
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
|
3
|
+
require 'pg'
|
4
|
+
require 'tty-prompt'
|
5
|
+
require 'tty-option'
|
6
|
+
require 'aws-sdk-s3'
|
7
|
+
|
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
|
+
|
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
|
+
|
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/quick_restore'
|
40
|
+
require 'pgchief/command/quick_backup'
|
41
|
+
require 'pgchief/command/retrieve_connection_string'
|
42
|
+
require 'pgchief/command/s3_upload'
|
43
|
+
require 'pgchief/command/store_connection_string'
|
44
|
+
require 'pgchief/command/user_create'
|
45
|
+
require 'pgchief/command/user_drop'
|
46
|
+
require 'pgchief/command/user_list'
|
45
47
|
|
46
48
|
module Pgchief
|
47
49
|
class Error < StandardError; end
|
48
50
|
|
49
51
|
module Errors
|
50
52
|
class UserExistsError < Error; end
|
51
|
-
|
52
|
-
class DatabaseMissingError < Error; end
|
53
|
+
|
53
54
|
class BackupError < Error; end
|
55
|
+
|
56
|
+
class ConfigMissingError < Error; end
|
57
|
+
|
58
|
+
class DatabaseExistsError < Error
|
59
|
+
def message
|
60
|
+
'The database already exists.'
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
class DatabaseMissingError < Error
|
65
|
+
def message
|
66
|
+
'The database requested does not exist.'
|
67
|
+
end
|
68
|
+
end
|
54
69
|
end
|
55
70
|
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.
|
4
|
+
version: 0.6.0
|
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: 1980-01-02 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
|
@@ -109,6 +108,8 @@ files:
|
|
109
108
|
- lib/pgchief/command/database_list.rb
|
110
109
|
- lib/pgchief/command/database_privileges_grant.rb
|
111
110
|
- lib/pgchief/command/database_restore.rb
|
111
|
+
- lib/pgchief/command/quick_backup.rb
|
112
|
+
- lib/pgchief/command/quick_restore.rb
|
112
113
|
- lib/pgchief/command/retrieve_connection_string.rb
|
113
114
|
- lib/pgchief/command/s3_upload.rb
|
114
115
|
- lib/pgchief/command/store_connection_string.rb
|
@@ -145,7 +146,6 @@ metadata:
|
|
145
146
|
source_code_uri: https://github.com/jayroh/pgchief
|
146
147
|
changelog_uri: https://github.com/jayroh/pgchief/blob/main/CHANGELOG.md
|
147
148
|
rubygems_mfa_required: 'true'
|
148
|
-
post_install_message:
|
149
149
|
rdoc_options: []
|
150
150
|
require_paths:
|
151
151
|
- lib
|
@@ -160,8 +160,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
160
160
|
- !ruby/object:Gem::Version
|
161
161
|
version: '0'
|
162
162
|
requirements: []
|
163
|
-
rubygems_version: 3.
|
164
|
-
signing_key:
|
163
|
+
rubygems_version: 3.6.8
|
165
164
|
specification_version: 4
|
166
165
|
summary: A simple ruby script to manage postgresql databases and users
|
167
166
|
test_files: []
|