Class: Aspisec::Clean

Inherits:
Object
  • Object
show all
Defined in:
lib-ruby/aspisec/clean.rb

Overview

Manage the cleaning operations

Instance Method Summary collapse

Constructor Details

#initialize(conf: nil, logger: nil) ⇒ Clean

Returns a new instance of Clean.

Parameters:

  • conf (Aspisec::Config) (defaults to: nil)

    an instance of the global configuration
    If none is provided, the default config is loaded.

  • logger (TTY::Logger) (defaults to: nil)

    logger instance. See Logger.
    If none is provided, a default logger with log level 2 is created.
    See Logger::LOG_LEVEL.



18
19
20
21
22
23
24
25
26
# File 'lib-ruby/aspisec/clean.rb', line 18

def initialize(conf: nil, logger: nil)
  @logger = logger || Aspisec::Logger.new.logger
  @conf = conf || Aspisec::Config.new(@logger).conf
  @modules = Aspisec::Modules.modules(conf:, logger:).select(&:enabled?)
  @autoclean = @conf.dig('aspisec', 'autoclean').fetch('enabled', false)
  @describe = @conf.dig('aspisec', 'describe').fetch('enabled', true)
  @prompt = TTY::Prompt.new
  @painter = Pastel.new(eachline: "\n")
end

Instance Method Details

#cleannil

Main method, handling the cleaning.
Only enabled modules and locations will be removed.
Works either with auto-cleaning or ask for manual confirmation.

Returns:

  • (nil)


160
161
162
163
164
165
166
167
168
169
170
# File 'lib-ruby/aspisec/clean.rb', line 160

def clean
  @modules.each do |mod|
    next unless mod.enabled?

    puts "━━━━━━━━━━━━ #{@painter.decorate(mod.name, :white, :bold, :on_blue)} ━━━━━━━━━━━━"
    mod.locations.each do |loc|
      delete_mode(loc)
    end
  end
  nil
end

#delete_location(path) ⇒ nil

Handles and logs deletion of locations

Parameters:

  • path (Pathname)

Returns:

  • (nil)


127
128
129
130
131
# File 'lib-ruby/aspisec/clean.rb', line 127

def delete_location(path)
  type_delete(path)
  @logger.info("#{path} was removed")
  nil
end

#delete_mode(loc) ⇒ Object

Handles the deletion mode. It could be automatic or manual cleaning.

Parameters:



135
136
137
138
139
140
141
142
143
# File 'lib-ruby/aspisec/clean.rb', line 135

def delete_mode(loc)
  return unless loc.enabled? && loc.exist?

  if @autoclean
    delete_location(loc.path)
  else
    manual_delete(loc)
  end
end

#directory_size(path) ⇒ Integer

Calculate directory size (size of all files stored in it).
It will be the real size of files not the size on disk.
It ignores anything else than files so it could be wrong for symlinks, mounts, etc.
It also don't take into consideration the size of the directory itself.

Parameters:

  • path (Pathname)

Returns:

  • (Integer)

    size in bytes



76
77
78
# File 'lib-ruby/aspisec/clean.rb', line 76

def directory_size(path)
  Dir[File.join(path, '**', '*')].select { |f| File.file?(f) }.sum { |f| File.size(f) }
end

#file_type(path) ⇒ String

Type of file

Parameters:

  • path (Pathname)

Returns:

  • (String)

    file, directory or other



52
53
54
55
56
57
58
59
60
# File 'lib-ruby/aspisec/clean.rb', line 52

def file_type(path)
  if path.file?
    'file'
  elsif path.directory?
    'directory'
  else
    'other'
  end
end

#human_size(size) ⇒ String

Formats number as bytes into a human-friendly representation.

Parameters:

  • size (Integer)

    file size in bytes

Returns:

  • (String)

    human-friendly size with the most suitable unit

See Also:



66
67
68
# File 'lib-ruby/aspisec/clean.rb', line 66

def human_size(size)
  ActiveSupport::NumberHelper.number_to_human_size(size)
end

#manual_delete(loc) ⇒ Object

Handles the manual deletion mode.

Parameters:



147
148
149
150
151
152
153
154
# File 'lib-ruby/aspisec/clean.rb', line 147

def manual_delete(loc)
  remove = prompt_removal(location: loc)
  if remove
    delete_location(loc.path)
  else
    @logger.debug("#{loc.path} was left untouched")
  end
end

#prompt_removal(location:) ⇒ true|false

Display location (file or directory) information and prompt user for deletion
It will follow the configuration wether it has to display the description or not.

Parameters:

Returns:

  • (true|false)


32
33
34
35
36
37
38
39
# File 'lib-ruby/aspisec/clean.rb', line 32

def prompt_removal(location:)
  puts "——— #{@painter.decorate(location.name, :cyan, :bold)} ———"
  puts_decorated('Path', location.path.to_s)
  puts_decorated('Type', file_type(location.path))
  puts_decorated('Size', type_size_human(location.path))
  puts_decorated('Description', location.description) if @describe
  @prompt.yes?("Do you want to remove #{location.name}?")
end

#puts_decorated(key, value) ⇒ nil

Display decorated key/value

Parameters:

  • key (String)
  • value (String)

Returns:

  • (nil)


45
46
47
# File 'lib-ruby/aspisec/clean.rb', line 45

def puts_decorated(key, value)
  puts @painter.decorate("#{key}: ", :bright_blue, :bold) + value
end

#type_delete(path) ⇒ nil

Delete the location regardless of whether it is a file or a directory.

Parameters:

  • path (Pathname)

Returns:

  • (nil)


112
113
114
115
116
117
118
119
120
121
122
# File 'lib-ruby/aspisec/clean.rb', line 112

def type_delete(path)
  @logger.warn("The current user doesn't have permission to remove #{path}") unless path.writable?
  if path.directory?
    path.rmtree
  elsif path.file?
    path.delete
  else # for example when the location contains glogging representing multiple files
    Dir[path].map { |path| Pathname.new(path).delete }
  end
  nil
end

#type_size(path) ⇒ Integer

Displays the size regardless of whether it is a file or a directory or path containing globbing.

Parameters:

  • path (Pathname)

Returns:

  • (Integer)

    size in bytes or -1 if it's a path with globbing



83
84
85
86
87
88
89
90
91
# File 'lib-ruby/aspisec/clean.rb', line 83

def type_size(path)
  if path.directory?
    directory_size(path)
  elsif path.file?
    path.size
  else # for example when the location contains glogging representing multiple files
    -1
  end
end

#type_size_human(path) ⇒ String

Displays the size (in human-friendly format with #human_size) regardless of whether it is a file or a directory.

Parameters:

  • path (Pathname)

Returns:

  • (String)

    human-friendly size with the most suitable unit, empty is the size is zero or unknown
    for any other cases



97
98
99
100
101
102
103
104
105
106
107
# File 'lib-ruby/aspisec/clean.rb', line 97

def type_size_human(path)
  size = type_size(path)
  case size
  when 0
    'empty'
  when -1
    'unknown'
  else
    human_size(size)
  end
end