i18n-tasks 1.0.8 → 1.0.9

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: 9d1d2fc604c929450bdf96a547513004630f57a1da7e368020b0313f4e4c67f4
4
- data.tar.gz: 4b1a226b25f08c76d92998bc8cecd37de5e698f2f805da606804b8faa3fc0203
3
+ metadata.gz: 7a1868afde19604950a807791f25669ec0faffda4c510cf80157ba457509396d
4
+ data.tar.gz: 83c7d124be22ace376b06ce11afb4e38db5eb3abbb395e688696bc04984e54c4
5
5
  SHA512:
6
- metadata.gz: aeff02b2b63a8d64a37e80342b4dcf41c1a2c0379a8792b1064c6af431e18350c3130b890ee8bb83b4cc0cc6527b0721dabd2c7eb96ea420414b749d7c1b7a35
7
- data.tar.gz: ce61d0886ca762588e101032f2d51207742f24f30d5c8d681594ea44ae08f508ac5f032f6bad2e27b117bf349794089753cd9669aa9e25de5d72831ac5db2d63
6
+ metadata.gz: b62fa2e8af521bf6e17e1d5e2fefbfbf928549d36176ced92f0d6e2692bb940b9f24900a95301ad8a51efc20fd917d049eafb52cec62b4fe1bfcd62bdfb53b10
7
+ data.tar.gz: 1c817158eb91249bc9c19adae843a020fc89f886258b46656e76b973c4e249c449e7a19452c9f5ece011982a959dccef2238714f4b995db93a1a6b21d5fe5a22
data/README.md CHANGED
@@ -24,7 +24,7 @@ i18n-tasks can be used with any project using the ruby [i18n gem][i18n-gem] (def
24
24
  Add i18n-tasks to the Gemfile:
25
25
 
26
26
  ```ruby
27
- gem 'i18n-tasks', '~> 1.0.8'
27
+ gem 'i18n-tasks', '~> 1.0.9'
28
28
  ```
29
29
 
30
30
  Copy the default [configuration file](#configuration):
@@ -355,7 +355,7 @@ If you have implemented a custom adapter please share it on [the wiki][wiki].
355
355
 
356
356
  ### Usage search
357
357
 
358
- i18n-tasks uses an AST scanner for `.rb` files, and a regexp scanner for all other files.
358
+ i18n-tasks uses an AST scanner for `.rb` and `.html.erb` files, and a regexp scanner for all other files.
359
359
  New scanners can be added easily: please refer to [this example](https://github.com/glebm/i18n-tasks/wiki/A-custom-scanner-example).
360
360
 
361
361
  See the `search` section in the [config file][config] for all available configuration options.
@@ -441,10 +441,10 @@ Custom tasks can be added easily, see the examples [on the wiki](https://github.
441
441
  [badge-ci]: https://github.com/glebm/i18n-tasks/actions/workflows/tests.yml/badge.svg
442
442
  [coverage]: https://codeclimate.com/github/glebm/i18n-tasks
443
443
  [badge-coverage]: https://api.codeclimate.com/v1/badges/5d173e90ada8df07cedc/test_coverage
444
- [config]: https://github.com/glebm/i18n-tasks/blob/master/templates/config/i18n-tasks.yml
444
+ [config]: https://github.com/glebm/i18n-tasks/blob/main/templates/config/i18n-tasks.yml
445
445
  [wiki]: https://github.com/glebm/i18n-tasks/wiki "i18n-tasks wiki"
446
446
  [i18n-gem]: https://github.com/svenfuchs/i18n "svenfuchs/i18n on Github"
447
447
  [screenshot-i18n-tasks]: https://i.imgur.com/XZBd8l7.png "i18n-tasks screenshot"
448
448
  [screenshot-find]: https://i.imgur.com/VxBrSfY.png "i18n-tasks find output screenshot"
449
- [adapter-example]: https://github.com/glebm/i18n-tasks/blob/master/lib/i18n/tasks/data/file_system_base.rb
449
+ [adapter-example]: https://github.com/glebm/i18n-tasks/blob/main/lib/i18n/tasks/data/file_system_base.rb
450
450
  [custom-scanner-docs]: https://github.com/glebm/i18n-tasks/wiki/A-custom-scanner-example
@@ -6,6 +6,10 @@ module I18n::Tasks::Scanners::AstMatchers
6
6
  @scanner = scanner
7
7
  end
8
8
 
9
+ def convert_to_key_occurrences(send_node, method_name, location: send_node.loc)
10
+ raise("Not implemented")
11
+ end
12
+
9
13
  protected
10
14
 
11
15
  # If the node type is of `%i(sym str int false true)`, return the value as a string.
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'i18n/tasks/scanners/results/occurrence'
4
+
5
+ module I18n::Tasks::Scanners::AstMatchers
6
+ class RailsModelMatcher < BaseMatcher
7
+ def convert_to_key_occurrences(send_node, _method_name, location: send_node.loc)
8
+ human_attribute_name_to_key_occurences(send_node: send_node, location: location) ||
9
+ model_name_human_to_key_occurences(send_node: send_node, location: location)
10
+ end
11
+
12
+ private
13
+
14
+ def human_attribute_name_to_key_occurences(send_node:, location:)
15
+ children = Array(send_node&.children)
16
+ receiver = children[0]
17
+ method_name = children[1]
18
+
19
+ return unless method_name == :human_attribute_name && receiver.type == :const
20
+
21
+ value = children[2]
22
+
23
+ model_name = underscore(receiver.to_a.last)
24
+ attribute = extract_string(value)
25
+ key = "activerecord.attributes.#{model_name}.#{attribute}"
26
+ [
27
+ key,
28
+ I18n::Tasks::Scanners::Results::Occurrence.from_range(
29
+ raw_key: key,
30
+ range: location.expression
31
+ )
32
+ ]
33
+ end
34
+
35
+ # User.model_name.human(count: 2)
36
+ # s(:send,
37
+ # s(:send,
38
+ # s(:const, nil, :User), :model_name), :human,
39
+ # s(:hash,
40
+ # s(:pair,
41
+ # s(:sym, :count),
42
+ # s(:int, 2))))
43
+ def model_name_human_to_key_occurences(send_node:, location:)
44
+ children = Array(send_node&.children)
45
+ return unless children[1] == :human
46
+
47
+ base_children = Array(children[0]&.children)
48
+ class_node = base_children[0]
49
+
50
+ return unless class_node&.type == :const && base_children[1] == :model_name
51
+
52
+ model_name = underscore(class_node.to_a.last)
53
+ key = "activerecord.models.#{model_name}"
54
+ [
55
+ key,
56
+ I18n::Tasks::Scanners::Results::Occurrence.from_range(
57
+ raw_key: key,
58
+ range: location.expression
59
+ )
60
+ ]
61
+ end
62
+
63
+ def underscore(value)
64
+ value = value.dup.to_s
65
+ value.gsub!(/(.)([A-Z])/, '\1_\2')
66
+ value.downcase!
67
+ end
68
+ end
69
+ end
@@ -122,7 +122,7 @@ module I18n::Tasks::Scanners
122
122
  )
123
123
  end
124
124
  else
125
- %i[t t! translate translate!].map do |message|
125
+ matchers = %i[t t! translate translate!].map do |message|
126
126
  AstMatchers::MessageReceiversMatcher.new(
127
127
  receivers: [
128
128
  AST::Node.new(:const, [nil, :I18n]),
@@ -132,6 +132,12 @@ module I18n::Tasks::Scanners
132
132
  scanner: self
133
133
  )
134
134
  end
135
+
136
+ Array(config[:ast_matchers]).each do |class_name|
137
+ matchers << ActiveSupport::Inflector.constantize(class_name).new(scanner: self)
138
+ end
139
+
140
+ matchers
135
141
  end
136
142
  end
137
143
  end
@@ -24,6 +24,7 @@ module I18n::Tasks
24
24
  ['::I18n::Tasks::Scanners::ErbAstScanner', { only: %w[*.erb] }],
25
25
  ['::I18n::Tasks::Scanners::PatternWithScopeScanner', { exclude: %w[*.erb *.rb] }]
26
26
  ],
27
+ ast_matchers: [],
27
28
  strict: true
28
29
  }.freeze
29
30
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module I18n
4
4
  module Tasks
5
- VERSION = '1.0.8'
5
+ VERSION = '1.0.9'
6
6
  end
7
7
  end
data/lib/i18n/tasks.rb CHANGED
@@ -34,6 +34,17 @@ module I18n
34
34
  ::I18n::Tasks::Commands.send :include, commands_module
35
35
  self
36
36
  end
37
+
38
+ # Add AST-matcher to i18n-tasks
39
+ #
40
+ # @param matcher_class_name
41
+ # @return self
42
+ def add_ast_matcher(matcher_class_name)
43
+ matchers = I18n::Tasks::Configuration::DEFAULTS[:search][:ast_matchers]
44
+ matchers << matcher_class_name
45
+ matchers.uniq!
46
+ self
47
+ end
37
48
  end
38
49
 
39
50
  @verbose = !ENV['VERBOSE'].nil?
@@ -85,6 +85,15 @@ search:
85
85
  ## If `strict` is `false`, guess usages such as t("categories.#{category}.title"). The default is `true`.
86
86
  # strict: true
87
87
 
88
+ ## Allows adding ast_matchers for finding translations using the AST-scanners
89
+ ## The available matchers are:
90
+ ## - RailsModelMatcher
91
+ ## Matches ActiveRecord translations like
92
+ ## User.human_attribute_name(:email) and User.model_name.human
93
+ ##
94
+ ## To implement your own, please see `I18n::Tasks::Scanners::AstMatchers::BaseMatcher`.
95
+ <%# I18n::Tasks.add_ast_matcher('I18n::Tasks::Scanners::AstMatchers::RailsModelMatcher') %>
96
+
88
97
  ## Multiple scanners can be used. Their results are merged.
89
98
  ## The options specified above are passed down to each scanner. Per-scanner options can be specified as well.
90
99
  ## See this example of a custom scanner: https://github.com/glebm/i18n-tasks/wiki/A-custom-scanner-example
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: i18n-tasks
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.8
4
+ version: 1.0.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - glebm
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-04-06 00:00:00.000000000 Z
11
+ date: 2022-04-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -373,6 +373,7 @@ files:
373
373
  - lib/i18n/tasks/reports/terminal.rb
374
374
  - lib/i18n/tasks/scanners/ast_matchers/base_matcher.rb
375
375
  - lib/i18n/tasks/scanners/ast_matchers/message_receivers_matcher.rb
376
+ - lib/i18n/tasks/scanners/ast_matchers/rails_model_matcher.rb
376
377
  - lib/i18n/tasks/scanners/erb_ast_processor.rb
377
378
  - lib/i18n/tasks/scanners/erb_ast_scanner.rb
378
379
  - lib/i18n/tasks/scanners/file_scanner.rb