file_tree_profiler 0.0.1

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 (45) hide show
  1. data/.gitignore +17 -0
  2. data/.rspec +2 -0
  3. data/Gemfile +4 -0
  4. data/Guardfile +24 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +29 -0
  7. data/Rakefile +1 -0
  8. data/bin/fipro +25 -0
  9. data/file_tree_profiler.gemspec +23 -0
  10. data/lib/file_tree_profiler/data_file.rb +21 -0
  11. data/lib/file_tree_profiler/dir_file.rb +45 -0
  12. data/lib/file_tree_profiler/export/csv.rb +31 -0
  13. data/lib/file_tree_profiler/export/sql.rb +63 -0
  14. data/lib/file_tree_profiler/file.rb +26 -0
  15. data/lib/file_tree_profiler/profile.rb +22 -0
  16. data/lib/file_tree_profiler/version.rb +3 -0
  17. data/lib/file_tree_profiler.rb +22 -0
  18. data/spec/example_folders/a/a.txt +1 -0
  19. data/spec/example_folders/a/empty.txt +0 -0
  20. data/spec/example_folders/a/sub_dir_a/sub_a.txt +1 -0
  21. data/spec/example_folders/b/b.txt +1 -0
  22. data/spec/example_folders/b/bb.txt +1 -0
  23. data/spec/example_folders/differents/profile_a/foo/bar.txt +1 -0
  24. data/spec/example_folders/differents/profile_a/foo/foo.txt +1 -0
  25. data/spec/example_folders/differents/profile_b/foo/bar.txt +1 -0
  26. data/spec/example_folders/differents/profile_c/foo/bar.txt +1 -0
  27. data/spec/example_folders/differents/profile_c/foo/foo.txt +1 -0
  28. data/spec/example_folders/differents/profile_c/partially_different.txt +1 -0
  29. data/spec/example_folders/equals/profile_a/bar.txt +1 -0
  30. data/spec/example_folders/equals/profile_a/foo/foo.txt +1 -0
  31. data/spec/example_folders/equals/profile_b/bar.txt +1 -0
  32. data/spec/example_folders/equals/profile_b/foo/foo.txt +1 -0
  33. data/spec/example_folders/profile-level-folder/a/bb/ccc.txt +1 -0
  34. data/spec/example_folders/profile-level-folder/a/bb.txt +0 -0
  35. data/spec/example_folders/profile-level-folder/b/cc.txt +1 -0
  36. data/spec/example_folders/profile-level-folder/c.txt +1 -0
  37. data/spec/lib/file_tree_profiler/data_file_spec.rb +29 -0
  38. data/spec/lib/file_tree_profiler/dir_file_spec.rb +43 -0
  39. data/spec/lib/file_tree_profiler/export/sql_export_spec.rb +18 -0
  40. data/spec/lib/file_tree_profiler/profile_spec.rb +40 -0
  41. data/spec/lib/file_tree_profiler_spec.rb +45 -0
  42. data/spec/spec_helper.rb +25 -0
  43. data/spec/support/examples_folder.rb +8 -0
  44. data/spec/support/file_examples.rb +8 -0
  45. metadata +165 -0
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in file_tree_profiler.gemspec
4
+ gemspec
data/Guardfile ADDED
@@ -0,0 +1,24 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard 'rspec' do
5
+ watch(%r{^spec/.+_spec\.rb$})
6
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
7
+ watch('spec/spec_helper.rb') { "spec" }
8
+
9
+ # Rails example
10
+ watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
11
+ watch(%r{^app/(.*)(\.erb|\.haml)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
12
+ watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
13
+ watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
14
+ watch('config/routes.rb') { "spec/routing" }
15
+ watch('app/controllers/application_controller.rb') { "spec/controllers" }
16
+
17
+ # Capybara features specs
18
+ watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) { |m| "spec/features/#{m[1]}_spec.rb" }
19
+
20
+ # Turnip features and steps
21
+ watch(%r{^spec/acceptance/(.+)\.feature$})
22
+ watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' }
23
+ end
24
+
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Jens Bissinger
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # FileTreeProfiler
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'file_tree_profiler'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install file_tree_profiler
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/fipro ADDED
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ lib = File.expand_path('../../lib', __FILE__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require 'file_tree_profiler'
6
+
7
+ dir_name = ARGV.first
8
+
9
+ puts "Profiling #{dir_name}..."
10
+ $profile = FileTreeProfiler.profile dir_name
11
+ puts "Profiling done!"
12
+
13
+ case ARGV.last
14
+ when /\.csv$/
15
+ puts "Writing CSV Report into #{ARGV.last}"
16
+ FileTreeProfiler.csv $profile, ARGV.last
17
+ when /\.sqlite3$/
18
+ puts "Writing SQL Report into #{ARGV.last}"
19
+ FileTreeProfiler.sql $profile, "sqlite://#{ARGV.last}"
20
+ else
21
+ puts "Starting console, please call $profile"
22
+ ARGV.clear
23
+ require 'irb'
24
+ IRB.start
25
+ end
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'file_tree_profiler/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "file_tree_profiler"
8
+ gem.version = FileTreeProfiler::VERSION
9
+ gem.authors = ["Jens Bissinger"]
10
+ gem.email = ["mail@jens-bissinger.de"]
11
+ gem.description = %q{Generates a profile of a given directory.}
12
+ gem.summary = %q{Analysed directory structure and file contents.}
13
+ gem.homepage = ""
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+
20
+ gem.add_dependency 'sequel'
21
+ gem.add_development_dependency 'sqlite3'
22
+ gem.add_development_dependency 'guard-rspec'
23
+ end
@@ -0,0 +1,21 @@
1
+ module FileTreeProfiler
2
+ class DataFile < File
3
+ EMPTY_CHECKSUM = ::Digest::MD5.hexdigest('/no-data/').freeze
4
+
5
+ def empty?
6
+ ::File.zero?(path)
7
+ end
8
+
9
+ def checksum
10
+ @checksum ||= begin
11
+ empty? ? EMPTY_CHECKSUM : ::Digest::MD5.file(path)
12
+ end.to_s
13
+ rescue Errno::ELOOP => e
14
+ puts "path=#{path} is a circular ref"
15
+ end
16
+
17
+ def size
18
+ 1
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,45 @@
1
+ module FileTreeProfiler
2
+ class DirFile < File
3
+ EMPTY_CHECKSUM = ::Digest::MD5.hexdigest('/no-children/').freeze
4
+ attr_reader :children
5
+
6
+ def initialize *args
7
+ super *args
8
+ walk
9
+ end
10
+
11
+ # collects all children as DirFile or DataFile objects
12
+ # and is invoked on each collected DirFile object
13
+ def walk
14
+ @children = []
15
+ Dir.foreach(self.path) do |entry|
16
+ next if (entry == '..' || entry == '.')
17
+ full_path = ::File.join(self.path, entry)
18
+ if ::File.directory?(full_path)
19
+ children.push DirFile.new(self, entry)
20
+ else
21
+ children.push DataFile.new(self, entry)
22
+ end
23
+ end
24
+ end
25
+
26
+ def empty?
27
+ children.empty?
28
+ end
29
+
30
+ def size
31
+ children.inject(1) {|sum, c| sum += c.size; sum }
32
+ end
33
+
34
+ # checksum generated using concatenated checksums of all children
35
+ def checksum
36
+ @checksum ||= begin
37
+ if empty?
38
+ EMPTY_CHECKSUM
39
+ else
40
+ ::Digest::MD5.hexdigest(children.map(&:checksum).join)
41
+ end
42
+ end.to_s
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,31 @@
1
+ require 'csv'
2
+
3
+ module FileTreeProfiler
4
+ module Export
5
+ class CSV
6
+ attr_reader :profile, :filename
7
+ def initialize(profile, filename)
8
+ @profile = profile
9
+ @filename = filename
10
+ ::CSV.open("#{filename}.csv", "wb") do |csv|
11
+ profile csv, profile.root
12
+ end
13
+ end
14
+
15
+ def write_line csv, file
16
+ csv << [file.class, file.path, file.relative_path, file.name, file.checksum, file.empty?, file.size]
17
+ end
18
+
19
+ def profile csv, dir_file
20
+ write_line csv, dir_file
21
+ dir_file.children.each do |child|
22
+ if child.class == DirFile
23
+ profile csv, child
24
+ else
25
+ write_line csv, child
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,63 @@
1
+ require 'sequel'
2
+
3
+ module FileTreeProfiler
4
+ module Export
5
+ class SQL
6
+ attr_reader :profile, :config, :root_id
7
+ def initialize(profile, config)
8
+ @profile = profile
9
+ @config = config
10
+
11
+ Sequel.connect(config) do |db|
12
+ create_schema db
13
+ @root_id = db[:roots].insert(:path => profile.root.path)
14
+ profile db, profile.root
15
+ end
16
+ end
17
+
18
+ def create_schema db
19
+ db.create_table :roots do
20
+ primary_key :id
21
+ String :path, :unique => true
22
+ end unless db.table_exists? :roots
23
+ db.create_table :files do
24
+ primary_key :id
25
+ foreign_key :root_id
26
+ String :type
27
+ String :name
28
+ String :path
29
+ String :relative_path
30
+ String :checksum
31
+ Boolean :empty
32
+ Integer :size
33
+ index :type
34
+ index [:root_id, :path], :unique => true
35
+ index :checksum
36
+ end unless db.table_exists? :files
37
+ end
38
+
39
+ def insert_file db, file
40
+ db[:files].insert(
41
+ :root_id => root_id,
42
+ :type => (file.class == DirFile ? 'dir' : 'data'),
43
+ :path => file.path,
44
+ :relative_path => file.relative_path,
45
+ :name => file.name,
46
+ :checksum => file.checksum,
47
+ :empty => file.empty?,
48
+ :size => file.size)
49
+ end
50
+
51
+ def profile db, dir_file
52
+ insert_file db, dir_file
53
+ dir_file.children.each do |child|
54
+ if child.class == DirFile
55
+ profile db, child
56
+ else
57
+ insert_file db, child
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,26 @@
1
+ module FileTreeProfiler
2
+ class File
3
+ attr_reader :parent, :name
4
+
5
+ def initialize parent, name
6
+ @parent = parent
7
+ @name = name
8
+ end
9
+
10
+ def path
11
+ ::File.join(parent.path, name)
12
+ end
13
+
14
+ def relative_path
15
+ if parent.respond_to? :parent
16
+ ::File.join(parent.relative_path, name)
17
+ else
18
+ '/'
19
+ end
20
+ end
21
+
22
+ def inspect
23
+ "<#{self.class} @name=#{name} #path=#{path}>"
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,22 @@
1
+ module FileTreeProfiler
2
+ class Profile
3
+ attr_reader :path, :root
4
+
5
+ # @param [String] full_path of the directory
6
+ def initialize full_path
7
+ raise ArgumentError, "Not a directory - #{full_path}" \
8
+ unless ::File.directory?(full_path)
9
+ dir_name = ::File.basename(full_path)
10
+ @path = full_path.gsub(::File.join('', dir_name), '')
11
+ @root = DirFile.new(self, dir_name)
12
+ end
13
+
14
+ def size
15
+ root.size
16
+ end
17
+
18
+ def checksum
19
+ root.checksum
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,3 @@
1
+ module FileTreeProfiler
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,22 @@
1
+ require 'digest/md5'
2
+ require 'file_tree_profiler/version'
3
+ require 'file_tree_profiler/file'
4
+ require 'file_tree_profiler/data_file'
5
+ require 'file_tree_profiler/dir_file'
6
+ require 'file_tree_profiler/profile'
7
+ require 'file_tree_profiler/export/csv'
8
+ require 'file_tree_profiler/export/sql'
9
+
10
+ module FileTreeProfiler
11
+ def self.profile path
12
+ Profile.new path
13
+ end
14
+
15
+ def self.csv profile, basename
16
+ Export::CSV.new profile, basename
17
+ end
18
+
19
+ def self.sql profile, config
20
+ Export::SQL.new profile, config
21
+ end
22
+ end
@@ -0,0 +1 @@
1
+ a.txt
File without changes
@@ -0,0 +1 @@
1
+ sub_a.txt
@@ -0,0 +1 @@
1
+ b.txt
@@ -0,0 +1 @@
1
+ bb.txt
@@ -0,0 +1 @@
1
+ bar.txt
@@ -0,0 +1 @@
1
+ foo.txt
@@ -0,0 +1 @@
1
+ bar.txt
@@ -0,0 +1 @@
1
+ foo.txt
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ describe FileTreeProfiler::DataFile do
4
+ let(:parent_mock) do
5
+ mock('parent').tap do |mock|
6
+ mock.stub(:path).and_return(example_folder('a'))
7
+ end
8
+ end
9
+
10
+ context :empty do
11
+ let(:data_file) { described_class.new(parent_mock, 'empty.txt') }
12
+ subject { data_file }
13
+
14
+ its(:checksum) { should == described_class::EMPTY_CHECKSUM }
15
+ its(:name) { should == 'empty.txt' }
16
+ its(:empty?) { should be_true }
17
+ it_behaves_like :file_on_root_level
18
+ end
19
+
20
+ context :not_empty do
21
+ let(:data_file) { described_class.new(parent_mock, 'a.txt') }
22
+ subject { data_file }
23
+
24
+ its(:checksum) { should == 'a5e54d1fd7bb69a228ef0dcd2431367e' }
25
+ its(:name) { should == 'a.txt' }
26
+ its(:empty?) { should be_false }
27
+ it_behaves_like :file_on_root_level
28
+ end
29
+ end
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+
3
+ describe FileTreeProfiler::DirFile do
4
+ let(:parent_mock) do
5
+ mock('parent').tap do |mock|
6
+ mock.stub(:path).and_return(example_folder)
7
+ end
8
+ end
9
+
10
+ context :empty do
11
+ let(:dir_file) { described_class.new(parent_mock, 'empty') }
12
+ subject { dir_file }
13
+
14
+ its(:checksum) { should == described_class::EMPTY_CHECKSUM }
15
+ its(:name) { should == 'empty' }
16
+ its(:empty?) { should be_true }
17
+ its(:path) { should match(/#{File.join('example_folders', 'empty')}$/) }
18
+ it_behaves_like :file_on_root_level
19
+ end
20
+
21
+ context :not_empty do
22
+ let(:dir_file) { described_class.new(parent_mock, 'a') }
23
+ subject { dir_file }
24
+
25
+ its(:checksum) { should == 'f3a9e0021f70623bb7e17ed325373d6d' }
26
+ its(:name) { should == 'a' }
27
+ its(:empty?) { should be_false }
28
+ its(:path) { should match(/#{File.join('example_folders', 'a')}$/) }
29
+ it_behaves_like :file_on_root_level
30
+ end
31
+
32
+ context :dir_in_dir do
33
+ let(:parent_dir_file) { described_class.new(parent_mock, 'a') }
34
+ let(:child_dir_file) { described_class.new(parent_dir_file, 'sub_dir_a') }
35
+ subject { child_dir_file }
36
+
37
+ its(:checksum) { should == '4095b34983e72363b14f12a0b5feba73' }
38
+ its(:name) { should == 'sub_dir_a' }
39
+ its(:empty?) { should be_false }
40
+ its(:path) { should match(/#{File.join('example_folders', 'a', 'sub_dir_a')}$/) }
41
+ it_behaves_like :file_on_sub_level, '/sub_dir_a'
42
+ end
43
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ describe FileTreeProfiler::Export::SQL do
4
+ let(:db_file) { 'rspec.sqlite3' }
5
+ before { File.unlink(db_file) if File.exists?(db_file) }
6
+ let(:expected_size) { 8 }
7
+
8
+ it 'profiles' do
9
+ profile = FileTreeProfiler.profile(example_folder('profile-level-folder'))
10
+ profile.size.should == expected_size
11
+ described_class.new(profile, 'sqlite://'+db_file)
12
+ db = Sequel.connect('sqlite://'+db_file)
13
+ db[:files].count.should == expected_size
14
+ db[:files].where(:type => 'dir').count.should == 4
15
+ db[:files].where(:type => 'data').count.should == 4
16
+ db[:roots].count.should == 1
17
+ end
18
+ end
@@ -0,0 +1,40 @@
1
+ require 'spec_helper'
2
+
3
+ describe FileTreeProfiler::Profile do
4
+ let(:profile) { described_class.new(example_folder('a')) }
5
+ subject { profile }
6
+
7
+ its(:checksum) { should == 'f3a9e0021f70623bb7e17ed325373d6d' }
8
+ its(:size) { should == 5 }
9
+
10
+ its(:root) { should be_instance_of(FileTreeProfiler::DirFile) }
11
+
12
+ context :root do
13
+ subject { profile.root }
14
+
15
+ its(:name) { should == 'a' }
16
+ its(:checksum) { should == profile.checksum }
17
+ its(:size) { should == profile.size }
18
+ end
19
+
20
+ context :equals do
21
+ let(:profile_a) { described_class.new(example_folder('equals', 'profile_a')) }
22
+ let(:profile_b) { described_class.new(example_folder('equals', 'profile_b')) }
23
+ subject { profile_a }
24
+ its(:checksum) { should == profile_b.checksum }
25
+ end
26
+
27
+ context :differents do
28
+ let(:profile_a) { described_class.new(example_folder('differents', 'profile_a')) }
29
+ let(:profile_b) { described_class.new(example_folder('differents', 'profile_b')) }
30
+ let(:profile_c) { described_class.new(example_folder('differents', 'profile_c')) }
31
+ subject { profile_a }
32
+ its(:checksum) { should_not == profile_b.checksum }
33
+ its(:checksum) { should_not == profile_c.checksum }
34
+
35
+ context :partially do
36
+ specify { profile_a.root.children.first.name.should == profile_c.root.children.first.name }
37
+ specify { profile_a.root.children.first.checksum.should == profile_c.root.children.first.checksum }
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+
3
+ describe FileTreeProfiler do
4
+ let(:profile) { described_class.profile(example_folder('profile-level-folder')) }
5
+
6
+ it 'profiles' do
7
+ profile.should be_instance_of(described_class::Profile)
8
+ end
9
+
10
+ it 'raises error on profiling data file' do
11
+ path = example_folder('a', 'a.txt')
12
+ lambda { described_class.profile(path) }.should \
13
+ raise_error(ArgumentError, "Not a directory - #{path}")
14
+ end
15
+
16
+ it 'csv' do
17
+ described_class.csv(profile, 'test')
18
+ end
19
+
20
+ it 'sql' do
21
+ File.unlink('rspec.sqlite3') if File.exists?('rspec.sqlite3')
22
+ described_class.sql(profile, 'sqlite://rspec.sqlite3')
23
+ end
24
+
25
+ context :profile do
26
+ subject { profile }
27
+ its(:size) {should == 8}
28
+ its(:root) {should be_instance_of(described_class::DirFile)}
29
+
30
+ context :root do
31
+ subject { profile.root }
32
+
33
+ its(:checksum) { should_not == described_class::DirFile::EMPTY_CHECKSUM }
34
+ its(:checksum) { should be_instance_of(String) }
35
+ its(:name) { should == 'profile-level-folder' }
36
+ its(:path) { should include(example_folder) }
37
+
38
+ it 'has children' do
39
+ subject.children.map(&:name).should == %w[ a b c.txt ]
40
+ end
41
+
42
+ end
43
+ end
44
+
45
+ end
@@ -0,0 +1,25 @@
1
+ # This file was generated by the `rspec --init` command. Conventionally, all
2
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
+ # Require this file using `require "spec_helper"` to ensure that it is only
4
+ # loaded once.
5
+ #
6
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
7
+ RSpec.configure do |config|
8
+ config.treat_symbols_as_metadata_keys_with_true_values = true
9
+ config.run_all_when_everything_filtered = true
10
+ config.filter_run :focus
11
+
12
+ # Run specs in random order to surface order dependencies. If you find an
13
+ # order dependency and want to debug it, you can fix the order by providing
14
+ # the seed, which is printed after each run.
15
+ # --seed 1234
16
+ config.order = 'random'
17
+ end
18
+
19
+ Dir.glob(File.join(File.dirname(__FILE__), 'support', '**', '*.rb')) do |path|
20
+ require path
21
+ end
22
+
23
+ lib = File.expand_path('../lib', __FILE__)
24
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
25
+ require 'file_tree_profiler'
@@ -0,0 +1,8 @@
1
+ def example_folder *parts
2
+ root_parts = [File.dirname(__FILE__), '..', 'example_folders']
3
+ if parts.empty?
4
+ File.join(*root_parts)
5
+ else
6
+ File.join(*root_parts, *parts)
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ shared_examples_for :file_on_root_level do
2
+ its(:relative_path) { should == '/' }
3
+ end
4
+
5
+ shared_examples_for :file_on_sub_level do |sub_path|
6
+ its(:relative_path) { should == sub_path }
7
+ end
8
+
metadata ADDED
@@ -0,0 +1,165 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: file_tree_profiler
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Jens Bissinger
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-01-05 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: sequel
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: sqlite3
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: guard-rspec
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ description: Generates a profile of a given directory.
63
+ email:
64
+ - mail@jens-bissinger.de
65
+ executables:
66
+ - fipro
67
+ extensions: []
68
+ extra_rdoc_files: []
69
+ files:
70
+ - .gitignore
71
+ - .rspec
72
+ - Gemfile
73
+ - Guardfile
74
+ - LICENSE.txt
75
+ - README.md
76
+ - Rakefile
77
+ - bin/fipro
78
+ - file_tree_profiler.gemspec
79
+ - lib/file_tree_profiler.rb
80
+ - lib/file_tree_profiler/data_file.rb
81
+ - lib/file_tree_profiler/dir_file.rb
82
+ - lib/file_tree_profiler/export/csv.rb
83
+ - lib/file_tree_profiler/export/sql.rb
84
+ - lib/file_tree_profiler/file.rb
85
+ - lib/file_tree_profiler/profile.rb
86
+ - lib/file_tree_profiler/version.rb
87
+ - spec/example_folders/a/a.txt
88
+ - spec/example_folders/a/empty.txt
89
+ - spec/example_folders/a/sub_dir_a/sub_a.txt
90
+ - spec/example_folders/b/b.txt
91
+ - spec/example_folders/b/bb.txt
92
+ - spec/example_folders/differents/profile_a/foo/bar.txt
93
+ - spec/example_folders/differents/profile_a/foo/foo.txt
94
+ - spec/example_folders/differents/profile_b/foo/bar.txt
95
+ - spec/example_folders/differents/profile_c/foo/bar.txt
96
+ - spec/example_folders/differents/profile_c/foo/foo.txt
97
+ - spec/example_folders/differents/profile_c/partially_different.txt
98
+ - spec/example_folders/equals/profile_a/bar.txt
99
+ - spec/example_folders/equals/profile_a/foo/foo.txt
100
+ - spec/example_folders/equals/profile_b/bar.txt
101
+ - spec/example_folders/equals/profile_b/foo/foo.txt
102
+ - spec/example_folders/profile-level-folder/a/bb.txt
103
+ - spec/example_folders/profile-level-folder/a/bb/ccc.txt
104
+ - spec/example_folders/profile-level-folder/b/cc.txt
105
+ - spec/example_folders/profile-level-folder/c.txt
106
+ - spec/lib/file_tree_profiler/data_file_spec.rb
107
+ - spec/lib/file_tree_profiler/dir_file_spec.rb
108
+ - spec/lib/file_tree_profiler/export/sql_export_spec.rb
109
+ - spec/lib/file_tree_profiler/profile_spec.rb
110
+ - spec/lib/file_tree_profiler_spec.rb
111
+ - spec/spec_helper.rb
112
+ - spec/support/examples_folder.rb
113
+ - spec/support/file_examples.rb
114
+ homepage: ''
115
+ licenses: []
116
+ post_install_message:
117
+ rdoc_options: []
118
+ require_paths:
119
+ - lib
120
+ required_ruby_version: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ required_rubygems_version: !ruby/object:Gem::Requirement
127
+ none: false
128
+ requirements:
129
+ - - ! '>='
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ requirements: []
133
+ rubyforge_project:
134
+ rubygems_version: 1.8.23
135
+ signing_key:
136
+ specification_version: 3
137
+ summary: Analysed directory structure and file contents.
138
+ test_files:
139
+ - spec/example_folders/a/a.txt
140
+ - spec/example_folders/a/empty.txt
141
+ - spec/example_folders/a/sub_dir_a/sub_a.txt
142
+ - spec/example_folders/b/b.txt
143
+ - spec/example_folders/b/bb.txt
144
+ - spec/example_folders/differents/profile_a/foo/bar.txt
145
+ - spec/example_folders/differents/profile_a/foo/foo.txt
146
+ - spec/example_folders/differents/profile_b/foo/bar.txt
147
+ - spec/example_folders/differents/profile_c/foo/bar.txt
148
+ - spec/example_folders/differents/profile_c/foo/foo.txt
149
+ - spec/example_folders/differents/profile_c/partially_different.txt
150
+ - spec/example_folders/equals/profile_a/bar.txt
151
+ - spec/example_folders/equals/profile_a/foo/foo.txt
152
+ - spec/example_folders/equals/profile_b/bar.txt
153
+ - spec/example_folders/equals/profile_b/foo/foo.txt
154
+ - spec/example_folders/profile-level-folder/a/bb.txt
155
+ - spec/example_folders/profile-level-folder/a/bb/ccc.txt
156
+ - spec/example_folders/profile-level-folder/b/cc.txt
157
+ - spec/example_folders/profile-level-folder/c.txt
158
+ - spec/lib/file_tree_profiler/data_file_spec.rb
159
+ - spec/lib/file_tree_profiler/dir_file_spec.rb
160
+ - spec/lib/file_tree_profiler/export/sql_export_spec.rb
161
+ - spec/lib/file_tree_profiler/profile_spec.rb
162
+ - spec/lib/file_tree_profiler_spec.rb
163
+ - spec/spec_helper.rb
164
+ - spec/support/examples_folder.rb
165
+ - spec/support/file_examples.rb