rubocop-teamtailor 0.3.0 → 0.3.3

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: a3415d0a918da6562c673c1113f17a517e8841834a7005efddd48931d2b7245d
4
- data.tar.gz: c3cd2927bc900eef6a7e55c6e96ff90087c7473ac2ce22b4ce6091ce3ca55abd
3
+ metadata.gz: 9d239f41ce1d3ccfa7e7ec01e35baa62e512dd550691054debeeea27331bf436
4
+ data.tar.gz: f05c4447fe2b7f8cd44a519a943e6e04a197a56dbb529437fad164cedcb4427a
5
5
  SHA512:
6
- metadata.gz: c3252311d281326157c2e70dce4ddf9cd7677baf442df466e4cde62e26784a632bcc7696fabd9bd279b743f1197f6823a0060af6d3acb9bab422408845a3454a
7
- data.tar.gz: e7b64854a74e7ef40b9fe1e03c8ae9e9f732d55c942b55ad640b29f429cb62c5d4eb2d14237c6595d03f523229b4c0c40a05324edf96710d04967935e24e59ce
6
+ metadata.gz: b8b43714b2124dd37e6e6504701d2a7a894aec05f81da507de4f6cc2ed52147aa7634bb50f25bd922b0c3631a89d907423056dd4949dbc21cc0302e3cdc6365f
7
+ data.tar.gz: 49dbe366e2d8f1d4054e14f113b6a75d94352fc4e26fb24f00326cdba371df651ad41f9a15d1252dc08b1a7d3b502669b9bce7d2c49a5f40c2fba2dbb4b29e49
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 4.0.1
data/config/default.yml CHANGED
@@ -1,5 +1,12 @@
1
1
  # Write it!
2
2
 
3
+ Teamtailor/AlphabeticalSerializerAttributes:
4
+ Description: "Serializer attributes should be in alphabetical order."
5
+ Enabled: true
6
+ Include:
7
+ - "app/serializers/**/*.rb"
8
+ VersionAdded: "<<next>>"
9
+
3
10
  Teamtailor/NoEmbeddingsInActiveModelSerializer:
4
11
  Description: "TODO: Write a description of the cop."
5
12
  Enabled: true
@@ -0,0 +1,112 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Teamtailor
6
+ class AlphabeticalSerializerAttributes < Base
7
+ extend AutoCorrector
8
+
9
+ MSG = "Serializer attributes should be in alphabetical order (symbols first, then hashes)"
10
+ RESTRICT_ON_SEND = %i[attributes serializer_attributes].freeze
11
+
12
+ def on_send(node)
13
+ return unless node.arguments.any?
14
+ return unless in_serializer_class?(node)
15
+
16
+ args = node.arguments
17
+ sorted_args = sort_arguments(args)
18
+ return if args_match?(args, sorted_args)
19
+
20
+ add_offense(node) do |corrector|
21
+ corrector.replace(arguments_range(node), format_arguments(sorted_args, node))
22
+ end
23
+ end
24
+
25
+ private
26
+
27
+ def in_serializer_class?(node)
28
+ node.each_ancestor(:class).any? do |class_node|
29
+ class_node.defined_module_name&.end_with?("Serializer")
30
+ end
31
+ end
32
+
33
+ def sort_arguments(args)
34
+ symbols = []
35
+ splats = []
36
+ others = []
37
+ hash_items = []
38
+
39
+ args.each do |arg|
40
+ if arg.splat_type?
41
+ splats << arg
42
+ elsif arg.sym_type?
43
+ symbols << arg
44
+ elsif arg.pair_type?
45
+ hash_items << arg
46
+ elsif arg.hash_type?
47
+ arg.children.each { |child| hash_items << child }
48
+ else
49
+ others << arg
50
+ end
51
+ end
52
+
53
+ sorted_symbols = symbols.sort_by { |symbol| symbol.value.to_s }
54
+ sorted_pairs = hash_items.select(&:pair_type?).sort_by { |pair| extract_hash_key(pair) }
55
+ sorted_hash_items = hash_items.map do |item|
56
+ item.pair_type? ? sorted_pairs.shift : item
57
+ end
58
+
59
+ splats + others + sorted_symbols + sorted_hash_items
60
+ end
61
+
62
+ def extract_hash_key(pair_node)
63
+ key = pair_node.key
64
+ key.sym_type? ? key.value.to_s : key.source
65
+ end
66
+
67
+ def args_match?(original, sorted)
68
+ original_flat = flatten_args(original)
69
+ original_flat.map(&:source) == sorted.map(&:source)
70
+ end
71
+
72
+ def flatten_args(args)
73
+ args.flat_map do |arg|
74
+ if arg.hash_type?
75
+ arg.children
76
+ else
77
+ arg
78
+ end
79
+ end
80
+ end
81
+
82
+ def arguments_range(node)
83
+ first_arg = node.arguments.first
84
+ last_arg = node.arguments.last
85
+ first_arg.source_range.join(last_arg.source_range)
86
+ end
87
+
88
+ def format_arguments(sorted_args, node)
89
+ return sorted_args.map(&:source).join(", ") if single_line_call?(node)
90
+
91
+ indent = argument_indent(node)
92
+ all_args = sorted_args.dup
93
+ first = all_args.shift
94
+
95
+ lines = [first.source]
96
+ all_args.each { |arg| lines << "#{indent}#{arg.source}" }
97
+
98
+ lines.join(",\n")
99
+ end
100
+
101
+ def single_line_call?(node)
102
+ node.source_range.first_line == node.source_range.last_line
103
+ end
104
+
105
+ def argument_indent(node)
106
+ first_arg = node.arguments.first
107
+ " " * first_arg.source_range.column
108
+ end
109
+ end
110
+ end
111
+ end
112
+ end
@@ -1,3 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "teamtailor/alphabetical_serializer_attributes"
3
4
  require_relative "teamtailor/no_embeddings_in_active_model_serializer"
@@ -2,6 +2,6 @@
2
2
 
3
3
  module RuboCop
4
4
  module Teamtailor
5
- VERSION = "0.3.0"
5
+ VERSION = "0.3.3"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop-teamtailor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonas Brusman
8
- autorequire:
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2025-08-22 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: rubocop
@@ -33,6 +32,7 @@ extra_rdoc_files: []
33
32
  files:
34
33
  - ".rspec"
35
34
  - ".rubocop.yml"
35
+ - ".ruby-version"
36
36
  - ".standard.yml"
37
37
  - ".zed/tasks.json"
38
38
  - CHANGELOG.md
@@ -42,6 +42,7 @@ files:
42
42
  - Rakefile
43
43
  - config/default.yml
44
44
  - lib/rubocop-teamtailor.rb
45
+ - lib/rubocop/cop/teamtailor/alphabetical_serializer_attributes.rb
45
46
  - lib/rubocop/cop/teamtailor/no_embeddings_in_active_model_serializer.rb
46
47
  - lib/rubocop/cop/teamtailor_cops.rb
47
48
  - lib/rubocop/teamtailor.rb
@@ -54,7 +55,6 @@ licenses:
54
55
  metadata:
55
56
  homepage_uri: https://github.com/teamtailor/rubocop-teamtailor
56
57
  source_code_uri: https://github.com/teamtailor/rubocop-teamtailor
57
- post_install_message:
58
58
  rdoc_options: []
59
59
  require_paths:
60
60
  - lib
@@ -69,8 +69,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
69
69
  - !ruby/object:Gem::Version
70
70
  version: '0'
71
71
  requirements: []
72
- rubygems_version: 3.5.22
73
- signing_key:
72
+ rubygems_version: 4.0.7
74
73
  specification_version: 4
75
74
  summary: Teamtailor's RuboCop cops
76
75
  test_files: []