code0-zero_track 0.0.1 → 0.0.2

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: 528e1dc7d30d7cc16b1507b9649429a03196747fe18b27086c23cbdfe9b85147
4
- data.tar.gz: ff9eae6c20639f631b0fce5b3de912a73d76bb1f0e77a7e16b32fac2d645cbbc
3
+ metadata.gz: 6d7131b86c5135e76e99a0b4edb22b76c5fdcc765ef7d00160ce6e85dc8f3ea4
4
+ data.tar.gz: ab601c8af299d5679e16a57748977b0762a71aab0802470acb2a43873109c892
5
5
  SHA512:
6
- metadata.gz: 7ee327ee87f60a1d8865d6abb3b1dc322a28bdc57b7a6d31f06a7d1af17425ed8e7d6af4178417d8db5ad9e84cd6794ae4a2612c1ebd65dfb4968f7b3d1e1e35
7
- data.tar.gz: eb42c512f19919608444053fb33be11229e7968a1e6bb231b82ec9415d528baabe83051d41ba5a0335afbc0a2ec6b428c4dd420c29a03d4afcf812667b34cad0
6
+ metadata.gz: 18fb171af0b27a2d1cf48a690a3d4529ad8daa95bb4d192e2ac6c0a7a5a2c501b922fa5ce48effee6ebced6ec545522b8ef9008587fd6b24d1115b21628ffd16
7
+ data.tar.gz: 5c6e8f01a01d2427aa75265260ea603eb902480e29b4342fa8c6d6ff9e7103da7c3a2be93d4b5b0ee739248de50e4c83d848c1701c8232e5d267e132b39da8a4
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Code0
4
4
  module ZeroTrack
5
- VERSION = '0.0.1'
5
+ VERSION = '0.0.2'
6
6
  end
7
7
  end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Code0
5
+ module ZeroTrack
6
+ module FileHelpers
7
+ def dirname(node)
8
+ File.dirname(filepath(node))
9
+ end
10
+
11
+ def basename(node)
12
+ File.basename(filepath(node))
13
+ end
14
+
15
+ def filepath(node)
16
+ node.location.expression.source_buffer.name
17
+ end
18
+
19
+ def in_migration?(node)
20
+ dirname(node).end_with?('db/migrate')
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Code0
6
+ module ZeroTrack
7
+ module Logs
8
+ # Cop that checks if 'timestamps' method is called with timezone information.
9
+ class RailsLogger < RuboCop::Cop::Base
10
+ MSG = 'Do not use `Rails.logger` directly, include `Code0::ZeroTrack::Loggable` instead'
11
+ LOG_METHODS = %i[debug error fatal info warn].freeze
12
+ LOG_METHODS_PATTERN = LOG_METHODS.map(&:inspect).join(' ').freeze
13
+
14
+ def_node_matcher :rails_logger_log?, <<~PATTERN
15
+ (send
16
+ (send (const nil? :Rails) :logger)
17
+ {#{LOG_METHODS_PATTERN}} ...
18
+ )
19
+ PATTERN
20
+
21
+ def on_send(node)
22
+ return unless rails_logger_log?(node)
23
+
24
+ add_offense(node)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../../../code0/zero_track/file_helpers'
4
+
5
+ module RuboCop
6
+ module Cop
7
+ module Code0
8
+ module ZeroTrack
9
+ module Migration
10
+ class CreateTableWithTimestamps < RuboCop::Cop::Base
11
+ include RuboCop::Code0::ZeroTrack::FileHelpers
12
+
13
+ MSG = 'Add timestamps when creating a new table.'
14
+ RESTRICT_ON_SEND = %i[create_table].freeze
15
+
16
+ def_node_matcher :create_table_with_timestamps_proc?, <<~PATTERN
17
+ (send nil? :create_table (sym _) ... (block-pass (sym :timestamps_with_timezone)))
18
+ PATTERN
19
+
20
+ def_node_search :timestamps_included?, <<~PATTERN
21
+ (send _var :timestamps_with_timezone ...)
22
+ PATTERN
23
+
24
+ def_node_search :created_at_included?, <<~PATTERN
25
+ (send _var :datetime_with_timezone
26
+ {(sym :created_at)(str "created_at")}
27
+ ...)
28
+ PATTERN
29
+
30
+ def_node_search :updated_at_included?, <<~PATTERN
31
+ (send _var :datetime_with_timezone
32
+ {(sym :updated_at)(str "updated_at")}
33
+ ...)
34
+ PATTERN
35
+
36
+ def_node_matcher :create_table_with_block?, <<~PATTERN
37
+ (block
38
+ (send nil? :create_table ...)
39
+ (args (arg _var)+)
40
+ _)
41
+ PATTERN
42
+
43
+ def on_send(node)
44
+ return unless in_migration?(node)
45
+ return unless node.command?(:create_table)
46
+
47
+ parent = node.parent
48
+
49
+ if create_table_with_block?(parent)
50
+ add_offense(parent) if parent.body.nil? || !time_columns_included?(parent.body)
51
+ elsif create_table_with_timestamps_proc?(node)
52
+ # nothing to do
53
+ else
54
+ add_offense(node)
55
+ end
56
+ end
57
+
58
+ private
59
+
60
+ def time_columns_included?(node)
61
+ timestamps_included?(node) || created_at_and_updated_at_included?(node)
62
+ end
63
+
64
+ def created_at_and_updated_at_included?(node)
65
+ created_at_included?(node) && updated_at_included?(node)
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../../../code0/zero_track/file_helpers'
4
+
5
+ module RuboCop
6
+ module Cop
7
+ module Code0
8
+ module ZeroTrack
9
+ module Migration
10
+ # Cop that checks if datetime data type is added with timezone information.
11
+ class Datetime < RuboCop::Cop::Base
12
+ include RuboCop::Code0::ZeroTrack::FileHelpers
13
+ extend AutoCorrector
14
+
15
+ MSG = 'Do not use the `%s` data type, use `datetime_with_timezone` instead'
16
+
17
+ # Check methods in table creation.
18
+ def on_def(node)
19
+ return unless in_migration?(node)
20
+
21
+ node.each_descendant(:send) do |send_node|
22
+ method_name = send_node.children[1]
23
+
24
+ next unless %i[datetime timestamp].include?(method_name)
25
+
26
+ add_offense(send_node.loc.selector, message: format(MSG, method_name)) do |corrector|
27
+ corrector.replace(send_node.loc.selector, 'datetime_with_timezone')
28
+ end
29
+ end
30
+ end
31
+
32
+ # Check methods.
33
+ def on_send(node)
34
+ return unless in_migration?(node)
35
+
36
+ node.each_descendant do |descendant|
37
+ next unless descendant.type == :sym
38
+
39
+ last_argument = descendant.children.last
40
+
41
+ next unless %i[datetime timestamp].include?(last_argument)
42
+
43
+ add_offense(descendant, message: format(MSG, last_argument)) do |corrector|
44
+ corrector.replace(descendant, ':datetime_with_timezone')
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../../../code0/zero_track/file_helpers'
4
+
5
+ module RuboCop
6
+ module Cop
7
+ module Code0
8
+ module ZeroTrack
9
+ module Migration
10
+ # Cop that checks if 'timestamps' method is called with timezone information.
11
+ class Timestamps < RuboCop::Cop::Base
12
+ include RuboCop::Code0::ZeroTrack::FileHelpers
13
+ extend AutoCorrector
14
+
15
+ MSG = 'Do not use `timestamps`, use `timestamps_with_timezone` instead'
16
+
17
+ # Check methods in table creation.
18
+ def on_def(node)
19
+ return unless in_migration?(node)
20
+
21
+ node.each_descendant(:send) do |send_node|
22
+ next unless method_name(send_node) == :timestamps
23
+
24
+ add_offense(send_node.loc.selector) do |corrector|
25
+ corrector.replace(send_node.loc.selector, 'timestamps_with_timezone')
26
+ end
27
+ end
28
+ end
29
+
30
+ def method_name(node)
31
+ node.children[1]
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,93 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../../../code0/zero_track/file_helpers'
4
+
5
+ module RuboCop
6
+ module Cop
7
+ module Code0
8
+ module ZeroTrack
9
+ module Migration
10
+ class VersionedClass < RuboCop::Cop::Base
11
+ include RuboCop::Code0::ZeroTrack::FileHelpers
12
+ extend AutoCorrector
13
+
14
+ MIGRATION_CLASS = 'Code0::ZeroTrack::Database::Migration'
15
+
16
+ # rubocop:disable Layout/LineLength
17
+ MSG_WRONG_BASE_CLASS = "Don't use `%<base_class>s`. Use `#{MIGRATION_CLASS}` instead.".freeze
18
+ MSG_WRONG_VERSION = "Don't use version `%<current_version>s` of `#{MIGRATION_CLASS}`. Use version `%<allowed_version>s` instead.".freeze
19
+ # rubocop:enable Layout/LineLength
20
+
21
+ def on_class(node)
22
+ return unless in_migration?(node)
23
+
24
+ return on_zerotrack_migration(node) if zerotrack_migration?(node)
25
+
26
+ add_offense(
27
+ node.parent_class,
28
+ message: format(MSG_WRONG_BASE_CLASS, base_class: superclass(node))
29
+ ) do |corrector|
30
+ corrector.replace(node.parent_class, "#{MIGRATION_CLASS}[#{find_allowed_versions(node).last}]")
31
+ end
32
+ end
33
+
34
+ private
35
+
36
+ def on_zerotrack_migration(node)
37
+ return if cop_config['AllowedVersions'].nil? # allow all versions if nothing configured
38
+ return if correct_migration_version?(node)
39
+
40
+ current_version = get_migration_version(node)
41
+ allowed_version = find_allowed_versions(node).last
42
+
43
+ version_node = get_migration_version_node(node)
44
+
45
+ add_offense(
46
+ version_node,
47
+ message: format(MSG_WRONG_VERSION, current_version: current_version, allowed_version: allowed_version)
48
+ ) do |corrector|
49
+ corrector.replace(version_node, find_allowed_versions(node).last.to_s)
50
+ end
51
+ end
52
+
53
+ def zerotrack_migration?(node)
54
+ superclass(node) == MIGRATION_CLASS
55
+ end
56
+
57
+ def superclass(class_node)
58
+ _, *others = class_node.descendants
59
+
60
+ others.find { |node| node.const_type? && node.const_name != 'Types' }&.const_name
61
+ end
62
+
63
+ def correct_migration_version?(node)
64
+ find_allowed_versions(node).include?(get_migration_version(node))
65
+ end
66
+
67
+ def get_migration_version_node(node)
68
+ node.parent_class.arguments[0]
69
+ end
70
+
71
+ def get_migration_version(node)
72
+ get_migration_version_node(node).value
73
+ end
74
+
75
+ def find_allowed_versions(node)
76
+ migration_version = basename(node).split('_').first.to_i
77
+ allowed_versions.select do |range, _|
78
+ range.include?(migration_version)
79
+ end.values
80
+ end
81
+
82
+ def allowed_versions
83
+ cop_config['AllowedVersions'].transform_keys do |range|
84
+ range_ints = range.split('..').map(&:to_i)
85
+ range_ints[0]..range_ints[1]
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rubocop:disable Lint/RedundantDirGlobSort
4
+ Dir[File.join(__dir__, 'cop', '**', '*.rb')].sort.each { |file| require file }
5
+ # rubocop:enable Lint/RedundantDirGlobSort
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: code0-zero_track
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Niklas van Schrick
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-02-22 00:00:00.000000000 Z
11
+ date: 2025-02-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -181,6 +181,13 @@ files:
181
181
  - lib/code0/zero_track/memoize.rb
182
182
  - lib/code0/zero_track/railtie.rb
183
183
  - lib/code0/zero_track/version.rb
184
+ - lib/rubocop/code0/zero_track/file_helpers.rb
185
+ - lib/rubocop/cop/code0/zero_track/logs/rails_logger.rb
186
+ - lib/rubocop/cop/code0/zero_track/migration/create_table_with_timestamps.rb
187
+ - lib/rubocop/cop/code0/zero_track/migration/datetime.rb
188
+ - lib/rubocop/cop/code0/zero_track/migration/timestamps.rb
189
+ - lib/rubocop/cop/code0/zero_track/migration/versioned_class.rb
190
+ - lib/rubocop/zero_track.rb
184
191
  - lib/tasks/code0/zero_track_tasks.rake
185
192
  homepage: https://github.com/code0-tech/code0-zero_track
186
193
  licenses: