treebis 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/README ADDED
@@ -0,0 +1,98 @@
1
+ <embed
2
+ style='position: absolute; right:0; top:0'
3
+ src="svg/go-green.svg" width="150px" height="150px"
4
+ type="image/svg+xml"
5
+ pluginspage="http://www.adobe.com/svg/viewer/install/" />
6
+
7
+
8
+ # treebis
9
+
10
+ ## summary
11
+ minimal single-file rake-like task DSL for wrapping common filesystem tasks like copying files.
12
+
13
+
14
+ ## description
15
+ Treebis is a minimal, general scripting/task utility written in ruby that wraps common actions for moving, copying and altering filetrees. It is geared towards things like generators. It is comparable to a shell script that does a lot of mkdir, mv, cp commmands etc.
16
+
17
+
18
+ ## what it is:
19
+ - task wrapper for external commands that make filetrees, e.g.
20
+ - maybe the generators in things like rails, ramaze, nandoc
21
+ - proxy around FileUtils that allows customizing its output
22
+ - copies filetrees to filetrees
23
+ - removes filetrees from filetrees
24
+ - applies diffs to filetrees
25
+ - different ways to represent trees and diffs - heredocs, diffs, filesystem.
26
+ - under 1000 SLOC
27
+ - rcov test coverage usually hovers between 95-100%
28
+
29
+ ## what it is not:
30
+ - a vcs or vcs wrapper (version control system)
31
+ - atomic
32
+
33
+ ## frequently asked questions
34
+
35
+ ### Q: why use it?
36
+ <span class='answer'>A</span>: Because you want a consistent way to wrap these common tasks that doesn't explicitly rely on shelling out to the underlying system, or other hodgepodges. (also see 'why did you make this?' below)
37
+
38
+ ### Q: why not use it?
39
+ <span class='answer'>A</span>: Because it doesn't do what you want or it does what you do not want.
40
+
41
+ ### Q: why is it named "Treebis?"
42
+ <span class='answer'>A</span>: because it rhymes with "Jeebus."
43
+
44
+ ### Q: why did you make this?
45
+ <span class='answer'>A</span>: by the third or fourth time i found myself re-writing this same kind of thing for different projects, or bleeding from its absence, i decided to abstract it. It's more readable than a bunch of FileUtils statements, it paves the way for possible future enhancements like atomicitiy and units of work; and wouldn't it be nice if every generator of every project used the same library?
46
+
47
+ ## requirements
48
+ - ruby 1.8.7
49
+ - Treebis supports the application of unified diffs to single files
50
+ and whole directories. If this functionality is desired,
51
+ Treebis was developed with GNU `patch` 2.5.8. Most versions of patch
52
+ will likely work.
53
+
54
+ ## installation
55
+
56
+ ### install the gem:
57
+
58
+ from the command line:
59
+ ~~~
60
+ ~ > gem install treebis
61
+ ~~~
62
+
63
+
64
+ ### or grab the file:
65
+
66
+ <em>
67
+ <a class='no-style' href='#' title='At The Time of This Writing'>ATTOTW</a>
68
+ treebis is a single file without dependencies except 'json'. You can
69
+ <a href='http://github.com/hipe/treebis/blob/master/lib/treebis.rb'>just download it</a> and throw it in your code directory
70
+ <sup id="fnref:trollop"><a href="#fn:trollop" rel="footnote">1</a></sup>
71
+ </em>
72
+
73
+
74
+ ## usage
75
+ May I refer you to these [usage examples](usage-examples)?
76
+
77
+ ## future promises made today:
78
+ - dry run ?
79
+ - two-pass units of work !!??
80
+
81
+
82
+ <br />
83
+ <br />
84
+ <hr />
85
+
86
+ ### Footnotes
87
+
88
+ <div class="footnotes">
89
+ <ol>
90
+ <li id="fn:trollop">
91
+ <p>Appologies to <a href='http://trollop.rubyforge.org/'>trollop</a>
92
+ from which is stole this langauge and idea of keeping things in a
93
+ single file when practical.
94
+ <a href="#fnref:trollop" rev="footnote">&#8617;</a>
95
+ </p>
96
+ </li>
97
+ </ol>
98
+ </div>
data/Rakefile ADDED
@@ -0,0 +1,49 @@
1
+ task :default => :test
2
+
3
+ me = "\e[35mtreebis\e[0m "
4
+
5
+ desc "#{me}generate rcov coverage"
6
+ task :rcov do
7
+ sh "rcov --exclude '.*gem.*' lib/treebis.rb"
8
+ end
9
+
10
+ desc "#{me}run them"
11
+ task :test do
12
+ sh "ruby -w lib/treebis.rb"
13
+ require File.dirname(__FILE__)+'/test/test-for-doc.rb'
14
+ end
15
+
16
+ desc "#{me}see if the tests for docs run"
17
+ task :doc do
18
+ require File.dirname(__FILE__)+'/test/test_for_doc.rb'
19
+ end
20
+
21
+ desc "#{me}hack turns the installed gem into a symlink to this directory"
22
+ task :hack do
23
+ kill_path = %x{gem which treebis}
24
+ kill_path = File.dirname(File.dirname(kill_path))
25
+ new_name = File.dirname(kill_path)+'/ok-to-erase-'+File.basename(kill_path)
26
+ FileUtils.mv(kill_path, new_name, :verbose => 1)
27
+ this_path = File.dirname(__FILE__)
28
+ FileUtils.ln_s(this_path, kill_path, :verbose => 1)
29
+ end
30
+
31
+
32
+ require 'jeweler'
33
+ require 'nandoc'
34
+ require 'nandoc/parse-readme'
35
+
36
+ Jeweler::Tasks.new do |s|
37
+ s.add_dependency 'json'
38
+ s.authors = ['Chip Malice']
39
+ s.description = NanDoc::ParseReadme.description('README')
40
+ s.files = FileList['[A-Z]*', '{bin,doc,generators,lib,test}/**/*']
41
+ s.email = 'chip.malice@gmail.com'
42
+ s.homepage = 'http://treebis.hipeland.org'
43
+ s.name = 'treebis'
44
+ s.rubyforge_project = 'treebis'
45
+ s.summary = NanDoc::ParseReadme.summary('README')
46
+
47
+ s.add_dependency 'json', '~> 1.2.3'
48
+ end
49
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,38 @@
1
+ # treebis
2
+
3
+ ## additional goodies
4
+
5
+ ### PersistentDotfile
6
+
7
+ Initially an auxilliary class for testing, `PeristentDotfile` proved to be a useful little utility in its own right which I may end up getting more miles out of than Treebis itself in my other projects. It simply:
8
+
9
+ * wraps `Dir#tmpdir` which gives you a platform-independent api to (the platform dependent location of) a temporary directory.
10
+ * gives you an awesome little persistent JSON structure that you can write to and read accross invocations to your app.[^sessions]
11
+
12
+ (see: test-for-doc.rb - 'persistent dotfile')
13
+
14
+
15
+ What's happening here is: 1) we're using the dubious pattern of making some modules and extending `self`, which is a quick and dirty way to get a singleton object[^sing].
16
+
17
+ 2) We're enhancing the modules in question with `PersistentDotfile`. Instead of `include`ing it, we employ the `include_to` pseudo-pattern. It's like an `include()` but it makes explicit (some of) the creepy metaprogramming going on behind the scenes, and it allows us to pass parameters to the enhancement.
18
+
19
+ In this case, we are passing `'somefile.json'` which is an argument that tells the module where to write its persistent data. (Making it a relative path like this, it will write the file to whatever the current working directory is when it goes to save it.)
20
+
21
+ As you can (sort of) see from the output, the first module writes the data to the file and the second module reads it.
22
+
23
+ Just for fun, let's see what it's writing to that file:
24
+
25
+ (see: test-for-doc.rb - 'persistent dotfile' -- 'see contents')
26
+
27
+
28
+ Simply amazing.
29
+
30
+ There're other mind-blowing things `PersistentDotfile` can achieve that will change your life, like making a temporary directory.
31
+
32
+ <br />
33
+ <br />
34
+ <hr />
35
+ ### _Footnotes_ ###
36
+
37
+ [^sessions]:comparable to a really cheap & easy session façade you find in all web frameworks
38
+ [^sing]:the other kind of purist would have you use the [singleton module](http://www.ruby-doc.org/stdlib/libdoc/singleton/rdoc/files/singleton_rb.html) to make a singleton module.
@@ -0,0 +1,19 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
3
+ "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
4
+ <svg width="175" height="175"
5
+ viewBox="0.00 0.00 175.00 175.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
6
+ <g id="blah1" class="whatevs" transform="scale(1 1) rotate(0) translate(0 0)">
7
+ <title>this_some_awesome_thing</title>
8
+ <polygon fill="white" stroke="white" points="5,140 5,0 140,0 140,140 5,140"/>
9
+ <g id="node1" class="node">
10
+ <polygon fill="#ccee33" points="19,0 175,0 175,132 169,122 162,132 157,122 148,130 145,119 136,127 133,116 124,124 121,113 112,120 109,109 99,116 98,104 87,109 87,98 76,104 76,92 65,97 65,86 54,91 55,80 43,84 45,73 33,75 38,64 26,64 32,54 21,53 28,44 17,42 25,34 14,32 23,25 12,21 22,16 12,12 21,7 13,3 15,0"/>
11
+
12
+ <g id="blah2" class="whatevs" transform="scale(1) rotate(20) translate(12, -30)">
13
+ <text text-anchor="middle" x="108" y="32" font-family="Super Sans; sans-serif" font-size="22" fill="#332200">go green!</text>
14
+ <text text-anchor="middle" x="108" y="59" font-family="serif" font-size="22" fill="#332200">go treebis!</text>
15
+ </g>
16
+
17
+ </g>
18
+ </g>
19
+ </svg>
@@ -0,0 +1,41 @@
1
+ # Treebis
2
+
3
+ ## Usage Examples
4
+
5
+ ### Using DirAsHash to write files
6
+ _quick and dirty way to make files and folders from a hash:_
7
+
8
+ (see: test-for-doc.rb - 'using dir as hash')
9
+
10
+ In the above example we see a way to write two folders with three files.
11
+
12
+ The class we make included DirAsHash and used its `hash_to_dir()` method.
13
+
14
+ For the hash elements that are strings, the keys become filenames and the string become file contents. For the hash values that are themselves hashes, the hash key becomes a folder name, and so on.
15
+
16
+ The last line shows that the files were written successfully.
17
+
18
+ ### Making and Running a Treebis Task
19
+ _minimal treebis example_
20
+
21
+ The above example was just for giving us some files to work with. In practice it is not a very practical way to write files of any significant length, if for no other reason than for how unreadable it would be (and hence useless to be in ruby.)[^in_prac]
22
+
23
+ Let's say you want to write a script that installs these files to some arbitrary directory. *That* is exactly what our little Treebis here is for.
24
+
25
+ Let's say also you don't want to write all the files to the target location, just those files matching a fileglob pattern. Furthermore let's say you want to process one of the files as an erb template, for which we will provide values to substitute for placeholders in the document:
26
+
27
+ (see: test-for-doc.rb - 'first task')
28
+
29
+ Above we see that a Task object is composed of a code block composed of a sequence of commands, many of which are wrappers around the familiar FileUtils methods.
30
+
31
+ Treebis tasks usually work with files _from_ a location and apply them _on_ another location (either copying files directly or interpolating them along the way, or applying diff patches.) A Task won't autmatically make any directories without explicitly being told to do so, so we make directories in two places above.
32
+
33
+ In the last line we see that the net result of this is that the task wrote to the target directory two of the three files from the source directory, and in one of the files it interpolated the erb template with values that we passed to it.
34
+
35
+ I really wanted to show you the pretty colors in the output but I must get going!
36
+
37
+ <br />
38
+ <hr />
39
+ ### _Footnotes_ ###
40
+
41
+ [^in_prac]: In practice I *do* however write files this way for many of my tests, including the one that generated the examples for this file ;)