trains 0.0.2 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5edc43c1d03aa434cb4166f79b9687574ac14a04548a8e2e8fc7f47b005573e0
4
- data.tar.gz: ebee4c7048d82d644e4c08de0cd9a828b2f6784747558a3ec041b0feadbc043d
3
+ metadata.gz: 7edd36bbbc3349d7b32a1719cb5e80038953853e18d5d927ab2e713b621f356f
4
+ data.tar.gz: 97c661e09da45575d54fca505ab1a967b941c0bca806e29a1155739ca387f1a4
5
5
  SHA512:
6
- metadata.gz: 7511a1b15fc8b908cee1ccacd6096d651169ee7ce5ab4eeb6b153c905b8bd949f3899fd20080b4b0f577f2c9d90260ac8e7d85940680fb7c0c74cf24386fa110
7
- data.tar.gz: f7607d015b516c24c33e74f0473c120a25070bd146411deda8be54cbbe66e945a9ed68f56dd3122cd3c6694dae5bf3b220a836f0584f64f19aab711ba871aa54
6
+ metadata.gz: f560a4e5f4adf6fb45238f4deb1fcc3bb4dbcbf8a7a5b5dec7c74ff27224dd6a7afa00fe4702c1fa939626f8200a88b5d0383615967a3cd46af0d64cb6ae4b17
7
+ data.tar.gz: e3ae6062e8aea943fdb3d030c962edfdb23b631d60f33d17a1a9a041ad05fdb78424d427668dd76e015aa22564a0d2e18ee2dba2c9138445a9870040cfb75209
data/.deepsource.toml CHANGED
@@ -2,6 +2,3 @@ version = 1
2
2
 
3
3
  [[analyzers]]
4
4
  name = "ruby"
5
-
6
- [[transformers]]
7
- name = "rubocop"
data/Gemfile.lock CHANGED
@@ -1,12 +1,3 @@
1
- PATH
2
- remote: .
3
- specs:
4
- trains (0.0.1)
5
- activesupport (~> 7.0)
6
- parallel (~> 1.22)
7
- rubocop-ast (~> 1.16)
8
- zeitwerk (~> 2.5)
9
-
10
1
  GEM
11
2
  remote: https://rubygems.org/
12
3
  specs:
@@ -54,6 +45,7 @@ GEM
54
45
  zeitwerk (2.5.4)
55
46
 
56
47
  PLATFORMS
48
+ x86_64-darwin-21
57
49
  x86_64-linux
58
50
 
59
51
  DEPENDENCIES
@@ -63,7 +55,6 @@ DEPENDENCIES
63
55
  rspec (~> 3.12)
64
56
  rubocop-ast
65
57
  ruby-lsp (~> 0.3.7)
66
- trains!
67
58
  zeitwerk (~> 2.5)
68
59
 
69
60
  BUNDLED WITH
data/README.md CHANGED
@@ -2,6 +2,21 @@
2
2
 
3
3
  A gem that statically analyses your Rails app and extracts information about its structure.
4
4
 
5
+ [![DeepSource](https://deepsource.io/gh/faraazahmad/trains.svg/?label=active+issues&show_trend=true&token=RKfXNZL_RQe6j2NEhXv2iOeh)](https://deepsource.io/gh/faraazahmad/trains/?ref=repository-badge)
6
+ [![DeepSource](https://deepsource.io/gh/faraazahmad/trains.svg/?label=resolved+issues&show_trend=true&token=RKfXNZL_RQe6j2NEhXv2iOeh)](https://deepsource.io/gh/faraazahmad/trains/?ref=repository-badge)
7
+
8
+ ## Index
9
+
10
+ 1. [Installation](#installation)
11
+ 2. [Usage](#usage)
12
+ 3. [Features](#features)
13
+ 1. [Create Model definitions from migrations](#create-model-definitions-from-migrations)
14
+ 2. [Create controller definitions from files](#create-controller-definitions-from-files)
15
+ 4. [Development](#development)
16
+ 5. [Contributing](#contributing)
17
+ 6. [License](#license)
18
+ 7. [Code of conduct](#code-of-conduct)
19
+
5
20
  ## Installation
6
21
 
7
22
  Install the gem and add it to the application's Gemfile by executing:
data/Rakefile CHANGED
@@ -5,8 +5,4 @@ require "rspec/core/rake_task"
5
5
 
6
6
  RSpec::Core::RakeTask.new(:spec)
7
7
 
8
- require "rubocop/rake_task"
9
-
10
- RuboCop::RakeTask.new
11
-
12
- task default: %i[spec rubocop]
8
+ task default: %i[spec]
@@ -1,13 +1,6 @@
1
1
  module Trains
2
2
  module DTO
3
- App = Struct.new(
4
- 'App',
5
- :name,
6
- :controllers,
7
- :models,
8
- :migrations,
9
- :helpers,
10
- keyword_init: true
11
- )
3
+ App =
4
+ Data.define(:name, :controllers, :models, :migrations, :helpers, :routes)
12
5
  end
13
6
  end
@@ -1,7 +1,7 @@
1
- require 'set'
1
+ require "set"
2
2
 
3
3
  module Trains
4
4
  module DTO
5
- Controller = Struct.new('Controller', :name, :method_list, keyword_init: true)
5
+ Controller = Data.define(:name, :method_list)
6
6
  end
7
7
  end
@@ -1,5 +1,5 @@
1
1
  module Trains
2
2
  module DTO
3
- Field = Struct.new(:name, :type)
3
+ Field = Data.define(:name, :type)
4
4
  end
5
5
  end
@@ -1,5 +1,5 @@
1
1
  module Trains
2
2
  module DTO
3
- Method = Struct.new('Method', :name, :source, :visibility, keyword_init: true)
3
+ Method = Data.define(:name)
4
4
  end
5
5
  end
@@ -1,5 +1,5 @@
1
1
  module Trains
2
2
  module DTO
3
- Model = Struct.new(:name, :fields, :version)
3
+ Model = Data.define(:name, :fields, :version)
4
4
  end
5
5
  end
@@ -0,0 +1,5 @@
1
+ module Trains
2
+ module DTO
3
+ Route = Data.define(:method, :param, :options)
4
+ end
5
+ end
@@ -3,21 +3,17 @@ module Trains
3
3
  class Scanner
4
4
  include Utils
5
5
 
6
- attr_accessor :models, :controllers, :helpers, :migrations
7
-
8
- def initialize(folder)
6
+ def initialize(folder, options = {})
9
7
  @root_folder = folder
10
8
  @nodes = []
11
9
  @models = []
12
10
  @controllers = []
13
11
  @helpers = []
14
- @dir = Dir.new(File.expand_path(folder))
15
- Dir.chdir @dir
12
+ @dir = File.expand_path(folder)
13
+ @options = options
16
14
  end
17
15
 
18
16
  def scan
19
- # @nodes = get_tree(@dir)
20
-
21
17
  # Check if @folder is a Rails directory before beginning analysis
22
18
  rails_dir_result = RailsDir.check @dir
23
19
  case rails_dir_result
@@ -27,15 +23,17 @@ module Trains
27
23
  return(
28
24
  Result.new(
29
25
  data: nil,
30
- error: ArgumentError.new('Not a Rails directory')
26
+ error: ArgumentError.new("Not a Rails directory")
31
27
  )
32
28
  )
33
29
  end
34
30
 
35
- @migrations = Set[*get_migrations]
36
- @controllers = Set[*get_controllers]
37
- # @helpers = get_helpers
38
- # @models = get_models
31
+ @models = get_models.to_set unless @options[:models] == false
32
+ @migrations = get_migrations.to_set unless @options[:migrations] == false
33
+ @controllers = get_controllers.to_set unless @options[:controllers] ==
34
+ false
35
+ @routes = get_routes.to_set unless @options[:routes] == false
36
+ # TODO: @helpers = get_helpers
39
37
 
40
38
  # Create instance of Trains::DTO::App
41
39
  DTO::App.new(
@@ -43,51 +41,61 @@ module Trains
43
41
  controllers: @controllers,
44
42
  models: @models,
45
43
  migrations: @migrations,
46
- helpers: @helpers
44
+ helpers: @helpers,
45
+ routes: @routes
47
46
  )
48
47
  end
49
48
 
50
- # Build central ASTStore
51
- def build_ast_store
52
- all_files = Dir.glob(File.join(@root_folder, '**', '*.rb'))
53
- Parallel.each(all_files) do |file_path|
54
- ASTStore.instance.set(
55
- file_path,
56
- RuboCop::AST::ProcessedSource.from_file(file_path, RUBY_VERSION.to_f)
57
- )
58
- end
49
+ private
50
+
51
+ def get_routes
52
+ route_file = [File.join(@dir, "config", "routes.rb")]
53
+
54
+ routes_results = parse_util(route_file, Visitor::Route)
55
+ routes_results
56
+ .select { |result| result.error.nil? }
57
+ .map { |result| result.data }
58
+ .flatten
59
59
  end
60
60
 
61
- def get_models; end
61
+ def get_models
62
+ schema_file = [File.join(@dir, "db", "schema.rb")]
63
+ return unless File.exist?(schema_file.first)
62
64
 
63
- def get_helpers
64
- app_folder = @nodes[:children].find { |node| node[:path].include? 'app' }
65
- helpers_folder =
66
- app_folder[:children].find { |node| node[:path].include? 'app/helpers' }
67
- helpers =
68
- helpers_folder[:children].filter do |node|
69
- node[:path].end_with? '_helper.rb'
70
- end
65
+ models_results = parse_util(schema_file, Visitor::Schema)
66
+ models_results
67
+ .select { |result| result.error.nil? }
68
+ .map { |result| result.data }
69
+ .flatten
70
+ end
71
71
 
72
- @helpers = parse_util(helpers, Visitor::Helper)
72
+ def get_helpers
73
73
  end
74
74
 
75
- def get_gemfile; end
75
+ def get_gemfile
76
+ end
76
77
 
77
78
  def get_controllers
78
79
  controllers =
79
- Dir.glob(File.join(@dir, 'app', 'controllers', '**', '*_controller.rb'))
80
+ Dir.glob(File.join(@dir, "app", "controllers", "**", "*_controller.rb"))
80
81
 
81
- parse_util(controllers, Visitor::Controller)
82
+ controller_results = parse_util(controllers, Visitor::Controller)
83
+ controller_results
84
+ .select { |result| result.error.nil? }
85
+ .map { |result| result.data }
86
+ .flatten
82
87
  end
83
88
 
84
89
  def get_migrations
85
- migrations = Dir.glob(File.join(@dir, 'db', 'migrate', '**', '*.rb'))
90
+ migrations = Dir.glob(File.join(@dir, "db", "migrate", "**", "*.rb"))
86
91
 
87
- parse_util(migrations, Visitor::Migration)
92
+ migration_results = parse_util(migrations, Visitor::Migration)
93
+ migration_results
94
+ .select { |result| result.error.nil? }
95
+ .map { |result| result.data }
88
96
  end
89
97
 
90
- def parse_util(file_nodes, klass)
98
+ def parse_util(file_nodes, visitor_class)
91
99
  unless file_nodes.class.include? Enumerable
92
100
  return(
93
101
  Result.new(
@@ -100,27 +108,30 @@ module Trains
100
108
  )
101
109
  end
102
110
 
103
- begin
104
- Parallel.map(file_nodes) do |node|
111
+ Parallel.map(file_nodes) do |node|
112
+ begin
105
113
  processed_source =
106
114
  RuboCop::AST::ProcessedSource.from_file(node, RUBY_VERSION.to_f)
107
- visitor = klass.new
115
+ visitor = visitor_class.new
108
116
  visitor.process(processed_source.ast)
109
- visitor.result
117
+
118
+ Result.new(data: visitor.result, error: nil)
119
+ rescue StandardError => e
120
+ puts "An error occurred while parsing #{node}. Use debug option to view backtrace. Skipping file..."
121
+ puts e.backtrace if @options[:debug]
122
+
123
+ Result.new(data: nil, error: e)
110
124
  end
111
- rescue StandardError => e
112
- puts e.backtrace
113
- Result.new(data: nil, error: e)
114
125
  end
115
126
  end
116
127
 
117
- def get_tree(node, prefix = '')
128
+ def get_tree(node, prefix = "")
118
129
  path = File.join(prefix, node)
119
130
  obj = { path: nil }
120
131
 
121
132
  # puts "DEBUG: #{path} #{ FastIgnore.new.allowed? path }"
122
133
  if path != @dir.to_path &&
123
- FastIgnore.new.allowed?(path, directory: false) == false
134
+ FastIgnore.new.allowed?(path, directory: false) == false
124
135
  return nil
125
136
  end
126
137
 
@@ -3,9 +3,9 @@ module Trains
3
3
  class RailsDir
4
4
  # checks if supplied dir is in a Rails app dir
5
5
  def self.check(root_path)
6
- rails_bin = File.join(root_path, 'bin', 'rails')
6
+ rails_bin = File.join(root_path, "bin", "rails")
7
7
 
8
- Result.new(File.exist?(rails_bin), nil)
8
+ Result.new(data: File.exist?(rails_bin), error: nil)
9
9
  end
10
10
  end
11
11
  end
@@ -1,5 +1,5 @@
1
1
  module Trains
2
2
  module Utils
3
- Result = Struct.new('Result', :data, :error)
3
+ Result = Struct.new("Result", :data, :error, keyword_init: true)
4
4
  end
5
5
  end
@@ -1,3 +1,3 @@
1
1
  module Trains
2
- VERSION = '0.0.2'
2
+ VERSION = '0.0.4'
3
3
  end
@@ -1,5 +1,5 @@
1
- require_relative '../dto/controller'
2
- require_relative '../dto/method'
1
+ require_relative "../dto/controller"
2
+ require_relative "../dto/method"
3
3
 
4
4
  module Trains
5
5
  module Visitor
@@ -12,31 +12,33 @@ module Trains
12
12
  end
13
13
 
14
14
  def on_class(node)
15
- class_name = node.identifier.const_name
16
- parent_class = node.parent_class.const_name.to_sym
17
-
18
- is_controller =
19
- if parent_class.nil?
20
- true if class_name == :ApplicationController
21
- else
22
- parent_class == :"ActionController::Base"
23
- end
24
- return unless is_controller
15
+ class_name = node.identifier.const_name.to_s
16
+ parent_class = node.parent_class.const_name.to_s
17
+ return unless controller?(parent_class)
25
18
 
26
19
  @class_name = class_name
27
- end
28
-
29
- # List out all controller methods
30
- def on_def(node)
31
- method_name = node.method_name
32
- @method_list.append(
33
- DTO::Method.new(name: method_name.to_s, visibility: nil, source: nil)
34
- )
20
+ parse_body(node.body) unless node.body.nil?
35
21
  end
36
22
 
37
23
  def result
38
24
  DTO::Controller.new(name: @class_name, method_list: @method_list.uniq)
39
25
  end
26
+
27
+ private
28
+
29
+ def parse_body(body)
30
+ body.each_child_node do |child|
31
+ @method_list << parse_method(child) if child.type == :def
32
+ end
33
+ end
34
+
35
+ def controller?(parent_class)
36
+ %w[ActionController::Base ApplicationController].include? parent_class
37
+ end
38
+
39
+ def parse_method(node)
40
+ DTO::Method.new(name: node.method_name.to_s)
41
+ end
40
42
  end
41
43
  end
42
44
  end
@@ -1,10 +1,10 @@
1
- require 'yaml'
1
+ require "yaml"
2
2
 
3
3
  module Trains
4
4
  module Visitor
5
5
  # Visitor that parses DB migration and associates them with Rails models
6
6
  class Migration < Base
7
- def_node_matcher :send_node?, '(send nil? ...)'
7
+ def_node_matcher :send_node?, "(send nil? ...)"
8
8
  attr_reader :is_migration, :model
9
9
 
10
10
  def initialize
@@ -19,7 +19,7 @@ module Trains
19
19
  end
20
20
 
21
21
  def on_class(node)
22
- unless node.parent_class.source.include? 'ActiveRecord::Migration'
22
+ unless node.parent_class.source.include? "ActiveRecord::Migration"
23
23
  return
24
24
  end
25
25
 
@@ -29,6 +29,12 @@ module Trains
29
29
  process_node(node.body)
30
30
  end
31
31
 
32
+ def result
33
+ DTO::Model.new(@table_name, @fields, @migration_version)
34
+ end
35
+
36
+ private
37
+
32
38
  def extract_version(class_const)
33
39
  match = class_const.match(/\d+.\d+/)
34
40
  return nil if match.nil?
@@ -37,44 +43,62 @@ module Trains
37
43
  end
38
44
 
39
45
  def process_node(node)
40
- process_def_node(node) if node.def_type?
46
+ return unless node.def_type?
47
+
48
+ process_def_node(node)
41
49
  end
42
50
 
43
51
  def process_def_node(node)
44
52
  allowed_method_names = %i[change up down]
45
- allowed_table_modifiers = %i[create_table update_column]
53
+ allowed_table_modifiers = %i[create_table update_column add_column]
54
+ block_type_modifier = false
46
55
 
47
56
  method_name = node.method_name
48
57
  return unless allowed_method_names.include? method_name
49
58
 
50
- table_modifier = node.body.children[0].method_name
59
+ table_modifier =
60
+ if node.body.children[0] == nil
61
+ block_type_modifier = false
62
+ # if table modifier is a one-liner method call
63
+ node.body.children[1]
64
+ elsif node.body.children[0].block_type?
65
+ block_type_modifier = true
66
+ # if table modifier is in a block
67
+ node.body.children[0].method_name
68
+ end
51
69
  return unless allowed_table_modifiers.include? table_modifier
52
70
 
53
- raw_table_name = node.body.children[0].children[0].children[2].value.to_s
54
- @table_name = raw_table_name.singularize.camelize
71
+ # Get the name of the table being modified
72
+ if block_type_modifier
73
+ raw_table_name =
74
+ node.body.children[0].children[0].children[2].value.to_s
75
+ @table_name = raw_table_name.singularize.camelize
55
76
 
56
- node.body.children[0].children[2].each_child_node do |child|
57
- process_migration_field(child)
77
+ node.body.children[0].children[2].each_child_node do |child|
78
+ process_migration_field(child)
79
+ end
80
+ else
81
+ raw_table_name = node.body.children[2].value.to_s
82
+ @table_name = raw_table_name.singularize.camelize
83
+
84
+ field_name = node.body.children[3].value
85
+ field_type = node.body.children[4].value
86
+ @fields.append(DTO::Field.new(field_name, field_type))
58
87
  end
59
88
  end
60
89
 
61
90
  def process_migration_field(node)
62
91
  return unless node.send_type?
63
92
 
64
- if node.children.count < 3
65
- if node.children[1] == :timestamps
66
- @fields.append(DTO::Field.new(:created_at, :datetime))
67
- @fields.append(DTO::Field.new(:updated_at, :datetime))
68
- end
69
- elsif node.children.count >= 3
70
- type = node.children[1]
71
- value = node.children[2].value
72
- @fields.append(DTO::Field.new(value, type))
93
+ if node.children[1] == :timestamps
94
+ @fields.append(DTO::Field.new(:created_at, :datetime))
95
+ @fields.append(DTO::Field.new(:updated_at, :datetime))
96
+ return
73
97
  end
74
- end
75
-
76
- def result
77
- DTO::Model.new(@table_name, @fields, @migration_version)
98
+
99
+ type = node.children[1]
100
+ value = node.children[2].value unless node.children[2].hash_type?
101
+ @fields.append(DTO::Field.new(value, type))
78
102
  end
79
103
  end
80
104
  end
@@ -0,0 +1,78 @@
1
+ require_relative "../dto/route"
2
+
3
+ module Trains
4
+ module Visitor
5
+ class Route < Base
6
+ def_node_matcher :route_parent?, <<~PATTERN
7
+ (block (send (send (send
8
+ (const nil? :Rails) :application) :routes) :draw)
9
+ ...)
10
+ PATTERN
11
+
12
+ def_node_matcher :route_method?, <<~PATTERN
13
+ (send nil? %1 ...)
14
+ PATTERN
15
+
16
+ ALLOWED_VERBS = %i[get put post update delete resources scope]
17
+
18
+ def initialize
19
+ @route_list = []
20
+ end
21
+
22
+ def result
23
+ @route_list
24
+ end
25
+
26
+ def on_block(node)
27
+ return unless route_parent?(node)
28
+
29
+ node.body.each_child_node do |child|
30
+ ALLOWED_VERBS.each do |verb|
31
+ if route_method?(child, verb)
32
+ @route_list << parse_route(child, verb)
33
+ end
34
+ end
35
+ end
36
+ end
37
+
38
+ private
39
+
40
+ def parse_route(node, verb)
41
+ method = verb
42
+ param =
43
+ case node.arguments[0].type
44
+ when :sym, :str
45
+ node.arguments[0].value
46
+ end
47
+ options = parse_hash(node.arguments[1])
48
+ DTO::Route.new(method: method, param: param, options: options)
49
+ end
50
+
51
+ def parse_hash(node)
52
+ options = {}
53
+ return options unless node.type == :hash
54
+
55
+ node.each_pair { |key, value| options[key.value] = parse_value(value) }
56
+ rescue StandardError => e
57
+ puts node.parent
58
+ ensure
59
+ return options
60
+ end
61
+
62
+ def parse_value(node)
63
+ case node.type
64
+ when :hash
65
+ parse_hash(node)
66
+ when :array
67
+ node.values.map { |value| parse_value(value) }
68
+ when :send
69
+ if node.method_name == :redirect
70
+ { redirect: node.arguments.first.value }
71
+ end
72
+ else
73
+ node.value
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,88 @@
1
+ module Trains
2
+ module Visitor
3
+ # Visitor that parses DB migration and associates them with Rails models
4
+ class Schema < Base
5
+ def_node_matcher :versioned_schema?, <<~PATTERN
6
+ (block
7
+ (send (send (const (const nil? :ActiveRecord) :Schema) :[] (float ...)) :define ...)
8
+ ...)
9
+ PATTERN
10
+
11
+ def_node_matcher :unversioned_schema?, <<~PATTERN
12
+ (block
13
+ (send (const (const nil? :ActiveRecord) :Schema) :define ...)
14
+ ...)
15
+ PATTERN
16
+
17
+ def initialize
18
+ @models = []
19
+ @columns = []
20
+ @is_versioned = false
21
+ end
22
+
23
+ def on_block(node)
24
+ is_schema = versioned_schema?(node) || unversioned_schema?(node)
25
+ return unless is_schema
26
+
27
+ process_schema_body(node)
28
+ end
29
+
30
+ def result
31
+ @models
32
+ end
33
+
34
+ private
35
+
36
+ def each_table(ast)
37
+ case ast.body.type
38
+ when :begin
39
+ ast.body.children.each do |node|
40
+ next unless node.block_type? && node.method?(:create_table)
41
+
42
+ yield(node)
43
+ end
44
+ else
45
+ yield ast.body
46
+ end
47
+ end
48
+
49
+ def each_content(node, &block)
50
+ return enum_for(__method__, node) unless block
51
+
52
+ case node.body&.type
53
+ when :begin
54
+ node.body.children.each(&block)
55
+ else
56
+ yield(node.body)
57
+ end
58
+ end
59
+
60
+ def build_columns(node)
61
+ each_content(node)
62
+ .map do |child|
63
+ next unless child&.send_type?
64
+ next if child.method?(:index)
65
+
66
+ DTO::Field.new(
67
+ name: child.first_argument.str_content,
68
+ type: child.method_name
69
+ )
70
+ end
71
+ .compact
72
+ end
73
+
74
+ def process_schema_body(node)
75
+ each_table(node) do |table|
76
+ @table_name = table.send_node.first_argument.value
77
+ @columns = build_columns(table)
78
+
79
+ @models << DTO::Model.new(
80
+ name: @table_name.singularize.camelize,
81
+ fields: @columns,
82
+ version: nil
83
+ )
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
data/trains.gemspec ADDED
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lib/trains/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'trains'
7
+ spec.version = Trains::VERSION
8
+ spec.authors = ['Syed Faraaz Ahmad']
9
+ spec.email = ['faraaz98@live.com']
10
+
11
+ spec.summary =
12
+ 'Collect metadata about your Rails app by statically analyzing it'
13
+ spec.homepage = 'https://github.com/faraazahmad/trains'
14
+ spec.license = 'MIT'
15
+ spec.required_ruby_version = '>= 2.6.0'
16
+
17
+ spec.metadata['homepage_uri'] = spec.homepage
18
+ spec.metadata['source_code_uri'] = spec.homepage
19
+ spec.metadata['changelog_uri'] = "https://github.com/faraazahmad/trains/blob/master/CHANGELOG.md"
20
+
21
+ # Specify which files should be added to the gem when it is released.
22
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
23
+ spec.files =
24
+ Dir.chdir(__dir__) do
25
+ `git ls-files -z`.split("\x0")
26
+ .reject do |f|
27
+ (f == __FILE__) ||
28
+ f.match(
29
+ %r{\A(?:(?:bin|test|spec|features)/|\.(?:git|travis|circleci)|appveyor)}
30
+ )
31
+ end
32
+ end
33
+ spec.require_paths = ['lib']
34
+
35
+ spec.add_dependency 'activesupport', '~> 7.0'
36
+ spec.add_dependency 'parallel', '~> 1.22'
37
+ spec.add_dependency 'rubocop-ast', '~> 1.16'
38
+ spec.add_dependency 'zeitwerk', '~> 2.5'
39
+ spec.metadata['rubygems_mfa_required'] = 'true'
40
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: trains
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Syed Faraaz Ahmad
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-02-19 00:00:00.000000000 Z
11
+ date: 2023-04-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -76,7 +76,6 @@ files:
76
76
  - ".deepsource.toml"
77
77
  - ".rspec"
78
78
  - ".rubocop.yml"
79
- - ".ruby-version"
80
79
  - CHANGELOG.md
81
80
  - CODE_OF_CONDUCT.md
82
81
  - Gemfile
@@ -90,8 +89,8 @@ files:
90
89
  - lib/trains/dto/field.rb
91
90
  - lib/trains/dto/method.rb
92
91
  - lib/trains/dto/model.rb
92
+ - lib/trains/dto/route.rb
93
93
  - lib/trains/scanner.rb
94
- - lib/trains/utils/ast_store.rb
95
94
  - lib/trains/utils/logger.rb
96
95
  - lib/trains/utils/rails_dir.rb
97
96
  - lib/trains/utils/result.rb
@@ -100,6 +99,9 @@ files:
100
99
  - lib/trains/visitor/controller.rb
101
100
  - lib/trains/visitor/helper.rb
102
101
  - lib/trains/visitor/migration.rb
102
+ - lib/trains/visitor/route.rb
103
+ - lib/trains/visitor/schema.rb
104
+ - trains.gemspec
103
105
  homepage: https://github.com/faraazahmad/trains
104
106
  licenses:
105
107
  - MIT
@@ -107,6 +109,7 @@ metadata:
107
109
  homepage_uri: https://github.com/faraazahmad/trains
108
110
  source_code_uri: https://github.com/faraazahmad/trains
109
111
  changelog_uri: https://github.com/faraazahmad/trains/blob/master/CHANGELOG.md
112
+ rubygems_mfa_required: 'true'
110
113
  post_install_message:
111
114
  rdoc_options: []
112
115
  require_paths:
data/.ruby-version DELETED
@@ -1 +0,0 @@
1
- 3.0.0
@@ -1,25 +0,0 @@
1
- require 'singleton'
2
-
3
- module Trains
4
- module Utils
5
- class ASTStore
6
- include Singleton
7
-
8
- def initialize
9
- @store = {}
10
- end
11
-
12
- def set(file_path, ast_object)
13
- @store[file_path] = ast_object
14
- end
15
-
16
- def get(file_path)
17
- unless @store.key? file_path
18
- set(file_path,
19
- RuboCop::AST::ProcessedSource.from_file(file_path, RUBY_VERSION.to_f))
20
- end
21
- @store[file_path]
22
- end
23
- end
24
- end
25
- end