Forum: Ruby Directory Diff Script

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Nick (Guest)
on 2006-05-29 14:59
Hi,

I am after a directory diff script in Ruby, so I can compare all the
files in multiple directories. Does anybody know of such a script?

Thanks.

Nick.
Suraj N. Kurapati (Guest)
on 2006-05-29 16:14
(Received via mailing list)
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Nick wrote:
> I am after a directory diff script in Ruby, so I can compare all the
> files in multiple directories. Does anybody know of such a script?

Yes, it's called diff. If you want a GUI try meld or kompare.

http://www.linuxjournal.com/article/1237


$ head a/* b/*
==> a/bar <==
bar

==> a/foo <==
foo

==> b/bar <==
foo

==> b/foo <==
bar

$ diff -u a b
diff -u a/bar b/bar
- --- a/bar	2006-05-29 05:08:11.000000000 -0700
+++ b/bar	2006-05-29 05:08:16.000000000 -0700
@@ -1 +1 @@
- -bar
+foo
diff -u a/foo b/foo
- --- a/foo	2006-05-29 05:07:49.000000000 -0700
+++ b/foo	2006-05-29 05:08:05.000000000 -0700
@@ -1 +1 @@
- -foo
+bar
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2.2 (GNU/Linux)

iD8DBQFEeuUYmV9O7RYnKMcRAvw6AKCygIWiiPpworeAI5HRaf8euu1f6QCePKRQ
pwYlDR5ANIy4Uk6f1797LLo=
=Mlsd
-----END PGP SIGNATURE-----
Suraj N. Kurapati (Guest)
on 2006-05-30 01:40
(Received via mailing list)
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Suraj N. Kurapati wrote:
> Nick wrote:
>>> I am after a directory diff script in Ruby, so I can compare all the
>>> files in multiple directories. Does anybody know of such a script?
>
> Yes, it's called diff. If you want a GUI try meld or kompare.
>
> http://www.linuxjournal.com/article/1237

Whoops, I misread the question. Sorry :-)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2.2 (GNU/Linux)

iD8DBQFEe0vQmV9O7RYnKMcRAnEwAJ4qrPD4B0lcgWi07B3T0x8QTyLBngCePtNr
m273oraSo/EQhPL5GA47jtI=
=bnMh
-----END PGP SIGNATURE-----
Niklas Frykholm (Guest)
on 2006-05-30 11:31
(Received via mailing list)
> Hi,
>
> I am after a directory diff script in Ruby, so I can compare all the
> files in multiple directories. Does anybody know of such a script?
>
> Thanks.
>
> Nick.
>
I wrote this a while ago. I'm not sure exactly what you are after, but
maybe you can use it as a starting point:

#!/usr/bin/ruby

IGNORE_EXT = %w(.scc .exe .xbe .lib .sbr .obj .dat .suo .pdb .res .idb
.pch)
IGNORE_BASE = %w(_darcs lib vultures buildlog.htm contentmeta.h rdiff)

class String
    def indent
        return "\t" + self.gsub("\n", "\n\t")
    end
end

class Diff

    def diff(f1, f2)
        if f1.respond_to?(:to_ary)
            filelist(f1.to_ary, f2.to_ary)
        else
            if File.directory?(f1) and File.directory?(f2)
                dir(f1,f2)
            elsif File.file?(f1) and File.file?(f2)
                file(f1,f2)
            elsif File.directory?(f1)
                report_directory(f1, f2)
            elsif File.directory?(f2)
                report_directory(f2, f1)
            elsif File.file?(f1)
                report_file(f1, f2)
            elsif File.file?(f2)
                report_file(f2, f1)
            end
        end
    end

    def file(f1, f2)
        res = `diff #{f1} #{f2}`
        report_diff(f1, f2, res) if res != ""
    end

    def filelist(l1, l2)
        map = {}
        s = Struct.new(:f1, :f2)
        for f in l1
            next if IGNORE_EXT.include?(File.extname(f))
            next if IGNORE_BASE.include?(File.basename(f))
            next if f[/~\d*$/]
            map[ File.basename(f) ]  = s.new(f, nil)
        end
        for f in l2
            next if IGNORE_EXT.include?(File.extname(f))
            next if IGNORE_BASE.include?(File.basename(f))
            next if f[/~\d*$/]
            b = File.basename(f)
            map[ b ] = s.new(nil, nil) if not map[ b ]
            map[ b ].f2 = f
        end
        for base, files in map
            if !files.f1
                report_missing(files.f2)
            elsif !files.f2
                report_missing(files.f1)
            else
                diff(files.f1, files.f2)
            end
        end
    end

    def dir(d1, d2)
        diff( Dir.glob(d1 + "/*").collect {|x| x.downcase},
            Dir.glob(d2 + "/*").collect {|x| x.downcase} )
    end

    # Reporting functions

    def report_directory(d, f)
        report(:type_mismatch, "#{d} is a directory, but #{f} is not")
    end

    def report_file(f, x)
        report(:type_mismatch, "#{f} is a regular file, but #{x} is
not")
    end

    def report_missing(f)
        report(:missing_file, "#{f} has no corresponding file") if
$report_missing
    end

    def report_diff(f1, f2, res)
        report(:diff, "\n#{f1} <--> #{f2}\n\n#{res.indent}")
    end

    def report(type, s)
        puts
        puts s
    end

end

require 'optparse'

$report_missing = false
$ignore_case = true

opts = OptionParser.new
opts.on('-m', '--missing', "Report missing files.")        {|val|
$report_missing = true;}
rest = opts.parse(*ARGV)

Diff.new().diff(rest[0], rest[1])
This topic is locked and can not be replied to.