trains 0.0.2 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
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