On 20.03.2008 16:46, Adam Boyle wrote: > I'm looking for a simple way to use Find.find to produce a list of > files/directories for NSIS. Ideally the list will sort files before > directories so as to minimize the number of times SetOutPath is used > (an NSIS function). > > The script so far is as follows: > -----------snip----------------------- > dirs = ["jruby-1.0.3"] > excludes = [] > for dir in dirs > folder = '' > Find.find(dir) do |path| > if FileTest.directory?(path) > if excludes.include?(File.basename(path)) > Find.prune # Don't look any further into this directory. > else > next > end > else > if folder != File.dirname(path) > folder = File.dirname(path) > puts 'SetOutPath "' + folder + '"' > end > puts 'File "' + path + '"' > end > end > end > > -----------------------end snip------------------- > > Simple directory traversal, no problem there. The issue is that > Find.find doesn't allow any sort of ordering to be specified; namely > that directories are mixed in with files. The script produces the > following output: > > ---------------output--------------------------------- > 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" > 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" > File "jruby-1.0.3/docs/LICENSE.bouncycastle" > File "jruby-1.0.3/docs/LICENSE.ant" > File "jruby-1.0.3/docs/LICENCE.bsf" > 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" > SetOutPath "jruby-1.0.3/docs" > File "jruby-1.0.3/docs/Glossary.txt" > File "jruby-1.0.3/docs/getting_involved.html" > -----------------------end output------------------------- > > The desired output would sort sub-folders before files when traversing > a given directory, thus eliminating the duplicate entries for > SetOutPath "jruby-1.0.3/docs" as seen above. > > ------------desired output-------------------------------- > 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" > ------------------------------end output-------------------------- > > Any ideas? IIRC Find.find does sort sub folders before files. To me your code seems pretty complex and I believe the major problem is that you check the same directory over and over again for exclusion because you use File.basename. Can't you just do this? Find.find base do |path| if File.directory? path if excludes.include? path Find.prune else puts "SetOutPath #{path}" end else puts "File #{path}" end end Kind regards robert