Class: NeetoCompliance::JsconfigVerifier

Inherits:
Base
  • Object
show all
Defined in:
lib/neeto_compliance/verifiers/jsconfig_verifier.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from Base

#app_is_exception?, #app_name, #apps_exception_list, #audit, #error_message, #print_description, #process, #verifier_name

Constructor Details

#initializeJsconfigVerifier

Returns a new instance of JsconfigVerifier.



9
10
11
# File 'lib/neeto_compliance/verifiers/jsconfig_verifier.rb', line 9

def initialize
  @diffs = []
end

Instance Attribute Details

#diffsObject

Returns the value of attribute diffs.



7
8
9
# File 'lib/neeto_compliance/verifiers/jsconfig_verifier.rb', line 7

def diffs
  @diffs
end

Instance Method Details

#add_comments_to_jsconfig_fileObject



82
83
84
85
86
87
# File 'lib/neeto_compliance/verifiers/jsconfig_verifier.rb', line 82

def add_comments_to_jsconfig_file
  text = File.read(local_copy)
  text['"commons_paths_comment": "",'] = "// don't modify the below paths without consulting with neetoCompliance team"
  text['"custom_paths_comment": ""'] = "// You can add custom project specific paths below this comment"
  File.open(local_copy, "w") { |file| file.puts text }
end

#add_place_holders_for_commentsObject



102
103
104
105
106
107
108
109
# File 'lib/neeto_compliance/verifiers/jsconfig_verifier.rb', line 102

def add_place_holders_for_comments
  # Adds placeholders into the entire object to keep track of places where we need to insert comments

  paths_with_comment =
    { "commons_paths_comment": "" }.merge(required_jsconfig["compilerOptions"]["paths"])
  paths_with_comment = paths_with_comment.merge("custom_paths_comment": "")
  paths_with_comment.merge(custom_paths)
end

#auto_correct!Object



119
120
121
122
123
124
125
126
127
128
# File 'lib/neeto_compliance/verifiers/jsconfig_verifier.rb', line 119

def auto_correct!
  unless valid?
    if !modified_paths.empty?
      raise StandardError.new exception_message(modified_paths)
    end

    write_jsconfig_object_to_file
    add_comments_to_jsconfig_file
  end
end

#autofix_commandObject



137
138
139
# File 'lib/neeto_compliance/verifiers/jsconfig_verifier.rb', line 137

def autofix_command
  "cp #{commons_copy} #{local_copy}"
end

#autofix_suggestionObject



149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# File 'lib/neeto_compliance/verifiers/jsconfig_verifier.rb', line 149

def autofix_suggestion
  base_message = %{
  Your jsconfig.json content doesn't match with the expected neeto-commons content.

  The following is the recommended jsconfig.json content in neeto ecosystem:
  1) View #{upstream_copy}
  2) Or open #{commons_copy}

  This can be fixed automatically by running:
  #{neeto_audit_script_command.yellow}

  To fix manually, start by fully replacing app/javascript/jsconfig.json
  of your app with above mentioned content, by running the following:
  #{autofix_command.yellow}
  }

  # The following is an example diff:
  # [["-", "compilerOptions.moduleResolution", "NodeNext"],
  # ["~", "compilerOptions.module", "ESNext", "ESNex"],
  # ["+", "compilerOptions.paths.neetou", ["../../node_modules/@bigbinary/neetoui/**"]],
  # For the above diff, we only need to get the newly added items marked by "+"
  # and also check whether it's a "path" that has been added.
  if newly_added_paths.empty?
    return base_message
  end

  message = %{
  #{base_message}
  ==================================================
  It seems that you've also added some custom paths in your jsconfig. You can cherry pick and
  append the custom paths to app/javascript/jsconfig.json, if need be, after running above mentioned copy command.
  Refer the comments in #{upstream_copy}
  to see how to add custom paths.
  The following are the custom paths that we have detected in your app/javascript/jsconfig.json:
  #{JSON.pretty_generate(custom_paths).yellow}
  }
end

#commons_copyObject



17
18
19
# File 'lib/neeto_compliance/verifiers/jsconfig_verifier.rb', line 17

def commons_copy
  NeetoCompliance::NeetoCommons.path.join "common_files", "app", "javascript", "jsconfig.json"
end

#custom_pathsObject



58
59
60
61
62
63
64
65
66
67
68
# File 'lib/neeto_compliance/verifiers/jsconfig_verifier.rb', line 58

def custom_paths
  paths = Hash.new
  newly_added_paths.each do |path|
    if path[0] == "+"
      key = path[1].split(".").last
      value = path[2]
      paths[key] = value
    end
  end
  @_custom_paths ||= paths
end

#exception_message(paths) ⇒ Object



89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/neeto_compliance/verifiers/jsconfig_verifier.rb', line 89

def exception_message(paths)
  modified_paths = ""
  paths.each do |key, value|
    modified_paths += "
      path: #{key}
        Common value: [\"#{value[:common]}\"]
        Project's value: [\"#{value[:local]}\"]"
  end
  exception_message = %{
    Could not autofix jsconfig changes. The below path(s) conflict with the one defined in neeto-commons-backend: #{modified_paths}
  }
end

#local_copyObject



13
14
15
# File 'lib/neeto_compliance/verifiers/jsconfig_verifier.rb', line 13

def local_copy
  "app/javascript/jsconfig.json"
end

#local_file_exists?Boolean

Returns:

  • (Boolean)


48
49
50
# File 'lib/neeto_compliance/verifiers/jsconfig_verifier.rb', line 48

def local_file_exists?
  File.file?(local_copy)
end

#local_jsconfigObject



21
22
23
# File 'lib/neeto_compliance/verifiers/jsconfig_verifier.rb', line 21

def local_jsconfig
  @_local_jsconfig ||= read_file local_copy
end

#modified_pathsObject



70
71
72
73
74
75
76
77
78
79
80
# File 'lib/neeto_compliance/verifiers/jsconfig_verifier.rb', line 70

def modified_paths
  paths = Hash.new
  newly_added_paths.each do |path|
    if path[0] == "~"
      # An unwanted '[0]' character is added at the to all modified diffs by the gem

      paths[path[1].split(".").last.chomp("[0]")] = { common: path[2], local: path[3] }
    end
  end
  @_modified_paths ||= paths
end

#neeto_audit_script_commandObject



141
142
143
# File 'lib/neeto_compliance/verifiers/jsconfig_verifier.rb', line 141

def neeto_audit_script_command
  "bundle exec neeto-audit -a"
end

#newly_added_pathsObject



52
53
54
55
56
# File 'lib/neeto_compliance/verifiers/jsconfig_verifier.rb', line 52

def newly_added_paths
  self.diffs = Hashdiff.diff(required_jsconfig, local_jsconfig, use_lcs: false)
  capture_addition_into_paths_key = "(?=.*\+)(?=.*compilerOptions.paths)"
  @_newly_added_paths ||= self.diffs.select { |diff| diff.join =~ /#{capture_addition_into_paths_key}.*/ }
end

#read_file(file) ⇒ Object



29
30
31
# File 'lib/neeto_compliance/verifiers/jsconfig_verifier.rb', line 29

def read_file(file)
  JSON.parse File.read(file)
end

#removed_or_modified?(diff) ⇒ Boolean

Returns:

  • (Boolean)


40
41
42
43
44
45
46
# File 'lib/neeto_compliance/verifiers/jsconfig_verifier.rb', line 40

def removed_or_modified?(diff)
  # A diff is of the format: ['-', 'a.x', 2]
  # A modified key is of the format: ['~', 'a.x', 2, 4]
  # First element is a symbol. '-' indicates removal and `~` indicates modification

  diff[0] == "-" || diff[0] == "~"
end

#required_jsconfigObject



25
26
27
# File 'lib/neeto_compliance/verifiers/jsconfig_verifier.rb', line 25

def required_jsconfig
  @_required_jsconfig ||= read_file commons_copy
end

#upstream_copyObject



145
146
147
# File 'lib/neeto_compliance/verifiers/jsconfig_verifier.rb', line 145

def upstream_copy
  "https://github.com/bigbinary/neeto-commons-backend/blob/stable/lib/neeto-commons-backend/common_files/app/javascript/jsconfig.json"
end

#valid?Boolean

Returns:

  • (Boolean)


130
131
132
133
134
135
# File 'lib/neeto_compliance/verifiers/jsconfig_verifier.rb', line 130

def valid?
  return false unless local_file_exists?

  is_modified_or_removed = verify_command
  !is_modified_or_removed
end

#verify_commandObject



33
34
35
36
37
38
# File 'lib/neeto_compliance/verifiers/jsconfig_verifier.rb', line 33

def verify_command
  self.diffs = Hashdiff.best_diff(required_jsconfig, local_jsconfig)
  # diffs is an array of differences and each element is a diff.

  self.diffs.any? { |diff| removed_or_modified?(diff) }
end

#write_jsconfig_object_to_fileObject



111
112
113
114
115
116
117
# File 'lib/neeto_compliance/verifiers/jsconfig_verifier.rb', line 111

def write_jsconfig_object_to_file
  jsconfig_data = required_jsconfig
  jsconfig_data["compilerOptions"]["paths"] = add_place_holders_for_comments
  File.open(local_copy, "w") do |file|
    file.write(JSON.pretty_generate(jsconfig_data))
  end
end