Skip to content

Instantly share code, notes, and snippets.

@chetan
Created February 27, 2010 01:04
Show Gist options
  • Save chetan/316361 to your computer and use it in GitHub Desktop.
Save chetan/316361 to your computer and use it in GitHub Desktop.
reduce buildr spec list
#!/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