Skip to content

Instantly share code, notes, and snippets.

@kou1okada
Last active October 13, 2015 21:19
Show Gist options
  • Save kou1okada/4257523 to your computer and use it in GitHub Desktop.
Save kou1okada/4257523 to your computer and use it in GitHub Desktop.
cygwin package dependency checker
#!/usr/bin/env ruby
#-----------------------------------------------------------------------------
# cygdep.rb - cygwin package dependency checker.
# Copyright (c) 2012 Koichi OKADA. All rights reserved.
#
# License:
# MIT license.
#-----------------------------------------------------------------------------
require 'optparse'
def scan_requires requires, pkg, count = {}, depth = 0
return if 0 < $conf[:depth] && $conf[:depth] < depth
count[pkg] = 0 if count[pkg].nil?
count[pkg] += 1
status = ""
status << "[pakcage not found] " if requires[pkg].nil?
status << "[loop] " if $conf[:loop] && 1 < count[pkg]
status << "=> " if status != ""
indent = $conf[:style] == "tree" ? ("| " * depth + "+ ") : ""
puts "#{indent}#{status}#{pkg}" if count[pkg] == 1 || $conf[:loop]
requires[pkg].each do |v|
scan_requires requires, v, count, depth + 1
end if !requires[pkg].nil? && count[pkg] == 1
end
requires_to = {}
requires_from = {}
lastcache = open("/etc/setup/last-cache" ) {|f| f.gets.chop!}
lastmirror = open("/etc/setup/last-mirror") {|f| f.gets.chop!}
unless RUBY_PLATFORM =~ /^(.+)-cygwin$/
STDERR.puts "This script is only for cygwin environment."
exit 1
end
arch = $1 == "x86_64" ? $1 : "x86"
$conf = {
:depth => 0,
:ini => "#{lastcache}/#{lastmirror.gsub(/[%\/:]/, {'%'=>'%25', '/'=>'%2f', ':'=>'%3a'})}/#{arch}/setup.ini",
:loop => nil,
:recursive => true,
:require => "both",
:style => "tree",
}
opts = OptionParser.new
opts.banner = "#{File.basename $0} [options] packagename ..."
opts.on("-d", "--depth DEPTH", Numeric, "scan depth. for infinite. (default: #{$conf[:depth]})") {|v| $conf[:depth] = v.to_i}
opts.on("-i", "--ini INIFILE", "Specify setup.ini file to use. (default: #{$conf[:ini]})") {|v| $conf[:ini] = v}
opts.on("-l", "--loop", "show looped dependency.") {|v| $conf[:loop] = true}
opts.on("-r", "--requires DIR", /to|from|both/, "one of to, from or both. (default: #{$conf[:require]})") {|v| $conf[:require] = v}
opts.on("-s", "--style STYLE", /tree|flat/, "tree or flat. (default: #{$conf[:style]})") {|v| $conf[:style] = v}
opts.parse! ARGV
open($conf[:ini], "r") do |f|
requires = []
while f.gets
$_.chop!
$F = $_.split
if $F[0] == "@"
name = $F[1]
requires = []
requires_from[name] = [] if requires_from[name].nil?
requires_to[name] = [] if requires_to[name].nil?
end
requires = $F[1..-1] if $F[0] == "requires:" && 1 < $F.length
if $_ == ""
requires.each do |v|
requires_from[v] = [] if requires_from[v].nil?
requires_from[v] << name
end
requires_to[name] = requires
end
end
end
if $conf[:require] =~ /from|both/
puts "[requires_from]"
ARGV.each do |v|
scan_requires requires_from, v
end
puts
end
if $conf[:require] =~ /to|both/
puts "[requires_to]"
ARGV.each do |v|
scan_requires requires_to, v
end
puts
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment