Class: Tng::Services::FileTypeDetector

Inherits:
Object
  • Object
show all
Defined in:
lib/tng/services/file_type_detector.rb

Constant Summary collapse

TYPE_PATTERNS =
{
  /app\/controllers\// => 'controller',
  /app\/models\// => 'model',
  /app\/services?\// => 'service',
  /app\/jobs\// => 'job',
  /app\/helpers\// => 'helper',
  /(?:app\/)?libs?\// => 'lib',
  /app\/mailers\// => 'mailer',
  /app\/channels\// => 'channel',
  /app\/decorators\// => 'decorator',
  /app\/presenters\// => 'presenter',
  /app\/serializers\// => 'serializer',
  /app\/policies\// => 'policy',
  /app\/forms\// => 'form',
  /app\/queries\// => 'query',
  /app\/graphql\/resolvers\// => 'resolver',
  /app\/graphql\/types\// => 'type',
  /app\/graphql\/mutations\// => 'mutation',
  /app\/graphql\/loaders\// => 'loader',
  /app\/graphql\/schemas\// => 'schema',
  /app\/graphql\// => 'graphql'
}.freeze
PATH_MAPPINGS =
{
  'controller' => 'app/controllers',
  'model' => 'app/models',
  'service' => 'app/services?',
  'job' => 'app/jobs',
  'helper' => 'app/helpers',
  'lib' => 'lib',
  'mailer' => 'app/mailers',
  'channel' => 'app/channels',
  'decorator' => 'app/decorators',
  'presenter' => 'app/presenters',
  'serializer' => 'app/serializers',
  'policy' => 'app/policies',
  'form' => 'app/forms',
  'query' => 'app/queries',
  'resolver' => 'app/graphql/resolvers',
  'type' => 'app/graphql/types',
  'mutation' => 'app/graphql/mutations',
  'loader' => 'app/graphql/loaders',
  'schema' => 'app/graphql/schemas',
  'graphql' => 'app/graphql'
}.freeze
SEARCH_PATHS =
%w[
  app/controllers app/models app/services app/service
  app/jobs app/helpers app/mailers app/channels
  app/decorators app/presenters app/serializers
  app/policies app/forms app/queries app/graphql
  lib app/lib
].freeze

Class Method Summary collapse

Class Method Details

.build_file_object(file_path, type) ⇒ Object



110
111
112
113
114
115
116
117
118
119
120
# File 'lib/tng/services/file_type_detector.rb', line 110

def build_file_object(file_path, type)
  actual_file_path = File.expand_path(file_path)
  relative_path = extract_relative_path(actual_file_path, type)
  namespaced_name = relative_path.split('/').map(&:camelize).join('::')

  {
    name: namespaced_name,
    path: actual_file_path,
    type: type
  }
end

.detect_type(file_path) ⇒ Object



55
56
57
58
# File 'lib/tng/services/file_type_detector.rb', line 55

def detect_type(file_path)
  normalized_path = normalize_path(file_path)
  TYPE_PATTERNS.find { |pattern, _| normalized_path.match?(pattern) }&.last || 'other'
end

.extract_relative_path(file_path, type) ⇒ Object



102
103
104
105
106
107
108
# File 'lib/tng/services/file_type_detector.rb', line 102

def extract_relative_path(file_path, type)
  base_path = PATH_MAPPINGS[type]
  return File.basename(file_path, '.rb') unless base_path

  pattern = base_path == 'lib' ? %r{^.*/#{base_path}/} : %r{^.*#{base_path}/}
  file_path.gsub(pattern, '').gsub('.rb', '')
end

.find_file_in_project(file_name) ⇒ Object



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/tng/services/file_type_detector.rb', line 73

def find_file_in_project(file_name)
  file_with_ext = file_name.end_with?('.rb') ? file_name : "#{file_name}.rb"

  return File.expand_path(file_with_ext) if File.exist?(file_with_ext)

  rails_root = defined?(Rails) && Rails.root ? Rails.root.to_s : Dir.pwd

  SEARCH_PATHS.each do |dir|
    full_path = File.join(rails_root, dir, file_with_ext)
    return full_path if File.exist?(full_path)

    found_files = Dir.glob(File.join(rails_root, dir, '**', file_with_ext))
    return found_files.first unless found_files.empty?
  end

  nil
end

.normalize_path(file_path) ⇒ Object



60
61
62
63
# File 'lib/tng/services/file_type_detector.rb', line 60

def normalize_path(file_path)
  path = file_path.sub(/\.rb$/, '')
  path.start_with?('/') ? path : (find_file_in_project(path) || path)
end

.resolve_file_path(file_path) ⇒ Object



91
92
93
94
95
96
97
98
99
100
# File 'lib/tng/services/file_type_detector.rb', line 91

def resolve_file_path(file_path)
  resolved = if file_path.start_with?('/')
               File.exist?(file_path) ? file_path : File.exist?("#{file_path}.rb") ? "#{file_path}.rb" : nil
             else
               found = find_file_in_project(file_path)
               found ? File.expand_path(found) : nil
             end

  resolved
end