redwood 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,17 +1,90 @@
1
- = redwood
1
+ # redwood
2
2
 
3
- Not quite baked yet.
3
+ Simple Ruby trees. Redwood is a simple implementation of a tree data structure in pure Ruby. It provides a few things:
4
4
 
5
- == Note on Patches/Pull Requests
6
-
7
- * Fork the project.
8
- * Make your feature addition or bug fix.
9
- * Add tests for it. This is important so I don't break it in a
10
- future version unintentionally.
11
- * Commit, do not mess with rakefile, version, or history.
12
- (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
13
- * Send me a pull request. Bonus points for topic branches.
5
+ + The `redwood` command-line tool: like the Unix [`tree`](http://mama.indstate.edu/users/ice/tree/) tool, but in Ruby!
6
+ + The Redwood module for basic tree-esqueness.
7
+ + Redwood::Node class for basic tree-nodiness
8
+ + Redwood::FileNode class for representing Directories and Files in a tree-like way.
14
9
 
15
- == Copyright
10
+ [RDoc](http://rdoc.info/projects/mwunsch/redwood) | [Gem](http://rubygems.org/gems/redwood)
16
11
 
17
- Copyright (c) 2010 Mark Wunsch. See LICENSE for details.
12
+ ## Installation
13
+
14
+ gem install redwood
15
+
16
+ ## `redwood`
17
+
18
+ The `redwood` command-line tool attempts a pure Ruby implementation of [tree](http://man.cx/tree).
19
+
20
+ USAGE: redwood [ OPTIONS ] [ DIRECTORY ]
21
+
22
+ Looks a bit like this:
23
+
24
+ Redwood
25
+ |-- bin
26
+ | `-- redwood
27
+ |-- Gemfile
28
+ |-- lib
29
+ | |-- redwood
30
+ | | |-- filenode.rb
31
+ | | `-- node.rb
32
+ | `-- redwood.rb
33
+ |-- LICENSE
34
+ |-- pkg
35
+ | `-- redwood-0.0.1.gem
36
+ |-- Rakefile
37
+ |-- README.md
38
+ |-- redwood.gemspec
39
+ `-- test
40
+ |-- helper.rb
41
+ `-- test_redwood.rb
42
+
43
+ 5 directories, 12 files
44
+
45
+ Help is a `redwood --help` away. See also: [redwood(1)](http://mwunsch.github.com/redwood/)
46
+
47
+ ## `Redwood`
48
+
49
+ The Redwood module is a module for including/extending tree-like features on your objects. It stores nodes in an Array. The only requirement for children is that they too include/extend tree-like features.
50
+
51
+ Methods include:
52
+
53
+ root? ## Is this a root node? Meaning, it has no parent.
54
+ leaf? ## Is this a leaf node? Meaning, is it without children?
55
+ root ## Get the root node in this tree.
56
+ children ## Get the children of this node.
57
+ siblings ## Get this nodes siblings.
58
+ only_child? ## Is this node without siblings?
59
+ has_children? ## Does this node have children?
60
+ ancestors ## All of the parent nodes of this node.
61
+ descendants ## All of the descendant nodes of this node.
62
+ depth ## Integer representing how deep this node is in the tree.
63
+ ## A root node has a depth of 1, its children: 2, etc.
64
+ unlink ## Detach this node from its parent.
65
+ prune ## Unlink all of this node's chidren.
66
+ walk ## Recursively yield every node in this tree to a block
67
+ view ## Make a fancy string representation of the tree
68
+ ## as seen in the command-line tool
69
+
70
+ ### Redwood::Node
71
+
72
+ The Redwood::Node class is a simple implementation of the Redwood module. It is a good starting point for other trees. It adds new methods:
73
+
74
+ add_child(name) ## Add a child node. Nodes can have a #name.
75
+ [](name) ## Lookup children node by their #name.
76
+ <<(node) ## Add a node to this node's children.
77
+
78
+ #### Redwood::FileNode
79
+
80
+ The Redwood::FileNode class is an example use-case for Redwood, and it powers the `redwood` CLI. It stores a directory tree in a Redwood-backed structure. It has one primary method that does the magic:
81
+
82
+ dir = Redwood::FileNode.scandir '~/Projects/Redwood'
83
+
84
+ That will go through the directory and build a Redwood tree. Redwood::FileNode objects have methods that correspond to the `File` class. So you can do things like `dir.directory?` or `dir.chmod`.
85
+
86
+ Now go forth and grow some Ruby-flavored trees.
87
+
88
+ ## Copyright
89
+
90
+ Redwood is Copyright (c) 2010 Mark Wunsch and is licensed under the [MIT License](http://creativecommons.org/licenses/MIT/).
data/Rakefile CHANGED
@@ -46,3 +46,13 @@ desc "Open an irb session preloaded with this library"
46
46
  task :console do
47
47
  sh "irb -rubygems -I lib -r redwood"
48
48
  end
49
+
50
+ desc "Build the manual"
51
+ task :build_man do
52
+ sh "ronn -br5 --organization='Mark Wunsch' --manual='Redwood Manual' man/*.ronn"
53
+ end
54
+
55
+ desc "Show the manual"
56
+ task :man => :build_man do
57
+ exec "man man/redwood.1"
58
+ end
data/bin/redwood ADDED
@@ -0,0 +1,120 @@
1
+ #!/usr/bin/env ruby
2
+ ## Redwood is an implementation of `tree` in Ruby
3
+ ##
4
+ ## Usage: redwood [ OPTIONS ] [ DIRECTORY ]
5
+ ##
6
+ ## Learn more about the original at:
7
+ ## http://mama.indstate.edu/users/ice/tree/
8
+ ##
9
+ ##
10
+
11
+ require 'optparse'
12
+
13
+ def usage
14
+ File.readlines(__FILE__).
15
+ grep(/^##.*/).
16
+ map { |line| line.chomp[3..-1] }.
17
+ join("\n")
18
+ end
19
+
20
+ begin
21
+ require 'redwood'
22
+ rescue LoadError
23
+ raise if $!.to_s !~ /redwood/
24
+ libdir = File.expand_path("../../lib", __FILE__).sub(/^#{Dir.pwd}/, '.')
25
+ if !$:.include?(libdir)
26
+ $:.unshift libdir
27
+ retry
28
+ end
29
+ raise
30
+ end
31
+
32
+ options = {
33
+ :follow_symlinks => false,
34
+ :show_hidden_files => false
35
+ }
36
+ ARGV.options do |option|
37
+ option.banner = usage
38
+ option.separator "Options"
39
+ option.on('-a','All files are listed.') { options[:show_hidden_files] = true }
40
+ option.on('-d','List directories only.') { options[:only_directories] = true }
41
+ option.on('-l','Follow symbolic links like directories.') { options[:follow_symlinks] = true }
42
+ option.on('-f','Print the full path prefix for each file.') { options[:full_path] = true }
43
+ option.on('-s','Print the size in bytes of each file.') { options[:size] = true }
44
+ option.on('-D','Print the date of last modification.') { options[:date] = :mtime }
45
+ option.on('-F',"Appends '/', '@', '=', '*', or '|' as per ls -F.") { options[:ftype] = true }
46
+ option.on('-L level','Descend only level directories deep.') { |depth| options[:depth] = depth.to_i + 1}
47
+ option.separator ""
48
+ option.on_tail('--version','Prints version and exits.') { puts Redwood::VERSION ; exit }
49
+ option.on_tail('--help','Prints this help screen.') { puts option ; exit }
50
+ option.parse!
51
+ end
52
+
53
+ def statement(tree)
54
+ directories = 0
55
+ files = 0
56
+ tree.descendants.each do |f|
57
+ if f.directory?
58
+ directories += 1
59
+ else
60
+ files += 1
61
+ end
62
+ end
63
+ d = directories.eql?(1) ? 'directory' : 'directories'
64
+ f = files.eql?(1) ? 'file' : 'files'
65
+ "#{directories} #{d}, #{files} #{f}"
66
+ end
67
+
68
+ def setup_tree(tree, options)
69
+ if options[:depth]
70
+ abort 'Invalid level, must be greater than 0' if options[:depth] <= 1
71
+ tree.descendants.each {|f| f.unlink if f.depth > options[:depth] }
72
+ end
73
+ if !options[:follow_symlinks]
74
+ tree.descendants.each do |f|
75
+ if f.symlink?
76
+ f.value << " -> #{f.readlink}"
77
+ end
78
+ f.unlink if f.parent.symlink?
79
+ end
80
+ end
81
+ if options[:only_directories]
82
+ tree.descendants.each {|f| f.unlink if !f.directory? }
83
+ end
84
+ if !options[:show_hidden_files]
85
+ tree.descendants.each do |f|
86
+ f.unlink if f.basename.index('.').eql?(0)
87
+ end
88
+ end
89
+ tree.walk {|f| f.value = f.path } if options[:full_path]
90
+
91
+ if options[:date]
92
+ tree.descendants.each {|f| f.value.insert(0,"[#{f.send(options[:date]).strftime('%b %d %H:%M')}] ") }
93
+ end
94
+ if options[:size]
95
+ tree.descendants.each {|f| f.value.insert(0,"[#{f.size}] ") if f.size? }
96
+ end
97
+ if options[:ftype]
98
+ tree.descendants.each do |f|
99
+ f.value << "|" if f.ftype == 'fifo'
100
+ if f.symlink?
101
+ f.value << "@"
102
+ elsif f.directory?
103
+ f.value << "/"
104
+ end
105
+ f.value << "*" if f.executable? && f.file?
106
+ f.value << "=" if f.socket?
107
+ end
108
+ end
109
+ tree
110
+ end
111
+
112
+ dir = ARGV.empty? ? '.' : ARGV.first
113
+ abort %Q{"#{dir}" is not a directory.} if !File.directory?(dir)
114
+
115
+ tree = setup_tree Redwood::FileNode.scandir(dir), options
116
+ puts tree.view(:value)
117
+ puts "\n"
118
+ puts statement(tree)
119
+ exit
120
+
data/lib/redwood.rb CHANGED
@@ -1,29 +1,27 @@
1
- # The Redood module can be mixed in to give tree-like methods to an object.
1
+ # The Redwood module can be mixed in to give tree-like methods to an object.
2
2
  # Its primary implementation is the Redwood::Node class. Its only requirement
3
3
  # is that the tree-infused-object's children and parent is an object that
4
- # also mixes in Redwood. See Redwood::Node for the canononical representation.
4
+ # also mixes in tree-like methods. See Redwood::Node for the canononical representation.
5
5
 
6
6
  module Redwood
7
- VERSION = "0.0.1"
7
+ VERSION = "0.1.0"
8
8
 
9
+ # This node's parent.
9
10
  def parent
10
11
  @parent
11
12
  end
12
13
 
13
- def name
14
- end
15
-
16
- def value
17
- end
18
-
14
+ # Is this node the root of the tree?
19
15
  def root?
20
16
  parent.nil?
21
17
  end
22
18
 
19
+ # Is this node a leaf node? Is this node childless?
23
20
  def leaf?
24
- children.empty?
21
+ children.nil? || children.empty?
25
22
  end
26
23
 
24
+ # Get the root node in this tree.
27
25
  def root
28
26
  if root?
29
27
  self
@@ -31,56 +29,84 @@ module Redwood
31
29
  parent.root
32
30
  end
33
31
  end
34
-
32
+
33
+ # Get the children of this node.
35
34
  def children
36
35
  @children ||= []
37
36
  end
38
37
 
38
+ # Get the siblings of this node. The other children belonging to this node's parent.
39
39
  def siblings
40
40
  if parent
41
41
  parent.children.reject {|child| child == self }
42
42
  end
43
43
  end
44
44
 
45
+ # Is this node the only child of its parent. Does it have any siblings?
45
46
  def only_child?
46
47
  if parent
47
48
  siblings.empty?
48
49
  end
49
50
  end
50
51
 
51
- def childless?
52
- children.nil? || children.empty?
53
- end
54
-
52
+ # Does this node have children? Is it not a leaf node?
55
53
  def has_children?
56
- !childless?
54
+ !leaf?
57
55
  end
58
-
56
+
57
+ # Get all of the ancestors for this node.
59
58
  def ancestors
60
- return @ancestors if @ancestors
61
- @ancestors = []
59
+ ancestors = []
62
60
  if parent
63
- @ancestors << parent
64
- parent.ancestors.each {|ancestor| @ancestors << ancestor }
61
+ ancestors << parent
62
+ parent.ancestors.each {|ancestor| ancestors << ancestor }
65
63
  end
66
- @ancestors
64
+ ancestors
67
65
  end
68
-
66
+
67
+ # Get all of the descendants of this node.
68
+ # All of its children, and its childrens' children, and its childrens' childrens' children...
69
69
  def descendants
70
- return @descendants if @descendants
71
- @descendants = []
70
+ descendants = []
72
71
  if !children.empty?
73
- (@descendants << children).flatten!
74
- children.each {|descendant| @descendants << descendant.descendants }
75
- @descendants.flatten!
72
+ (descendants << children).flatten!
73
+ children.each {|descendant| descendants << descendant.descendants }
74
+ descendants.flatten!
76
75
  end
77
- @descendants
76
+ descendants
78
77
  end
79
-
78
+
79
+ # An integer representation of how deep in the tree this node is.
80
+ # The root node has a depth of 1, its children have a depth of 2, etc.
80
81
  def depth
81
82
  ancestors.size + 1
82
83
  end
83
84
 
85
+ # Orphan this node. Remove it from its parent node.
86
+ def unlink
87
+ if parent
88
+ parent.children.delete(self)
89
+ self.instance_variable_set(:@parent, nil)
90
+ return self
91
+ end
92
+ end
93
+
94
+ # Abandon all of this node's children.
95
+ def prune
96
+ if children
97
+ children.each {|child| child.unlink }
98
+ end
99
+ end
100
+
101
+ # Recursively yield every node in the tree.
102
+ def walk(&block)
103
+ if block_given?
104
+ yield self
105
+ children.each {|child| child.walk(&block) }
106
+ end
107
+ end
108
+
109
+ # Makes a pretty string representation of the tree.
84
110
  def view(content = :name)
85
111
  treeview = ''
86
112
  if parent
@@ -88,7 +114,7 @@ module Redwood
88
114
  treeview << "--\s"
89
115
  end
90
116
  treeview << "#{self.send(content)}"
91
- if !children.empty?
117
+ if has_children?
92
118
  treeview << "\n"
93
119
  children.each do |child|
94
120
  if parent
@@ -109,6 +135,6 @@ module Redwood
109
135
  treeview
110
136
  end
111
137
 
112
- end
113
-
114
- require 'redwood/node'
138
+ autoload :FileNode, 'redwood/filenode'
139
+ autoload :Node, 'redwood/node'
140
+ end
@@ -0,0 +1,46 @@
1
+ # Redwood::FileNode stores a Directory tree in a Redwood structure.
2
+ # FileNodes respond to methods of the File class.
3
+ # eg. FileNode#chmod, FileNode#stat, etc.
4
+
5
+ module Redwood
6
+ class FileNode < Node
7
+
8
+ # Takes a path and scans the directory, creating a Redwood tree.
9
+ def self.scandir(dir = Dir.pwd, tree=nil)
10
+ node = tree ? tree : self.new(dir)
11
+ if File.directory?(dir)
12
+ Dir.foreach(dir) do |d|
13
+ if File.directory?("#{dir}/#{d}")
14
+ node << scandir("#{dir}/#{d}",tree) unless (d.eql?('..') || d.eql?('.'))
15
+ else
16
+ node.add_child("#{dir}/#{d}")
17
+ end
18
+ end
19
+ else
20
+ node.add_child(dir)
21
+ end
22
+ node
23
+ end
24
+
25
+ attr_reader :path
26
+
27
+ def initialize(name, parent=nil)
28
+ super
29
+ @path = File.expand_path(name)
30
+ end
31
+
32
+ # Some information to store in the node. Defaults to the basename of the file/directory
33
+ def value
34
+ @value ||= basename
35
+ end
36
+
37
+ def method_missing(method, *args, &block)
38
+ if File.respond_to?(method)
39
+ File.send method, path
40
+ else
41
+ super
42
+ end
43
+ end
44
+
45
+ end
46
+ end
data/lib/redwood/node.rb CHANGED
@@ -1,8 +1,11 @@
1
+ # A basic representation of a Redwood tree.
2
+
1
3
  module Redwood
2
4
  class Node
3
5
  include Redwood
4
6
 
5
7
  attr_reader :name
8
+ attr_accessor :value
6
9
 
7
10
  def initialize(name=nil, parent=nil)
8
11
  @name = name
@@ -12,10 +15,19 @@ module Redwood
12
15
  # Creates a child, adds it to children, and returns the child
13
16
  def add_child(name)
14
17
  child = self.class.new(name, self)
18
+ yield child if block_given?
15
19
  children << child
16
20
  child
17
21
  end
18
22
 
23
+ # Add a node to this nodes children, and return the child
24
+ def <<(child)
25
+ child.instance_variable_set(:@parent, self)
26
+ children << child
27
+ child
28
+ end
29
+
30
+ # Lookup a child node by its name
19
31
  def [](key)
20
32
  selected_child = children.select {|child| child.name == key }
21
33
  selected_child.size.eql?(1) ? selected_child.first : selected_child
data/man/redwood.1 ADDED
@@ -0,0 +1,86 @@
1
+ .\" generated with Ronn/v0.5
2
+ .\" http://github.com/rtomayko/ronn/
3
+ .
4
+ .TH "REDWOOD" "1" "April 2010" "Mark Wunsch" "Redwood Manual"
5
+ .
6
+ .SH "NAME"
7
+ \fBredwood\fR \-\- Ruby\-flavored tree
8
+ .
9
+ .SH "SYNOPSIS"
10
+ \fBredwood\fR [\fIOPTIONS\fR] \fIDIRECTORY\fR
11
+ .
12
+ .SH "DESCRIPTION"
13
+ \fBredwood\fR is an implementation of \fBtree\fR in Ruby. Like the original \fBTree\fR, \fBRedwood\fR is a recursive directory listing program, producing a pretty\-looking depth indented listing of directory contents. Without arguments, \fBredwood\fR lists the files in the current directory. Like \fBtree\fR, after listing, \fBredwood\fR prints a summary of the total number of files and/or directories listed.
14
+ .
15
+ .P
16
+ And, again like the original \fBtree\fR, symbolic links are not followed and hidden files (those beginning with a '.') remain unseen by default. You can reveal them with options. File system constructs, the current directory as '.' and the parent directory as '..', are never printed.
17
+ .
18
+ .P
19
+ Learn more about the original \fBtree\fR with tree(1) and at http://mama.indstate.edu/users/ice/tree/
20
+ .
21
+ .P
22
+ This is a proof\-of\-concept. It's written in Ruby. It does half of what \fBtree\fR does pretty well. You should probably just use \fBtree\fR.
23
+ .
24
+ .SH "OPTIONS"
25
+ .
26
+ .TP
27
+ \fB\-a\fR
28
+ Print all files, even hidden ones (that begin with a '.').
29
+ .
30
+ .TP
31
+ \fB\-d\fR
32
+ Only list directories.
33
+ .
34
+ .TP
35
+ \fB\-l\fR
36
+ Follow symbolic links (that point to directories), as though they were directories. There is no protection from recursion, so don't do that.
37
+ .
38
+ .TP
39
+ \fB\-f\fR
40
+ Print the full path prefix for each file.
41
+ .
42
+ .TP
43
+ \fB\-s\fR
44
+ Print the size of each file in bytes.
45
+ .
46
+ .TP
47
+ \fB\-D\fR
48
+ Print the date of last modification for the file, in the format like: 'Aug 25 14:92'
49
+ .
50
+ .TP
51
+ \fB\-F\fR
52
+ Appends '/' to directories, '@' to symlinks, '=' to sockets, '*' to executables, and '|' to FIFO's, as per ls \-F.
53
+ .
54
+ .TP
55
+ \fB\-L\fR \fIlevel\fR
56
+ Max display depth of the directory tree. Has got to be greater than 0.
57
+ .
58
+ .P
59
+ Other:
60
+ .
61
+ .TP
62
+ \fB\-\-help\fR
63
+ Print the help message and quit.
64
+ .
65
+ .TP
66
+ \fB\-\-version\fR
67
+ Print the \fBredwood\fR version and quit.
68
+ .
69
+ .SH "INSTALLATION"
70
+ If you have RubyGems installed:
71
+ .
72
+ .IP "" 4
73
+ .
74
+ .nf
75
+
76
+ gem install redwood
77
+ .
78
+ .fi
79
+ .
80
+ .IP "" 0
81
+ .
82
+ .SH "COPYRIGHT"
83
+ Redwood is Copyright (C) 2010 Mark Wunsch
84
+ .
85
+ .SH "SEE ALSO"
86
+ tree(1), ls(1)
@@ -0,0 +1,128 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta http-equiv='content-type' value='text/html;charset=utf8'>
5
+ <meta name='generator' value='Ronn/v0.5'>
6
+ <title>redwood(1) -- Ruby-flavored tree</title>
7
+ <style type='text/css'>
8
+ body {margin:0}
9
+ #man, #man code, #man pre, #man tt, #man kbd, #man samp {
10
+ font-family:consolas,monospace;
11
+ font-size:16px;
12
+ line-height:1.3;
13
+ color:#343331;
14
+ background:#fff; }
15
+ #man { max-width:89ex; text-align:justify; margin:0 25px 25px 25px }
16
+ #man h1, #man h2, #man h3 { color:#232221;clear:left }
17
+ #man h1 { font-size:28px; margin:15px 0 30px 0; text-align:center }
18
+ #man h2 { font-size:18px; margin-bottom:0; margin-top:10px; line-height:1.3; }
19
+ #man h3 { font-size:16px; margin:0 0 0 4ex; }
20
+ #man p, #man ul, #man ol, #man dl, #man pre { margin:0 0 18px 0; }
21
+ #man pre {
22
+ color:#333231;
23
+ background:#edeceb;
24
+ padding:5px 7px;
25
+ margin:0px 0 20px 0;
26
+ border-left:2ex solid #ddd}
27
+ #man pre + h2, #man pre + h3 {
28
+ margin-top:22px;
29
+ }
30
+ #man h2 + pre, #man h3 + pre {
31
+ margin-top:5px;
32
+ }
33
+ #man > p, #man > ul, #man > ol, #man > dl, #man > pre { margin-left:8ex; }
34
+ #man dt { margin:0; clear:left }
35
+ #man dt.flush { float:left; width:8ex }
36
+ #man dd { margin:0 0 0 9ex }
37
+ #man code, #man strong, #man b { font-weight:bold; color:#131211; }
38
+ #man pre code { font-weight:normal; color:#232221; background:inherit }
39
+ #man em, var, u {
40
+ font-style:normal; color:#333231; border-bottom:1px solid #999; }
41
+ #man h1.man-title { display:none; }
42
+ #man ol.man, #man ol.man li { margin:2px 0 10px 0; padding:0;
43
+ float:left; width:33%; list-style-type:none;
44
+ text-transform:uppercase; font-size:18px; color:#999;
45
+ letter-spacing:1px;}
46
+ #man ol.man { width:100%; }
47
+ #man ol.man li.tl { text-align:left }
48
+ #man ol.man li.tc { text-align:center;letter-spacing:4px }
49
+ #man ol.man li.tr { text-align:right }
50
+ #man ol.man a { color:#999 }
51
+ #man ol.man a:hover { color:#333231 }
52
+ </style>
53
+ </head>
54
+ <body>
55
+ <div id='man'>
56
+
57
+ <h1 class='man-title'>redwood(1)</h1>
58
+
59
+ <ol class='head man'>
60
+ <li class='tl'>redwood(1)</li>
61
+ <li class='tc'>Redwood Manual</li>
62
+ <li class='tr'>redwood(1)</li>
63
+ </ol>
64
+
65
+ <h2 id='NAME'>NAME</h2>
66
+ <p><code>redwood</code> -- Ruby-flavored tree</p>
67
+
68
+ <h2>SYNOPSIS</h2>
69
+
70
+ <p><code>redwood</code> [<var>OPTIONS</var>] <var>DIRECTORY</var></p>
71
+
72
+ <h2>DESCRIPTION</h2>
73
+
74
+ <p><code>redwood</code> is an implementation of <code>tree</code> in Ruby. Like the original <code>Tree</code>, <code>Redwood</code> is a recursive directory listing program, producing a pretty-looking depth indented listing of directory contents. Without arguments, <code>redwood</code> lists the files in the current directory. Like <code>tree</code>, after listing, <code>redwood</code> prints a summary of the total number of files and/or directories listed.</p>
75
+
76
+ <p>And, again like the original <code>tree</code>, symbolic links are not followed and hidden files (those beginning with a '.') remain unseen by default. You can reveal them with options. File system constructs, the current directory as '.' and the parent directory as '..', are never printed.</p>
77
+
78
+ <p>Learn more about the original <code>tree</code> with tree(1) and at http://mama.indstate.edu/users/ice/tree/</p>
79
+
80
+ <p>This is a proof-of-concept. It's written in Ruby. It does half of what <code>tree</code> does pretty well. You should probably just use <code>tree</code>.</p>
81
+
82
+ <h2>OPTIONS</h2>
83
+
84
+ <dl>
85
+ <dt class="flush"><code>-a</code></dt><dd><p> Print all files, even hidden ones (that begin with a '.').</p></dd>
86
+ <dt class="flush"><code>-d</code></dt><dd><p> Only list directories.</p></dd>
87
+ <dt class="flush"><code>-l</code></dt><dd><p> Follow symbolic links (that point to directories), as though they were directories. There is no protection from recursion, so don't do that.</p></dd>
88
+ <dt class="flush"><code>-f</code></dt><dd><p> Print the full path prefix for each file.</p></dd>
89
+ <dt class="flush"><code>-s</code></dt><dd><p> Print the size of each file in bytes.</p></dd>
90
+ <dt class="flush"><code>-D</code></dt><dd><p> Print the date of last modification for the file, in the format like: 'Aug 25 14:92'</p></dd>
91
+ <dt class="flush"><code>-F</code></dt><dd><p> Appends '/' to directories, '@' to symlinks, '=' to sockets, '*' to executables, and '|' to FIFO's, as per ls -F.</p></dd>
92
+ <dt><code>-L</code> <em>level</em></dt><dd><p> Max display depth of the directory tree. Has got to be greater than 0.</p></dd>
93
+ </dl>
94
+
95
+
96
+ <p>Other:</p>
97
+
98
+ <dl>
99
+ <dt class="flush"><code>--help</code></dt><dd><p> Print the help message and quit.</p></dd>
100
+ <dt><code>--version</code></dt><dd><p> Print the <code>redwood</code> version and quit.</p></dd>
101
+ </dl>
102
+
103
+
104
+ <h2>INSTALLATION</h2>
105
+
106
+ <p>If you have RubyGems installed:</p>
107
+
108
+ <pre><code>gem install redwood
109
+ </code></pre>
110
+
111
+ <h2>COPYRIGHT</h2>
112
+
113
+ <p>Redwood is Copyright (C) 2010 Mark Wunsch</p>
114
+
115
+ <h2>SEE ALSO</h2>
116
+
117
+ <p>tree(1), ls(1)</p>
118
+
119
+
120
+ <ol class='foot man'>
121
+ <li class='tl'>Mark Wunsch</li>
122
+ <li class='tc'>April 2010</li>
123
+ <li class='tr'>redwood(1)</li>
124
+ </ol>
125
+
126
+ </div>
127
+ </body>
128
+ </html>
@@ -0,0 +1,64 @@
1
+ redwood(1) -- Ruby-flavored tree
2
+ ===================================
3
+
4
+ ## SYNOPSIS
5
+
6
+ `redwood` [<OPTIONS>] <DIRECTORY>
7
+
8
+ ## DESCRIPTION
9
+
10
+ `redwood` is an implementation of `tree` in Ruby. Like the original `Tree`, `Redwood` is a recursive directory listing program, producing a pretty-looking depth indented listing of directory contents. Without arguments, `redwood` lists the files in the current directory. Like `tree`, after listing, `redwood` prints a summary of the total number of files and/or directories listed.
11
+
12
+ And, again like the original `tree`, symbolic links are not followed and hidden files (those beginning with a '.') remain unseen by default. You can reveal them with options. File system constructs, the current directory as '.' and the parent directory as '..', are never printed.
13
+
14
+ Learn more about the original `tree` with tree(1) and at http://mama.indstate.edu/users/ice/tree/
15
+
16
+ This is a proof-of-concept. It's written in Ruby. It does half of what `tree` does pretty well. You should probably just use `tree`.
17
+
18
+ ## OPTIONS
19
+
20
+ * `-a`:
21
+ Print all files, even hidden ones (that begin with a '.').
22
+
23
+ * `-d`:
24
+ Only list directories.
25
+
26
+ * `-l`:
27
+ Follow symbolic links (that point to directories), as though they were directories. There is no protection from recursion, so don't do that.
28
+
29
+ * `-f`:
30
+ Print the full path prefix for each file.
31
+
32
+ * `-s`:
33
+ Print the size of each file in bytes.
34
+
35
+ * `-D`:
36
+ Print the date of last modification for the file, in the format like: 'Aug 25 14:92'
37
+
38
+ * `-F`:
39
+ Appends '/' to directories, '@' to symlinks, '=' to sockets, '*' to executables, and '|' to FIFO's, as per ls -F.
40
+
41
+ * `-L` _level_:
42
+ Max display depth of the directory tree. Has got to be greater than 0.
43
+
44
+ Other:
45
+
46
+ * `--help`:
47
+ Print the help message and quit.
48
+
49
+ * `--version`:
50
+ Print the `redwood` version and quit.
51
+
52
+ ## INSTALLATION
53
+
54
+ If you have RubyGems installed:
55
+
56
+ gem install redwood
57
+
58
+ ## COPYRIGHT
59
+
60
+ Redwood is Copyright (C) 2010 Mark Wunsch
61
+
62
+ ## SEE ALSO
63
+
64
+ tree(1), ls(1)
data/redwood.gemspec ADDED
@@ -0,0 +1,62 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{redwood}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Mark Wunsch"]
12
+ s.date = %q{2010-04-10}
13
+ s.default_executable = %q{redwood}
14
+ s.description = %q{A simple library to create and manage basic tree-esque structures.}
15
+ s.email = ["mark@markwunsch.com"]
16
+ s.executables = ["redwood"]
17
+ s.extra_rdoc_files = [
18
+ "LICENSE",
19
+ "README.md"
20
+ ]
21
+ s.files = [
22
+ ".document",
23
+ ".gitignore",
24
+ "Gemfile",
25
+ "LICENSE",
26
+ "README.md",
27
+ "Rakefile",
28
+ "bin/redwood",
29
+ "lib/redwood.rb",
30
+ "lib/redwood/filenode.rb",
31
+ "lib/redwood/node.rb",
32
+ "man/redwood.1",
33
+ "man/redwood.1.html",
34
+ "man/redwood.1.ronn",
35
+ "redwood.gemspec",
36
+ "test/helper.rb",
37
+ "test/test_redwood.rb"
38
+ ]
39
+ s.homepage = %q{http://github.com/mwunsch/redwood}
40
+ s.rdoc_options = ["--charset=UTF-8"]
41
+ s.require_paths = ["lib"]
42
+ s.rubygems_version = %q{1.3.6}
43
+ s.summary = %q{Ruby trees}
44
+ s.test_files = [
45
+ "test/helper.rb",
46
+ "test/test_redwood.rb"
47
+ ]
48
+
49
+ if s.respond_to? :specification_version then
50
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
51
+ s.specification_version = 3
52
+
53
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
54
+ s.add_development_dependency(%q<bundler>, [">= 0.9.7"])
55
+ else
56
+ s.add_dependency(%q<bundler>, [">= 0.9.7"])
57
+ end
58
+ else
59
+ s.add_dependency(%q<bundler>, [">= 0.9.7"])
60
+ end
61
+ end
62
+
data/test/test_redwood.rb CHANGED
@@ -7,12 +7,6 @@ class TestRedwood < Test::Unit::TestCase
7
7
  assert_equal :test, node.name
8
8
  end
9
9
 
10
- test 'can be without children' do
11
- node = Redwood::Node.new
12
- assert node.childless?
13
- assert !node.has_children?
14
- end
15
-
16
10
  test 'can be a root element' do
17
11
  node = Redwood::Node.new
18
12
  assert node.root?
@@ -126,6 +120,79 @@ class TestRedwood < Test::Unit::TestCase
126
120
  assert_respond_to node, :view
127
121
  assert_equal String, node.view.class
128
122
  end
129
-
123
+
124
+ test 'is a leaf node' do
125
+ node = Redwood::Node.new(:parent)
126
+ child = node.add_child(:child)
127
+
128
+ assert !node.leaf?
129
+ assert child.leaf?
130
+ end
131
+
132
+ test 'walks the tree' do
133
+ node = Redwood::Node.new(:parent)
134
+ dog = node.add_child(:dog)
135
+ puppy = dog.add_child(:puppy)
136
+ son = node.add_child(:son)
137
+ daughter = node.add_child(:daughter)
138
+ grandson = son.add_child(:grandson)
139
+ counter = 0
140
+ node.walk {|n| counter += 1 }
141
+ assert_equal 6, counter
142
+ end
143
+
144
+ test 'add a child with the << method' do
145
+ node = Redwood::Node.new(:parent)
146
+ dog = Redwood::Node.new(:dog)
147
+
148
+ node << dog
149
+ assert_equal node, dog.parent
150
+ assert node.children.include?(dog)
151
+ assert !dog.root?
152
+ assert !node.leaf?
153
+ end
154
+
155
+ test 'has an optional arbitrary value' do
156
+ node = Redwood::Node.new(:parent)
157
+ node.value = "hello world"
158
+ assert_equal "hello world", node.value
159
+ end
160
+
161
+ test 'unlinks a node from its parent' do
162
+ node = Redwood::Node.new(:parent)
163
+ dog = node.add_child :dog
164
+
165
+ dog.unlink
166
+ assert node.leaf?
167
+ assert !node.children.include?(dog)
168
+ assert dog.root?
169
+ end
170
+
171
+ test 'prunes its children' do
172
+ node = Redwood::Node.new(:parent)
173
+ dog = node.add_child :dog
174
+
175
+ node.prune
176
+ assert node.children.empty?
177
+ assert node.leaf?
178
+ assert !dog.parent
179
+ end
180
+ end
181
+
182
+ describe 'FileNode' do
183
+ test 'scan a directory' do
184
+ dir = Redwood::FileNode.scandir
185
+ assert_equal Dir.pwd, dir.name
186
+ end
187
+
188
+ test 'implements File methods on the Node' do
189
+ dir = Redwood::FileNode.scandir
190
+ assert dir.directory?
191
+ end
192
+
193
+ test 'has a full path' do
194
+ dir = Redwood::FileNode.scandir('.')
195
+ assert_equal File.expand_path('.'), dir.path
196
+ end
130
197
  end
131
198
  end
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 0
8
7
  - 1
9
- version: 0.0.1
8
+ - 0
9
+ version: 0.1.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Mark Wunsch
@@ -14,8 +14,8 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-04-09 00:00:00 -04:00
18
- default_executable:
17
+ date: 2010-04-10 00:00:00 -04:00
18
+ default_executable: redwood
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: bundler
@@ -34,8 +34,8 @@ dependencies:
34
34
  description: A simple library to create and manage basic tree-esque structures.
35
35
  email:
36
36
  - mark@markwunsch.com
37
- executables: []
38
-
37
+ executables:
38
+ - redwood
39
39
  extensions: []
40
40
 
41
41
  extra_rdoc_files:
@@ -48,8 +48,14 @@ files:
48
48
  - LICENSE
49
49
  - README.md
50
50
  - Rakefile
51
+ - bin/redwood
51
52
  - lib/redwood.rb
53
+ - lib/redwood/filenode.rb
52
54
  - lib/redwood/node.rb
55
+ - man/redwood.1
56
+ - man/redwood.1.html
57
+ - man/redwood.1.ronn
58
+ - redwood.gemspec
53
59
  - test/helper.rb
54
60
  - test/test_redwood.rb
55
61
  has_rdoc: true