expire 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +15 -0
- data/.reek.yml +23 -0
- data/.rspec +3 -0
- data/.rubocop.yml +45 -0
- data/.simplecov +3 -0
- data/.travis.yml +7 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +152 -0
- data/LICENSE.txt +21 -0
- data/README.md +551 -0
- data/Rakefile +11 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/example_rules/bad_rules.yml +2 -0
- data/example_rules/good_rules.yml +1 -0
- data/exe/expire +7 -0
- data/expire.gemspec +54 -0
- data/lib/expire.rb +51 -0
- data/lib/expire/all_backups_expired_error.rb +7 -0
- data/lib/expire/backup.rb +74 -0
- data/lib/expire/backup_from_path_service.rb +56 -0
- data/lib/expire/backup_list.rb +69 -0
- data/lib/expire/cli.rb +221 -0
- data/lib/expire/command.rb +122 -0
- data/lib/expire/commands/newest.rb +21 -0
- data/lib/expire/commands/oldest.rb +21 -0
- data/lib/expire/commands/purge.rb +23 -0
- data/lib/expire/commands/remove.rb +26 -0
- data/lib/expire/commands/rule_classes.rb +18 -0
- data/lib/expire/commands/rule_names.rb +20 -0
- data/lib/expire/commands/rule_option_names.rb +20 -0
- data/lib/expire/from_now_keep_adjective_for_rule_base.rb +38 -0
- data/lib/expire/from_now_keep_daily_for_rule.rb +7 -0
- data/lib/expire/from_now_keep_hourly_for_rule.rb +7 -0
- data/lib/expire/from_now_keep_monthly_for_rule.rb +7 -0
- data/lib/expire/from_now_keep_most_recent_for_rule.rb +41 -0
- data/lib/expire/from_now_keep_weekly_for_rule.rb +8 -0
- data/lib/expire/from_now_keep_yearly_for_rule.rb +8 -0
- data/lib/expire/from_range_value.rb +29 -0
- data/lib/expire/generate_backup_list_service.rb +45 -0
- data/lib/expire/invalid_path_error.rb +7 -0
- data/lib/expire/keep_adjective_for_rule_base.rb +34 -0
- data/lib/expire/keep_adjective_rule_base.rb +97 -0
- data/lib/expire/keep_daily_for_rule.rb +7 -0
- data/lib/expire/keep_daily_rule.rb +7 -0
- data/lib/expire/keep_hourly_for_rule.rb +7 -0
- data/lib/expire/keep_hourly_rule.rb +7 -0
- data/lib/expire/keep_monthly_for_rule.rb +7 -0
- data/lib/expire/keep_monthly_rule.rb +7 -0
- data/lib/expire/keep_most_recent_for_rule.rb +31 -0
- data/lib/expire/keep_most_recent_rule.rb +38 -0
- data/lib/expire/keep_weekly_for_rule.rb +8 -0
- data/lib/expire/keep_weekly_rule.rb +7 -0
- data/lib/expire/keep_yearly_for_rule.rb +7 -0
- data/lib/expire/keep_yearly_rule.rb +7 -0
- data/lib/expire/no_backups_error.rb +7 -0
- data/lib/expire/no_rules_error.rb +7 -0
- data/lib/expire/numerus_unit.rb +10 -0
- data/lib/expire/path_already_exists_error.rb +7 -0
- data/lib/expire/playground.rb +62 -0
- data/lib/expire/purge_service.rb +91 -0
- data/lib/expire/refine_all_and_none.rb +29 -0
- data/lib/expire/report_base.rb +23 -0
- data/lib/expire/report_enhanced.rb +14 -0
- data/lib/expire/report_expired.rb +10 -0
- data/lib/expire/report_kept.rb +10 -0
- data/lib/expire/report_null.rb +21 -0
- data/lib/expire/report_simple.rb +14 -0
- data/lib/expire/rule_base.rb +56 -0
- data/lib/expire/rule_list.rb +52 -0
- data/lib/expire/rules.rb +66 -0
- data/lib/expire/templates/newest/.gitkeep +1 -0
- data/lib/expire/templates/oldest/.gitkeep +1 -0
- data/lib/expire/templates/purge/.gitkeep +1 -0
- data/lib/expire/templates/remove/.gitkeep +1 -0
- data/lib/expire/templates/rule_classes/.gitkeep +1 -0
- data/lib/expire/templates/rule_names/.gitkeep +1 -0
- data/lib/expire/templates/rule_option_names/.gitkeep +1 -0
- data/lib/expire/unknown_rule_error.rb +10 -0
- data/lib/expire/version.rb +9 -0
- metadata +321 -0
data/Rakefile
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
require 'cucumber/rake/task'
|
3
|
+
require 'rspec/core/rake_task'
|
4
|
+
|
5
|
+
Cucumber::Rake::Task.new(:cucumber) do |task|
|
6
|
+
task.cucumber_opts = '--format pretty'
|
7
|
+
end
|
8
|
+
|
9
|
+
RSpec::Core::RakeTask.new(:spec)
|
10
|
+
|
11
|
+
task :default => [:spec, :cucumber]
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "expire"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
monthly: 5
|
data/exe/expire
ADDED
data/expire.gemspec
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "expire/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "expire"
|
8
|
+
spec.version = Expire::VERSION
|
9
|
+
spec.authors = ["Thomas Regnet"]
|
10
|
+
# spec.email = ["TODO: Write your email address"]
|
11
|
+
|
12
|
+
spec.summary = %q{Calculate expired backups.}
|
13
|
+
spec.homepage = 'https://github.com/thomasregnet/expire'
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
# Prevent pushing this gem to RubyGems.org.
|
17
|
+
# To allow pushes either set the 'allowed_push_host'
|
18
|
+
# to allow pushing to a single host or delete this section
|
19
|
+
# to allow pushing to any host.
|
20
|
+
if spec.respond_to?(:metadata)
|
21
|
+
# spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
|
22
|
+
|
23
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
24
|
+
spec.metadata['source_code_uri'] = spec.homepage
|
25
|
+
else
|
26
|
+
raise "RubyGems 2.0 or newer is required to protect against " \
|
27
|
+
"public gem pushes."
|
28
|
+
end
|
29
|
+
|
30
|
+
# Specify which files should be added to the gem when it is released.
|
31
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
32
|
+
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
33
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
34
|
+
end
|
35
|
+
spec.bindir = "exe"
|
36
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
37
|
+
spec.require_paths = ["lib"]
|
38
|
+
|
39
|
+
spec.add_dependency 'activesupport', '~> 6.1'
|
40
|
+
spec.add_dependency 'pastel', '~> 0.8'
|
41
|
+
spec.add_dependency 'thor', '~> 1.1'
|
42
|
+
spec.add_dependency 'zeitwerk', "~> 2.4"
|
43
|
+
|
44
|
+
spec.add_development_dependency 'aruba', '~> 1.0'
|
45
|
+
spec.add_development_dependency 'bundler', '~> 2.1'
|
46
|
+
spec.add_development_dependency 'byebug', '~> 11.1'
|
47
|
+
spec.add_development_dependency 'cucumber', '~> 5.3'
|
48
|
+
spec.add_development_dependency 'rake', '~> 13.0'
|
49
|
+
spec.add_development_dependency 'reek', '~> 6.0'
|
50
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
51
|
+
spec.add_development_dependency 'rubocop', '~> 1.9'
|
52
|
+
spec.add_development_dependency 'rubocop-rspec', '~> 2.2'
|
53
|
+
spec.add_development_dependency 'simplecov', '~> 0.21'
|
54
|
+
end
|
data/lib/expire.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_support'
|
4
|
+
require 'active_support/core_ext'
|
5
|
+
require 'active_support/core_ext/date_and_time/calculations'
|
6
|
+
require 'date'
|
7
|
+
require 'yaml'
|
8
|
+
require 'zeitwerk'
|
9
|
+
|
10
|
+
loader = Zeitwerk::Loader.for_gem
|
11
|
+
loader.inflector.inflect('cli' => 'CLI')
|
12
|
+
loader.setup
|
13
|
+
|
14
|
+
# Expire backup directories
|
15
|
+
module Expire
|
16
|
+
# Exception derived from StandardError
|
17
|
+
class Error < StandardError; end
|
18
|
+
# Your code goes here...
|
19
|
+
|
20
|
+
def self.create_playground(base)
|
21
|
+
Playground.create(base)
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.newest(path)
|
25
|
+
GenerateBackupListService.call(path).newest
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.oldest(path)
|
29
|
+
GenerateBackupListService.call(path).oldest
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.purge(path, options)
|
33
|
+
PurgeService.call(path, options)
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.remove(path)
|
37
|
+
FileUtils.rm_r(path)
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.rule_classes
|
41
|
+
Expire::RuleList.class_names
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.rule_names
|
45
|
+
Expire::RuleList.names
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.rule_option_names
|
49
|
+
Expire::RuleList.option_names
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Expire
|
4
|
+
# Representation of a single backup
|
5
|
+
class Backup < Delegator
|
6
|
+
include Comparable
|
7
|
+
|
8
|
+
def initialize(datetime:, pathname:)
|
9
|
+
@datetime = datetime
|
10
|
+
@pathname = pathname
|
11
|
+
|
12
|
+
# @reasons_to_keep is a Set so a reason can added multiple times
|
13
|
+
# but appears only once
|
14
|
+
@reasons_to_keep = Set.new
|
15
|
+
end
|
16
|
+
|
17
|
+
attr_reader :datetime, :pathname, :reasons_to_keep
|
18
|
+
alias __getobj__ datetime
|
19
|
+
|
20
|
+
def same_hour?(other)
|
21
|
+
return false unless same_day?(other)
|
22
|
+
return true if hour == other.hour
|
23
|
+
|
24
|
+
false
|
25
|
+
end
|
26
|
+
|
27
|
+
def same_day?(other)
|
28
|
+
return false unless same_week?(other)
|
29
|
+
return true if day == other.day
|
30
|
+
|
31
|
+
false
|
32
|
+
end
|
33
|
+
|
34
|
+
def same_week?(other)
|
35
|
+
return false unless same_year?(other)
|
36
|
+
return true if cweek == other.cweek
|
37
|
+
|
38
|
+
false
|
39
|
+
end
|
40
|
+
|
41
|
+
def same_month?(other)
|
42
|
+
return false unless same_year?(other)
|
43
|
+
return true if month == other.month
|
44
|
+
|
45
|
+
false
|
46
|
+
end
|
47
|
+
|
48
|
+
def same_year?(other)
|
49
|
+
year == other.year
|
50
|
+
end
|
51
|
+
|
52
|
+
# The <=> method seems not to be delegated so we need to implement it
|
53
|
+
# Note that this Class includes the Comparable module
|
54
|
+
def <=>(other)
|
55
|
+
datetime <=> other.datetime
|
56
|
+
end
|
57
|
+
|
58
|
+
def add_reason_to_keep(reason)
|
59
|
+
reasons_to_keep << reason
|
60
|
+
end
|
61
|
+
|
62
|
+
# def datetime
|
63
|
+
# backup.datetime
|
64
|
+
# end
|
65
|
+
|
66
|
+
def expired?
|
67
|
+
reasons_to_keep.empty?
|
68
|
+
end
|
69
|
+
|
70
|
+
def keep?
|
71
|
+
reasons_to_keep.any?
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Expire
|
4
|
+
# Take a path and return an instance of Expire::Backup
|
5
|
+
class BackupFromPathService
|
6
|
+
def self.call(path:, by: :path)
|
7
|
+
new(path: path, by: by).call
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize(path:, by: :path)
|
11
|
+
@by = by
|
12
|
+
@pathname = Pathname.new(path)
|
13
|
+
|
14
|
+
raise ArgumentError, "by: must be :ctime, :mtime or :path, not #{by}" unless %i[ctime mtime path].include?(by)
|
15
|
+
end
|
16
|
+
|
17
|
+
attr_reader :by, :pathname
|
18
|
+
|
19
|
+
def call
|
20
|
+
Backup.new(datetime: datetime, pathname: pathname)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def datetime
|
26
|
+
digits = extract_digits
|
27
|
+
|
28
|
+
year = digits[0..3].to_i
|
29
|
+
month = digits[4..5].to_i
|
30
|
+
day = digits[6..7].to_i
|
31
|
+
hour = digits[8..9].to_i
|
32
|
+
minute = digits[10..11].to_i
|
33
|
+
|
34
|
+
datetime_for(year, month, day, hour, minute)
|
35
|
+
end
|
36
|
+
|
37
|
+
def datetime_for(year, month, day, hour, minute)
|
38
|
+
DateTime.new(year, month, day, hour, minute)
|
39
|
+
rescue Date::Error
|
40
|
+
raise InvalidPathError, "can't construct date and time from #{pathname}"
|
41
|
+
end
|
42
|
+
|
43
|
+
def extract_digits
|
44
|
+
basename = pathname.basename.to_s
|
45
|
+
|
46
|
+
digits = basename.gsub(/[^0-9]/, '')
|
47
|
+
|
48
|
+
digits_length = digits.length
|
49
|
+
|
50
|
+
return digits if digits_length == 12
|
51
|
+
return digits if digits_length == 14
|
52
|
+
|
53
|
+
raise InvalidPathError, "can't extract date and time from #{basename}"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'forwardable'
|
4
|
+
|
5
|
+
module Expire
|
6
|
+
# All Backups go here
|
7
|
+
class BackupList
|
8
|
+
include Enumerable
|
9
|
+
extend Forwardable
|
10
|
+
|
11
|
+
def initialize(backups = [])
|
12
|
+
# @backups = backups.sort.reverse
|
13
|
+
@backups = backups
|
14
|
+
end
|
15
|
+
|
16
|
+
attr_reader :backups
|
17
|
+
|
18
|
+
def_delegators :backups, :each, :empty?, :last, :length, :<<
|
19
|
+
|
20
|
+
def one_per(noun)
|
21
|
+
backups_per_noun = self.class.new
|
22
|
+
return backups_per_noun unless any?
|
23
|
+
|
24
|
+
reversed = sort.reverse
|
25
|
+
|
26
|
+
backups_per_noun << reversed.first
|
27
|
+
|
28
|
+
message = "same_#{noun}?"
|
29
|
+
|
30
|
+
reversed.each do |backup|
|
31
|
+
backups_per_noun << backup unless backup.send(message, backups_per_noun.last)
|
32
|
+
end
|
33
|
+
|
34
|
+
backups_per_noun
|
35
|
+
end
|
36
|
+
|
37
|
+
def most_recent(amount = 1)
|
38
|
+
self.class.new(sort.reverse.first(amount))
|
39
|
+
end
|
40
|
+
|
41
|
+
def newest
|
42
|
+
backups.max
|
43
|
+
end
|
44
|
+
|
45
|
+
def oldest
|
46
|
+
backups.min
|
47
|
+
end
|
48
|
+
|
49
|
+
def not_older_than(reference_datetime)
|
50
|
+
sort.select { |backup| backup.datetime >= reference_datetime }
|
51
|
+
end
|
52
|
+
|
53
|
+
def expired
|
54
|
+
self.class.new(backups.select(&:expired?))
|
55
|
+
end
|
56
|
+
|
57
|
+
def expired_count
|
58
|
+
expired.length
|
59
|
+
end
|
60
|
+
|
61
|
+
def keep
|
62
|
+
self.class.new(backups.select(&:keep?))
|
63
|
+
end
|
64
|
+
|
65
|
+
def keep_count
|
66
|
+
keep.length
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
data/lib/expire/cli.rb
ADDED
@@ -0,0 +1,221 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'expire'
|
4
|
+
require 'thor'
|
5
|
+
|
6
|
+
module Expire
|
7
|
+
# Command line interface
|
8
|
+
# rubocop:disable Metrics/ClassLength
|
9
|
+
class CLI < Thor
|
10
|
+
desc 'rule_option_names', 'List rule option names ordered by their rank'
|
11
|
+
method_option(
|
12
|
+
:help,
|
13
|
+
aliases: '-h',
|
14
|
+
type: :boolean,
|
15
|
+
desc: 'Display usage information'
|
16
|
+
)
|
17
|
+
def rule_option_names(*)
|
18
|
+
if options[:help]
|
19
|
+
invoke :help, ['rule_option_names']
|
20
|
+
else
|
21
|
+
require_relative 'commands/rule_option_names'
|
22
|
+
Expire::Commands::RuleOptionNames.new(options).execute
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
desc 'rule_names', 'List rule names ordered by their rank'
|
27
|
+
method_option(
|
28
|
+
:help,
|
29
|
+
aliases: '-h',
|
30
|
+
type: :boolean,
|
31
|
+
desc: 'Display usage information'
|
32
|
+
)
|
33
|
+
def rule_names(*)
|
34
|
+
if options[:help]
|
35
|
+
invoke :help, ['rule_names']
|
36
|
+
else
|
37
|
+
require_relative 'commands/rule_names'
|
38
|
+
Expire::Commands::RuleNames.new(options).execute
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
desc 'rule_classes', 'List rule classes ordered by their rank'
|
43
|
+
method_option(
|
44
|
+
:help,
|
45
|
+
aliases: '-h',
|
46
|
+
type: :boolean,
|
47
|
+
desc: 'Display usage information'
|
48
|
+
)
|
49
|
+
def rule_classes(*)
|
50
|
+
if options[:help]
|
51
|
+
invoke :help, ['rule_classes']
|
52
|
+
else
|
53
|
+
require_relative 'commands/rule_classes'
|
54
|
+
Expire::Commands::RuleClasses.new(options).execute
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
desc 'remove PATH', 'Remove PATH from the filesystem'
|
59
|
+
method_option :help, aliases: '-h', type: :boolean,
|
60
|
+
desc: 'Display usage information'
|
61
|
+
def remove(path)
|
62
|
+
if options[:help]
|
63
|
+
invoke :help, ['remove']
|
64
|
+
else
|
65
|
+
require_relative 'commands/remove'
|
66
|
+
Expire::Commands::Remove.new(path: path).execute
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
desc 'oldest PATH', 'Show the oldest backup'
|
71
|
+
method_option :help, aliases: '-h', type: :boolean,
|
72
|
+
desc: 'Display usage information'
|
73
|
+
def oldest(path)
|
74
|
+
if options[:help]
|
75
|
+
invoke :help, ['oldest']
|
76
|
+
else
|
77
|
+
require_relative 'commands/oldest'
|
78
|
+
Expire::Commands::Oldest.new(path, options).execute
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
desc 'newest PATH', 'Show the newest backup'
|
83
|
+
method_option :help, aliases: '-h', type: :boolean,
|
84
|
+
desc: 'Display usage information'
|
85
|
+
def newest(path)
|
86
|
+
if options[:help]
|
87
|
+
invoke :help, ['newest']
|
88
|
+
else
|
89
|
+
require_relative 'commands/newest'
|
90
|
+
Expire::Commands::Newest.new(path, options).execute
|
91
|
+
end
|
92
|
+
end
|
93
|
+
# Play with test-data
|
94
|
+
class Playground < Thor
|
95
|
+
desc 'create PATH', 'play with test-data'
|
96
|
+
def create(path)
|
97
|
+
Expire.create_playground(path)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
desc 'purge PATH', 'Remove expired backups from PATH'
|
102
|
+
method_option :help, aliases: '-h', type: :boolean,
|
103
|
+
desc: 'Display usage information'
|
104
|
+
method_option :format, aliases: '-f', type: :string,
|
105
|
+
enum: %w[expired kept none simple enhanced],
|
106
|
+
default: 'none',
|
107
|
+
desc: 'output format'
|
108
|
+
method_option :purge_command, aliases: '--cmd', type: :string,
|
109
|
+
desc: 'run command to purge the backup'
|
110
|
+
method_option :rules_file, aliases: '-r', type: :string,
|
111
|
+
desc: 'read expire-rules from file'
|
112
|
+
method_option :simulate, aliases: '-s', type: :boolean,
|
113
|
+
desc: 'Simulate purge, do not delete anything'
|
114
|
+
method_option(
|
115
|
+
:keep_most_recent,
|
116
|
+
type: :string,
|
117
|
+
desc: 'keep the <integer> most recent backups'
|
118
|
+
)
|
119
|
+
method_option(
|
120
|
+
:keep_most_recent_for,
|
121
|
+
type: :string,
|
122
|
+
desc: 'keep the most recent backups for <integer> <unit>'
|
123
|
+
)
|
124
|
+
method_option(
|
125
|
+
:from_now_keep_most_recent_for,
|
126
|
+
type: :string,
|
127
|
+
desc: 'keep the most recent backups for <integer> <unit> calculated from now'
|
128
|
+
)
|
129
|
+
method_option(
|
130
|
+
:keep_hourly,
|
131
|
+
type: :string,
|
132
|
+
desc: 'keep the <integer> most recent backups from different hours'
|
133
|
+
)
|
134
|
+
method_option(
|
135
|
+
:keep_daily,
|
136
|
+
type: :string,
|
137
|
+
desc: 'keep the <integer> most recent backups from different days'
|
138
|
+
)
|
139
|
+
method_option(
|
140
|
+
:keep_weekly,
|
141
|
+
type: :string,
|
142
|
+
desc: 'keep the <integer> most recent backups from different weeks'
|
143
|
+
)
|
144
|
+
method_option(
|
145
|
+
:keep_monthly,
|
146
|
+
type: :string,
|
147
|
+
desc: 'keep the <integer> most recent backups from different months'
|
148
|
+
)
|
149
|
+
method_option(
|
150
|
+
:keep_yearly,
|
151
|
+
type: :string,
|
152
|
+
desc: 'keep the <integer> most recent backups from different years'
|
153
|
+
)
|
154
|
+
method_option(
|
155
|
+
:keep_hourly_for,
|
156
|
+
type: :string,
|
157
|
+
desc: 'keep one backup per hour for <integer> <unit>'
|
158
|
+
)
|
159
|
+
method_option(
|
160
|
+
:keep_daily_for,
|
161
|
+
type: :string,
|
162
|
+
desc: 'keep one backup per day for <integer> <unit>'
|
163
|
+
)
|
164
|
+
method_option(
|
165
|
+
:keep_weekly_for,
|
166
|
+
type: :string,
|
167
|
+
desc: 'keep one backup per week for <integer> <unit>'
|
168
|
+
)
|
169
|
+
method_option(
|
170
|
+
:keep_monthly_for,
|
171
|
+
type: :string,
|
172
|
+
desc: 'keep one backup per month for <integer> <unit>'
|
173
|
+
)
|
174
|
+
method_option(
|
175
|
+
:keep_yearly_for,
|
176
|
+
type: :string,
|
177
|
+
desc: 'keep one backup per year for <integer> <unit>'
|
178
|
+
)
|
179
|
+
method_option(
|
180
|
+
:from_now_keep_hourly_for,
|
181
|
+
type: :string,
|
182
|
+
desc: 'keep one backup per hour for <integer> <unit> calculated from now'
|
183
|
+
)
|
184
|
+
method_option(
|
185
|
+
:from_now_keep_daily_for,
|
186
|
+
type: :string,
|
187
|
+
desc: 'keep one backup per hour for <integer> <unit> calculated from now'
|
188
|
+
)
|
189
|
+
method_option(
|
190
|
+
:from_now_keep_weekly_for,
|
191
|
+
type: :string,
|
192
|
+
desc: 'keep one backup per hour for <integer> <unit> calculated from now'
|
193
|
+
)
|
194
|
+
method_option(
|
195
|
+
:from_now_keep_monthly_for,
|
196
|
+
type: :string,
|
197
|
+
desc: 'keep one backup per hour for <integer> <unit> calculated from now'
|
198
|
+
)
|
199
|
+
method_option(
|
200
|
+
:from_now_keep_yearly_for,
|
201
|
+
type: :string,
|
202
|
+
desc: 'keep one backup per hour for <integer> <unit> calculated from now'
|
203
|
+
)
|
204
|
+
def purge(path)
|
205
|
+
if options[:help]
|
206
|
+
invoke :help, ['purge']
|
207
|
+
else
|
208
|
+
require_relative 'commands/purge'
|
209
|
+
Expire::Commands::Purge.new(path, options).execute
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
desc 'playground', 'play with test-data'
|
214
|
+
subcommand 'playground', Playground
|
215
|
+
|
216
|
+
def self.exit_on_failure?
|
217
|
+
true
|
218
|
+
end
|
219
|
+
end
|
220
|
+
# rubocop:enable Metrics/ClassLength
|
221
|
+
end
|