Follow me
RSS feed
My sources
My Viadeo

Visualiser un fichier Ant avec GraphViz

Greg | 29 Oct 2011

Projets Depuis quelques jours, nous travaillons, avec @syl20j sur la refonte des installeurs des applications CD VIDAL. Dans leurs versions actuelles, ces installeurs sont générés via des scripts Ant utilisant du NSIS sous Windows et du PackageMaker sous Mac. Nous avons décidé de supprimer ces scripts pour remplacer tout cela par du maven et de l'install4j. Une des étapes consiste donc à comprendre ce que font les scripts Ant. Afin de faciliter notre travail, j'ai développé un petit script permettant de faire une représentation d'un fichier de build sous forme de graph.

Le voici :

#!/usr/bin/env ruby

require 'rubygems'
require 'open-uri'
require 'nokogiri'
require 'graphviz'
require 'getoptlong'

class Ant2Gv
   def initialize(build_file, gv_path) 
      @build_file = build_file
      @build_doc = Nokogiri::XML(open(@build_file))
      @build_graph = GraphViz.new(:ANT, :path => gv_path)
      @build_graph.node["shape"] = "polygon"
      parse
   end

   def save(format, file)
      @build_graph.output(format => file)
   end

   def parse
      @build_doc.xpath("/project/target").each do |target|
         add_target(target)
      end
   end

   def add_target(target)
      target_name = target.attributes["name"].value.strip
      target_node = @build_graph.add_node(target_name)

      unless target.attributes["depends"].nil?
         target.attributes["depends"].value.split(",").each do |dep|
            @build_graph.add_edge(dep.strip, target_node)
         end
      end

      (target.children / "subant").each do |subant|
         subant_name = subant.attributes["target"].value
         (subant.children / "fileset").each do |fileset|
            subant_file = fileset.attributes["dir"].value.strip + "/" + fileset.attributes["includes"].value.strip
            node_name = (subant_name + "_" + subant_file).gsub(/\.|\//, "_")
            subant_node = @build_graph.add_node( node_name, "shape" => "record", "label" => "{#{subant_name} | #{subant_file}}" )
            @build_graph.add_edge(target_node, subant_node)
         end
      end
   end
end

def usage
  puts "usage: ant2gv [-Tformat] [-ofile] [-h] [build.xml]"
  puts "-T, --output-format format    Output format (default: DOT)"
  puts "-o, --output-file file        Output file (default: STDOUT)"
  puts "-p, --path                    Graphviz path"
  puts "-h, --help                    Show this usage message"
end

out_file = String
out_format = :dot
gv_path = ""

oOpt = GetoptLong.new(
  ['--output-file',   '-o', GetoptLong::REQUIRED_ARGUMENT],
  ['--output-format', '-T', GetoptLong::REQUIRED_ARGUMENT],
  ['--path',          '-p', GetoptLong::REQUIRED_ARGUMENT],
  ['--help',          '-h', GetoptLong::NO_ARGUMENT]
)

begin
  oOpt.each_option do |option, value|
    case option
      when '--output-file'
        out_file = value
      when '--output-format'
        out_format = value.to_sym
      when '--path'
        gv_path = value
      when '--help'
        usage( )
        exit
    end 
  end 
rescue GetoptLong::InvalidOption => e
  usage( )
  exit
end

build_file=ARGV[0] || "build.xml"
out = Ant2Gv.new(build_file, gv_path).save(out_format, out_file)
print out unless out.nil?

Si vous souhaitez récupérer ce script, il est disponible ici.

Copyright © 2009 - 2011 Grégoire Lejeune.
All documents licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 2.5 License, except ones with specified licence.
Powered by Jekyll.