Created
February 27, 2010 01:04
-
-
Save chetan/316361 to your computer and use it in GitHub Desktop.
reduce buildr spec list
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/ruby | |
if ARGV.empty? then | |
puts "usage: reduce_deps.rb <file with dep constants>" | |
exit | |
end | |
deps_file = ARGV[0] | |
orig_consts = Object.constants | |
require deps_file | |
new_consts = Object.constants - orig_consts | |
class Artifact | |
include Comparable | |
attr_accessor :name, :specs, :joins, :main | |
def initialize(name) | |
@name = name | |
@specs = [] | |
@joins = [] | |
end | |
def <<(const) | |
@specs << const | |
end | |
def simple? | |
@specs.size == 1 and @joins.empty? | |
end | |
def to_s | |
return str = "#{@name} = [ \"#{@specs.first}\" ]" if simple? | |
str = "#{@name} = [\n" | |
str += @specs.sort.map { |s| " \"#{s}\"" }.join(",\n") | |
str += "\n]" | |
str += " + " + @joins.sort.join(" + ") if not @joins.empty? | |
return str | |
end | |
def <=> (b) | |
if simple? then | |
if b.simple? then | |
return (@name <=> b.name) | |
else | |
return -1 | |
end | |
end | |
if b.simple? then | |
return 1 | |
end | |
# both are 'complex' | |
if b.joins.include? @name then | |
return -1 | |
elsif @joins.include? b.name then | |
return 1 | |
else | |
return (@name <=> b.name) | |
end | |
end | |
end | |
new_specs = {} | |
new_consts.each { |c| | |
#puts "const: #{c}" | |
spec = Kernel.const_get(c) | |
case spec | |
when Array | |
# loop through and see if any of the subspecs are declared elsewhere | |
new_spec = Artifact.new(c) | |
spec.each { |s| | |
id = s.split(":")[1].gsub(/[-.]/, "_").upcase | |
if id == c then | |
new_spec << s | |
new_spec.main = s | |
elsif new_consts.include? id then | |
new_spec.joins << id | |
else | |
new_spec << s | |
end | |
} | |
when String | |
new_spec = Artifact.new(c) | |
new_spec << spec | |
new_spec.main = spec | |
end | |
new_specs[c] = new_spec | |
} | |
new_specs.each { |id, artifact| | |
# on this pass, check if ALL of this artifact's specs are contained in some other artifact. | |
# if so, cleanup that artifact | |
next if artifact.specs.size == 1 | |
new_specs.each { |oid, other| | |
next if id == oid | |
otherspecs = other.specs.dup | |
if other.joins.include? id then | |
otherspecs << artifact.main | |
end | |
diff = artifact.specs - otherspecs | |
if diff.empty? then | |
other.specs = other.specs - artifact.specs | |
other.joins << id if not other.joins.include? id | |
end | |
} | |
} | |
### DONE - PRINT OUTPUT | |
# we do this in 2 steps so we can get 'pretty' output :) | |
# get all the simple one liners | |
out = new_specs.values.find_all { |a| a.simple? } | |
puts out.sort | |
puts | |
# now try to order the complex ones | |
complex = new_specs.values - out | |
puts complex.sort.join("\n\n") | |
# look for and report on any remaining dupes: | |
dupes = {} | |
new_specs.each { |id, artifact| | |
artifact.specs.each { |spec| | |
if not dupes.include? spec then | |
dupes[spec] = [] | |
end | |
dupes[spec] << artifact.name | |
} | |
} | |
dupes.reject!{ |i,a| a.size < 2 } | |
if not dupes.empty? then | |
puts "REMAINING DUPLICATES:" | |
dupes.each { |i,a| puts " #{i}: " + a.join(", ") } | |
puts | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment