expire 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 +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
|