rustic 0.1.0 → 0.3.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/.github/workflows/main.yml +57 -12
- data/.gitignore +2 -1
- data/.rspec +1 -1
- data/.rubocop.yml +1 -1
- data/.tool-versions +1 -0
- data/Gemfile.lock +4 -2
- data/lib/rustic/application.rb +15 -0
- data/lib/rustic/{script/command_builder.rb → command_builder.rb} +4 -16
- data/lib/rustic/command_builders/backup.rb +24 -0
- data/lib/rustic/command_builders/check.rb +24 -0
- data/lib/rustic/command_builders/forget.rb +20 -0
- data/lib/rustic/{script/validator.rb → command_builders/prune.rb} +3 -3
- data/lib/rustic/command_builders/snapshots.rb +11 -0
- data/lib/rustic/{script/config.rb → config.rb} +17 -4
- data/lib/rustic/{script/backup_config.rb → configs/backup.rb} +3 -5
- data/lib/rustic/configs/check.rb +22 -0
- data/lib/rustic/configs/forget.rb +21 -0
- data/lib/rustic/evaluator.rb +27 -0
- data/lib/rustic/{script/hooks.rb → hooks.rb} +1 -1
- data/lib/rustic/{script/hooks_ext.rb → hooks_ext.rb} +1 -1
- data/lib/rustic/validator.rb +42 -0
- data/lib/rustic/version.rb +1 -1
- data/lib/rustic.rb +28 -6
- data/rustic.gemspec +1 -0
- data/rustic.rb +25 -20
- data/rustic_script.rb +32 -0
- metadata +37 -17
- data/exe/rustic +0 -8
- data/lib/rustic/cli.rb +0 -18
- data/lib/rustic/script/evaluator.rb +0 -40
- data/lib/rustic/script/reader.rb +0 -27
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3cffcd950bd1cafc45ac925deed3c4d5ffeed28feecd547f83fbe270b990d8c6
|
4
|
+
data.tar.gz: aa028fac39c981b0b4a6667dd1d84da19157ff2666a44abe06143c7b8f0473c1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4877cbfd5481d617d15cd4a58332516e533f9af4168a9e05e1099edbf0b3572fb087bd01b985958ca77d8f96053bea3c5e660ce545af36d7a26ab2c718f03faa
|
7
|
+
data.tar.gz: ad3f12c6b8cba8de97544d91481569ccc7dd0152dcdcb53a73f27f0b2b56ffeb70cca5747fc5966d0de093ce4c05e621b95842fc3fae68e60d6a7c6c7fe2c45d
|
data/.github/workflows/main.yml
CHANGED
@@ -1,18 +1,63 @@
|
|
1
1
|
name: Ruby
|
2
2
|
|
3
|
-
on: [push
|
3
|
+
on: [push]
|
4
4
|
|
5
5
|
jobs:
|
6
|
-
|
6
|
+
lint:
|
7
7
|
runs-on: ubuntu-latest
|
8
8
|
steps:
|
9
|
-
|
10
|
-
|
11
|
-
uses: ruby/setup-ruby@v1
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
9
|
+
- uses: actions/checkout@v2
|
10
|
+
|
11
|
+
- uses: ruby/setup-ruby@v1
|
12
|
+
with:
|
13
|
+
bundler-cache: true
|
14
|
+
|
15
|
+
- name: Run the default task
|
16
|
+
run: |
|
17
|
+
gem install bundler -v 2.2.27
|
18
|
+
bundle install
|
19
|
+
bundle exec rubocop
|
20
|
+
test:
|
21
|
+
runs-on: ubuntu-latest
|
22
|
+
steps:
|
23
|
+
- uses: actions/checkout@v2
|
24
|
+
|
25
|
+
- uses: ruby/setup-ruby@v1
|
26
|
+
with:
|
27
|
+
bundler-cache: true
|
28
|
+
|
29
|
+
- name: Install deps
|
30
|
+
run: |
|
31
|
+
gem install bundler -v 2.2.27
|
32
|
+
bundle install
|
33
|
+
|
34
|
+
- name: Run tests
|
35
|
+
run: bundle exec rspec
|
36
|
+
publish:
|
37
|
+
runs-on: ubuntu-latest
|
38
|
+
needs:
|
39
|
+
- lint
|
40
|
+
- test
|
41
|
+
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
|
42
|
+
steps:
|
43
|
+
- uses: actions/checkout@v2
|
44
|
+
|
45
|
+
- uses: ruby/setup-ruby@v1
|
46
|
+
with:
|
47
|
+
ruby-version: 3.0
|
48
|
+
bundler-cache: true
|
49
|
+
|
50
|
+
- name: Build gem
|
51
|
+
run: gem build
|
52
|
+
|
53
|
+
- name: Create credentials
|
54
|
+
run: |
|
55
|
+
mkdir ~/.gem
|
56
|
+
cat << EOF > ~/.gem/credentials
|
57
|
+
---
|
58
|
+
:rubygems_api_key: ${{ secrets.RUBYGEMS_TOKEN }}
|
59
|
+
EOF
|
60
|
+
chmod 0600 /home/runner/.gem/credentials
|
61
|
+
|
62
|
+
- name: Push gem
|
63
|
+
run: gem push *gem
|
data/.gitignore
CHANGED
data/.rspec
CHANGED
data/.rubocop.yml
CHANGED
data/.tool-versions
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ruby 3.0.2
|
data/Gemfile.lock
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
rustic (0.
|
4
|
+
rustic (0.3.0)
|
5
5
|
async-process (~> 1.3)
|
6
|
+
ptools (~> 1.4)
|
6
7
|
zeitwerk (~> 2.5)
|
7
8
|
|
8
9
|
GEM
|
@@ -24,7 +25,7 @@ GEM
|
|
24
25
|
rspec-memory (~> 1.0)
|
25
26
|
backport (1.2.0)
|
26
27
|
benchmark (0.2.0)
|
27
|
-
console (1.
|
28
|
+
console (1.14.0)
|
28
29
|
fiber-local
|
29
30
|
diff-lcs (1.4.4)
|
30
31
|
docile (1.4.0)
|
@@ -41,6 +42,7 @@ GEM
|
|
41
42
|
parallel (1.21.0)
|
42
43
|
parser (3.0.2.0)
|
43
44
|
ast (~> 2.4.1)
|
45
|
+
ptools (1.4.2)
|
44
46
|
racc (1.6.0)
|
45
47
|
rainbow (3.0.0)
|
46
48
|
rake (13.0.6)
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Rustic::Application
|
4
|
+
class UnknownCommandError < Rustic::Error; end
|
5
|
+
|
6
|
+
def initialize(config)
|
7
|
+
@config = config
|
8
|
+
end
|
9
|
+
|
10
|
+
def run(argv)
|
11
|
+
command = argv.first || "backup"
|
12
|
+
command, env = Rustic::CommandBuilder.new(command, @config).build
|
13
|
+
Rustic::Wrapper.new(command, env).run
|
14
|
+
end
|
15
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
class Rustic::
|
3
|
+
class Rustic::CommandBuilder
|
4
4
|
class UnknownPasswordMethodError < Rustic::Error; end
|
5
5
|
class UnknownCommandError < Rustic::Error; end
|
6
6
|
class MissingConfigError < Rustic::Error; end
|
@@ -35,21 +35,9 @@ class Rustic::Script::CommandBuilder
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def add_command!
|
38
|
-
|
39
|
-
|
40
|
-
|
38
|
+
command_class = Rustic::CommandBuilders.const_get(@command.capitalize)
|
39
|
+
@args.concat(command_class.new(@config).build)
|
40
|
+
rescue NameError
|
41
41
|
raise UnknownCommandError, "Unknown command #{@command}"
|
42
42
|
end
|
43
|
-
|
44
|
-
def excludes = ["--exclude"].product(@config.backup_config.excluded_paths).flatten
|
45
|
-
|
46
|
-
def command_snapshots = ["snapshots"]
|
47
|
-
|
48
|
-
def command_backup
|
49
|
-
config = @config.backup_config
|
50
|
-
raise MissingConfigError, "Command `backup` misses it's configuration" if config.nil?
|
51
|
-
raise MalformedConfigError, "Backup paths cannot be empty" if config.paths.empty?
|
52
|
-
|
53
|
-
["backup", config.one_fs ? "-x" : nil, *config.paths, *excludes].compact
|
54
|
-
end
|
55
43
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Rustic::CommandBuilders::Backup
|
4
|
+
def initialize(config)
|
5
|
+
@config = config
|
6
|
+
end
|
7
|
+
|
8
|
+
def build
|
9
|
+
config = @config.backup_config
|
10
|
+
raise Rustic::CommandBuilder::MissingConfigError, "Command `backup` misses it's configuration" if config.nil?
|
11
|
+
raise Rustic::CommandBuilder::MalformedConfigError, "Backup paths cannot be empty" if config.paths.empty?
|
12
|
+
|
13
|
+
[
|
14
|
+
"backup",
|
15
|
+
config.one_fs ? "-x" : nil,
|
16
|
+
*config.paths,
|
17
|
+
*excludes
|
18
|
+
].compact
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def excludes = ["--exclude"].product(@config.backup_config.excluded_paths).flatten
|
24
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Rustic::CommandBuilders::Check
|
4
|
+
def initialize(config)
|
5
|
+
@config = config
|
6
|
+
end
|
7
|
+
|
8
|
+
def build
|
9
|
+
config = @config.check_config
|
10
|
+
[
|
11
|
+
"check",
|
12
|
+
config&.check_unused ? "--check-unused" : nil,
|
13
|
+
read_data_subset(config),
|
14
|
+
config&.with_cache ? "--with-cache" : nil
|
15
|
+
].compact
|
16
|
+
end
|
17
|
+
|
18
|
+
def read_data_subset(config)
|
19
|
+
return nil if config.nil? || config.read_data_subset.nil?
|
20
|
+
return "--read-data" if config.read_data_subset == 100
|
21
|
+
|
22
|
+
"--read-data-subset=#{config.read_data_subset}%"
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Rustic::CommandBuilders::Forget
|
4
|
+
def initialize(config)
|
5
|
+
@config = config
|
6
|
+
end
|
7
|
+
|
8
|
+
def build
|
9
|
+
config = @config.forget_config
|
10
|
+
raise Rustic::CommandBuilder::MissingConfigError, "Command `forget` misses it's configuration" if config.nil?
|
11
|
+
|
12
|
+
[
|
13
|
+
"forget",
|
14
|
+
config.keep_last ? "--keep-last=#{config.keep_last}" : nil,
|
15
|
+
config.keep_weekly ? "--keep-weekly=#{config.keep_weekly}" : nil,
|
16
|
+
config.keep_monthly ? "--keep-monthly=#{config.keep_monthly}" : nil,
|
17
|
+
config.prune ? "--prune" : nil
|
18
|
+
].compact
|
19
|
+
end
|
20
|
+
end
|
@@ -1,12 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
class Rustic::
|
4
|
-
include Rustic::
|
3
|
+
class Rustic::Config
|
4
|
+
include Rustic::HooksExt
|
5
5
|
|
6
|
-
attr_reader :restic_path, :backup_config
|
6
|
+
attr_reader :restic_path, :backup_config, :check_config, :forget_config, :strict_validation
|
7
7
|
|
8
8
|
def initialize
|
9
9
|
@restic_path = "restic"
|
10
|
+
@strict_validation = false
|
10
11
|
end
|
11
12
|
|
12
13
|
def restic(path)
|
@@ -38,7 +39,19 @@ class Rustic::Script::Config
|
|
38
39
|
end
|
39
40
|
|
40
41
|
def backup(&block)
|
41
|
-
@backup_config ||= Rustic::
|
42
|
+
@backup_config ||= Rustic::Configs::Backup.new
|
42
43
|
@backup_config.instance_eval(&block)
|
43
44
|
end
|
45
|
+
|
46
|
+
def check(&block)
|
47
|
+
@check_config ||= Rustic::Configs::Check.new
|
48
|
+
@check_config.instance_eval(&block) unless block.nil?
|
49
|
+
end
|
50
|
+
|
51
|
+
def forget(&block)
|
52
|
+
@forget_config ||= Rustic::Configs::Forget.new
|
53
|
+
@forget_config.instance_eval(&block)
|
54
|
+
end
|
55
|
+
|
56
|
+
def strict_validation! = @strict_validation = true
|
44
57
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
class Rustic::
|
4
|
-
include Rustic::
|
3
|
+
class Rustic::Configs::Backup
|
4
|
+
include Rustic::HooksExt
|
5
5
|
|
6
6
|
attr_reader :paths, :excluded_paths, :one_fs
|
7
7
|
|
@@ -23,7 +23,5 @@ class Rustic::Script::BackupConfig
|
|
23
23
|
@excluded_paths = paths
|
24
24
|
end
|
25
25
|
|
26
|
-
def one_fs!
|
27
|
-
@one_fs = true
|
28
|
-
end
|
26
|
+
def one_fs! = @one_fs = true
|
29
27
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Rustic::Configs::Check
|
4
|
+
include Rustic::HooksExt
|
5
|
+
|
6
|
+
attr_reader :check_unused, :read_data_subset, :with_cache
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@check_unused = false
|
10
|
+
@read_data_subset = nil
|
11
|
+
@with_cache = false
|
12
|
+
end
|
13
|
+
|
14
|
+
def check_unused! = @check_unused = true
|
15
|
+
def with_cache! = @with_cache = true
|
16
|
+
|
17
|
+
def subset(percent)
|
18
|
+
raise ArgumentError, "percent must be > 0 and <= 100. Given: #{percent}" if percent <= 0 || percent > 100
|
19
|
+
|
20
|
+
@read_data_subset = percent
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Rustic::Configs::Forget
|
4
|
+
include Rustic::HooksExt
|
5
|
+
|
6
|
+
attr_reader :keep_last, :keep_weekly, :keep_monthly, :prune
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@prune = false
|
10
|
+
end
|
11
|
+
|
12
|
+
def keep(last: nil, weekly: nil, monthly: nil)
|
13
|
+
raise ArgumentError, "keep options must be provided" if [last, weekly, monthly].all?(&:nil?)
|
14
|
+
|
15
|
+
@keep_last = last
|
16
|
+
@keep_weekly = weekly
|
17
|
+
@keep_monthly = monthly
|
18
|
+
end
|
19
|
+
|
20
|
+
def prune! = @prune = true
|
21
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Rustic::Evaluator
|
4
|
+
include Console
|
5
|
+
|
6
|
+
def initialize(config) = @config = config
|
7
|
+
|
8
|
+
def evaluate
|
9
|
+
with_hooks(@config) do
|
10
|
+
backup! unless @config.backup_config.nil?
|
11
|
+
end
|
12
|
+
rescue StandardError => e
|
13
|
+
on_error(e)
|
14
|
+
raise
|
15
|
+
end
|
16
|
+
|
17
|
+
def on_error(error) = @config.on_error&.call(error)
|
18
|
+
|
19
|
+
def backup!
|
20
|
+
with_hooks(@config.backup_config) do
|
21
|
+
command, env = Rustic::CommandBuilder.new("backup", @config).build
|
22
|
+
Rustic::Wrapper.new(command, env).run
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def with_hooks(config, args = nil, &block) = Rustic::Hooks.new(config).with_hooks(args, &block)
|
27
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Rustic::Validator
|
4
|
+
def initialize(config)
|
5
|
+
@config = config
|
6
|
+
end
|
7
|
+
|
8
|
+
def validate
|
9
|
+
@errors = []
|
10
|
+
@warnings = []
|
11
|
+
validate_config!
|
12
|
+
validate_backup_config!
|
13
|
+
[@errors, @warnings]
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def validate_config! # rubocop:disable Metrics/AbcSize
|
19
|
+
if @config.restic_path.nil? || File.which(@config.restic_path).nil?
|
20
|
+
error!("restic path is miconfigured: '#{@config.restic_path.inspect}'")
|
21
|
+
end
|
22
|
+
error!("repository is not configured") if @config.repository.nil?
|
23
|
+
error!("password is not configured") if @config.password.nil? && @config.password_file.nil?
|
24
|
+
warning!("backup is not configured") if @config.backup_config.nil?
|
25
|
+
end
|
26
|
+
|
27
|
+
def validate_backup_config! # rubocop:disable Metrics/AbcSize
|
28
|
+
config = @config.backup_config
|
29
|
+
return if config.nil?
|
30
|
+
|
31
|
+
return unless @config.strict_validation
|
32
|
+
|
33
|
+
error!("backup paths must be alphabetically sorted") if config.paths != config.paths.sort
|
34
|
+
error!("backup paths contain duplicates") if config.paths != config.paths.uniq
|
35
|
+
error!("excluded paths must be alphabetically sorted") if config.excluded_paths != config.excluded_paths.sort
|
36
|
+
error!("excluded paths contain duplicates") if config.excluded_paths != config.excluded_paths.uniq
|
37
|
+
end
|
38
|
+
|
39
|
+
def error!(message) = @errors << message
|
40
|
+
|
41
|
+
def warning!(message) = @warnings << message
|
42
|
+
end
|
data/lib/rustic/version.rb
CHANGED
data/lib/rustic.rb
CHANGED
@@ -1,17 +1,39 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "async/process"
|
4
|
+
require "ptools" # file File.which
|
4
5
|
|
5
6
|
require "zeitwerk"
|
6
7
|
|
7
8
|
loader = Zeitwerk::Loader.for_gem
|
8
9
|
|
9
|
-
loader.inflector.inflect(
|
10
|
-
"cli" => "CLI"
|
11
|
-
)
|
12
|
-
|
13
10
|
loader.setup
|
14
11
|
|
15
|
-
|
16
|
-
class
|
12
|
+
module Rustic
|
13
|
+
class Error < StandardError; end
|
14
|
+
class ValidationError < Error; end
|
15
|
+
|
16
|
+
class << self
|
17
|
+
def define(run: true, &block)
|
18
|
+
Sync do
|
19
|
+
config = Rustic::Config.new
|
20
|
+
config.instance_eval(&block)
|
21
|
+
validate!(config)
|
22
|
+
Rustic::Application.new(config).tap do |app|
|
23
|
+
app.run(ARGV) if run
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def validate!(config)
|
31
|
+
errors, warnings = Rustic::Validator.new(config).validate
|
32
|
+
warnings.each do |warning|
|
33
|
+
# TODO: print warning
|
34
|
+
end
|
35
|
+
|
36
|
+
raise ValidationError, errors.join("\n") if errors.any?
|
37
|
+
end
|
38
|
+
end
|
17
39
|
end
|
data/rustic.gemspec
CHANGED
@@ -28,6 +28,7 @@ Gem::Specification.new do |spec|
|
|
28
28
|
spec.require_paths = ["lib"]
|
29
29
|
|
30
30
|
spec.add_dependency "async-process", "~> 1.3"
|
31
|
+
spec.add_dependency "ptools", "~> 1.4"
|
31
32
|
spec.add_dependency "zeitwerk", "~> 2.5"
|
32
33
|
|
33
34
|
# For more information and examples about making a new gem, checkout our
|
data/rustic.rb
CHANGED
@@ -1,32 +1,37 @@
|
|
1
|
+
#!/bin/env ruby
|
1
2
|
# frozen_string_literal: true
|
2
3
|
|
3
|
-
|
4
|
+
require "rustic"
|
4
5
|
|
5
|
-
|
6
|
+
Rustic.define do
|
7
|
+
repository "tmp/repository"
|
6
8
|
|
7
|
-
|
8
|
-
|
9
|
-
|
9
|
+
password "password"
|
10
|
+
|
11
|
+
before do
|
12
|
+
logger.info(self, "BEFORE")
|
13
|
+
end
|
14
|
+
|
15
|
+
backup do
|
16
|
+
one_fs!
|
17
|
+
|
18
|
+
before do |exists|
|
19
|
+
logger.info(self, "BEFORE BACKUP #{exists}")
|
20
|
+
end
|
10
21
|
|
11
|
-
|
12
|
-
|
22
|
+
after do
|
23
|
+
logger.info(self, "AFTER BACKUP")
|
24
|
+
end
|
13
25
|
|
14
|
-
|
15
|
-
|
26
|
+
backup "lib"
|
27
|
+
exclude "lib/rustic"
|
16
28
|
end
|
17
29
|
|
18
30
|
after do
|
19
|
-
logger.info(self, "AFTER
|
31
|
+
logger.info(self, "AFTER")
|
20
32
|
end
|
21
33
|
|
22
|
-
|
23
|
-
|
24
|
-
end
|
25
|
-
|
26
|
-
after do
|
27
|
-
logger.info(self, "AFTER")
|
28
|
-
end
|
29
|
-
|
30
|
-
on_error do |error|
|
31
|
-
logger.warn(self, "ERROR:", error)
|
34
|
+
on_error do |error|
|
35
|
+
logger.warn(self, "ERROR:", error)
|
36
|
+
end
|
32
37
|
end
|
data/rustic_script.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
repository "tmp/repository"
|
4
|
+
|
5
|
+
password "password"
|
6
|
+
|
7
|
+
before do
|
8
|
+
logger.info(self, "BEFORE")
|
9
|
+
end
|
10
|
+
|
11
|
+
backup do
|
12
|
+
one_fs!
|
13
|
+
|
14
|
+
before do |exists|
|
15
|
+
logger.info(self, "BEFORE BACKUP #{exists}")
|
16
|
+
end
|
17
|
+
|
18
|
+
after do
|
19
|
+
logger.info(self, "AFTER BACKUP")
|
20
|
+
end
|
21
|
+
|
22
|
+
backup "lib"
|
23
|
+
exclude "lib/rustic"
|
24
|
+
end
|
25
|
+
|
26
|
+
after do
|
27
|
+
logger.info(self, "AFTER")
|
28
|
+
end
|
29
|
+
|
30
|
+
on_error do |error|
|
31
|
+
logger.warn(self, "ERROR:", error)
|
32
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rustic
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gleb Sinyavskiy
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-11-
|
11
|
+
date: 2021-11-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: async-process
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: ptools
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.4'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.4'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: zeitwerk
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -41,8 +55,7 @@ dependencies:
|
|
41
55
|
description: DSL for the restic backup tool.
|
42
56
|
email:
|
43
57
|
- zhulik.gleb@gmail.com
|
44
|
-
executables:
|
45
|
-
- rustic
|
58
|
+
executables: []
|
46
59
|
extensions: []
|
47
60
|
extra_rdoc_files: []
|
48
61
|
files:
|
@@ -50,6 +63,7 @@ files:
|
|
50
63
|
- ".gitignore"
|
51
64
|
- ".rspec"
|
52
65
|
- ".rubocop.yml"
|
66
|
+
- ".tool-versions"
|
53
67
|
- CHANGELOG.md
|
54
68
|
- CODE_OF_CONDUCT.md
|
55
69
|
- Gemfile
|
@@ -59,27 +73,33 @@ files:
|
|
59
73
|
- Rakefile
|
60
74
|
- bin/console
|
61
75
|
- bin/setup
|
62
|
-
- exe/rustic
|
63
76
|
- lib/rustic.rb
|
64
|
-
- lib/rustic/
|
65
|
-
- lib/rustic/
|
66
|
-
- lib/rustic/
|
67
|
-
- lib/rustic/
|
68
|
-
- lib/rustic/
|
69
|
-
- lib/rustic/
|
70
|
-
- lib/rustic/
|
71
|
-
- lib/rustic/
|
72
|
-
- lib/rustic/
|
77
|
+
- lib/rustic/application.rb
|
78
|
+
- lib/rustic/command_builder.rb
|
79
|
+
- lib/rustic/command_builders/backup.rb
|
80
|
+
- lib/rustic/command_builders/check.rb
|
81
|
+
- lib/rustic/command_builders/forget.rb
|
82
|
+
- lib/rustic/command_builders/prune.rb
|
83
|
+
- lib/rustic/command_builders/snapshots.rb
|
84
|
+
- lib/rustic/config.rb
|
85
|
+
- lib/rustic/configs/backup.rb
|
86
|
+
- lib/rustic/configs/check.rb
|
87
|
+
- lib/rustic/configs/forget.rb
|
88
|
+
- lib/rustic/evaluator.rb
|
89
|
+
- lib/rustic/hooks.rb
|
90
|
+
- lib/rustic/hooks_ext.rb
|
91
|
+
- lib/rustic/validator.rb
|
73
92
|
- lib/rustic/version.rb
|
74
93
|
- lib/rustic/wrapper.rb
|
75
94
|
- rustic.gemspec
|
76
95
|
- rustic.rb
|
96
|
+
- rustic_script.rb
|
77
97
|
homepage: https://github.com/zhulik/rustic
|
78
98
|
licenses:
|
79
99
|
- MIT
|
80
100
|
metadata:
|
81
101
|
rubygems_mfa_required: 'true'
|
82
|
-
post_install_message:
|
102
|
+
post_install_message:
|
83
103
|
rdoc_options: []
|
84
104
|
require_paths:
|
85
105
|
- lib
|
@@ -95,7 +115,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
95
115
|
version: '0'
|
96
116
|
requirements: []
|
97
117
|
rubygems_version: 3.2.22
|
98
|
-
signing_key:
|
118
|
+
signing_key:
|
99
119
|
specification_version: 4
|
100
120
|
summary: DSL for the restic backup tool.
|
101
121
|
test_files: []
|
data/exe/rustic
DELETED
data/lib/rustic/cli.rb
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
class Rustic::CLI
|
4
|
-
def initialize(argv)
|
5
|
-
@argv = argv
|
6
|
-
end
|
7
|
-
|
8
|
-
def run
|
9
|
-
case @argv.first
|
10
|
-
when "script"
|
11
|
-
config = Rustic::Script::Reader.new(@argv[1]).read
|
12
|
-
Rustic::Script::Evaluator.new(config).evaluate
|
13
|
-
|
14
|
-
else
|
15
|
-
Rustic::Wrapper.new(["restic", *@argv]).run
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
@@ -1,40 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
class Rustic::Script::Evaluator
|
4
|
-
include Console
|
5
|
-
|
6
|
-
def initialize(config)
|
7
|
-
@config = config
|
8
|
-
end
|
9
|
-
|
10
|
-
def evaluate
|
11
|
-
check!
|
12
|
-
|
13
|
-
with_hooks(@config) do
|
14
|
-
backup! unless @config.backup_config.nil?
|
15
|
-
end
|
16
|
-
rescue StandardError => e
|
17
|
-
on_error(e)
|
18
|
-
raise
|
19
|
-
end
|
20
|
-
|
21
|
-
def check!
|
22
|
-
command, env = Rustic::Script::CommandBuilder.new("snapshots", @config).build
|
23
|
-
Rustic::Wrapper.new(command, env).run
|
24
|
-
end
|
25
|
-
|
26
|
-
def on_error(error)
|
27
|
-
@config.on_error&.call(error)
|
28
|
-
end
|
29
|
-
|
30
|
-
def backup!
|
31
|
-
with_hooks(@config.backup_config) do
|
32
|
-
command, env = Rustic::Script::CommandBuilder.new("backup", @config).build
|
33
|
-
Rustic::Wrapper.new(command, env).run
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def with_hooks(config, args = nil, &block)
|
38
|
-
Rustic::Script::Hooks.new(config).with_hooks(args, &block)
|
39
|
-
end
|
40
|
-
end
|
data/lib/rustic/script/reader.rb
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
class Rustic::Script::Reader
|
4
|
-
class FileReadingError < Rustic::Error; end
|
5
|
-
class EvaluationError < Rustic::Error; end
|
6
|
-
|
7
|
-
def initialize(file_path)
|
8
|
-
@file_path = file_path
|
9
|
-
end
|
10
|
-
|
11
|
-
def read
|
12
|
-
Rustic::Script::Config.new.tap do |config|
|
13
|
-
config.instance_eval(script)
|
14
|
-
Rustic::Script::Validator.new(@config).validate!
|
15
|
-
end
|
16
|
-
rescue SyntaxError, NameError
|
17
|
-
raise EvaluationError
|
18
|
-
end
|
19
|
-
|
20
|
-
private
|
21
|
-
|
22
|
-
def script
|
23
|
-
@script ||= File.read(@file_path)
|
24
|
-
rescue StandardError
|
25
|
-
raise FileReadingError
|
26
|
-
end
|
27
|
-
end
|