5 ## This file is part of INAV.
7 ## INAV is free software. You can redistribute this software
8 ## and/or modify this software under the terms of the
9 ## GNU General Public License as published by the Free Software
10 ## Foundation, either version 3 of the License, or (at your option)
13 ## INAV is distributed in the hope that they will be
14 ## useful, but WITHOUT ANY WARRANTY; without even the implied
15 ## warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16 ## See the GNU General Public License for more details.
18 ## You should have received a copy of the GNU General Public License
19 ## along with this software.
21 ## If not, see <http://www.gnu.org/licenses/>.
24 #########################################################################
26 # Generates a formatted (Markdown) report of CLI settings differences
27 # between two INAV branches or tags. Primarily intended for inclusion
30 # Note that the report will require review / editing before inclusing
31 # in the RN, but it will jabe done the vast majority of the work for
36 # draft_rn_settings.rb -f 5.1.0 -t release_6.0.0 > /tmp/draft-set6.0RN.md
37 # # now review /tmp/draft-set6.0RN.md for inclusion in the offical RN
40 # * ruby (v3 recommended)
43 #########################################################################
49 base = File.join(ENV["HOME"], "Projects/fc/inav")
54 opt.banner = "#{File.basename($0)} [options]"
55 opt.on('-t','--tag=TAG', 'New tag or branch') {|o|ntag=o}
56 opt.on('-f','--from-tag=TAG', 'previous release tag or branch'){|o|otag=o}
57 opt.on('-b','--base=DIR', "Base of the INAV repo [#{base}]" ) {|o|base=o}
58 opt.on('-?', "--help", "Show this message") {puts opt.to_s; exit}
67 abort 'New tag / branch is mandatory' unless ntag
68 abort 'Old tag / branch is mandatory' unless otag
73 abort "Cannot chdir to #{base}"
76 oldyaml = File.join(Dir.tmpdir, ".setting_old.yaml")
77 newyaml = File.join(Dir.tmpdir, ".setting_new.yaml")
79 system "> #{oldyaml} git show #{otag}:src/main/fc/settings.yaml"
80 system "> #{newyaml} git show #{ntag}:src/main/fc/settings.yaml"
84 h_old = YAML.load_file(oldyaml)
86 abort "Error reading old settings yaml"
91 h_new = YAML.load_file(newyaml)
93 abort "Error reading new settings yaml"
97 h_old["tables"].each do |t|
102 h_new["tables"].each do |t|
103 nt_names << t["name"]
106 puts "# Draft Rel Notes -- settings helper"
108 puts "The following should make a reasonable first pass at new / changed / removed settings"
109 puts "Will require manual checking / refining / formatting."
111 d = nt_names.difference(ot_names).sort
114 puts "# New (Tables) -- to update group values"
116 puts "| Name | Values |"
117 puts "| ---- | ------ |"
119 t = h_new["tables"].select{|k| k["name"] == dn}.first
122 if vals[0].class == String
123 vals.map!{|a| "`#{a}`"}
126 puts "| #{dn} | #{vs} |"
132 d= ot_names.difference(nt_names).sort
135 puts "## Removed (tables -- check for group value later)"
137 puts "| Name | Comment |"
138 puts "| ---- | ------ |"
140 t = h_old["tables"].select{|k| k["name"] == dn}.first
147 d=ot_names.intersection(nt_names).sort
150 puts "## Changed (table values -- check for group value later)"
152 puts "| Name | Values |"
153 puts "| ---- | ------ |"
155 tnew = h_new["tables"].select{|k| k["name"] == dn}.first
156 told = h_old["tables"].select{|k| k["name"] == dn}.first
157 unless told.nil? && tnew.nil?
158 if told["values"] != tnew["values"]
159 vals = tnew["values"].difference(told["values"])
161 if vals[0].class == String
162 vals.map!{|a| "`#{a}`"}
164 newvals = vals.join(", ")
165 puts "| #{dn} | New: #{newvals} |"
168 vals = told["values"].difference(tnew["values"])
170 if vals[0].class == String
171 vals.map!{|a| "`#{a}`"}
173 remvals = vals.join(", ")
174 puts "| #{dn} | Removed: #{remvals} |"
182 h_old["groups"].each do |h|
183 h["members"].each do |m|
184 og_names << m["name"]
189 h_new["groups"].each do |h|
190 h["members"].each do |m|
191 ng_names << m["name"]
195 d = ng_names.difference(og_names).sort
200 puts "| Name | Description |"
201 puts "| ---- | ------ |"
204 h_new["groups"].each do |hh|
205 t = hh["members"].select{|k| k["name"] == dn}.first
207 desc = t["description"]||""
233 minmax[0] = 0 if !minmax[1].nil? && minmax[0].nil?
236 desc = [desc," Values: #{minmax[0]} - #{minmax[1]}"].join
240 if t.has_key?("default_value")
241 default = t["default_value"].to_s.upcase
243 desc = "#{desc} Default: #{default}"
247 # default_value max min
248 puts "| #{dn} | #{desc} |"
256 d = og_names.difference(ng_names).sort
259 puts "## Removed Items"
261 puts "| Name | Description |"
262 puts "| ---- | ------ |"
269 d=ot_names.intersection(nt_names).sort
272 puts "## Changed Items (desc, range, default -- requires checking)"
274 puts "Most of the content here will be indicated by a change at the table level"
276 puts "| Name | Values |"
277 puts "| ---- | ------ |"
280 h_new["groups"].each do |hh|
281 tnew = hh["members"].select{|k| k["name"] == dn}.first
282 break unless tnew.nil?
284 h_old["groups"].each do |hh|
285 told = hh["members"].select{|k| k["name"] == dn}.first
286 break unless told.nil?
288 # in the following tests we discard just the addtion of an attribute
289 unless (told.nil? && tnew.nil?)
291 if told["default_value"] && told["default_value"] != tnew["default_value"]
292 diffs << "Default: #{tnew["default_value"]}"
295 if told["description"] && told["description"] != tnew["description"]
296 diffs << tnew["description"]
300 diffstr = diffs.join(" ")
301 puts "| #{dn} | #{diffstr} |"
308 puts "Last updated: #{Time.now.utc.strftime("%FT%T%Z")}"
310 File.unlink(oldyaml, newyaml)