Class: Packwerk::Privacy::Checker

Inherits:
Object
  • Object
show all
Extended by:
T::Sig
Includes:
Checker
Defined in:
lib/packwerk/privacy/checker.rb

Overview

Checks whether a given reference references a private constant of another package.

Constant Summary collapse

VIOLATION_TYPE =
T.let('privacy', String)
PUBLICIZED_SIGIL =
T.let('pack_public: true', String)
PUBLICIZED_SIGIL_REGEX =
T.let(/#.*pack_public:\s*true/, Regexp)

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.check_for_publicized_sigil(location) ⇒ Object



37
38
39
# File 'lib/packwerk/privacy/checker.rb', line 37

def check_for_publicized_sigil(location)
  content_contains_sigil?(File.readlines(location))
end

.content_contains_sigil?(lines) ⇒ Boolean

Returns:

  • (Boolean)


42
43
44
# File 'lib/packwerk/privacy/checker.rb', line 42

def content_contains_sigil?(lines)
  T.must(lines[0..4]).any? { |l| l =~ PUBLICIZED_SIGIL_REGEX }
end

.publicized_location?(location) ⇒ Boolean

Returns:

  • (Boolean)


28
29
30
31
32
33
34
# File 'lib/packwerk/privacy/checker.rb', line 28

def publicized_location?(location)
  unless publicized_locations.key?(location)
    publicized_locations[location] = check_for_publicized_sigil(location)
  end

  T.must(publicized_locations[location])
end

.publicized_locationsObject



23
24
25
# File 'lib/packwerk/privacy/checker.rb', line 23

def publicized_locations
  @publicized_locations
end

Instance Method Details

#invalid_reference?(reference) ⇒ Boolean

Returns:

  • (Boolean)


57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/packwerk/privacy/checker.rb', line 57

def invalid_reference?(reference)
  constant_package = reference.constant.package
  privacy_package = Package.from(constant_package)

  return false if privacy_package.public_path?(reference.constant.location)
  return false if self.class.publicized_location?(reference.constant.location)

  privacy_option = privacy_package.enforce_privacy
  return false if enforcement_disabled?(privacy_option)

  return false if privacy_package.ignored_private_constants.include?(reference.constant.name)

  explicitly_private_constant?(reference.constant, explicitly_private_constants: privacy_package.private_constants)
end

#message(reference) ⇒ Object



94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/packwerk/privacy/checker.rb', line 94

def message(reference)
  source_desc = "'#{reference.package}'"

  message = <<~MESSAGE
    Privacy violation: '#{reference.constant.name}' is private to '#{reference.constant.package}' but referenced from #{source_desc}.
    Is there a public entrypoint in '#{Package.from(reference.constant.package).public_path}' that you can use instead?

    #{standard_help_message(reference)}
  MESSAGE

  message.chomp
end

#strict_mode_violation?(listed_offense) ⇒ Boolean

Returns:

  • (Boolean)


77
78
79
80
81
82
83
84
85
86
87
# File 'lib/packwerk/privacy/checker.rb', line 77

def strict_mode_violation?(listed_offense)
  publishing_package = listed_offense.reference.constant.package

  return false unless publishing_package.config['enforce_privacy'] == 'strict'
  return false if exclude_from_strict?(
    publishing_package.config['strict_privacy_ignored_patterns'] || [],
    Pathname.new(listed_offense.reference.relative_path).cleanpath
  )

  true
end

#violation_typeObject



48
49
50
# File 'lib/packwerk/privacy/checker.rb', line 48

def violation_type
  VIOLATION_TYPE
end