Class: RuboCop::Cop::PackageProtections::NamespacedUnderPackageName

Inherits:
Packs::NamespaceConvention
  • Object
show all
Extended by:
T::Sig
Includes:
PackageProtections::RubocopProtectionInterface
Defined in:
lib/rubocop/cop/package_protections/namespaced_under_package_name.rb

Constant Summary collapse

IDENTIFIER =
T.let('prevent_this_package_from_creating_other_namespaces'.freeze, String)

Instance Method Summary collapse

Methods included from PackageProtections::RubocopProtectionInterface

#custom_cop_config, #get_offenses_for_existing_violations, #get_offenses_for_new_violations

Methods included from PackageProtections::ProtectionInterface

#default_behavior, #get_offenses, #get_offenses_for_existing_violations, #get_offenses_for_new_violations, #supports_violation_behavior?

Instance Method Details

#cop_configs(packages) ⇒ Object



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/rubocop/cop/package_protections/namespaced_under_package_name.rb', line 22

def cop_configs(packages)
  include_packs = T.let([], T::Array[String])
  packages.each do |p|
    enabled_for_pack = !p.violation_behavior_for(NamespacedUnderPackageName::IDENTIFIER).fail_never?
    if enabled_for_pack
      include_packs << p.name
    end
  end

  [
    ::PackageProtections::RubocopProtectionInterface::CopConfig.new(
      name: cop_name,
      enabled: include_packs.any?,
      metadata: {
        'IncludePacks' => include_packs,
        'GloballyPermittedNamespaces' => ::RuboCop::Packs.config.globally_permitted_namespaces
      }
    )
  ]
end

#cop_nameObject



84
85
86
# File 'lib/rubocop/cop/package_protections/namespaced_under_package_name.rb', line 84

def cop_name
  'PackageProtections/NamespacedUnderPackageName'
end

#humanized_protection_descriptionObject



94
95
96
97
98
99
100
101
102
103
# File 'lib/rubocop/cop/package_protections/namespaced_under_package_name.rb', line 94

def humanized_protection_description
  <<~MESSAGE
    These files cannot have ANY modules/classes that are not submodules of the package's allowed namespaces.
    This is failing because these files are in `.rubocop_todo.yml` under `#{cop_name}`.
    If you want to be able to ignore these files, you'll need to open the file's package's `package.yml` file and
    change `#{IDENTIFIER}` to `#{::PackageProtections::ViolationBehavior::FailOnNew.serialize}`

    See https://go/packwerk_cheatsheet_namespaces for more info.
  MESSAGE
end

#humanized_protection_nameObject



89
90
91
# File 'lib/rubocop/cop/package_protections/namespaced_under_package_name.rb', line 89

def humanized_protection_name
  'Multiple Namespaces Violations'
end

#identifierObject



54
55
56
# File 'lib/rubocop/cop/package_protections/namespaced_under_package_name.rb', line 54

def identifier
  IDENTIFIER
end

#included_globs_for_packObject



44
45
46
47
48
49
# File 'lib/rubocop/cop/package_protections/namespaced_under_package_name.rb', line 44

def included_globs_for_pack
  [
    'app/**/*',
    'lib/**/*'
  ]
end

#message_for_fail_on_any(file) ⇒ Object



79
80
81
# File 'lib/rubocop/cop/package_protections/namespaced_under_package_name.rb', line 79

def message_for_fail_on_any(file)
  "`#{file}` should be namespaced under the package namespace"
end

#unmet_preconditions_for_behavior(behavior, package) ⇒ Object



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/rubocop/cop/package_protections/namespaced_under_package_name.rb', line 59

def unmet_preconditions_for_behavior(behavior, package)
  # We don't need to validate if the behavior is currentely fail_never
  return if behavior.fail_never?

  # The reason for this is precondition is the `MultipleNamespacesProtection` assumes this to work properly.
  # To remove this precondition, we need to modify `MultipleNamespacesProtection` to be more generalized!
  is_root_package = package.name == ParsePackwerk::ROOT_PACKAGE_NAME
  in_allowed_directory = ::PackageProtections::EXPECTED_PACK_DIRECTORIES.any? do |expected_package_directory|
    package.directory.to_s.start_with?(expected_package_directory)
  end
  if in_allowed_directory || is_root_package
    nil
  else
    "Package #{package.name} must be located in one of #{::PackageProtections::EXPECTED_PACK_DIRECTORIES.join(', ')} (or be the root) to use this protection"
  end
end