walk 0.1.0

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 35dbff654a1f378d8ae59b0784cd69fc0917d5cf
4
+ data.tar.gz: 04ee5b5848b503b109d38f4e2ed6403e09a166e6
5
+ SHA512:
6
+ metadata.gz: ffc26b6b715e2635876f4047df805daff356d0a0b4a96a2a5072d710a4d31b5c8e8d45b84cb8f3ddf163f08e9edcbd7638d3569a4ff827b3b3f8ad00a4b2a5c1
7
+ data.tar.gz: f7a01444325625ea4fd1db51dad507d63f03c652c3c3201015bdcb3cb7b0bb5250256136eabc55f2954ed79a34f398f90696c80a55479eaa7f10f19318da4790
@@ -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/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in walk.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 samonzeweb
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.
@@ -0,0 +1,37 @@
1
+ # Walk
2
+
3
+ Walk is a simple tool to explore a directory tree, inspired by [python os.walk][1]. For each directory (and subdirectories) it give path, files and directories.
4
+
5
+ During the exploration, it don't go down into unreadable directories, and ignore content which have disappeared.
6
+
7
+ Unlike python walk, there is no error callback (now).
8
+
9
+ ## Usage
10
+
11
+ The Walk.walk function require at least the root of the tree to explore. It can be used with a code block which is called for each directory and receiving 3 arguments : the full path of the current directory, the directories, and the files inside the current directory.
12
+
13
+ require 'walk'
14
+
15
+ Walk.walk('/') do |path, dirs, files|
16
+ puts "In #{path} there are #{dirs.length} directories and #{files.length} files"
17
+ end
18
+
19
+ Without a block, Walk.walk return an enumerator :
20
+
21
+ require 'walk'
22
+
23
+ # Directories containing a least 10 files
24
+ puts Walk.walk('/')
25
+ .select { |path,dirs,files| files.length>=10 }
26
+ .map { |path,_,_| path }
27
+
28
+ Optional (keywords) arguments are :
29
+
30
+ - topdown : when true (default) the content is returned from top to bottom during tree exploration. When topdown is false, the content is returned beginning with the bottom.
31
+ - followlinks : when false (default) it doesn't explore subdirectories which are symbolic links. When followlinks is true, it can produce an infinite loop in some cases.
32
+
33
+ ## Licence
34
+
35
+ Walk is released under the MIT license. See LICENSE.txt file for details.
36
+
37
+ [1]: http://docs.python.org/3.3/library/os.html#os.walk
@@ -0,0 +1,9 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+
5
+ task :default => :spec
6
+ task :test => :spec
7
+
8
+ desc "Run all the specs"
9
+ RSpec::Core::RakeTask.new
@@ -0,0 +1,84 @@
1
+ require_relative "walk/version"
2
+
3
+
4
+ module Walk
5
+
6
+
7
+ CURRENT_DIR = '.'
8
+ PARENT_DIR = '..'
9
+
10
+
11
+ def self.walk(root, topdown: true, followlinks: false, &block)
12
+
13
+ if block_given?
14
+ inner_walk(root, topdown, followlinks, &block)
15
+ else
16
+ Enumerator.new do |enum|
17
+ inner_walk(root, topdown, followlinks) do |path, dirs, files|
18
+ enum << [path, dirs, files]
19
+ end
20
+ end
21
+ end
22
+
23
+ end
24
+
25
+
26
+ def self.inner_walk(root, topdown, followlinks, &block)
27
+
28
+ dirs = []
29
+ files = []
30
+ path_to_explore = []
31
+
32
+ begin
33
+ Dir.entries(root).each do |entry|
34
+
35
+ next if entry==CURRENT_DIR or entry==PARENT_DIR
36
+
37
+ fullpath = File.join(root, entry)
38
+ is_file, is_dir, go_down = inspect_entry(fullpath, followlinks)
39
+ files << entry if is_file
40
+ dirs << entry if is_dir
41
+ path_to_explore << fullpath if go_down
42
+
43
+ end
44
+ rescue Errno::ENOENT => e
45
+ # current dir disappeared since parent scan, it's not an error
46
+ return
47
+ end
48
+
49
+ yield root, dirs, files if topdown
50
+
51
+ path_to_explore.each do |fullpath|
52
+ inner_walk(fullpath, topdown, followlinks, &block)
53
+ end
54
+
55
+ yield root, dirs, files unless topdown
56
+
57
+ end
58
+
59
+
60
+ def self.inspect_entry(fullpath, followlinks)
61
+
62
+ is_file = is_dir = go_down = false
63
+
64
+ if File.file?(fullpath)
65
+ is_file = true
66
+ elsif File.directory?(fullpath)
67
+ is_dir = true
68
+ if (followlinks or not File.symlink?(fullpath)) and
69
+ File.readable?(fullpath)
70
+ go_down = true
71
+ end
72
+ end
73
+
74
+ return is_file, is_dir, go_down
75
+
76
+ rescue Errno::ENOENT => e
77
+ return nil, nil, nil
78
+ end
79
+
80
+ private_class_method :inner_walk
81
+ private_class_method :inspect_entry
82
+
83
+
84
+ end
@@ -0,0 +1,3 @@
1
+ module Walk
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,36 @@
1
+ require 'tmpdir'
2
+
3
+ RSpec.configure do |config|
4
+ config.color_enabled = true
5
+ end
6
+
7
+
8
+ def create_test_tree
9
+ tmpdir = Dir.mktmpdir
10
+ FileUtils.touch File.join(tmpdir, "dummy.txt")
11
+
12
+ subdir_1 = File.join(tmpdir, 'subdir_1')
13
+ Dir.mkdir(subdir_1)
14
+ FileUtils.touch File.join(subdir_1, "dummy_1.txt")
15
+ FileUtils.touch File.join(subdir_1, "dummy_2.txt")
16
+
17
+ subdir_2 = File.join(tmpdir, 'subdir_2')
18
+ Dir.mkdir(subdir_2)
19
+ FileUtils.touch File.join(subdir_1, "dummy.txt")
20
+
21
+ tmpdir
22
+ end
23
+
24
+
25
+ def remove_test_tree(path)
26
+ must_begin_with = Dir.tmpdir + File::SEPARATOR
27
+ raise "Path not in temporary directory !" unless path.index(must_begin_with) == 0
28
+ FileUtils.rm_r(path)
29
+ end
30
+
31
+
32
+ def add_simlink(path)
33
+ File.symlink File.join(path, 'subdir_2'), File.join(path, 'symlink')
34
+ end
35
+
36
+
@@ -0,0 +1,75 @@
1
+ require 'spec_helper'
2
+ require 'walk'
3
+
4
+ describe Walk do
5
+
6
+ before :each do
7
+ @test_path = create_test_tree
8
+ end
9
+
10
+ after :each do
11
+ remove_test_tree @test_path
12
+ end
13
+
14
+ it 'should find all files in directory tree' do
15
+ files_count = 0
16
+ Walk.walk(@test_path) do |path, subdirs, files|
17
+ files_count += files.length
18
+ end
19
+ expect(files_count).to be == 4
20
+ end
21
+
22
+ it 'should find all directories in directory tree' do
23
+ dirs_count = 0
24
+ Walk.walk(@test_path) do |path, subdirs, files|
25
+ dirs_count += subdirs.length
26
+ end
27
+ expect(dirs_count).to be == 2
28
+ end
29
+
30
+ it 'should return an enumerator if no block is passed' do
31
+ expect(Walk.walk(@test_path)).to be_an(Enumerator)
32
+ end
33
+
34
+ it 'should give same result with enumerator than with block style' do
35
+ files_count = Walk.walk(@test_path).map { |_,_,f| f.length}.reduce(:+)
36
+ expect(files_count).to be == 4
37
+ end
38
+
39
+ it 'should return content from top to bottom by default' do
40
+ path_order = Walk.walk(@test_path).map { |path,_,_| File.basename(path) }
41
+ expect(path_order).to be == [File.basename(@test_path), 'subdir_1', 'subdir_2']
42
+ end
43
+
44
+ it 'should return content from bottom to top if speficied' do
45
+ path_order = Walk.walk(@test_path, topdown: false).map { |path,_,_| File.basename(path) }
46
+ expect(path_order).to be == ['subdir_1', 'subdir_2', File.basename(@test_path)]
47
+ end
48
+
49
+ it 'should not explore symlink by default' do
50
+ add_simlink(@test_path)
51
+ simlink_found = Walk.walk(@test_path).detect do |path,_,_|
52
+ File.basename(path) == 'symlink'
53
+ end
54
+ expect(simlink_found).to be_nil
55
+ end
56
+
57
+ it 'should explore symlink if needed' do
58
+ add_simlink(@test_path)
59
+ simlink_found = Walk.walk(@test_path, followlinks: true).detect do |path,_,_|
60
+ File.basename(path) == 'symlink'
61
+ end
62
+ expect(simlink_found).not_to be_nil
63
+ end
64
+
65
+ it 'should ignore disapearing entries' do
66
+ expect {
67
+ Walk.walk(@test_path) do |path, subdirs, files|
68
+ if path == @test_path
69
+ remove_test_tree File.join(@test_path, 'subdir_2')
70
+ end
71
+ end
72
+ }.not_to raise_error()
73
+ end
74
+
75
+ end
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'walk/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "walk"
8
+ spec.version = Walk::VERSION
9
+ spec.authors = ["Samuel GAY"]
10
+ spec.email = ["sam.onzeweb@gmail.com"]
11
+ spec.summary = 'Directory tree traversal tool inspired by python os.walk'
12
+ spec.homepage = ""
13
+ spec.license = "MIT"
14
+
15
+ spec.files = `git ls-files -z`.split("\x0")
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_development_dependency "bundler", "~> 1.5"
21
+ spec.add_development_dependency "rake"
22
+ spec.add_development_dependency "rspec", "~> 2.14"
23
+ end
metadata ADDED
@@ -0,0 +1,98 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: walk
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Samuel GAY
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-01-25 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.5'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.5'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '2.14'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '2.14'
55
+ description:
56
+ email:
57
+ - sam.onzeweb@gmail.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - .gitignore
63
+ - Gemfile
64
+ - LICENSE.txt
65
+ - README.md
66
+ - Rakefile
67
+ - lib/walk.rb
68
+ - lib/walk/version.rb
69
+ - spec/spec_helper.rb
70
+ - spec/walk_spec.rb
71
+ - walk.gemspec
72
+ homepage: ''
73
+ licenses:
74
+ - MIT
75
+ metadata: {}
76
+ post_install_message:
77
+ rdoc_options: []
78
+ require_paths:
79
+ - lib
80
+ required_ruby_version: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - '>='
83
+ - !ruby/object:Gem::Version
84
+ version: '0'
85
+ required_rubygems_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ requirements: []
91
+ rubyforge_project:
92
+ rubygems_version: 2.0.14
93
+ signing_key:
94
+ specification_version: 4
95
+ summary: Directory tree traversal tool inspired by python os.walk
96
+ test_files:
97
+ - spec/spec_helper.rb
98
+ - spec/walk_spec.rb