sekrit 0.1.0 → 0.2.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/.gitignore +4 -16
- data/.ruby-version +1 -1
- data/Gemfile.lock +23 -21
- data/LICENSE +1 -1
- data/exe/sekrit +1 -1
- data/lib/sekrit.rb +47 -47
- data/lib/sekrit/bundle.rb +9 -9
- data/lib/sekrit/config.rb +16 -16
- data/lib/sekrit/decoder.rb +23 -23
- data/lib/sekrit/encoder.rb +27 -27
- data/lib/sekrit/logger.rb +10 -10
- data/lib/sekrit/pull.rb +71 -71
- data/lib/sekrit/push.rb +75 -75
- data/lib/sekrit/runner.rb +102 -102
- data/lib/sekrit/version.rb +1 -1
- data/sekrit.gemspec +20 -20
- metadata +22 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fdb5cc787a221cf931501213f362f2d8a0ea65544b8f4e65459b5a04a73b249a
|
4
|
+
data.tar.gz: f35d2eb4e77c1e01395020686d1f027b7d128e117a545576c74ca94515e9e236
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a9132cc14af6122d319168af61056788854591785d26ad474fee3c47c8b861eb823fd7359a16047e1fa913267460edbf801eb6efbc6a8fd1e4ca0cdf37330b1a
|
7
|
+
data.tar.gz: 5c6d3c10ea5c6c80a20a30973b7a830947ec07f43a7d26aa014fd8a4493536a0038751c324882b94bc172dc50b5bb526a31bdb35e38ee62a59f41bd8bd75b8a9
|
data/.gitignore
CHANGED
@@ -13,22 +13,6 @@
|
|
13
13
|
# Used by dotenv library to load environment variables.
|
14
14
|
# .env
|
15
15
|
|
16
|
-
## Specific to RubyMotion:
|
17
|
-
.dat*
|
18
|
-
.repl_history
|
19
|
-
build/
|
20
|
-
*.bridgesupport
|
21
|
-
build-iPhoneOS/
|
22
|
-
build-iPhoneSimulator/
|
23
|
-
|
24
|
-
## Specific to RubyMotion (use of CocoaPods):
|
25
|
-
#
|
26
|
-
# We recommend against adding the Pods directory to your .gitignore. However
|
27
|
-
# you should judge for yourself, the pros and cons are mentioned at:
|
28
|
-
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
|
29
|
-
#
|
30
|
-
# vendor/Pods/
|
31
|
-
|
32
16
|
## Documentation cache and generated files:
|
33
17
|
/.yardoc/
|
34
18
|
/_yardoc/
|
@@ -48,3 +32,7 @@ build-iPhoneSimulator/
|
|
48
32
|
|
49
33
|
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
50
34
|
.rvmrc
|
35
|
+
|
36
|
+
# Jetbrains
|
37
|
+
.idea/
|
38
|
+
.rakeTasks
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.7.0
|
data/Gemfile.lock
CHANGED
@@ -2,41 +2,43 @@ PATH
|
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
4
|
sekrit (0.1.0)
|
5
|
-
git (~> 1
|
6
|
-
rainbow (~> 3
|
7
|
-
terminal-table (~> 1
|
8
|
-
thor (~>
|
5
|
+
git (~> 1)
|
6
|
+
rainbow (~> 3)
|
7
|
+
terminal-table (~> 1)
|
8
|
+
thor (~> 1)
|
9
9
|
|
10
10
|
GEM
|
11
11
|
remote: https://rubygems.org/
|
12
12
|
specs:
|
13
|
-
byebug (11.
|
13
|
+
byebug (11.1.1)
|
14
14
|
coderay (1.1.2)
|
15
|
-
git (1.
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
15
|
+
git (1.6.0)
|
16
|
+
rchardet (~> 1.8)
|
17
|
+
method_source (1.0.0)
|
18
|
+
minitest (5.14.0)
|
19
|
+
pry (0.13.0)
|
20
|
+
coderay (~> 1.1)
|
21
|
+
method_source (~> 1.0)
|
22
|
+
pry-byebug (3.9.0)
|
22
23
|
byebug (~> 11.0)
|
23
|
-
pry (~> 0.
|
24
|
+
pry (~> 0.13.0)
|
24
25
|
rainbow (3.0.0)
|
25
|
-
rake (
|
26
|
+
rake (13.0.1)
|
27
|
+
rchardet (1.8.0)
|
26
28
|
terminal-table (1.8.0)
|
27
29
|
unicode-display_width (~> 1.1, >= 1.1.1)
|
28
|
-
thor (0.
|
29
|
-
unicode-display_width (1.
|
30
|
+
thor (1.0.1)
|
31
|
+
unicode-display_width (1.7.0)
|
30
32
|
|
31
33
|
PLATFORMS
|
32
34
|
ruby
|
33
35
|
|
34
36
|
DEPENDENCIES
|
35
|
-
bundler (~> 2
|
36
|
-
minitest (~> 5
|
37
|
-
pry-byebug (~> 3
|
38
|
-
rake (~>
|
37
|
+
bundler (~> 2)
|
38
|
+
minitest (~> 5)
|
39
|
+
pry-byebug (~> 3)
|
40
|
+
rake (~> 13)
|
39
41
|
sekrit!
|
40
42
|
|
41
43
|
BUNDLED WITH
|
42
|
-
2.
|
44
|
+
2.1.4
|
data/LICENSE
CHANGED
data/exe/sekrit
CHANGED
data/lib/sekrit.rb
CHANGED
@@ -5,64 +5,64 @@ require 'sekrit/config'
|
|
5
5
|
require 'sekrit/decoder'
|
6
6
|
require 'sekrit/encoder'
|
7
7
|
require 'sekrit/logger'
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
11
|
-
require
|
8
|
+
require 'sekrit/pull'
|
9
|
+
require 'sekrit/push'
|
10
|
+
require 'sekrit/runner'
|
11
|
+
require 'sekrit/version'
|
12
12
|
require 'terminal-table'
|
13
13
|
require 'thor'
|
14
14
|
|
15
15
|
module Sekrit
|
16
|
-
|
16
|
+
class Error < StandardError; end
|
17
17
|
|
18
|
-
|
19
|
-
|
18
|
+
class CLI < Thor
|
19
|
+
class_option :verbose, aliases: :v, type: :boolean, default: false
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
21
|
+
desc 'push --config <path to Sekritfile> --git_ref <branch>', 'Encrypts and pushes files according to the contents of `Sekritfile`'
|
22
|
+
option :bundle_id, aliases: :b, type: :string
|
23
|
+
option :config, aliases: :c, type: :string, default: "#{ENV['PWD']}/Sekritfile"
|
24
|
+
option :git_ref, aliases: :g, type: :string, default: 'master'
|
25
|
+
option :passphrase, aliases: :p, type: :string
|
26
|
+
option :working_directory, aliases: :d, type: :string, default: '.'
|
27
|
+
def push
|
28
|
+
configure_logger(verbose: options[:verbose])
|
29
|
+
driver = lambda do |bundle_id, config, passphrase|
|
30
|
+
Push.new(
|
31
|
+
bundle_id: bundle_id,
|
32
|
+
config: config,
|
33
|
+
passphrase: passphrase
|
34
|
+
)
|
35
|
+
end
|
36
36
|
|
37
|
-
|
38
|
-
|
39
|
-
|
37
|
+
runner = Runner.new(name: 'Push', options: options, driver: driver)
|
38
|
+
runner.run
|
39
|
+
end
|
40
40
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
41
|
+
desc 'pull --config <path to Sekritfile> --git_ref <branch>', 'Pulls and decrypts files according to the contents of `Sekritfile`'
|
42
|
+
option :bundle_id, aliases: :b, type: :string
|
43
|
+
option :config, aliases: :c, type: :string, default: "#{ENV['PWD']}/Sekritfile"
|
44
|
+
option :git_ref, aliases: :g, type: :string, default: 'master'
|
45
|
+
option :passphrase, aliases: :p, type: :string
|
46
|
+
option :working_directory, aliases: :d, type: :string, default: '.'
|
47
|
+
def pull
|
48
|
+
configure_logger(verbose: options[:verbose])
|
49
|
+
driver = lambda do |bundle_id, config, passphrase|
|
50
|
+
Pull.new(
|
51
|
+
bundle_id: bundle_id,
|
52
|
+
config: config,
|
53
|
+
passphrase: passphrase
|
54
|
+
)
|
55
|
+
end
|
56
56
|
|
57
|
-
|
58
|
-
|
59
|
-
|
57
|
+
runner = Runner.new(name: 'Pull', options: options, driver: driver)
|
58
|
+
runner.run
|
59
|
+
end
|
60
60
|
|
61
|
-
|
61
|
+
private
|
62
62
|
|
63
|
-
|
64
|
-
|
65
|
-
end
|
63
|
+
def configure_logger(verbose: Boolean)
|
64
|
+
log.level = verbose ? Logger::DEBUG : Logger::INFO
|
66
65
|
end
|
66
|
+
end
|
67
67
|
|
68
68
|
end
|
data/lib/sekrit/bundle.rb
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
module Sekrit
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
3
|
+
class Bundle
|
4
|
+
attr_reader :encrypted
|
5
|
+
attr_reader :files
|
6
|
+
attr_reader :id
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
end
|
8
|
+
def initialize(hash: Hash)
|
9
|
+
@encrypted = hash['encrypted'] || []
|
10
|
+
@files = hash['files'] || []
|
11
|
+
@id = hash['id']
|
13
12
|
end
|
13
|
+
end
|
14
14
|
|
15
15
|
end
|
data/lib/sekrit/config.rb
CHANGED
@@ -2,23 +2,23 @@ require 'yaml'
|
|
2
2
|
|
3
3
|
module Sekrit
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
5
|
+
class Config
|
6
|
+
attr_reader :bundles
|
7
|
+
attr_reader :shared_files
|
8
|
+
attr_reader :bundled_files
|
9
|
+
attr_reader :passphrase
|
10
|
+
attr_reader :repo
|
11
|
+
attr_reader :raw
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
end
|
13
|
+
def initialize(path: 'Sekritfile')
|
14
|
+
@raw = File.read(path)
|
15
|
+
config = YAML::load_file(path)
|
16
|
+
@bundled_files = Bundle.new(hash: config['bundled_files']) unless config['bundled_files'].nil?
|
17
|
+
@bundles = (config['bundles'] || []).map { |b| Bundle.new(hash: b) }
|
18
|
+
@passphrase = config['passphrase']
|
19
|
+
@repo = config['repo']
|
20
|
+
@shared_files = Bundle.new(hash: config['shared_files']) unless config['shared_files'].nil?
|
22
21
|
end
|
22
|
+
end
|
23
23
|
|
24
24
|
end
|
data/lib/sekrit/decoder.rb
CHANGED
@@ -4,32 +4,32 @@ require 'securerandom'
|
|
4
4
|
|
5
5
|
module Sekrit
|
6
6
|
|
7
|
-
|
7
|
+
class Decoder
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
def initialize(password: String)
|
10
|
+
@password = password
|
11
|
+
end
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
13
|
+
# [bsarrazin] July 20th, 2019
|
14
|
+
# Stolen from Fastlane, as I am not an expert on encryption/decryption.
|
15
|
+
# If you have experience and want to help, please submit a pull request :)
|
16
|
+
#
|
17
|
+
# > We encrypt with MD5 because that was the most common default value in older fastlane versions which used the local OpenSSL installation
|
18
|
+
# > A more secure key and IV generation is needed in the future, IV should be randomly generated and provided unencrypted
|
19
|
+
# > salt should be randomly generated and provided unencrypted (like in the current implementation)
|
20
|
+
# > key should be generated with OpenSSL::KDF::pbkdf2_hmac with properly chosen parameters
|
21
|
+
# > Short explanation about salt and IV: https://stackoverflow.com/a/1950674/6324550
|
22
|
+
def decode(string: String)
|
23
|
+
data = Base64.decode64(string)
|
24
|
+
salt = data[8..15]
|
25
|
+
data = data[16..-1]
|
26
26
|
|
27
|
-
|
28
|
-
|
29
|
-
|
27
|
+
decipher = OpenSSL::Cipher.new('AES-256-CBC')
|
28
|
+
decipher.decrypt
|
29
|
+
decipher.pkcs5_keyivgen(@password, salt, 1, "MD5")
|
30
30
|
|
31
|
-
|
32
|
-
end
|
31
|
+
decipher.update(data) + decipher.final
|
33
32
|
end
|
33
|
+
end
|
34
34
|
|
35
|
-
end
|
35
|
+
end
|
data/lib/sekrit/encoder.rb
CHANGED
@@ -4,32 +4,32 @@ require 'securerandom'
|
|
4
4
|
|
5
5
|
module Sekrit
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
end
|
7
|
+
class Encoder
|
8
|
+
|
9
|
+
def initialize(password: String)
|
10
|
+
@password = password
|
11
|
+
end
|
12
|
+
|
13
|
+
# [bsarrazin] July 20th, 2019
|
14
|
+
# Stolen from Fastlane, as I am not an expert on encryption/decryption.
|
15
|
+
# If you have experience and want to help, please submit a pull request :)
|
16
|
+
#
|
17
|
+
# > We encrypt with MD5 because that was the most common default value in older fastlane versions which used the local OpenSSL installation
|
18
|
+
# > A more secure key and IV generation is needed in the future, IV should be randomly generated and provided unencrypted
|
19
|
+
# > salt should be randomly generated and provided unencrypted (like in the current implementation)
|
20
|
+
# > key should be generated with OpenSSL::KDF::pbkdf2_hmac with properly chosen parameters
|
21
|
+
# > Short explanation about salt and IV: https://stackoverflow.com/a/1950674/6324550
|
22
|
+
def encode(string: String)
|
23
|
+
|
24
|
+
salt = SecureRandom.random_bytes(8)
|
25
|
+
|
26
|
+
cipher = OpenSSL::Cipher.new('AES-256-CBC')
|
27
|
+
cipher.encrypt
|
28
|
+
cipher.pkcs5_keyivgen(@password, salt, 1, "MD5")
|
29
|
+
data = "Salted__" + salt + cipher.update(string) + cipher.final
|
30
|
+
|
31
|
+
Base64.encode64(data)
|
33
32
|
end
|
33
|
+
end
|
34
34
|
|
35
|
-
end
|
35
|
+
end
|
data/lib/sekrit/logger.rb
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
require 'logger'
|
2
2
|
|
3
3
|
class Object
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
end
|
9
|
-
|
10
|
-
@logger
|
4
|
+
def self.logger
|
5
|
+
if @logger.nil?
|
6
|
+
@logger = Logger.new(STDOUT)
|
7
|
+
@logger.level = Logger::DEBUG
|
11
8
|
end
|
12
9
|
|
13
|
-
|
14
|
-
|
15
|
-
|
10
|
+
@logger
|
11
|
+
end
|
12
|
+
|
13
|
+
def log
|
14
|
+
Object.logger
|
15
|
+
end
|
16
16
|
end
|
data/lib/sekrit/pull.rb
CHANGED
@@ -2,89 +2,89 @@ require 'rainbow'
|
|
2
2
|
|
3
3
|
module Sekrit
|
4
4
|
|
5
|
-
|
5
|
+
class Pull
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
7
|
+
def initialize(bundle_id: String, config: Config, passphrase: String)
|
8
|
+
@bundle_id = bundle_id
|
9
|
+
@config = config
|
10
|
+
@decoder = Decoder.new(password: passphrase)
|
11
11
|
|
12
|
-
|
13
|
-
|
12
|
+
raise Thor::Error, Rainbow("Bundle id cannot be nil").red if @bundle_id.nil?
|
13
|
+
end
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
|
15
|
+
def bundle
|
16
|
+
@config.bundles.select { |b| b.id == @bundle_id }.first
|
17
|
+
end
|
18
18
|
|
19
|
-
|
20
|
-
|
19
|
+
def copy_bundled_files(dir: String)
|
20
|
+
raise Thor::Error, Rainbow("Cannot find bundle with id '#{@bundle_id}' in Sekritfile").red if bundle.nil?
|
21
21
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
22
|
+
config_bundled_files = @config.bundled_files.nil? ? [] : @config.bundled_files.files
|
23
|
+
config_bundled_files += bundle.files
|
24
|
+
config_bundled_files.each do |f|
|
25
|
+
src = "#{dir}/#{bundle.id}/#{f}"
|
26
|
+
file_path = "#{Dir.pwd}/#{f}"
|
27
|
+
if File.exist?(src)
|
28
|
+
log.debug Rainbow("Preparing to copy '#{src}' to '#{file_path}'").purple
|
29
|
+
FileUtils.cp(src, f)
|
30
|
+
log.debug Rainbow("Copied '#{src}' to '#{file_path}'").purple
|
31
|
+
else
|
32
|
+
log.warn(Rainbow("Could not find file at path '#{src}'").yellow)
|
33
|
+
end
|
34
|
+
end
|
35
35
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
36
|
+
config_encrypted_files = @config.bundled_files.nil? ? [] : @config.bundled_files.encrypted
|
37
|
+
config_encrypted_files += bundle.encrypted
|
38
|
+
config_encrypted_files.each do |f|
|
39
|
+
src = "#{dir}/#{bundle.id}/#{f}"
|
40
|
+
file_path = "#{Dir.pwd}/#{f}"
|
41
|
+
if File.exist?(src)
|
42
|
+
log.debug Rainbow("Preparing to decrypt and copy '#{src}' to '#{file_path}'").purple
|
43
|
+
FileUtils.cp(src, f)
|
44
|
+
log.debug Rainbow("Copied '#{src}' to '#{file_path}'").purple
|
45
45
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
end
|
52
|
-
end
|
46
|
+
log.debug Rainbow("Preparing to decrypt '#{file_path}'").purple
|
47
|
+
File.write(file_path, @decoder.decode(string: File.read(file_path)))
|
48
|
+
log.debug Rainbow("Decrypted '#{file_path}'").purple
|
49
|
+
else
|
50
|
+
log.warn(Rainbow("Could not find file at path '#{src}'").yellow)
|
53
51
|
end
|
52
|
+
end
|
53
|
+
end
|
54
54
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
55
|
+
def copy_shared_files(dir: String)
|
56
|
+
config_shared_files = @config.shared_files.nil? ? [] : @config.shared_files.files
|
57
|
+
config_shared_files += bundle.files
|
58
|
+
config_shared_files.each do |f|
|
59
|
+
src = "#{dir}/shared/#{f}"
|
60
|
+
file_path = "#{Dir.pwd}/#{f}"
|
61
|
+
if File.exist?(src)
|
62
|
+
log.debug Rainbow("Preparing to copy '#{src}' to '#{file_path}'").purple
|
63
|
+
FileUtils.cp(src, f)
|
64
|
+
log.debug Rainbow("Copied '#{src}' to '#{file_path}'").purple
|
65
|
+
else
|
66
|
+
log.warn(Rainbow("Could not find file at path '#{src}'").yellow)
|
67
|
+
end
|
68
|
+
end
|
69
69
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
70
|
+
config_encrypted_files = @config.shared_files.nil? ? [] : @config.shared_files.encrypted
|
71
|
+
config_encrypted_files += bundle.encrypted
|
72
|
+
config_encrypted_files.each do |f|
|
73
|
+
src = "#{dir}/shared/#{f}"
|
74
|
+
file_path = "#{Dir.pwd}/#{f}"
|
75
|
+
if File.exist?(src)
|
76
|
+
log.debug Rainbow("Preparing to decrypt and copy '#{src}' to '#{file_path}'").purple
|
77
|
+
FileUtils.cp(src, f)
|
78
|
+
log.debug Rainbow("Copied '#{src}' to '#{file_path}'").purple
|
79
79
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
end
|
86
|
-
end
|
80
|
+
log.debug Rainbow("Preparing to decrypt '#{file_path}'").purple
|
81
|
+
File.write(file_path, @decoder.decode(string: File.read(file_path)))
|
82
|
+
log.debug Rainbow("Decrypted '#{file_path}'").purple
|
83
|
+
else
|
84
|
+
log.warn(Rainbow("Could not find file at path '#{src}'").yellow)
|
87
85
|
end
|
86
|
+
end
|
88
87
|
end
|
88
|
+
end
|
89
89
|
|
90
90
|
end
|
data/lib/sekrit/push.rb
CHANGED
@@ -2,93 +2,93 @@ require 'rainbow'
|
|
2
2
|
|
3
3
|
module Sekrit
|
4
4
|
|
5
|
-
|
5
|
+
class Push
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
7
|
+
def initialize(bundle_id: String, config: Config, passphrase: String)
|
8
|
+
@bundle_id = bundle_id
|
9
|
+
@config = config
|
10
|
+
@encoder = Encoder.new(password: passphrase)
|
11
11
|
|
12
|
-
|
13
|
-
|
12
|
+
raise Thor::Error, Rainbow("Bundle id cannot be nil").red if @bundle_id.nil?
|
13
|
+
end
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
|
15
|
+
def bundle
|
16
|
+
@config.bundles.select { |b| b.id == @bundle_id }.first
|
17
|
+
end
|
18
18
|
|
19
|
-
|
20
|
-
|
19
|
+
def copy_bundled_files(dir: String)
|
20
|
+
raise Thor::Error, Rainbow("Cannot find bundle with id '#{@bundle_id}' in Sekritfile").red if bundle.nil?
|
21
21
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
22
|
+
config_bundled_files = @config.bundled_files.nil? ? [] : @config.bundled_files.files
|
23
|
+
config_bundled_files += bundle.files
|
24
|
+
config_bundled_files.each do |f|
|
25
|
+
dest = "#{dir}/#{bundle.id}/#{f}"
|
26
|
+
file_path = "#{Dir.pwd}/#{f}"
|
27
|
+
if File.exist?(file_path)
|
28
|
+
log.debug Rainbow("Preparing to copy '#{file_path}' to '#{dest}'").purple
|
29
|
+
FileUtils.mkdir_p(File.dirname(dest))
|
30
|
+
FileUtils.cp(f, dest)
|
31
|
+
log.debug Rainbow("Copied '#{file_path}' to '#{dest}'").purple
|
32
|
+
else
|
33
|
+
log.warn(Rainbow("Could not find file at path '#{file_path}'").yellow)
|
34
|
+
end
|
35
|
+
end
|
36
36
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
37
|
+
config_encrypted_files = @config.bundled_files.nil? ? [] : @config.bundled_files.encrypted
|
38
|
+
config_encrypted_files += bundle.encrypted
|
39
|
+
config_encrypted_files.each do |f|
|
40
|
+
dest = "#{dir}/#{bundle.id}/#{f}"
|
41
|
+
file_path = "#{Dir.pwd}/#{f}"
|
42
|
+
if File.exist?(file_path)
|
43
|
+
log.debug Rainbow("Preparing to encrypt and copy '#{file_path}' to '#{dest}'").purple
|
44
|
+
FileUtils.mkdir_p(File.dirname(dest))
|
45
|
+
FileUtils.cp(f, dest)
|
46
|
+
log.debug Rainbow("Copied '#{file_path}' to '#{dest}'").purple
|
47
47
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
end
|
54
|
-
end
|
48
|
+
log.debug Rainbow("Preparing to encrypt '#{dest}'").purple
|
49
|
+
File.write(dest, @encoder.encode(string: File.read(dest)))
|
50
|
+
log.debug Rainbow("Encrypted '#{dest}'").purple
|
51
|
+
else
|
52
|
+
log.warn(Rainbow("Could not find file at path '#{file_path}'").yellow)
|
55
53
|
end
|
54
|
+
end
|
55
|
+
end
|
56
56
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
57
|
+
def copy_shared_files(dir: String)
|
58
|
+
config_shared_files = @config.shared_files.nil? ? [] : @config.shared_files.files
|
59
|
+
config_shared_files += bundle.files
|
60
|
+
config_shared_files.each do |f|
|
61
|
+
dest = "#{dir}/shared/#{f}"
|
62
|
+
file_path = "#{Dir.pwd}/#{f}"
|
63
|
+
if File.exist?(file_path)
|
64
|
+
log.debug Rainbow("Preparing to copy '#{file_path}' to '#{dest}'").purple
|
65
|
+
FileUtils.mkdir_p(File.dirname(dest))
|
66
|
+
FileUtils.cp(f, dest)
|
67
|
+
log.debug Rainbow("Copied '#{file_path}' to '#{dest}'").purple
|
68
|
+
else
|
69
|
+
log.warn(Rainbow("Could not find file at path '#{file_path}'").yellow)
|
70
|
+
end
|
71
|
+
end
|
72
72
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
73
|
+
config_encrypted_files = @config.shared_files.nil? ? [] : @config.shared_files.encrypted
|
74
|
+
config_encrypted_files += bundle.encrypted
|
75
|
+
config_encrypted_files.each do |f|
|
76
|
+
dest = "#{dir}/shared/#{f}"
|
77
|
+
file_path = "#{Dir.pwd}/#{f}"
|
78
|
+
if File.exist?(file_path)
|
79
|
+
log.debug Rainbow("Preparing to encrypt and copy '#{file_path}' to '#{dest}'").purple
|
80
|
+
FileUtils.mkdir_p(File.dirname(dest))
|
81
|
+
FileUtils.cp(f, dest)
|
82
|
+
log.debug Rainbow("Copied '#{file_path}' to '#{dest}'").purple
|
83
83
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
end
|
90
|
-
end
|
84
|
+
log.debug Rainbow("Preparing to encrypt '#{dest}'").purple
|
85
|
+
File.write(dest, @encoder.encode(string: File.read(dest)))
|
86
|
+
log.debug Rainbow("Encrypted '#{dest}'").purple
|
87
|
+
else
|
88
|
+
log.warn(Rainbow("Could not find file at path '#{file_path}'").yellow)
|
91
89
|
end
|
90
|
+
end
|
92
91
|
end
|
92
|
+
end
|
93
93
|
|
94
94
|
end
|
data/lib/sekrit/runner.rb
CHANGED
@@ -1,115 +1,115 @@
|
|
1
1
|
module Sekrit
|
2
2
|
|
3
|
-
|
3
|
+
class Runner
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
5
|
+
def initialize(name: String, options: Hash, driver: lambda)
|
6
|
+
@name = name
|
7
|
+
@options = options
|
8
|
+
@driver = driver
|
9
|
+
end
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
begin
|
15
|
-
print_command_config(name: @name)
|
16
|
-
|
17
|
-
raise Thor::Error, Rainbow("Cannot find Sekritfile at #{@options[:config]}").red unless File.exist?(@options[:config])
|
18
|
-
|
19
|
-
@config = Sekrit::Config.new(path: @options[:config])
|
20
|
-
bundle_id = @options[:bundle_id] || @config.bundles.first.id
|
21
|
-
|
22
|
-
print_sekrit_config(bundle_id: bundle_id)
|
23
|
-
|
24
|
-
@passphrase = @options[:passphrase] || ENV[@config.passphrase]
|
25
|
-
raise Thor::Error, Rainbow("passphrase cannot be nil").red if @passphrase.nil?
|
26
|
-
raise Thor::Error, Rainbow("passphrase cannot be empty").red if @passphrase.empty?
|
27
|
-
|
28
|
-
git_name = @config.repo.split('/').last.chomp('.git')
|
29
|
-
git = Git.clone(@config.repo, git_name, path: sekrit_dir, log: log)
|
30
|
-
begin
|
31
|
-
git.checkout(@options[:git_ref])
|
32
|
-
log.info Rainbow("Checking out #{@options[:git_ref]}").blue
|
33
|
-
rescue
|
34
|
-
git.branch(@options[:git_ref]).checkout
|
35
|
-
log.info Rainbow("Creating new branch #{@options[:git_ref]}").blue
|
36
|
-
end
|
37
|
-
|
38
|
-
directory = "#{working_directory}/#{git_name}"
|
39
|
-
driver = @driver.call(bundle_id, @config, @passphrase)
|
40
|
-
driver.copy_bundled_files(dir: directory)
|
41
|
-
driver.copy_shared_files(dir: directory)
|
42
|
-
|
43
|
-
if driver.class == Push
|
44
|
-
log.info Rainbow("git adding...").green
|
45
|
-
git.add
|
46
|
-
log.info Rainbow("git committing...").green
|
47
|
-
git.commit "[Sekrit] Updating files for #{bundle_id}"
|
48
|
-
log.info Rainbow("git pushing...").green
|
49
|
-
git.push(git.remote('origin'), git.branch(@options[:git_ref]))
|
50
|
-
log.info Rainbow("git completed!").green
|
51
|
-
end
|
52
|
-
|
53
|
-
rescue => error
|
54
|
-
log.warn Rainbow("git repo at `#{sekrit_dir}/#{git_name}` was not deleted").yellow
|
55
|
-
raise Thor::Error, Rainbow(error.full_message).red
|
56
|
-
end
|
57
|
-
|
58
|
-
delete_sekrit_dir_if_exist?
|
59
|
-
end
|
11
|
+
def run
|
12
|
+
delete_sekrit_dir_if_exist?
|
60
13
|
|
61
|
-
|
62
|
-
|
63
|
-
def print_command_config(name: String)
|
64
|
-
title = Rainbow("Sekrit #{name}").green
|
65
|
-
headings = ['Option', 'Value']
|
66
|
-
rows = []
|
67
|
-
rows << ['config file', @options[:config]]
|
68
|
-
rows << ['git reference (branch)', @options[:git_ref]]
|
69
|
-
rows << ['working directory', @options[:working_directory]]
|
70
|
-
table = Terminal::Table.new(title: title, headings: headings, rows: rows)
|
71
|
-
puts("\n" + table.to_s + "\n")
|
72
|
-
end
|
14
|
+
begin
|
15
|
+
print_command_config(name: @name)
|
73
16
|
|
74
|
-
|
75
|
-
title = Rainbow('Sekrit Config').green
|
76
|
-
headings = ['Option', 'Value']
|
77
|
-
rows = []
|
78
|
-
rows << ['bundle_id', bundle_id]
|
79
|
-
rows << ['repo', @config.repo]
|
80
|
-
rows << ['passphrase key', @config.passphrase]
|
81
|
-
rows << ['bundles', @config.bundles.map { |b| '- ' + b.id }.join("\n") ]
|
82
|
-
|
83
|
-
if @config.shared_files.nil?
|
84
|
-
rows << ['shared_files', '<does not exist in Sekritfile>']
|
85
|
-
else
|
86
|
-
rows << ['shared_files', @config.shared_files.files.nil? ? '<none>' : @config.shared_files.files.map { |f| '- ' + f }.join("\n")]
|
87
|
-
rows << ['shared_encrypted', @config.shared_files.encrypted.nil? ? '<none>' : @config.shared_files.encrypted.map { |f| '- ' + f }.join("\n")]
|
88
|
-
end
|
89
|
-
|
90
|
-
if @config.bundled_files.nil?
|
91
|
-
rows << ['bundled_files', '<does not exist in Sekritfile>']
|
92
|
-
else
|
93
|
-
rows << ['bundled_files', @config.bundled_files.files.nil? ? '<none>' : @config.bundled_files.files.map { |f| '- ' + f }.join("\n")]
|
94
|
-
rows << ['bundled_encrypted', @config.bundled_files.encrypted.nil? ? '<none>' : @config.bundled_files.encrypted.map { |f| '- ' + f }.join("\n")]
|
95
|
-
end
|
96
|
-
|
97
|
-
rows << ['Sekrifile', @config.raw]
|
98
|
-
|
99
|
-
table = Terminal::Table.new(title: title, headings: headings, rows: rows, style: { all_separators: true })
|
100
|
-
puts("\n" + table.to_s + "\n")
|
101
|
-
end
|
17
|
+
raise Thor::Error, Rainbow("Cannot find Sekritfile at #{@options[:config]}").red unless File.exist?(@options[:config])
|
102
18
|
|
103
|
-
|
104
|
-
|
105
|
-
|
19
|
+
@config = Sekrit::Config.new(path: @options[:config])
|
20
|
+
bundle_id = @options[:bundle_id] || @config.bundles.first.id
|
21
|
+
|
22
|
+
print_sekrit_config(bundle_id: bundle_id)
|
23
|
+
|
24
|
+
@passphrase = @options[:passphrase] || ENV[@config.passphrase]
|
25
|
+
raise Thor::Error, Rainbow("passphrase cannot be nil").red if @passphrase.nil?
|
26
|
+
raise Thor::Error, Rainbow("passphrase cannot be empty").red if @passphrase.empty?
|
106
27
|
|
107
|
-
|
108
|
-
|
28
|
+
git_name = @config.repo.split('/').last.chomp('.git')
|
29
|
+
git = Git.clone(@config.repo, git_name, path: sekrit_dir, log: log)
|
30
|
+
begin
|
31
|
+
git.checkout(@options[:git_ref])
|
32
|
+
log.info Rainbow("Checking out #{@options[:git_ref]}").blue
|
33
|
+
rescue
|
34
|
+
git.branch(@options[:git_ref]).checkout
|
35
|
+
log.info Rainbow("Creating new branch #{@options[:git_ref]}").blue
|
109
36
|
end
|
110
37
|
|
111
|
-
|
112
|
-
|
38
|
+
directory = "#{working_directory}/#{git_name}"
|
39
|
+
driver = @driver.call(bundle_id, @config, @passphrase)
|
40
|
+
driver.copy_bundled_files(dir: directory)
|
41
|
+
driver.copy_shared_files(dir: directory)
|
42
|
+
|
43
|
+
if driver.class == Push
|
44
|
+
log.info Rainbow("git adding...").green
|
45
|
+
git.add
|
46
|
+
log.info Rainbow("git committing...").green
|
47
|
+
git.commit "[Sekrit] Updating files for #{bundle_id}"
|
48
|
+
log.info Rainbow("git pushing...").green
|
49
|
+
git.push(git.remote('origin'), git.branch(@options[:git_ref]))
|
50
|
+
log.info Rainbow("git completed!").green
|
113
51
|
end
|
52
|
+
|
53
|
+
rescue => error
|
54
|
+
log.warn Rainbow("git repo at `#{sekrit_dir}/#{git_name}` was not deleted").yellow
|
55
|
+
raise Thor::Error, Rainbow(error.full_message).red
|
56
|
+
end
|
57
|
+
|
58
|
+
delete_sekrit_dir_if_exist?
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def print_command_config(name: String)
|
64
|
+
title = Rainbow("Sekrit #{name}").green
|
65
|
+
headings = ['Option', 'Value']
|
66
|
+
rows = []
|
67
|
+
rows << ['config file', @options[:config]]
|
68
|
+
rows << ['git reference (branch)', @options[:git_ref]]
|
69
|
+
rows << ['working directory', @options[:working_directory]]
|
70
|
+
table = Terminal::Table.new(title: title, headings: headings, rows: rows)
|
71
|
+
puts("\n" + table.to_s + "\n")
|
72
|
+
end
|
73
|
+
|
74
|
+
def print_sekrit_config(bundle_id: String)
|
75
|
+
title = Rainbow('Sekrit Config').green
|
76
|
+
headings = ['Option', 'Value']
|
77
|
+
rows = []
|
78
|
+
rows << ['bundle_id', bundle_id]
|
79
|
+
rows << ['repo', @config.repo]
|
80
|
+
rows << ['passphrase key', @config.passphrase]
|
81
|
+
rows << ['bundles', @config.bundles.map { |b| '- ' + b.id }.join("\n") ]
|
82
|
+
|
83
|
+
if @config.shared_files.nil?
|
84
|
+
rows << ['shared_files', '<does not exist in Sekritfile>']
|
85
|
+
else
|
86
|
+
rows << ['shared_files', @config.shared_files.files.nil? ? '<none>' : @config.shared_files.files.map { |f| '- ' + f }.join("\n")]
|
87
|
+
rows << ['shared_encrypted', @config.shared_files.encrypted.nil? ? '<none>' : @config.shared_files.encrypted.map { |f| '- ' + f }.join("\n")]
|
88
|
+
end
|
89
|
+
|
90
|
+
if @config.bundled_files.nil?
|
91
|
+
rows << ['bundled_files', '<does not exist in Sekritfile>']
|
92
|
+
else
|
93
|
+
rows << ['bundled_files', @config.bundled_files.files.nil? ? '<none>' : @config.bundled_files.files.map { |f| '- ' + f }.join("\n")]
|
94
|
+
rows << ['bundled_encrypted', @config.bundled_files.encrypted.nil? ? '<none>' : @config.bundled_files.encrypted.map { |f| '- ' + f }.join("\n")]
|
95
|
+
end
|
96
|
+
|
97
|
+
rows << ['Sekrifile', @config.raw]
|
98
|
+
|
99
|
+
table = Terminal::Table.new(title: title, headings: headings, rows: rows, style: { all_separators: true })
|
100
|
+
puts("\n" + table.to_s + "\n")
|
101
|
+
end
|
102
|
+
|
103
|
+
def sekrit_dir
|
104
|
+
'.sekrit'
|
105
|
+
end
|
106
|
+
|
107
|
+
def working_directory
|
108
|
+
"#{@options[:working_directory]}/#{sekrit_dir}"
|
109
|
+
end
|
110
|
+
|
111
|
+
def delete_sekrit_dir_if_exist?
|
112
|
+
FileUtils.remove_dir(working_directory) if Dir.exist?(working_directory)
|
114
113
|
end
|
114
|
+
end
|
115
115
|
end
|
data/lib/sekrit/version.rb
CHANGED
data/sekrit.gemspec
CHANGED
@@ -1,37 +1,37 @@
|
|
1
|
-
lib = File.expand_path(
|
1
|
+
lib = File.expand_path('lib', __dir__)
|
2
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
-
require
|
3
|
+
require 'sekrit/version'
|
4
4
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
|
-
spec.name =
|
6
|
+
spec.name = 'sekrit'
|
7
7
|
spec.version = Sekrit::VERSION
|
8
|
-
spec.authors = [
|
9
|
-
spec.email = [
|
8
|
+
spec.authors = ['Ben Sarrazin']
|
9
|
+
spec.email = ['b@srz.io']
|
10
10
|
|
11
11
|
spec.summary = %q{A gem for encrypting/decrypting files for your projects.}
|
12
12
|
spec.description = %q{Register files to encrypt/decrypt and store them in a separate git repository.}
|
13
|
-
spec.homepage =
|
14
|
-
spec.license =
|
13
|
+
spec.homepage = 'https://github.com/fourtytwohq/sekrit'
|
14
|
+
spec.license = 'MIT'
|
15
15
|
|
16
|
-
spec.metadata[
|
17
|
-
spec.metadata[
|
18
|
-
spec.metadata[
|
16
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
17
|
+
spec.metadata['source_code_uri'] = 'https://github.com/fourtytwohq/sekrit'
|
18
|
+
spec.metadata['changelog_uri'] = 'https://github.com/fourtytwohq/sekrit'
|
19
19
|
|
20
20
|
# Specify which files should be added to the gem when it is released.
|
21
21
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
22
22
|
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
23
23
|
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
24
24
|
end
|
25
|
-
spec.bindir =
|
25
|
+
spec.bindir = 'exe'
|
26
26
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
27
|
-
spec.require_paths = [
|
27
|
+
spec.require_paths = ['lib']
|
28
28
|
|
29
|
-
spec.add_development_dependency
|
30
|
-
spec.add_development_dependency '
|
31
|
-
spec.add_development_dependency
|
32
|
-
spec.add_development_dependency
|
33
|
-
spec.add_runtime_dependency 'git', '~> 1
|
34
|
-
spec.add_runtime_dependency 'rainbow', '~> 3
|
35
|
-
spec.add_runtime_dependency 'terminal-table', '~> 1
|
36
|
-
spec.add_runtime_dependency 'thor', '~>
|
29
|
+
spec.add_development_dependency 'bundler', '~> 2'
|
30
|
+
spec.add_development_dependency 'minitest', '~> 5'
|
31
|
+
spec.add_development_dependency 'pry-byebug', '~> 3'
|
32
|
+
spec.add_development_dependency 'rake', '~> 13'
|
33
|
+
spec.add_runtime_dependency 'git', '~> 1'
|
34
|
+
spec.add_runtime_dependency 'rainbow', '~> 3'
|
35
|
+
spec.add_runtime_dependency 'terminal-table', '~> 1'
|
36
|
+
spec.add_runtime_dependency 'thor', '~> 1'
|
37
37
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sekrit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ben Sarrazin
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-03-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -16,112 +16,112 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '2
|
19
|
+
version: '2'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '2
|
26
|
+
version: '2'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: minitest
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: '5'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
40
|
+
version: '5'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: pry-byebug
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '3'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
54
|
+
version: '3'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: rake
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
61
|
+
version: '13'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
68
|
+
version: '13'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: git
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: 1
|
75
|
+
version: '1'
|
76
76
|
type: :runtime
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: 1
|
82
|
+
version: '1'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: rainbow
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
87
|
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: 3
|
89
|
+
version: '3'
|
90
90
|
type: :runtime
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: 3
|
96
|
+
version: '3'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: terminal-table
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
101
|
- - "~>"
|
102
102
|
- !ruby/object:Gem::Version
|
103
|
-
version: 1
|
103
|
+
version: '1'
|
104
104
|
type: :runtime
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
108
|
- - "~>"
|
109
109
|
- !ruby/object:Gem::Version
|
110
|
-
version: 1
|
110
|
+
version: '1'
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
112
|
name: thor
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
114
114
|
requirements:
|
115
115
|
- - "~>"
|
116
116
|
- !ruby/object:Gem::Version
|
117
|
-
version:
|
117
|
+
version: '1'
|
118
118
|
type: :runtime
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
122
|
- - "~>"
|
123
123
|
- !ruby/object:Gem::Version
|
124
|
-
version:
|
124
|
+
version: '1'
|
125
125
|
description: Register files to encrypt/decrypt and store them in a separate git repository.
|
126
126
|
email:
|
127
127
|
- b@srz.io
|
@@ -171,7 +171,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
171
171
|
- !ruby/object:Gem::Version
|
172
172
|
version: '0'
|
173
173
|
requirements: []
|
174
|
-
rubygems_version: 3.
|
174
|
+
rubygems_version: 3.1.2
|
175
175
|
signing_key:
|
176
176
|
specification_version: 4
|
177
177
|
summary: A gem for encrypting/decrypting files for your projects.
|