Robert Klemme
3/25/2008 8:19:00 AM
2008/3/24, Adam Boyle <briefcase.speakers@gmail.com>:
> > Why do you need that? I mean, if a folder is excluded then you want to
> > exclude all files and subfolders, don't you?
>
>
> Yes, an excluded folder would also exclude its children files and
> folders.
>
> I'm thinking that I haven't exactly made it clear what my goal is...
>
> Using Find.find, I want to traverse through a directory structure and
> make an NSIS-style list of files and their paths for use in an NSIS
> installer script. A list of this sort would be best organized if a
> directory's file children are listed before the directory children.
>
> Example:
>
> SetOutPath "jruby-1.0.3/docs"
> File "jruby-1.0.3/docs/README.rails"
> File "jruby-1.0.3/docs/README.coverage"
> File "jruby-1.0.3/docs/Readline-HOWTO.txt"
> File "jruby-1.0.3/docs/LICENSE.bouncycastle"
> File "jruby-1.0.3/docs/LICENSE.ant"
> File "jruby-1.0.3/docs/LICENCE.bsf"
> File "jruby-1.0.3/docs/Glossary.txt"
> File "jruby-1.0.3/docs/getting_involved.html"
>
> SetOutPath "jruby-1.0.3/docs/rbyaml"
> File "jruby-1.0.3/docs/rbyaml/README"
> File "jruby-1.0.3/docs/rbyaml/LICENSE"
>
> SetOutPath "jruby-1.0.3/docs/jvyaml"
> File "jruby-1.0.3/docs/jvyaml/README"
> File "jruby-1.0.3/docs/jvyaml/LICENSE"
> File "jruby-1.0.3/docs/jvyaml/CREDITS"
>
> ...
>
>
> The "SetOutPath" lines are the directories, the "File" lines are the
> files.
>
> The code you gave will gave results like this (once I used Ruby
> instead of JRuby :)...):
>
> SetOutPath jruby-1.0.3
>
> SetOutPath jruby-1.0.3/samples
> File jruby-1.0.3/samples/xslt.rb
> File jruby-1.0.3/samples/thread.rb
> File jruby-1.0.3/samples/swing2.rb
> File jruby-1.0.3/samples/scripting.rb
> File jruby-1.0.3/samples/javascript.rb
> File jruby-1.0.3/samples/java2.rb
> File jruby-1.0.3/samples/error.rb
> File jruby-1.0.3/samples/dom-applet.html
> File jruby-1.0.3/samples/applet.html
> File jruby-1.0.3/README
> SetOutPath jruby-1.0.3/lib
> SetOutPath jruby-1.0.3/lib/ruby
> SetOutPath jruby-1.0.3/lib/ruby/site_ruby
> SetOutPath jruby-1.0.3/lib/ruby/site_ruby/1.8
> File jruby-1.0.3/lib/ruby/site_ruby/1.8/ubygems.rb
> File jruby-1.0.3/lib/ruby/site_ruby/1.8/securerandom.rb
> File jruby-1.0.3/lib/ruby/site_ruby/1.8/rubygems.rb
> SetOutPath jruby-1.0.3/lib/ruby/site_ruby/1.8/rubygems
> File jruby-1.0.3/lib/ruby/site_ruby/1.8/rubygems/version.rb
> File jruby-1.0.3/lib/ruby/site_ruby/1.8/rubygems/validator.rb
> File jruby-1.0.3/lib/ruby/site_ruby/1.8/rubygems/
> user_interaction.rb
> File jruby-1.0.3/lib/ruby/site_ruby/1.8/rubygems/timer.rb
> File jruby-1.0.3/lib/ruby/site_ruby/1.8/rubygems/
> specification.rb
> File jruby-1.0.3/lib/ruby/site_ruby/1.8/rubygems/
> source_info_cache_entry.rb
> ...
>
>
> The issue is that it is very important that the SetOutPath call for
> any particular file comes directly before it in the list (ie,
> SetOutPath jruby-1.0.3 for the line File jruby-1.0.3/README). That
> way the output path is set correctly when the file is extracted from
> the installer executable.
>
> The selected lines from the previous example would ideally be listed
> this way:
>
> SetOutPath jruby-1.0.3
>
> File jruby-1.0.3/README
> SetOutPath jruby-1.0.3/samples
> File jruby-1.0.3/samples/xslt.rb
> File jruby-1.0.3/samples/thread.rb
> File jruby-1.0.3/samples/swing2.rb
> File jruby-1.0.3/samples/scripting.rb
> File jruby-1.0.3/samples/javascript.rb
> File jruby-1.0.3/samples/java2.rb
> File jruby-1.0.3/samples/error.rb
> File jruby-1.0.3/samples/dom-applet.html
> File jruby-1.0.3/samples/applet.html
> SetOutPath jruby-1.0.3/lib/ruby/site_ruby/1.8
> File jruby-1.0.3/lib/ruby/site_ruby/1.8/ubygems.rb
> File jruby-1.0.3/lib/ruby/site_ruby/1.8/securerandom.rb
> File jruby-1.0.3/lib/ruby/site_ruby/1.8/rubygems.rb
> SetOutPath jruby-1.0.3/lib/ruby/site_ruby/1.8/rubygems
> File jruby-1.0.3/lib/ruby/site_ruby/1.8/rubygems/version.rb
> File jruby-1.0.3/lib/ruby/site_ruby/1.8/rubygems/validator.rb
> File jruby-1.0.3/lib/ruby/site_ruby/1.8/rubygems/
> user_interaction.rb
> File jruby-1.0.3/lib/ruby/site_ruby/1.8/rubygems/timer.rb
> File jruby-1.0.3/lib/ruby/site_ruby/1.8/rubygems/
> specification.rb
> File jruby-1.0.3/lib/ruby/site_ruby/1.8/rubygems/
> source_info_cache_entry.rb
> ...
>
>
> It's beginning to seem to me that Find.find just doesn't have an easy
> way of sorting the elements being traversed. Any additional help is
> greatly appreciated.
Thanks for clarifying. You could do something like this:
require 'find'
base='.'
excludes = []
dirs = Hash.new {|h,p| h[p]=[]}
Find.find base do |path|
if File.directory? path
Find.prune if excludes.include? path
else
dirs[File.dirname(path)] << path
end
end
dirs.sort.each do |dir,files|
puts "SetOutPath #{dir}"
files.each {|f| puts "File #{f}"}
end
If you want to do printing while traversing then the code becomes more
complicated (either using Find or manual traversal via Dir[]).
Kind regards
robert
--
use.inject do |as, often| as.you_can - without end