Module: Kettle::Drift

Defined in:
lib/kettle/drift.rb,
lib/kettle/drift/cli.rb,
lib/kettle/drift/diff.rb,
lib/kettle/drift/plugin.rb,
lib/kettle/drift/outcome.rb,
lib/kettle/drift/process.rb,
lib/kettle/drift/version.rb,
lib/kettle/drift/lock_file.rb,
lib/kettle/drift/serializer.rb,
lib/kettle/drift/process/printer.rb,
lib/kettle/drift/process/calculate_diff.rb,
lib/kettle/drift/duplicate_line_validator.rb,
sig/kettle/drift.rbs

Defined Under Namespace

Modules: DuplicateLineValidator, Plugin, Serializer, Version Classes: CLI, Diff, Error, LockFile, Outcome, Process

Constant Summary collapse

DEFAULT_LOCKFILE =
".kettle-drift.lock"
EXCLUDED_PATH_SEGMENTS =
Set.new(%w[
  .bundle
  .git
  .idea
  coverage
  docs
  log
  node_modules
  pkg
  results
  tmp
  vendor
]).freeze
EXCLUDED_FILE_EXTENSIONS =
Set.new(%w[
  .7z
  .bz2
  .class
  .dll
  .exe
  .gem
  .gif
  .gz
  .ico
  .jar
  .jpeg
  .jpg
  .pdf
  .png
  .so
  .tar
  .tgz
  .ttf
  .woff
  .woff2
  .xz
  .zip
]).freeze
VAR_HOME_PREFIX =
%r{\A/var/home(?=/|\z)}
VAR_HOME_TEXT =
%r{/var/home(?=/|\z)}
VERSION =

Current gem version exposed at the traditional constant location.

Returns:

  • (String)
Version::VERSION

Class Method Summary collapse

Class Method Details

.dependency_lockfile?(path) ⇒ Boolean

Returns:

  • (Boolean)


96
97
98
99
# File 'lib/kettle/drift.rb', line 96

def dependency_lockfile?(path)
  basename = File.basename(path)
  basename == "Gemfile.lock" || basename.end_with?(".gemfile.lock") || basename == "package-lock.json"
end

.display_path(path) ⇒ Object



62
63
64
65
66
# File 'lib/kettle/drift.rb', line 62

def display_path(path)
  return path if path.nil?

  path.to_s.sub(VAR_HOME_PREFIX, "/home")
end

.display_text(text) ⇒ Object



68
69
70
71
72
# File 'lib/kettle/drift.rb', line 68

def display_text(text)
  return text if text.nil?

  text.to_s.gsub(VAR_HOME_TEXT, "/home")
end

.install_tasksObject



74
75
76
# File 'lib/kettle/drift.rb', line 74

def install_tasks
  load("kettle/drift/tasks.rb")
end

.register_kettle_jem_plugin(registrar) ⇒ Object



78
79
80
# File 'lib/kettle/drift.rb', line 78

def register_kettle_jem_plugin(registrar)
  Kettle::Drift::Plugin.register!(registrar)
end

.run(project_root:, files: nil, template_dir: nil, min_chars: Kettle::Drift::DuplicateLineValidator::DEFAULT_MIN_CHARS, json_path: nil, lock_path: DEFAULT_LOCKFILE, mode: :update, printer_class: Kettle::Drift::Process::Printer) ⇒ Object



101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/kettle/drift.rb', line 101

def run(
  project_root:,
  files: nil,
  template_dir: nil,
  min_chars: Kettle::Drift::DuplicateLineValidator::DEFAULT_MIN_CHARS,
  json_path: nil,
  lock_path: DEFAULT_LOCKFILE,
  mode: :update,
  printer_class: Kettle::Drift::Process::Printer
)
  expanded_project_root = File.expand_path(project_root)
  expanded_template_dir = template_dir.to_s.strip.empty? ? nil : File.expand_path(template_dir, expanded_project_root)
  expanded_lock_path = File.expand_path(lock_path, expanded_project_root)
  selected_files = Array(files || target_files(project_root: expanded_project_root, template_dir: expanded_template_dir))
  baseline_set = expanded_template_dir ? Kettle::Drift::DuplicateLineValidator.baseline(template_dir: expanded_template_dir, min_chars: min_chars) : Set.new
  results = Kettle::Drift::DuplicateLineValidator.scan(files: selected_files, min_chars: min_chars)
  results = Kettle::Drift::DuplicateLineValidator.subtract_baseline(results, baseline_set: baseline_set)
  warning_count = Kettle::Drift::DuplicateLineValidator.warning_count(results)

  process_result = Kettle::Drift::Process.new(
    project_root: expanded_project_root,
    lock_path: expanded_lock_path,
    mode: mode,
    results: results,
    printer_class: printer_class
  ).run
  expanded_json_path = nil
  if write_json_report?(results, process_result.diff)
    expanded_json_path = if json_path
      File.expand_path(json_path, expanded_project_root)
    else
      File.join(expanded_project_root, "tmp", "kettle-drift", "duplicate-lines-#{Time.now.utc.strftime("%Y%m%d-%H%M%S")}.json")
    end
    Kettle::Drift::DuplicateLineValidator.write_json(results, expanded_json_path)
  end

  Kettle::Drift::Outcome.new(
    project_root: expanded_project_root,
    files: selected_files,
    template_dir: expanded_template_dir,
    baseline_set: baseline_set,
    results: results,
    warning_count: warning_count,
    json_path: expanded_json_path,
    lock_path: expanded_lock_path,
    mode: mode,
    diff: process_result.diff,
    exit_code: process_result.exit_code
  )
end

.target_files(project_root:, template_dir: nil) ⇒ Object



82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/kettle/drift.rb', line 82

def target_files(project_root:, template_dir: nil)
  return Kettle::Drift::DuplicateLineValidator.template_managed_files(project_root: project_root, template_dir: template_dir) if template_dir

  Dir.glob(File.join(project_root, "**", "*"), File::FNM_DOTMATCH).select do |path|
    next false unless File.file?(path)
    next false if EXCLUDED_FILE_EXTENSIONS.include?(File.extname(path).downcase)
    next false if dependency_lockfile?(path)

    relative = path.delete_prefix("#{project_root}/")
    segments = relative.split("/")
    segments.none? { |segment| segment.start_with?(".") || EXCLUDED_PATH_SEGMENTS.include?(segment) }
  end
end

.write_json_report?(results, diff) ⇒ Boolean

Returns:

  • (Boolean)


152
153
154
# File 'lib/kettle/drift.rb', line 152

def write_json_report?(results, diff)
  !results.empty? && diff.state != :no_changes
end