github.com/cozy/cozy-stack@v0.0.0-20240603063001-31110fa4cae1/tests/system/lib/debug.rb (about) 1 class Debug 2 def self.visualize_tree(instances, sharing) 3 @count ||= 0 4 Visualizer.new(instances, sharing, @count).render 5 @count += 1 6 end 7 8 class Visualizer 9 def initialize(instances, sharing, suffix) 10 @instances = instances 11 @sharing = sharing 12 @output = File.join Helpers.current_dir, "tree_#{suffix}" 13 end 14 15 def render 16 File.write "#{@output}.gv", to_dot 17 system "dot -Tpng -o #{@output}.png #{@output}.gv" 18 system "xdg-open #{@output}.png" 19 end 20 21 def to_dot 22 @buf = [] 23 @buf << 'digraph debug {' 24 @buf << ' node [shape="box", fontname="lato", fontsize=10, margin=0.12, color="#297EF2", fontcolor="#32363F"];' 25 @buf << ' edge [color="#32363F"];' 26 @buf << ' ranksep=0.4; nodesep=0.5;' 27 28 @instances.each_with_index do |inst, idx| 29 @buf << '' << " subgraph cluster_#{inst.name} {" 30 @buf << " label=\"#{inst.name}\"; labeljust=\"l\"; fontname=\"lato\"; fontsize=12" << '' 31 @buf << " #{esc Folder::ROOT_DIR, inst} [label=\"/\"]" 32 if idx == 0 33 @buf << " invisible [style=invis]" 34 @buf << " invisible -> #{esc Folder::ROOT_DIR, inst} [style=invis]" 35 end 36 tree_for(inst).sort_by { |doc| doc['name'] || '' }.each do |doc| 37 next if ignored? doc 38 @buf << " #{esc doc['_id'], inst} [label=<#{doc['name']}<BR/>#{doc['_id']}<BR/>#{doc['_rev']}>]" 39 @buf << " #{esc doc['dir_id'], inst} -> #{esc doc['_id'], inst}" 40 end 41 @buf << ' }' 42 end 43 44 @buf << '}' << '' 45 @buf.join "\n" 46 end 47 48 def ignored?(doc) 49 return true if doc["_id"].start_with?("_") # Design docs 50 return true if doc["_id"] == Folder::ROOT_DIR 51 path = doc["path"] 52 return false if path.nil? 53 return true if path.start_with?("/Photos") 54 return true if path.start_with?("/Administrati") 55 false 56 end 57 58 # Escape identifiers for graphviz 59 def esc(id, inst) 60 case id 61 when Folder::ROOT_DIR then "#{inst.name}_root" 62 when Folder::TRASH_DIR then "#{inst.name}_trash" 63 when Folder::SHARED_WITH_ME_DIR then "#{inst.name}_shared" 64 when Folder::NO_LONGER_SHARED_DIR then "#{inst.name}_no_longer" 65 else 'x' + id 66 end 67 end 68 69 def tree_for(inst) 70 Helpers.couch.all_docs inst.domain, CozyFile.doctype 71 end 72 end 73 end