On Fri, 5 Aug 2005, Jacob Fugal wrote:

> On 8/3/05, Lothar Scholz <mailinglists / scriptolutions.com> wrote:
>> JF> Though Brian Schr=F6der gave an interesting irb implementation, what =
> you
>> JF> really need is diff[1]. And don't despair, there is diff for
>> JF> Windows[2] (via the command line).
>> =20
>> JF> The GNU developers have put a *lot*
>> JF> of work and refinement into this heavily used tool -- don't reinvent
>> JF> the wheel.
>> =20
>> <flame>
>> And they still got nothing what even comes close to "AraxisMerge" on
>> Windows, neither from the GUI nor from the quality of the diff algorithm.
>> </flame>
>
> Ok, to qualify my statement: Don't reinvent this particular wheel for
> a once-off solution. I won't say that someone else can make a better
> wheel when that's their primary goal. I don't think Dave Davidson's
> goal is to develop a new diff utility. Regarding AraxisMerge, I've
> never heard of it. It may be better than GNU DiffUtils. I can't make
> any judgement there.
>
>> But back to the question from the original poster, i think diff is a
>> complete wrong idea as he said he only needs the file names and the conte=
> nt
>> does not matter for an installer as he puts the complete file into the
>> setup.exe.
>
> diff -qr | grep '^Only'
>
> Know the tool before dismissing it.

the way i read the OP's post the original contents should be stored and
alterable.  the diff approach would require both directories to exist and be
stored and i think the OP wanted to store only the __inventory__ of the dir -
not the actual dir.  so not only would the storage/database requirements
skyrocket, but you'd be using a sledgehammer to pound in a mini-tack.  this
problem is quite easily solved in only a few lines of ruby - including
database code, command line parsing, etc:


here's the code:


     harp:~ > cat ./dirlist

     #! /usr/bin/env ruby
     require 'pstore'
     require 'yaml'
     require 'getoptlong'

     class DirDb < ::PStore
       def [] dir
         transaction{ super(exp(dir)) rescue nil}
       end
       def []= dir, filelist
         transaction{ super(exp(dir), filelist) }
       end
       def exp dir
         File::expand_path dir
       end
     end

     class FileList < ::Array
       def initialize dir
         @dir = File::expand_path dir
         @glob = File::join @dir, '**', '*'
         replace Dir[@glob].map{|f| File::expand_path f}
       end
       def basenames
         map{|f| f.gsub(%r|^#{ Regexp::escape @dir }/*|,'')}
       end
       def add filename
         self << File::expand_path(File::join(@dir, filename))
       end
       def delete filename
         super(File::expand_path(File::join(@dir, filename)))
       end
       def to_yaml
         to_a.to_yaml
       end
     end

     class Main
       def self::main(*a, &b)
         new(*a, &b).run
       end
       def initialize
         gl = GetoptLong::new ['--db', '-d', GetoptLong::REQUIRED_ARGUMENT]
         gl.each do |opt, arg|
           case opt
             when /db/
               @db_path = arg
           end
         end
         @db_path ||= File::expand_path(File::join('~', '.dirdb'))
         @mode, @mode_args = ARGV.shift, ARGV
         @mode ||= 'help'
         @db = DirDb::new @db_path
       end
       def run
         send(@mode, *@mode_args)
       end
       def scan dir
         @db[dir] = FileList::new dir
         show dir
       end
       def show dir
         y @db[dir]
       end
       def report old_dir, new_dir
         previous = @db[old_dir]
         current = FileList::new new_dir
         report = {}
         report['identical'] = previous.basenames & current.basenames
         report['extra'] = current.basenames - previous.basenames
         report['removed'] = previous.basenames - current.basenames
         y report
       end
       def add dir, filename
         filelist = @db[dir]
         filelist.add filename
         @db[dir] = filelist
       end
       def delete dir, filename
         filelist = @db[dir]
         filelist.delete filename
         @db[dir] = filelist
       end
       def help
         puts "#{ $0 } scan dir | show dir | report new_dir old_dir | add dir filename | delete dir filename"
       end
     end

     $0 == __FILE__ and Main::main



and here's how you use it:


     harp:~ > mkdir version-1.0.0 && touch version-1.0.0/a version-1.0.0/b version-1.0.0/c


     harp:~ > ./dirlist
     ./dirlist scan dir | show dir | report new_dir old_dir | add dir filename | delete dir filename


     harp:~ > ./dirlist scan version-1.0.0/
     ---
     - /home/ahoward/version-1.0.0/a
     - /home/ahoward/version-1.0.0/b
     - /home/ahoward/version-1.0.0/c


     harp:~ > rm -rf version-1.0.0/


     harp:~ > mkdir version-2.0.0 && touch version-2.0.0/a version-2.0.0/b


     harp:~ > ./dirlist report version-1.0.0 version-2.0.0
     ---
     removed:
       - c
     extra: []
     identical:
       - a
       - b


     harp:~ > touch version-2.0.0/c


     harp:~ > ./dirlist report version-1.0.0 version-2.0.0
     ---
     removed: []
     extra: []
     identical:
       - a
       - b
       - c


     harp:~ > touch version-2.0.0/d


     harp:~ > ./dirlist report version-1.0.0 version-2.0.0
     ---
     removed: []
     extra:
       - d
     identical:
       - a
       - b
       - c


     harp:~ > ./dirlist add version-1.0.0 d


     harp:~ > ./dirlist report version-1.0.0 version-2.0.0
     ---
     removed: []
     extra: []
     identical:
       - a
       - b
       - c
       - d


     harp:~ > rm version-2.0.0/a


     harp:~ > ./dirlist report version-1.0.0 version-2.0.0
     ---
     removed:
       - a
     extra: []
     identical:
       - b
       - c
       - d


     harp:~ > ./dirlist delete version-1.0.0 a


     harp:~ > ./dirlist report version-1.0.0 version-2.0.0
     ---
     removed: []
     extra: []
     identical:
       - b
       - c
       - d


in any case, i'm all for using built-in tools to accomplish tasks - but this
task is so basic it seem silly not to just write it in pure ruby...

kind regards.

-a
-- 
===============================================================================
| email :: ara [dot] t [dot] howard [at] noaa [dot] gov
| phone :: 303.497.6469
| My religion is very simple.  My religion is kindness.
| --Tenzin Gyatso
===============================================================================