1 #!/usr/bin/ruby -Eutf-8
4 # Find dependencies between ruby packages
6 # Must run inside a openwrt with all *ruby* packages installed
11 puts
"Looking for installed ruby packages..."
12 packages
=`opkg list-installed '*ruby*' | cut -d' ' -f 1`.split("\n")
14 puts
"Looking for packages files..."
15 package_files
=Hash
.new([])
18 files
=`opkg files "#{pkg}" | sed -e 1d`.split("\n")
19 package_files
[pkg
]=files
if files
22 require_regex
=/^require ["']([^"']+)["'].*/
23 require_regex_ignore
=/^require ([a-zA-Z\$]|["']$|.*\/$
)/
24 require_ignore
=%w
{drb
/invokemethod16 foo rubygems/defaults
/operating_system win32console java Win32API
25 builder
/xchar json/pure simplecov win32
/sspi rdoc/markdown
/literals_1_8 enumerator win32/resolv rbtree
26 nqxml
/streamingparser nqxml/treeparser xmlscan
/parser xmlscan/scanner xmltreebuilder xml
/parser xmlparser xml/encoding-ja xmlencoding-ja
27 iconv uconv win32ole gettext
/po_parser gettext/mo libxml
}
30 Encoding
.find("ASCII-8BIT"),
31 Encoding
.find("UTF-8"),
32 Encoding
.find("UTF-7"),
33 Encoding
.find("US-ASCII"),
36 puts
"Looking for requires in files..."
37 files_requires
=Hash
.new([])
40 package_files
[pkg
].each
do
42 next if not File
.file
?(file
)
45 if File
.executable
?(file
)
46 magic
=`head -c50 '#{file}' | head -1`
48 if not magic
=~
/ruby/
58 #puts "Checking #{file}..."
59 File
.open(file
, "r") do
62 while line
=f
.gets() do
63 lineno
+=1; encs
=[]; requires
=[]; need_encdb
=false
65 line
=line
.chomp
.gsub
!(/^[[:blank:]]*/,"")
70 enc
=line
.sub(/.*coding *: */,"").sub(/ .*/,"")
71 encs
<< Encoding
.find(enc
)
79 #puts "#{file}:#{line}"
80 if require_regex_ignore
=~ line
81 #puts "Ignoring #{line} at #{file}:#{lineno} (REGEX)..."
84 if not require_regex
=~ line
85 $stderr.puts
"Unknown require: '#{line}' at file #{file}:#{lineno}"
88 require=line
.gsub(require_regex
,"\\1")
89 require.gsub
!(/\.(so|rb)$/,"")
91 if require_ignore
.include?(require)
92 #puts "Ignoring #{line} at #{file}:#{lineno} (STR)..."
96 files_requires
[file
]=files_requires
[file
] + [require]
99 encs
=line
.scan(/Encoding::[[:alnum:]_]+/).collect
{|enc
| eval(enc
) }.select
{|enc
| enc
.kind_of
? Encoding
}
104 required_encs
= (encs
- builtin_enc
).collect
{|enc
| "enc/#{enc.name.downcase.gsub("-","_
")}" }
105 required_encs
<< "enc/encdb" if need_encdb
107 files_requires
[file
] = files_requires
[file
] + required_encs
115 package_files
.each
do |(pkg
,files
)| files
.each
do |file
|
118 files_requires
[file
]= files_requires
[file
] + ["enc/encdb"]
122 puts
"Merging requirements into packages..."
123 package_requires
= Hash
[packages
.collect
{ |pkg
| [pkg
, package_files
[pkg
].collect
{|file
| files_requires
[file
] }.inject([],:+).uniq
] }]
125 weak_dependency
=Hash
.new([])
126 weak_dependency
.merge
!({
127 "ruby-misc"=>["ruby-openssl","ruby-fiddle"], #securerandom.rb
128 "ruby-debuglib"=>["ruby-readline"], #debug.rb
129 "ruby-drb"=>["ruby-openssl"], #drb/ssl.rb
130 "ruby-irb"=>["ruby-rdoc", "ruby-readline"], #irb/cmd/help.rb
131 "ruby-gems"=>["ruby-openssl","ruby-io-console","ruby-webrick"], #rubygems/commands/cert_command.rb rubygems/user_interaction.rb rubygems/server.rb
132 "ruby-mkmf"=>["ruby-webrick"], #un.rb
133 "ruby-net"=>["ruby-openssl","ruby-io-console","ruby-zlib"], #net/*.rb
134 "ruby-optparse"=>["ruby-uri","ruby-datetime"], #optparse/date.rb optparse/uri.rb
135 "ruby-rake"=>["ruby-net","ruby-gems"], #rake/contrib/ftptools.rb /usr/bin/rake
136 "ruby-rdoc"=>["ruby-gems","ruby-readline","ruby-webrick", #/usr/bin/rdoc and others
137 "ruby-io-console"], #rdoc/stats/normal.rb
138 "ruby-webrick"=>["ruby-openssl"], #webrick/ssl.rb
141 puts
"Preloading gems..."
142 Gem
::Specification.all
.each
{ |x
| gem x
.name
}
144 puts
"Looking for package dependencies..."
145 package_provides
= {}
146 package_dependencies
= Hash
.new([])
147 package_requires
.each
do
152 if package_provides
.include?(require)
153 found
= package_provides
[require]
155 found
= package_files
.detect
{|(pkg
,files
)| files
.detect
{|file
| $
:.detect
{|path
| "#{path}/#{require}" == file
.gsub(/\
.(so
|rb
)$/,"") } } }
157 $stderr.puts
"#{pkg}: Nothing provides #{require}"
162 package_provides
[require]=found
164 if weak_dependency
[pkg
].include?(found
)
165 puts
"#{pkg}: #{found} provides #{require} (ignored WEAK dep)"
167 puts
"#{pkg}: #{found} provides #{require}"
168 package_dependencies
[pkg
]=package_dependencies
[pkg
] + [found
]
173 puts
"There is some missing requirements not mapped to files in packages."
174 puts
"Please, fix the missing files or ignore them on require_ignore var"
178 package_dependencies
.each
do
180 package_dependencies
[pkg
]=deps
.uniq
.sort
- [pkg
]
183 puts
"Expanding dependencies..."
186 package_dependencies
.each
do
191 deps_new
= deps
.collect
{|dep
| [dep
] + package_dependencies
[dep
] }.inject([],:+).uniq
.sort
192 if not deps
== deps_new
193 puts
"#{pkg}: #{deps.join(",")}"
194 puts
"#{pkg}: #{deps_new.join(",")}"
195 package_dependencies
[pkg
]=deps_new
201 puts
"Checking for mutual dependencies..."
202 package_dependencies
.each
do
205 $stderr.puts
"#{pkg}: Cycle dependency detected! "
211 puts
"Removing redundant dependencies..."
212 package_dependencies
.each
do
214 package_dependencies
[pkg
]=deps
.uniq
- [pkg
]
217 package_dependencies2
=package_dependencies
.dup
218 package_dependencies
.each
do
221 # Ignore dependencies that are aready required by another dependency
222 deps_clean
= deps
.reject
{|dep_suspect
| deps
.detect
{|dep_provider
|
223 if package_dependencies
[dep_provider
].include?(dep_suspect
)
224 puts
"#{pkg}: #{dep_suspect} is already required by #{dep_provider}"
229 if not deps
==deps_clean
230 puts
"before: #{deps.join(",")}"
231 puts
"after: #{deps_clean.join(",")}"
232 package_dependencies2
[pkg
]=deps_clean
235 package_dependencies
=package_dependencies2
237 puts
"Checking current packages dependencies..."
239 package_dependencies
.each
do
241 current_deps
=`opkg depends #{pkg} | sed -r -e '1d;s/^[[:blank:]]*//'`.split("\n")
242 current_deps
.reject
!{|dep
| dep
=~
/^lib/ }
243 current_deps
-= ["ruby"]
245 extra_dep
= current_deps
- deps
246 $stderr.puts
"Package #{pkg} does not need to depend on #{extra_dep.join(" ")} " if not extra_dep
.empty
?
247 missing_dep
= deps
- current_deps
248 $stderr.puts
"Package #{pkg} needs to depend on #{missing_dep.join(" ")} " if not missing_dep
.empty
?
250 if not extra_dep
.empty
? or not missing_dep
.empty
?
251 $stderr.puts
"define Package/#{pkg}"
252 $stderr.puts
" DEPENDS:=ruby#{([""] +deps).join(" +")}"
257 puts
"All dependencies are OK." if ok
262 puts
RUBY_VERSION, RUBY_PLATFORM
268 #RUBY_ARCH=i486-linux-gnu
269 #RUBYLIB=/usr/lib/ruby/$RUBY_VER/
270 #RUBYLIB_A=/usr/lib/ruby/$RUBY_ARCH/$RUBY_VER/