redwood 0.0.1 → 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.
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