dircat 0.0.5 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. data/LICENSE +1 -1
  2. data/README.rdoc +1 -1
  3. data/Rakefile +9 -0
  4. data/VERSION.yml +5 -0
  5. data/bin/dircat-build +6 -0
  6. data/bin/dircat-diff +6 -0
  7. data/bin/dircat-query +6 -0
  8. data/dircat.gemspec +88 -0
  9. data/examples/example.rb +10 -0
  10. data/lib/dircat/cat.rb +192 -0
  11. data/lib/dircat/cli/dircat_build.rb +92 -83
  12. data/lib/dircat/cli/dircat_diff.rb +85 -0
  13. data/lib/dircat/cli/dircat_query.rb +53 -43
  14. data/lib/dircat/entry.rb +60 -0
  15. data/lib/dircat/extension_md5.rb +24 -0
  16. data/lib/dircat/extension_numeric.rb +17 -0
  17. data/lib/dircat/report.rb +61 -0
  18. data/lib/dircat.rb +29 -2
  19. data/spec/dircat/cat_spec.rb +71 -0
  20. data/spec/dircat/cli/dircat_build_spec.rb +59 -0
  21. data/spec/dircat/cli/dircat_query_diff_spec.rb +26 -0
  22. data/spec/dircat/cli/dircat_query_spec.rb +35 -0
  23. data/spec/dircat/md5_spec.rb +12 -0
  24. data/spec/dircat/numeric_spec.rb +11 -0
  25. data/spec/spec_helper.rb +25 -0
  26. metadata +136 -40
  27. data/bin/dircat-build.rb +0 -8
  28. data/bin/dircat-cfr.rb +0 -8
  29. data/bin/dircat-cmp.rb +0 -8
  30. data/bin/dircat-query.rb +0 -8
  31. data/lib/dircat/cli/dircat_cfr.rb +0 -69
  32. data/lib/dircat/cli/dircat_cmp.rb +0 -65
  33. data/lib/dircat/dircat.rb +0 -263
  34. data/test/dircat/tc_dircat.rb +0 -83
  35. data/test/dircat/tc_dircat_build.rb +0 -43
  36. data/test/test_dircat.rb +0 -6
  37. /data/{test_data/dircat/data → spec/fixtures}/certified_output/dircat1.yaml +0 -0
  38. /data/{test_data/dircat/data → spec/fixtures}/certified_output/dircat2.yaml +0 -0
  39. /data/{test_data/dircat/data → spec/fixtures}/dir1/file1.txt +0 -0
  40. /data/{test_data/dircat/data → spec/fixtures}/dir1/subdir/file3.txt +0 -0
  41. /data/{test_data/dircat/data → spec/fixtures}/dir2/file1.txt +0 -0
  42. /data/{test_data/dircat/data → spec/fixtures}/dir2/file2.txt +0 -0
  43. /data/{test_data/dircat/data → spec/fixtures}/dir2/subdir/file3.txt +0 -0
  44. /data/{test_data/dircat/data → spec/fixtures}/dir3/file1.txt +0 -0
  45. /data/{test_data/dircat/data → spec/fixtures}/dir3/subdir/file1.txt +0 -0
  46. /data/{test_data/dircat/data → spec/fixtures}/tmp/dummy.txt +0 -0
@@ -1,59 +1,69 @@
1
- require 'optparse'
2
- require 'dircat/dircat.rb'
1
+ module DirCat
3
2
 
4
- #
5
- # DirCatQuery
6
- #
7
- class DirCatQuery
3
+ class DirCatQuery
8
4
 
9
- def self.run
10
- self.new.parse_args( ARGV)
11
- end
5
+ def self.run
6
+ return self.new.parse_args( ARGV)
7
+ end
12
8
 
13
- def parse_args( args )
14
- options = {}
15
- opts = OptionParser.new
16
- opts.banner =
17
- "Usage: dircat_query [options] <filedircat> <command>\n" +
18
- "mostra informazioni su un dircat\n"
9
+ def parse_args( args )
10
+ options = {}
11
+ opts = OptionParser.new
12
+ opts.banner =
13
+ "Usage: dircat-query [options] <filedircat> [<command>]\n" +
14
+ "show info on dircat catalogs\n"
19
15
 
20
- opts.on("-h", "--help", "Print this message") do
21
- puts opts
22
- return
23
- end
16
+ opts.on("--version", "show the dircat version") do
17
+ puts "dircat version #{DirCat::version}"
18
+ return 0
19
+ end
24
20
 
25
- opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
26
- options[:verbose] = v
27
- end
21
+ opts.on("-h", "--help", "Print this message") do
22
+ puts opts
23
+ return 0
24
+ end
28
25
 
29
- rest = opts.parse( args )
26
+ opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
27
+ options[:verbose] = v
28
+ end
30
29
 
31
- # p options
32
- # p ARGV
30
+ rest = opts.parse( args )
33
31
 
34
- if rest.length < 2
35
- puts "inserire il nome del catalogo da interrogare e il comando da eseguire"
36
- puts "-h to print help"
37
- return
38
- end
32
+ # p options
33
+ # p ARGV
39
34
 
40
- cat_filename = rest[0]
41
- command = rest[1]
35
+ if rest.length < 1
36
+ puts "missing catalog!"
37
+ puts "-h to print help"
38
+ return 0
39
+ end
42
40
 
43
- #
44
- # option verbose
45
- #
46
- if options.has_key?(:verbose)
47
- if options[:verbose]
48
- $VERBOSE_LEVEL = 1
41
+ cat_opts = {}
42
+ cat_filename = rest[0]
43
+ unless File.exists?(cat_filename)
44
+ puts "first args must be a catalogue"
45
+ return 1
49
46
  end
50
- end
51
47
 
52
- s = DirCat.loadfromfile( cat_filename )
48
+ if rest.length > 1
49
+ command = rest[1]
50
+ else
51
+ command = "report"
52
+ end
53
+
54
+ #
55
+ # option verbose
56
+ #
57
+ if options.has_key?(:verbose)
58
+ if options[:verbose]
59
+ cat_opts[:verbose_level] = 1
60
+ end
61
+ end
62
+
63
+ s = Cat.from_file( cat_filename, cat_opts )
53
64
 
54
- #case command
55
- #else
56
65
  puts s.send( command.to_sym )
57
- #end
66
+ 0
67
+ end
58
68
  end
59
69
  end
@@ -0,0 +1,60 @@
1
+ module DirCat
2
+
3
+ class EntrySer < OpenStruct
4
+ end
5
+
6
+ #
7
+ # Entry
8
+ #
9
+ class Entry
10
+
11
+ attr_reader :md5
12
+ attr_reader :name
13
+ attr_reader :path
14
+ attr_reader :size
15
+ attr_reader :mtime
16
+
17
+ def from_filename( filename )
18
+ @name = File.basename(filename)
19
+ @path = File.dirname(filename)
20
+ stat = File.stat(filename)
21
+ @size = stat.size
22
+ @mtime = stat.mtime
23
+ # self.md5 = Digest::MD5.hexdigest(File.read( f ))
24
+ @md5 = MD5.file( filename ).hexdigest
25
+ self
26
+ end
27
+
28
+ def from_ser( entry_ser )
29
+ @md5 = entry_ser.md5
30
+ @name = entry_ser.name
31
+ @path = entry_ser.path
32
+ @size = entry_ser.size
33
+ @mtime = entry_ser.mtime
34
+ self
35
+ end
36
+
37
+ def to_ser
38
+ entry_ser = EntrySer.new
39
+ entry_ser.md5 = @md5
40
+ entry_ser.name = @name
41
+ entry_ser.path = @path
42
+ entry_ser.size = @size
43
+ entry_ser.mtime = @mtime
44
+ entry_ser
45
+ end
46
+
47
+ def to_s
48
+ @md5 + " " + @name + "\t " + @path + "\n"
49
+ end
50
+
51
+ end
52
+
53
+ class DirCatSer < OpenStruct
54
+ end
55
+
56
+
57
+ class DirCatException < RuntimeError
58
+ end
59
+
60
+ end
@@ -0,0 +1,24 @@
1
+ #
2
+ # calculate md5 of big files, found on usenet
3
+ #
4
+
5
+ if RUBY_VERSION =~ /1\.8/
6
+ # stdlib
7
+ require 'md5'
8
+ else
9
+ # stdlib
10
+ require 'digest/md5'
11
+ include Digest
12
+ end
13
+
14
+ class MD5
15
+ def self.file(file)
16
+ File.open(file, "rb") do |f|
17
+ res = self.new
18
+ while (data = f.read(4096))
19
+ res << data
20
+ end
21
+ res
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,17 @@
1
+ class Numeric
2
+ #
3
+ # ritorna una stringa con le migliaia serparate da <separator>
4
+ # es.: 100000 -> 1.000.000
5
+ #
6
+ #
7
+ # copiata da http://wiki.rubygarden.org/Ruby/page/show/FixNumFormat
8
+ #
9
+ def with_separator( separator = ',', length = 3 )
10
+ splitter = Regexp.compile "(\\d{#{length}})"
11
+ before, after = self.to_s.split('.')
12
+ before = before.reverse.gsub splitter, '\1' + separator
13
+ str = "#{ before.chomp( separator ).reverse }"
14
+ str += ".#{ after }" if after
15
+ str
16
+ end
17
+ end
@@ -0,0 +1,61 @@
1
+ module DirCat
2
+
3
+ # From http://gist.github.com/72234
4
+ #
5
+ # mysql-style output for an array of ActiveRecord objects
6
+ #
7
+ # Usage:
8
+ # report(records) # displays report with all fields
9
+ # report(records, :field1, :field2, ...) # displays report with given fields
10
+ #
11
+ # Example:
12
+ # >> report(records, :id, :amount, :created_at)
13
+ # +------+-----------+--------------------------------+
14
+ # | id | amount | created_at |
15
+ # +------+-----------+--------------------------------+
16
+ # | 8301 | $12.40 | Sat Feb 28 09:20:47 -0800 2009 |
17
+ # | 6060 | $39.62 | Sun Feb 15 14:45:38 -0800 2009 |
18
+ # | 6061 | $167.52 | Sun Feb 15 14:45:38 -0800 2009 |
19
+ # | 6067 | $12.00 | Sun Feb 15 14:45:40 -0800 2009 |
20
+ # | 6059 | $1,000.00 | Sun Feb 15 14:45:38 -0800 2009 |
21
+ # +------+-----------+--------------------------------+
22
+ # 5 rows in set
23
+ #
24
+ def self.report(items, *fields)
25
+ # find max length for each field; start with the field names themselves
26
+ max_len = Hash[*fields.map {|f| [f, f.to_s.length]}.flatten]
27
+
28
+ items.each do |item|
29
+ fields.each do |field|
30
+ len = item.send(field).to_s.length
31
+ max_len[field] = len if len > max_len[field]
32
+ end
33
+ end
34
+
35
+ border = '+-' + fields.map {|f| '-' * max_len[f] }.join('-+-') + '-+'
36
+ title_row = '| ' + fields.map {|f| sprintf("%-#{max_len[f]}s", f.to_s) }.join(' | ') + ' |'
37
+
38
+ puts border
39
+ puts title_row
40
+ puts border
41
+
42
+ items.each do |item|
43
+ row = '| ' + fields.map {|f| sprintf("%-#{max_len[f]}s", item.send(f)) }.join(' | ') + ' |'
44
+ puts row
45
+ end
46
+
47
+ puts border
48
+ puts "#{items.length} rows in set\n"
49
+ end
50
+ end
51
+
52
+ if __FILE__ == $0
53
+ require 'ostruct'
54
+ o1 = OpenStruct.new
55
+ o1.a = 1
56
+ o1.b = 2
57
+
58
+ o2 = OpenStruct.new :a => 2, :b => 4
59
+
60
+ DirCat::report( [o1, o2], :a, :b )
61
+ end
data/lib/dircat.rb CHANGED
@@ -1,3 +1,30 @@
1
- class Dircat
2
- VERSION = '0.0.1'
1
+ #
2
+ # stdlib
3
+ #
4
+ require 'fileutils'
5
+ require 'tmpdir'
6
+ require 'yaml'
7
+ require 'ostruct'
8
+ require 'optparse'
9
+
10
+ module DirCat
11
+ def self.version
12
+ cwd = File.dirname( __FILE__)
13
+ yaml = YAML.load_file(cwd + '/../VERSION.yml')
14
+ major = (yaml['major'] || yaml[:major]).to_i
15
+ minor = (yaml['minor'] || yaml[:minor]).to_i
16
+ patch = (yaml['patch'] || yaml[:patch]).to_i
17
+ "#{major}.#{minor}.#{patch}"
18
+ end
3
19
  end
20
+
21
+ require 'dircat/extension_md5'
22
+ require 'dircat/extension_numeric'
23
+
24
+ require 'dircat/cat'
25
+ require 'dircat/entry'
26
+ require 'dircat/report'
27
+
28
+ require 'dircat/cli/dircat_build'
29
+ require 'dircat/cli/dircat_diff'
30
+ require 'dircat/cli/dircat_query'
@@ -0,0 +1,71 @@
1
+ require File.expand_path( File.join(File.dirname(__FILE__), "..", "spec_helper") )
2
+
3
+ #
4
+ # dir1 contains 2 files
5
+ #
6
+ # dir2 contains 3 files (one more than dir2)
7
+ #
8
+ # dir3 contains two duplicated files
9
+
10
+ describe Cat do
11
+
12
+ before do
13
+ @data_dir = TEST_DIR
14
+ @tmp_dir = File.join( @data_dir, "tmp" )
15
+ end
16
+
17
+ it "should build catalog from dir1" do
18
+ cat1 = Cat.from_dir( File.join(@data_dir, "dir1") )
19
+ cat1.size.should == 2
20
+ cat1.bytes.size.should == 8
21
+ end
22
+
23
+ it "should load catalog from dir2" do
24
+ cat2 = Cat.from_dir( File.join(@data_dir, "dir2") )
25
+ cat2.size.should == 3
26
+ cat2.bytes.should == 6
27
+ end
28
+
29
+ it "(dir1 - dir2) the difference from dir1 and dir2 is empty" do
30
+ cat1 = Cat.from_dir( File.join(@data_dir, "dir1") )
31
+ cat2 = Cat.from_dir( File.join(@data_dir, "dir2") )
32
+ # dir1 contiene tutti i file di dir2
33
+ cat_diff = cat1 - cat2
34
+ cat_diff.size.should == 0
35
+ end
36
+
37
+ it "(dir2 - dir1) the difference from dir2 and dir1 is a file" do
38
+ cat1 = Cat.from_dir( File.join(@data_dir, "dir1") )
39
+ cat2 = Cat.from_dir( File.join(@data_dir, "dir2") )
40
+
41
+ # dir2 contiene un file in piu' di dir1
42
+ cat_diff = cat2 - cat1
43
+ cat_diff.size.should == 1
44
+ end
45
+
46
+ it "saving to an inexistents file shoud raise an exception" do
47
+ cat1 = Cat.from_dir( File.join(@data_dir, "dir1") )
48
+
49
+ not_existent_file = File.join(@tmp_dir, "not_existent", "dircat1.yaml")
50
+ lambda {cat1.save_to( not_existent_file )}.should raise_exception(DirCatException)
51
+ end
52
+
53
+ it "saving to a file" do
54
+ cat1 = Cat.from_dir( File.join(@data_dir, "dir1") )
55
+ tmp_file = File.join(@tmp_dir, "dircat1.yaml")
56
+ cat1.save_to( tmp_file )
57
+
58
+ dircat1_bis = Cat.from_file( tmp_file )
59
+ (cat1 - dircat1_bis).size.should == 0
60
+ (dircat1_bis - cat1).size.should == 0
61
+
62
+ FileUtils.rm( tmp_file )
63
+ end
64
+
65
+
66
+ it "should detect duplicates" do
67
+ cat1 = Cat.from_dir( File.join(@data_dir, "dir3") )
68
+ cat1.duplicates.should have(1).files
69
+ end
70
+
71
+ end
@@ -0,0 +1,59 @@
1
+ require File.expand_path( File.join(File.dirname(__FILE__), "..", "..", "spec_helper") )
2
+
3
+ describe DirCatBuild do
4
+
5
+ before do
6
+ @testdata_dirname = TEST_DIR
7
+ @dir1_dirname = File.join( @testdata_dirname, "dir1" )
8
+ @dir2_dirname = File.join( @testdata_dirname, "dir2" )
9
+ @certified_output_dirname = File.join( @testdata_dirname, "certified_output" )
10
+ @tmp_output_dirname = File.join( @testdata_dirname, "tmp" )
11
+ end
12
+
13
+ it "should accept -h (-help) option" do
14
+ out = with_stdout_captured do
15
+ args = %w{-h}
16
+ DirCatBuild.new.parse_args(args)
17
+ end
18
+ out.should match /Usage:/
19
+ end
20
+
21
+ it "should accept --version option" do
22
+ out = with_stdout_captured do
23
+ args = %w{--version}
24
+ DirCatBuild.new.parse_args(args)
25
+ end
26
+ out.should match /#{DirCat::version}/
27
+ end
28
+
29
+ it "should not accept more then -o options" do
30
+ out = with_stdout_captured do
31
+ args = "-f -o filename -o filename1"
32
+ DirCatBuild.new.parse_args( args.split )
33
+ end
34
+ out.should match /only one file/
35
+ end
36
+
37
+
38
+ it "should build a catalog from a directory" do
39
+ expect_filename = File.join( @certified_output_dirname, "dircat1.yaml" )
40
+ result_filename = File.join( @tmp_output_dirname, "dircat1.yaml")
41
+
42
+ out = with_stdout_captured do
43
+ args = "-f -o #{result_filename} #{@dir1_dirname}"
44
+ DirCatBuild.new.parse_args( args.split )
45
+ end
46
+ # out.should match /Usage:/
47
+
48
+ cat_expect = Cat.from_file( expect_filename )
49
+ cat_result = Cat.from_file( result_filename )
50
+
51
+ (cat_result - cat_result).size.should == 0
52
+
53
+ (cat_result - cat_expect).size.should == 0
54
+ (cat_expect - cat_result).size.should == 0
55
+
56
+ FileUtils.rm(result_filename)
57
+ end
58
+
59
+ end
@@ -0,0 +1,26 @@
1
+ require File.expand_path( File.join(File.dirname(__FILE__), "..", "..", "spec_helper") )
2
+
3
+ describe DirCatDiff do
4
+
5
+ before do
6
+ @testdata_dirname = TEST_DIR
7
+ @certified_output_dirname = File.join( @testdata_dirname, "certified_output" )
8
+ end
9
+
10
+ it "should accept -h (help) option" do
11
+ out = with_stdout_captured do
12
+ args = %w{-h}
13
+ DirCatDiff.new.parse_args(args)
14
+ end
15
+ out.should match /Usage:/
16
+ end
17
+
18
+ it "should accept --version option" do
19
+ out = with_stdout_captured do
20
+ args = %w{--version}
21
+ DirCatDiff.new.parse_args(args)
22
+ end
23
+ out.should match /#{DirCat::version}/
24
+ end
25
+
26
+ end
@@ -0,0 +1,35 @@
1
+ require File.expand_path( File.join(File.dirname(__FILE__), "..", "..", "spec_helper") )
2
+
3
+ describe DirCatQuery do
4
+
5
+ before do
6
+ @testdata_dirname = TEST_DIR
7
+ @certified_output_dirname = File.join( @testdata_dirname, "certified_output" )
8
+ end
9
+
10
+ it "should accept -h (help) option" do
11
+ out = with_stdout_captured do
12
+ args = %w{-h}
13
+ DirCatQuery.new.parse_args(args)
14
+ end
15
+ out.should match /Usage:/
16
+ end
17
+
18
+ it "should accept --version option" do
19
+ out = with_stdout_captured do
20
+ args = %w{--version}
21
+ DirCatQuery.new.parse_args(args)
22
+ end
23
+ out.should match /#{DirCat::version}/
24
+ end
25
+
26
+ it "should show catalogs info" do
27
+ cat_filename = File.join( @certified_output_dirname, "dircat1.yaml" )
28
+ out = with_stdout_captured do
29
+ args = "#{cat_filename}"
30
+ DirCatQuery.new.parse_args(args.split)
31
+ end
32
+ out.should match /file: 2/
33
+ out.should match /Bytes: 4/
34
+ end
35
+ end
@@ -0,0 +1,12 @@
1
+ require File.expand_path( File.join(File.dirname(__FILE__), "..", "spec_helper") )
2
+
3
+ describe "MD5" do
4
+
5
+ TEST_FILE = File.expand_path( File.join( File.dirname(__FILE__), "..", "..", "lib", "dircat", "extension_md5.rb" ) )
6
+
7
+ it "test_simple_md5" do
8
+ file_name = File.join( TEST_FILE )
9
+ MD5.file( file_name ).to_s.should == "8777d9d35da17496e21dcc8a4f9f8191"
10
+ end
11
+
12
+ end
@@ -0,0 +1,11 @@
1
+ require File.expand_path( File.join(File.dirname(__FILE__), "..", "spec_helper") )
2
+
3
+ describe "TCNumeric" do
4
+
5
+ it "test_simple" do
6
+ 10.with_separator.should == "10"
7
+ 10.0.with_separator.should == "10.0"
8
+ 1000000.with_separator.should == "1,000,000"
9
+ end
10
+
11
+ end
@@ -0,0 +1,25 @@
1
+ $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $:.unshift(File.dirname(__FILE__))
3
+
4
+ require 'dircat'
5
+ include DirCat
6
+
7
+ TEST_DIR = File.expand_path( File.join( File.dirname(__FILE__), "fixtures" ) )
8
+
9
+ # Spec::Runner.configure do |config|
10
+ # end
11
+
12
+ # require 'test/unit'
13
+ require "stringio"
14
+
15
+ def with_stdout_captured
16
+ old_stdout = $stdout
17
+ out = StringIO.new
18
+ $stdout = out
19
+ begin
20
+ yield
21
+ ensure
22
+ $stdout = old_stdout
23
+ end
24
+ out.string
25
+ end