dircat 0.0.5 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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