platformos-check 0.4.9 → 0.4.11
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 +4 -4
- data/CHANGELOG.md +15 -0
- data/README.md +18 -18
- data/config/default.yml +9 -0
- data/data/platformos_liquid/documentation/filters.json +1 -1
- data/data/platformos_liquid/documentation/latest.json +1 -1
- data/data/platformos_liquid/documentation/tags.json +1 -1
- data/docs/checks/translation_files_match.md +70 -0
- data/docs/checks/translation_key_exists.md +44 -0
- data/docs/platformos-check.jpg +0 -0
- data/lib/platformos_check/app.rb +13 -0
- data/lib/platformos_check/app_file.rb +22 -3
- data/lib/platformos_check/checks/missing_template.rb +19 -26
- data/lib/platformos_check/checks/translation_files_match.rb +83 -0
- data/lib/platformos_check/checks/translation_key_exists.rb +48 -0
- data/lib/platformos_check/checks/undefined_object.rb +1 -1
- data/lib/platformos_check/ext/hash.rb +19 -0
- data/lib/platformos_check/graphql_file.rb +10 -6
- data/lib/platformos_check/language_server/constants.rb +18 -2
- data/lib/platformos_check/language_server/document_link_provider.rb +67 -10
- data/lib/platformos_check/language_server/document_link_providers/localize_document_link_provider.rb +38 -0
- data/lib/platformos_check/language_server/document_link_providers/theme_render_document_link_provider.rb +2 -1
- data/lib/platformos_check/language_server/document_link_providers/translation_document_link_provider.rb +36 -0
- data/lib/platformos_check/translation_file.rb +40 -0
- data/lib/platformos_check/version.rb +1 -1
- data/lib/platformos_check/yaml_file.rb +7 -2
- data/lib/platformos_check.rb +1 -0
- metadata +11 -4
- data/docs/preview.png +0 -0
@@ -34,7 +34,6 @@ module PlatformosCheck
|
|
34
34
|
severity :suggestion
|
35
35
|
category :liquid
|
36
36
|
doc docs_url(__FILE__)
|
37
|
-
single_file false
|
38
37
|
|
39
38
|
def initialize(ignore_missing: [])
|
40
39
|
@ignore_missing = ignore_missing
|
@@ -44,30 +43,37 @@ module PlatformosCheck
|
|
44
43
|
partial = node.value.template_name_expr
|
45
44
|
return unless partial.is_a?(String)
|
46
45
|
|
47
|
-
|
46
|
+
add_missing_template_offense(partial, file_type: PartialFile, node:)
|
48
47
|
end
|
49
48
|
|
50
49
|
def on_render(node)
|
51
50
|
partial = node.value.template_name_expr
|
52
51
|
return unless partial.is_a?(String)
|
53
52
|
|
54
|
-
|
53
|
+
add_missing_template_offense(partial, file_type: PartialFile, node:)
|
54
|
+
end
|
55
|
+
|
56
|
+
def on_background(node)
|
57
|
+
partial = node.value.partial_name
|
58
|
+
return unless partial.is_a?(String)
|
59
|
+
|
60
|
+
add_missing_template_offense(partial, file_type: PartialFile, node:)
|
55
61
|
end
|
56
62
|
|
57
63
|
def on_function(node)
|
58
64
|
partial = node.value.from
|
59
65
|
return unless partial.is_a?(String)
|
60
66
|
|
61
|
-
|
67
|
+
add_missing_template_offense(partial, file_type: PartialFile, node:)
|
62
68
|
end
|
63
69
|
|
64
70
|
def on_graphql(node)
|
65
71
|
return if node.value.inline_query
|
66
72
|
|
67
|
-
|
68
|
-
return unless
|
73
|
+
path = node.value.partial_name
|
74
|
+
return unless path.is_a?(String)
|
69
75
|
|
70
|
-
|
76
|
+
add_missing_template_offense(path, file_type: GraphqlFile, node:)
|
71
77
|
end
|
72
78
|
|
73
79
|
private
|
@@ -80,28 +86,15 @@ module PlatformosCheck
|
|
80
86
|
@all_ignored_patterns ||= @ignore_missing + ignored_patterns
|
81
87
|
end
|
82
88
|
|
83
|
-
def
|
84
|
-
return if ignore?(path)
|
89
|
+
def add_missing_template_offense(path, file_type:, node:)
|
90
|
+
return if ignore?(path)
|
85
91
|
|
86
|
-
|
87
|
-
# corrector.create_file(@platformos_app.storage, MissingFileCorrection.new(path:, directory: 'views/partials', extension: '.liquid').full_relative_path, "")
|
88
|
-
# end
|
89
|
-
end
|
90
|
-
|
91
|
-
def add_missing_function_offense(path, node:)
|
92
|
-
return if ignore?(path) || platformos_app.grouped_files[PartialFile][path]
|
93
|
-
|
94
|
-
add_offense("'#{path}' is not found", node:) # do |corrector|
|
95
|
-
# corrector.create_file(@platformos_app.storage, MissingFileCorrection.new(path:, directory: 'lib', extension: '.liquid').full_relative_path, "")
|
96
|
-
# end
|
97
|
-
end
|
92
|
+
file = platformos_app.grouped_files[file_type][path]
|
98
93
|
|
99
|
-
|
100
|
-
return
|
94
|
+
return add_offense("'#{path}' is missing", node:) if file.nil?
|
95
|
+
return add_offense("'#{path}' is blank", node:) if file.source.strip == ''
|
101
96
|
|
102
|
-
|
103
|
-
# corrector.create_file(@platformos_app.storage, MissingFileCorrection.new(path:, directory: 'graphql', extension: '.graphql').full_relative_path, "")
|
104
|
-
# end
|
97
|
+
nil
|
105
98
|
end
|
106
99
|
end
|
107
100
|
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module PlatformosCheck
|
4
|
+
class TranslationFilesMatch < YamlCheck
|
5
|
+
severity :error
|
6
|
+
category :translation
|
7
|
+
doc docs_url(__FILE__)
|
8
|
+
|
9
|
+
PLURALIZATION_KEYS = Set.new(%w[zero one two few many other])
|
10
|
+
|
11
|
+
def on_file(file)
|
12
|
+
return unless file.translation?
|
13
|
+
return if file.parse_error
|
14
|
+
return add_offense_wrong_language_in_file(file) if file.language != file.language_from_path
|
15
|
+
return check_if_file_exists_for_all_other_languages(file) if file.language == @platformos_app.default_language
|
16
|
+
|
17
|
+
default_language_file = @platformos_app.grouped_files[PlatformosCheck::TranslationFile][file.name.sub(file.language, @platformos_app.default_language)]
|
18
|
+
|
19
|
+
return add_offense_missing_file(file) if default_language_file.nil?
|
20
|
+
|
21
|
+
add_offense_different_structure(file, default_language_file) unless same_structure?(default_language_file.content[@platformos_app.default_language], file.content[file.language])
|
22
|
+
end
|
23
|
+
|
24
|
+
protected
|
25
|
+
|
26
|
+
def add_offense_wrong_language_in_file(file)
|
27
|
+
add_offense("Mismatch detected - file inside #{file.language_from_path} directory defines translations for `#{file.language}`", app_file: file) do |_corrector|
|
28
|
+
file.update_contents(file.content[file.language_from_path] = file.content.delete(file.content[file.language]))
|
29
|
+
file.write
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def add_offense_missing_file(file)
|
34
|
+
add_offense("Mismatch detected - missing `#{file.relative_path.to_s.sub(file.language, @platformos_app.default_language)}` to define translations the default language", app_file: file)
|
35
|
+
end
|
36
|
+
|
37
|
+
def check_if_file_exists_for_all_other_languages(file)
|
38
|
+
@platformos_app.translations_hash.each_key do |lang|
|
39
|
+
next if lang == @platformos_app.default_language
|
40
|
+
|
41
|
+
language_file = @platformos_app.grouped_files[PlatformosCheck::TranslationFile][file.name.sub(file.language, lang)]
|
42
|
+
add_offense_missing_translation_file(file, lang) if language_file.nil?
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def add_offense_missing_translation_file(file, lang)
|
47
|
+
missing_file_path = file.relative_path.to_s.sub(file.language, lang)
|
48
|
+
add_offense("Mismatch detected - missing `#{missing_file_path}` file to define translations for `#{lang}`", app_file: file) do |corrector|
|
49
|
+
missing_file_content = file.content.clone
|
50
|
+
missing_file_content[lang] = missing_file_content.delete(file.language)
|
51
|
+
corrector.create_file(@platformos_app.storage, missing_file_path, YAML.dump(missing_file_content))
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def same_structure?(hash1, hash2)
|
56
|
+
if !hash1.is_a?(Hash) && !hash2.is_a?(Hash)
|
57
|
+
true
|
58
|
+
elsif (hash1.is_a?(Hash) && !hash2.is_a?(Hash)) || (!hash1.is_a?(Hash) && hash2.is_a?(Hash))
|
59
|
+
false
|
60
|
+
elsif pluralization?(hash1) && pluralization?(hash2)
|
61
|
+
true
|
62
|
+
elsif hash1.keys.map(&:to_s).sort != hash2.keys.map(&:to_s).sort
|
63
|
+
false
|
64
|
+
else
|
65
|
+
hash1.keys.all? { |key| same_structure?(hash1[key], hash2[key]) }
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def add_offense_different_structure(file, default_language_file)
|
70
|
+
add_offense("Mismatch detected - structure differs from the default language file #{default_language_file.relative_path}", app_file: file) do |_corrector|
|
71
|
+
file.content[file.language].transform_values! { |v| v.nil? ? {} : v }
|
72
|
+
file.content[file.language] = default_language_file.content[default_language_file.language].deep_merge(file.content[file.language])
|
73
|
+
file.write
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def pluralization?(hash)
|
78
|
+
hash.all? do |key, value|
|
79
|
+
PLURALIZATION_KEYS.include?(key) && !value.is_a?(Hash)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module PlatformosCheck
|
4
|
+
# Recommends using {% liquid ... %} if 5 or more consecutive {% ... %} are found.
|
5
|
+
class TranslationKeyExists < LiquidCheck
|
6
|
+
severity :error
|
7
|
+
categories :translation, :liquid
|
8
|
+
doc docs_url(__FILE__)
|
9
|
+
|
10
|
+
def on_variable(node)
|
11
|
+
return unless node.value.name.is_a?(String)
|
12
|
+
return unless node.filters.size == 1
|
13
|
+
|
14
|
+
translation_filter = node.filters.detect { |f| TranslationFile::TRANSLATION_FILTERS.include?(f[0]) }
|
15
|
+
return unless translation_filter
|
16
|
+
return unless translation_filter
|
17
|
+
|
18
|
+
filter_attributes = translation_filter[2] || {}
|
19
|
+
|
20
|
+
return unless filter_attributes['default'].nil?
|
21
|
+
return if !filter_attributes['scope'].nil? && !filter_attributes['scope'].is_a?(String)
|
22
|
+
|
23
|
+
lang = filter_attributes['language'].is_a?(String) ? filter_attributes['language'] : @platformos_app.default_language
|
24
|
+
translation_components = node.value.name.split('.')
|
25
|
+
|
26
|
+
translation_components = filter_attributes['scope'].split('.') + translation_components if filter_attributes['scope']
|
27
|
+
|
28
|
+
return add_translation_offense(node:, lang:) if @platformos_app.translations_hash.empty?
|
29
|
+
|
30
|
+
hash = @platformos_app.translations_hash[lang] || {}
|
31
|
+
index = 0
|
32
|
+
while translation_components[index]
|
33
|
+
hash = hash[translation_components[index]]
|
34
|
+
if hash.nil?
|
35
|
+
add_translation_offense(node:, lang:)
|
36
|
+
break
|
37
|
+
end
|
38
|
+
index += 1
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
protected
|
43
|
+
|
44
|
+
def add_translation_offense(node:, lang:)
|
45
|
+
add_offense("Translation `#{lang}.#{node.value.name}` does not exists", node:)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Hash
|
4
|
+
def deep_merge!(other_hash, &block)
|
5
|
+
merge!(other_hash) do |key, this_val, other_val|
|
6
|
+
if this_val.is_a?(Hash) && other_val.is_a?(Hash)
|
7
|
+
this_val.deep_merge(other_val, &block)
|
8
|
+
elsif block
|
9
|
+
yield(key, this_val, other_val)
|
10
|
+
else
|
11
|
+
other_val
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def deep_merge(other_hash, &)
|
17
|
+
dup.deep_merge!(other_hash, &)
|
18
|
+
end
|
19
|
+
end
|
@@ -50,15 +50,15 @@ module PlatformosCheck
|
|
50
50
|
end
|
51
51
|
|
52
52
|
def parse
|
53
|
-
@parse ||= GraphQL.parse(source)
|
53
|
+
@parse ||= source && source.strip != '' ? GraphQL.parse(source) : nil
|
54
54
|
end
|
55
55
|
|
56
56
|
def warnings
|
57
|
-
parse
|
57
|
+
parse&.warnings || {}
|
58
58
|
end
|
59
59
|
|
60
60
|
def root
|
61
|
-
parse
|
61
|
+
parse&.root || {}
|
62
62
|
end
|
63
63
|
|
64
64
|
def self.parse(_source)
|
@@ -80,11 +80,15 @@ module PlatformosCheck
|
|
80
80
|
end
|
81
81
|
|
82
82
|
def selections
|
83
|
-
definition
|
83
|
+
definition&.selections
|
84
84
|
end
|
85
85
|
|
86
86
|
def fragments
|
87
|
-
@fragments ||= parse
|
87
|
+
@fragments ||= parse&.definitions&.select { |d| d.is_a?(GraphQL::Language::Nodes::FragmentDefinition) } || []
|
88
|
+
end
|
89
|
+
|
90
|
+
def graphql?
|
91
|
+
true
|
88
92
|
end
|
89
93
|
|
90
94
|
private
|
@@ -94,7 +98,7 @@ module PlatformosCheck
|
|
94
98
|
end
|
95
99
|
|
96
100
|
def definition
|
97
|
-
@definition ||= parse
|
101
|
+
@definition ||= parse&.definitions&.detect { |d| d.is_a?(GraphQL::Language::Nodes::OperationDefinition) }
|
98
102
|
end
|
99
103
|
|
100
104
|
def bounded(lower, x, upper)
|
@@ -32,13 +32,29 @@ module PlatformosCheck
|
|
32
32
|
PARTIAL_GRAPHQL = partial_tag_with_result('graphql')
|
33
33
|
PARTIAL_BACKGROUND = partial_tag_with_result('background')
|
34
34
|
|
35
|
+
TAGS_FOR_FILTERS = 'echo|print|log|hash_assign|assign'
|
36
|
+
TRANSLATION_FILTERS_NAMES = 'translate|t_escape|translate_escape|t[^\\w]'
|
37
|
+
OPTIONAL_SCOPE_ARGUMENT = %((:?([\\w:'"\\s]*)\\s*(scope:\\s*['"](?<scope>[^'"]*)['"]))?)
|
38
|
+
|
39
|
+
LOCALIZE_FILTERS_NAMES = ''
|
40
|
+
|
35
41
|
ASSET_INCLUDE = /
|
36
42
|
\{\{-?\s*'(?<partial>[^']*)'\s*\|\s*asset_url|
|
37
43
|
\{\{-?\s*"(?<partial>[^"]*)"\s*\|\s*asset_url|
|
38
44
|
|
39
45
|
# in liquid tags the whole line is white space until the asset partial
|
40
|
-
^\s*(
|
41
|
-
^\s*(
|
46
|
+
^\s*(?:#{TAGS_FOR_FILTERS}[^=]*=)\s*'(?<partial>[^']*)'\s*\|\s*asset_url|
|
47
|
+
^\s*(?:#{TAGS_FOR_FILTERS}[^=]*=)\s*"(?<partial>[^"]*)"\s*\|\s*asset_url
|
48
|
+
/mix
|
49
|
+
|
50
|
+
TRANSLATION_FILTER = /
|
51
|
+
'(?<key>[^']*)'\s*\|\s*(#{TRANSLATION_FILTERS_NAMES})#{OPTIONAL_SCOPE_ARGUMENT}|
|
52
|
+
"(?<key>[^"]*)"\s*\|\s*(#{TRANSLATION_FILTERS_NAMES})#{OPTIONAL_SCOPE_ARGUMENT}
|
53
|
+
/mix
|
54
|
+
|
55
|
+
LOCALIZE_FILTER = /
|
56
|
+
[\s\w'"-:.]+\|\s*(localize|l):\s*'(?<key>[^']*)'|
|
57
|
+
[\s\w'"-:.]+\|\s*(localize|l):\s*"(?<key>[^"]*)"
|
42
58
|
/mix
|
43
59
|
end
|
44
60
|
end
|
@@ -7,6 +7,16 @@ module PlatformosCheck
|
|
7
7
|
include PositionHelper
|
8
8
|
include URIHelper
|
9
9
|
|
10
|
+
class DefaultTranslationFile
|
11
|
+
def initialize(default_language)
|
12
|
+
@default_language = default_language
|
13
|
+
end
|
14
|
+
|
15
|
+
def relative_path
|
16
|
+
Pathname.new(@default_language, "#{@default_language}.yml")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
10
20
|
class << self
|
11
21
|
attr_accessor :partial_regexp, :app_file_type, :default_dir, :default_extension
|
12
22
|
|
@@ -41,18 +51,12 @@ module PlatformosCheck
|
|
41
51
|
|
42
52
|
def document_links(buffer, platformos_app)
|
43
53
|
matches(buffer, partial_regexp).map do |match|
|
44
|
-
start_row, start_column =
|
45
|
-
buffer,
|
46
|
-
match.begin(:partial)
|
47
|
-
)
|
54
|
+
start_row, start_column = start_coordinates(buffer, match)
|
48
55
|
|
49
|
-
end_row, end_column =
|
50
|
-
buffer,
|
51
|
-
match.end(:partial)
|
52
|
-
)
|
56
|
+
end_row, end_column = end_coordinates(buffer, match)
|
53
57
|
|
54
58
|
{
|
55
|
-
target: file_link(match
|
59
|
+
target: file_link(match, platformos_app),
|
56
60
|
range: {
|
57
61
|
start: {
|
58
62
|
line: start_row,
|
@@ -67,13 +71,66 @@ module PlatformosCheck
|
|
67
71
|
end
|
68
72
|
end
|
69
73
|
|
70
|
-
def
|
74
|
+
def start_coordinates(buffer, match)
|
75
|
+
from_index_to_row_column(
|
76
|
+
buffer,
|
77
|
+
match.begin(:partial)
|
78
|
+
)
|
79
|
+
end
|
80
|
+
|
81
|
+
def end_coordinates(buffer, match)
|
82
|
+
from_index_to_row_column(
|
83
|
+
buffer,
|
84
|
+
match.end(:partial)
|
85
|
+
)
|
86
|
+
end
|
87
|
+
|
88
|
+
def file_link(match, platformos_app)
|
89
|
+
partial = match[:partial]
|
71
90
|
relative_path = platformos_app.send(app_file_type).detect { |f| f.name == partial }&.relative_path
|
72
91
|
relative_path ||= default_relative_path(partial)
|
73
92
|
|
74
93
|
file_uri(@storage.path(relative_path))
|
75
94
|
end
|
76
95
|
|
96
|
+
def translation_file_link(match, platformos_app)
|
97
|
+
@current_best_fit = platformos_app.translations.first || DefaultTranslationFile.new(platformos_app.default_language)
|
98
|
+
@current_best_fit_level = 0
|
99
|
+
array_of_translation_components = translation_components_for_match(match)
|
100
|
+
platformos_app.translations.each do |translation_file|
|
101
|
+
array_of_translation_components.each do |translation_components|
|
102
|
+
exact_match_level = translation_components.size
|
103
|
+
component_result = translation_file.content[platformos_app.default_language]
|
104
|
+
next if component_result.nil?
|
105
|
+
|
106
|
+
i = 0
|
107
|
+
while i < exact_match_level
|
108
|
+
component_result = yaml(component_result, translation_components[i])
|
109
|
+
|
110
|
+
break if component_result.nil?
|
111
|
+
|
112
|
+
i += 1
|
113
|
+
if i > @current_best_fit_level
|
114
|
+
@current_best_fit = translation_file
|
115
|
+
@current_best_fit_level = i
|
116
|
+
end
|
117
|
+
|
118
|
+
break unless component_result.is_a?(Hash)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
file_uri(@storage.path(@current_best_fit&.relative_path))
|
124
|
+
end
|
125
|
+
|
126
|
+
def translation_components_for_match(match)
|
127
|
+
raise NotImplementedError
|
128
|
+
end
|
129
|
+
|
130
|
+
def yaml(component_result, component)
|
131
|
+
component_result[component]
|
132
|
+
end
|
133
|
+
|
77
134
|
def default_relative_path(partial)
|
78
135
|
return Pathname.new("app/#{default_dir}/#{partial}#{default_extension}") unless partial.start_with?('modules/')
|
79
136
|
|
data/lib/platformos_check/language_server/document_link_providers/localize_document_link_provider.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module PlatformosCheck
|
4
|
+
module LanguageServer
|
5
|
+
class LocalizeDocumentLinkProvider < DocumentLinkProvider
|
6
|
+
@partial_regexp = LOCALIZE_FILTER
|
7
|
+
@app_file_type = :translations
|
8
|
+
@default_dir = 'translations'
|
9
|
+
@default_extension = '.yml'
|
10
|
+
|
11
|
+
def file_link(match, platformos_app)
|
12
|
+
translation_file_link(match, platformos_app)
|
13
|
+
end
|
14
|
+
|
15
|
+
def translation_components_for_match(match)
|
16
|
+
key = match[:key].split('.')
|
17
|
+
[
|
18
|
+
%w[time formats] + key,
|
19
|
+
%w[date formats] + key
|
20
|
+
]
|
21
|
+
end
|
22
|
+
|
23
|
+
def start_coordinates(buffer, match)
|
24
|
+
from_index_to_row_column(
|
25
|
+
buffer,
|
26
|
+
match.begin(:key)
|
27
|
+
)
|
28
|
+
end
|
29
|
+
|
30
|
+
def end_coordinates(buffer, match)
|
31
|
+
from_index_to_row_column(
|
32
|
+
buffer,
|
33
|
+
match.end(:key)
|
34
|
+
)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -8,7 +8,8 @@ module PlatformosCheck
|
|
8
8
|
@default_dir = 'views/partials'
|
9
9
|
@default_extension = '.liquid'
|
10
10
|
|
11
|
-
def file_link(
|
11
|
+
def file_link(match, platformos_app)
|
12
|
+
partial = match[:partial]
|
12
13
|
relative_path = nil
|
13
14
|
path_prefixes(platformos_app).each do |prefix|
|
14
15
|
prefix ||= ''
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module PlatformosCheck
|
4
|
+
module LanguageServer
|
5
|
+
class TranslationDocumentLinkProvider < DocumentLinkProvider
|
6
|
+
@partial_regexp = TRANSLATION_FILTER
|
7
|
+
@app_file_type = :translations
|
8
|
+
@default_dir = 'translations'
|
9
|
+
@default_extension = '.yml'
|
10
|
+
|
11
|
+
def file_link(match, platformos_app)
|
12
|
+
translation_file_link(match, platformos_app)
|
13
|
+
end
|
14
|
+
|
15
|
+
def translation_components_for_match(match)
|
16
|
+
translation_components = match[:key].split('.')
|
17
|
+
translation_components = match[:scope].split('.') + translation_components if match[:scope]
|
18
|
+
[translation_components]
|
19
|
+
end
|
20
|
+
|
21
|
+
def start_coordinates(buffer, match)
|
22
|
+
from_index_to_row_column(
|
23
|
+
buffer,
|
24
|
+
match.begin(:key)
|
25
|
+
)
|
26
|
+
end
|
27
|
+
|
28
|
+
def end_coordinates(buffer, match)
|
29
|
+
from_index_to_row_column(
|
30
|
+
buffer,
|
31
|
+
match.end(:key)
|
32
|
+
)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -2,5 +2,45 @@
|
|
2
2
|
|
3
3
|
module PlatformosCheck
|
4
4
|
class TranslationFile < YamlFile
|
5
|
+
DIR_PREFIX = %r{\A/?((marketplace_builder|app)/(translations)/|modules/((\w|-)*)/(private|public)/(translations)/)}
|
6
|
+
TRANSLATION_FILTERS = Set.new(%w[t t_escape translate translate_escape]).freeze
|
7
|
+
attr_reader :language
|
8
|
+
|
9
|
+
def load!
|
10
|
+
before_load
|
11
|
+
super
|
12
|
+
after_load
|
13
|
+
end
|
14
|
+
|
15
|
+
def before_load
|
16
|
+
@storage.platformos_app.instance_variable_set(:@translations_hash, nil) unless @loaded
|
17
|
+
end
|
18
|
+
|
19
|
+
def after_load
|
20
|
+
@language = @content&.keys&.first
|
21
|
+
return if module_name.nil?
|
22
|
+
|
23
|
+
@content[@language].transform_keys! { |key| key.start_with?(module_prefix) ? key : "#{module_prefix}#{key}" }
|
24
|
+
end
|
25
|
+
|
26
|
+
def language_from_path
|
27
|
+
@language_from_path ||= name.sub(module_prefix, '').split(File::SEPARATOR).first
|
28
|
+
end
|
29
|
+
|
30
|
+
def update_contents(new_content = {})
|
31
|
+
before_load
|
32
|
+
super(new_content)
|
33
|
+
@loaded = true
|
34
|
+
|
35
|
+
after_load
|
36
|
+
end
|
37
|
+
|
38
|
+
def dir_prefix
|
39
|
+
DIR_PREFIX
|
40
|
+
end
|
41
|
+
|
42
|
+
def translation?
|
43
|
+
true
|
44
|
+
end
|
5
45
|
end
|
6
46
|
end
|
@@ -28,14 +28,19 @@ module PlatformosCheck
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def write
|
31
|
+
pretty = content_to_string
|
32
|
+
@storage.write(@relative_path, pretty)
|
33
|
+
@source = pretty
|
34
|
+
end
|
35
|
+
|
36
|
+
def content_to_string
|
31
37
|
pretty = YAML.dump(@content)
|
32
38
|
return unless source.rstrip != pretty.rstrip
|
33
39
|
|
34
40
|
# Most editors add a trailing \n at the end of files. Here we
|
35
41
|
# try to maintain the convention.
|
36
42
|
eof = source.end_with?("\n") ? "\n" : ""
|
37
|
-
|
38
|
-
@source = pretty
|
43
|
+
pretty.gsub("\n", @eol) + eof
|
39
44
|
end
|
40
45
|
|
41
46
|
def yaml?
|
data/lib/platformos_check.rb
CHANGED
@@ -5,6 +5,7 @@ require "liquid"
|
|
5
5
|
require_relative "platformos_check/version"
|
6
6
|
require_relative "platformos_check/bug"
|
7
7
|
require_relative "platformos_check/exceptions"
|
8
|
+
require_relative "platformos_check/ext/hash"
|
8
9
|
require_relative "platformos_check/json_helper"
|
9
10
|
require_relative "platformos_check/app_file_rewriter"
|
10
11
|
require_relative "platformos_check/app_file"
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: platformos-check
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Piotr Bliszczyk
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: exe
|
12
12
|
cert_chain: []
|
13
|
-
date: 2024-
|
13
|
+
date: 2024-03-11 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: graphql
|
@@ -134,6 +134,8 @@ files:
|
|
134
134
|
- docs/checks/space_inside_braces.md
|
135
135
|
- docs/checks/syntax_error.md
|
136
136
|
- docs/checks/template_length.md
|
137
|
+
- docs/checks/translation_files_match.md
|
138
|
+
- docs/checks/translation_key_exists.md
|
137
139
|
- docs/checks/undefined_object.md
|
138
140
|
- docs/checks/unknown_filter.md
|
139
141
|
- docs/checks/unreachable_code.md
|
@@ -148,7 +150,7 @@ files:
|
|
148
150
|
- docs/language_server/code-action-problem.png
|
149
151
|
- docs/language_server/code-action-quickfix.png
|
150
152
|
- docs/language_server/how_to_correct_code_with_code_actions_and_execute_command.md
|
151
|
-
- docs/
|
153
|
+
- docs/platformos-check.jpg
|
152
154
|
- exe/platformos-check
|
153
155
|
- exe/platformos-check-language-server
|
154
156
|
- lib/platformos_check.rb
|
@@ -181,6 +183,8 @@ files:
|
|
181
183
|
- lib/platformos_check/checks/space_inside_braces.rb
|
182
184
|
- lib/platformos_check/checks/syntax_error.rb
|
183
185
|
- lib/platformos_check/checks/template_length.rb
|
186
|
+
- lib/platformos_check/checks/translation_files_match.rb
|
187
|
+
- lib/platformos_check/checks/translation_key_exists.rb
|
184
188
|
- lib/platformos_check/checks/undefined_object.rb
|
185
189
|
- lib/platformos_check/checks/unknown_filter.rb
|
186
190
|
- lib/platformos_check/checks/unreachable_code.rb
|
@@ -196,6 +200,7 @@ files:
|
|
196
200
|
- lib/platformos_check/disabled_checks.rb
|
197
201
|
- lib/platformos_check/email_file.rb
|
198
202
|
- lib/platformos_check/exceptions.rb
|
203
|
+
- lib/platformos_check/ext/hash.rb
|
199
204
|
- lib/platformos_check/file_system_storage.rb
|
200
205
|
- lib/platformos_check/form_file.rb
|
201
206
|
- lib/platformos_check/graphql_file.rb
|
@@ -244,8 +249,10 @@ files:
|
|
244
249
|
- lib/platformos_check/language_server/document_link_providers/graphql_document_link_provider.rb
|
245
250
|
- lib/platformos_check/language_server/document_link_providers/include_document_link_provider.rb
|
246
251
|
- lib/platformos_check/language_server/document_link_providers/include_form_document_link_provider.rb
|
252
|
+
- lib/platformos_check/language_server/document_link_providers/localize_document_link_provider.rb
|
247
253
|
- lib/platformos_check/language_server/document_link_providers/render_document_link_provider.rb
|
248
254
|
- lib/platformos_check/language_server/document_link_providers/theme_render_document_link_provider.rb
|
255
|
+
- lib/platformos_check/language_server/document_link_providers/translation_document_link_provider.rb
|
249
256
|
- lib/platformos_check/language_server/execute_command_engine.rb
|
250
257
|
- lib/platformos_check/language_server/execute_command_provider.rb
|
251
258
|
- lib/platformos_check/language_server/execute_command_providers/correction_execute_command_provider.rb
|
@@ -366,7 +373,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
366
373
|
- !ruby/object:Gem::Version
|
367
374
|
version: '0'
|
368
375
|
requirements: []
|
369
|
-
rubygems_version: 3.
|
376
|
+
rubygems_version: 3.5.6
|
370
377
|
signing_key:
|
371
378
|
specification_version: 4
|
372
379
|
summary: A platformOS App Linter
|
data/docs/preview.png
DELETED
Binary file
|