Class: Packwerk::PackageTodo

Inherits:
Object
  • Object
show all
Extended by:
T::Sig
Defined in:
lib/packwerk/package_todo.rb

Constant Summary collapse

PackageName =
T.type_alias { String }
ConstantName =
T.type_alias { String }
FilePath =
T.type_alias { String }
Entry =
T.type_alias { T::Hash[ConstantName, T::Hash[ConstantName, T::Array[FilePath]]] }
Entries =
T.type_alias do
  T::Hash[PackageName, Entry]
end

Instance Method Summary collapse

Constructor Details

#initialize(package, path) ⇒ PackageTodo

Returns a new instance of PackageTodo.



19
20
21
22
23
24
# File 'lib/packwerk/package_todo.rb', line 19

def initialize(package, path)
  @package = package
  @path = path
  @new_entries = T.let({}, Entries)
  @old_entries = T.let(nil, T.nilable(Entries))
end

Instance Method Details

#add_entries(reference, violation_type) ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/packwerk/package_todo.rb', line 43

def add_entries(reference, violation_type)
  package_violations = new_entries.fetch(reference.constant.package.name, {})
  entries_for_constant = package_violations[reference.constant.name] ||= {}

  entries_for_constant["violations"] ||= []
  entries_for_constant.fetch("violations") << violation_type

  entries_for_constant["files"] ||= []
  entries_for_constant.fetch("files") << reference.relative_path.to_s

  new_entries[reference.constant.package.name] = package_violations
  listed?(reference, violation_type: violation_type)
end

#delete_if_existsObject



97
98
99
# File 'lib/packwerk/package_todo.rb', line 97

def delete_if_exists
  File.delete(@path) if File.exist?(@path)
end

#dumpObject



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/packwerk/package_todo.rb', line 75

def dump
  if new_entries.empty?
    delete_if_exists
  else
    prepare_entries_for_dump
    message = <<~MESSAGE
      # This file contains a list of dependencies that are not part of the long term plan for the
      # '#{@package.name}' package.
      # We should generally work to reduce this list over time.
      #
      # You can regenerate this file using the following command:
      #
      # bin/packwerk update-todo
    MESSAGE
    File.open(@path, "w") do |f|
      f.write(message)
      f.write(new_entries.to_yaml)
    end
  end
end

#listed?(reference, violation_type:) ⇒ Boolean

Returns:

  • (Boolean)


30
31
32
33
34
35
36
37
38
# File 'lib/packwerk/package_todo.rb', line 30

def listed?(reference, violation_type:)
  violated_constants_found = old_entries.dig(reference.constant.package.name, reference.constant.name)
  return false unless violated_constants_found

  violated_constant_in_file = violated_constants_found.fetch("files", []).include?(reference.relative_path)
  return false unless violated_constant_in_file

  violated_constants_found.fetch("violations", []).include?(violation_type)
end

#stale_violations?(for_files) ⇒ Boolean

Returns:

  • (Boolean)


58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/packwerk/package_todo.rb', line 58

def stale_violations?(for_files)
  prepare_entries_for_dump

  old_entries.any? do |package, violations|
    files = for_files + deleted_files_for(package)
    violations_for_files = package_violations_for(violations, files: files)

    # We `next false` because if we cannot find existing violations for `for_files` within
    # the `package_todo.yml` file, then there are no violations that
    # can be considered stale.
    next false if violations_for_files.empty?

    stale_violation_for_package?(package, violations: violations_for_files)
  end
end