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/
···
On Fri, 5 Aug 2005, Jacob Fugal wrote:
On 8/3/05, Lothar Scholz <mailinglists@scriptolutions.com> wrote:
> Though Brian Schr=F6der gave an interesting irb implementation, what =
you
> really need is diff[1]. And don't despair, there is diff for
> Windows[2] (via the command line).
=20
> The GNU developers have put a *lot*
> of work and refinement into this heavily used tool -- don't reinvent
> 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.
---
- /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
===============================================================================