folio 0.3.0 → 0.4.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/CHANGES +91 -7
- data/COPYING +162 -669
- data/MANIFEST +52 -16
- data/README +1 -1
- data/RELEASE +14 -0
- data/VERSION +1 -1
- data/demo/sample1/tryme.rb +1 -1
- data/doc/log/basic_stats/index.html +39 -0
- data/doc/log/changelog.html +323 -0
- data/doc/log/changelog.xml +129 -0
- data/doc/log/changelog.xsl +33 -0
- data/doc/log/notes.xml +35 -0
- data/{NEWS → doc/note/release-0.3.0.txt} +1 -1
- data/doc/spec/index.html +552 -0
- data/lib/folio.rb +15 -3
- data/lib/folio/directory.rb +10 -5
- data/lib/folio/document.rb +11 -8
- data/lib/folio/errors.rb +15 -0
- data/lib/folio/fileobject.rb +6 -3
- data/lib/folio/filetest.rb +88 -0
- data/lib/folio/fileutils.rb +39 -0
- data/lib/folio/link.rb +2 -5
- data/lib/folio/minitar.rb +1063 -0
- data/lib/folio/multiglob.rb +91 -0
- data/lib/folio/path.rb +56 -0
- data/lib/folio/shell.rb +289 -50
- data/lib/folio/uploadutils.rb +434 -0
- data/lib/folio/xdg.rb +4 -0
- data/lib/folio/ziputils.rb +489 -0
- data/spec/document/basic.rd +53 -0
- data/spec/document/fixtures/foo.txt +1 -0
- data/spec/document/fixtures/out.txt +1 -0
- data/spec/link/fixtures/foo.txt +1 -0
- data/spec/link/general.rd +44 -0
- data/spec/shell/fixtures/foo.txt +1 -0
- data/spec/shell/fixtures/out.txt +1 -0
- data/spec/shell/general.rd +30 -0
- data/spec/shell/issues.rd +100 -0
- metadata +58 -27
@@ -0,0 +1,129 @@
|
|
1
|
+
<?xml version="1.0"?>
|
2
|
+
<log>
|
3
|
+
<entry>
|
4
|
+
<date>Tue Sep 16 13:18:40 -0400 2008</date>
|
5
|
+
<author> trans <transfire@gmail.com></author>
|
6
|
+
<revison>77b1389e5bccf8b5052152a8d75cc0c00b1d1b52</revison>
|
7
|
+
<type></type>
|
8
|
+
<message>added more spec fictures</message>
|
9
|
+
</entry>
|
10
|
+
<entry>
|
11
|
+
<date>Tue Sep 16 13:18:06 -0400 2008</date>
|
12
|
+
<author> trans <transfire@gmail.com></author>
|
13
|
+
<revison>8a2eb973587d99ef4978191eececf6d0f588b90a</revison>
|
14
|
+
<type></type>
|
15
|
+
<message>improved error messages</message>
|
16
|
+
</entry>
|
17
|
+
<entry>
|
18
|
+
<date>Tue Sep 16 13:16:36 -0400 2008</date>
|
19
|
+
<author> trans <transfire@gmail.com></author>
|
20
|
+
<revison>7e0c67bf84574d0343ce78330959f5bf5335247f</revison>
|
21
|
+
<type></type>
|
22
|
+
<message>added LinkNotFound error</message>
|
23
|
+
</entry>
|
24
|
+
<entry>
|
25
|
+
<date>Tue Sep 16 13:16:03 -0400 2008</date>
|
26
|
+
<author> trans <transfire@gmail.com></author>
|
27
|
+
<revison>8b72d67261db24f2b40597c34827a35441d76c30</revison>
|
28
|
+
<type></type>
|
29
|
+
<message>remarked out Folio shortcut #[] method for time being</message>
|
30
|
+
</entry>
|
31
|
+
<entry>
|
32
|
+
<date>Tue Sep 16 11:53:43 -0400 2008</date>
|
33
|
+
<author> trans <transfire@gmail.com></author>
|
34
|
+
<revison>b1ed5ded2ec3798397461004186bb7b59b9d1ef9</revison>
|
35
|
+
<type></type>
|
36
|
+
<message>added spec for link.rb</message>
|
37
|
+
</entry>
|
38
|
+
<entry>
|
39
|
+
<date>Tue Sep 16 11:42:22 -0400 2008</date>
|
40
|
+
<author> trans <transfire@gmail.com></author>
|
41
|
+
<revison>5d2f4d23c060c92d5e7e843079379f43e4d881e0</revison>
|
42
|
+
<type></type>
|
43
|
+
<message>removed relpath</message>
|
44
|
+
</entry>
|
45
|
+
<entry>
|
46
|
+
<date>Tue Sep 16 11:41:04 -0400 2008</date>
|
47
|
+
<author> trans <transfire@gmail.com></author>
|
48
|
+
<revison>b9a38c5a8370aa7e4cf57bba80bdafbc39cdb674</revison>
|
49
|
+
<type></type>
|
50
|
+
<message>renamed spec_prompt.rb to spec_shell.rb</message>
|
51
|
+
</entry>
|
52
|
+
<entry>
|
53
|
+
<date>Tue Sep 16 11:30:40 -0400 2008</date>
|
54
|
+
<author> trans <transfire@gmail.com></author>
|
55
|
+
<revison>da2eb57bccd4400e0b272836ad9cf23ce23d6b19</revison>
|
56
|
+
<type>major</type>
|
57
|
+
<message>Renamed Prompt to Shell. </message>
|
58
|
+
</entry>
|
59
|
+
<entry>
|
60
|
+
<date>Thu Sep 11 12:50:59 -0400 2008</date>
|
61
|
+
<author> trans <transfire@gmail.com></author>
|
62
|
+
<revison>e8dadfff85bbf3dc5cf8cced5be17b0789b04650</revison>
|
63
|
+
<type></type>
|
64
|
+
<message>moved test directory to spec directory</message>
|
65
|
+
</entry>
|
66
|
+
<entry>
|
67
|
+
<date>Thu Sep 11 12:44:48 -0400 2008</date>
|
68
|
+
<author> trans <transfire@gmail.com></author>
|
69
|
+
<revison>94d3c4989d012173606ddbc37ddf0a8bc702b661</revison>
|
70
|
+
<type></type>
|
71
|
+
<message>turned tests into specs</message>
|
72
|
+
</entry>
|
73
|
+
<entry>
|
74
|
+
<date>Thu Sep 11 12:44:07 -0400 2008</date>
|
75
|
+
<author> trans <transfire@gmail.com></author>
|
76
|
+
<revison>2454fe9d762aee096db7143dacc398582269690e</revison>
|
77
|
+
<type></type>
|
78
|
+
<message>fixed tests by adding #== to FileObject class</message>
|
79
|
+
</entry>
|
80
|
+
<entry>
|
81
|
+
<date>Wed Sep 10 16:30:28 -0400 2008</date>
|
82
|
+
<author> trans <transfire@gmail.com></author>
|
83
|
+
<revison>c07c7bd87c0109db8019cac1be89b217855397b5</revison>
|
84
|
+
<type></type>
|
85
|
+
<message>custom rdoc-template</message>
|
86
|
+
</entry>
|
87
|
+
<entry>
|
88
|
+
<date>Wed Sep 10 15:10:48 -0400 2008</date>
|
89
|
+
<author> trans <transfire@gmail.com></author>
|
90
|
+
<revison>b4cb8082c81719d5fa0788f0566fe28656f1533d</revison>
|
91
|
+
<type></type>
|
92
|
+
<message>added TODO and VERSION files</message>
|
93
|
+
</entry>
|
94
|
+
<entry>
|
95
|
+
<date>Wed Sep 10 15:06:56 -0400 2008</date>
|
96
|
+
<author> trans <transfire@gmail.com></author>
|
97
|
+
<revison>9a926a12a0b061c3ec9bfbd23f5387e65c1e7201</revison>
|
98
|
+
<type>major</type>
|
99
|
+
<message>Added XDG methods to Prompt class. </message>
|
100
|
+
</entry>
|
101
|
+
<entry>
|
102
|
+
<date>Wed Sep 10 14:16:35 -0400 2008</date>
|
103
|
+
<author> trans <transfire@gmail.com></author>
|
104
|
+
<revison>474f3f77720a102e47bcd699ae5700b7a40e741b</revison>
|
105
|
+
<type></type>
|
106
|
+
<message>moved METADATA to meta/</message>
|
107
|
+
</entry>
|
108
|
+
<entry>
|
109
|
+
<date>Sat Sep 06 12:59:40 -0400 2008</date>
|
110
|
+
<author> trans <transfire@gmail.com></author>
|
111
|
+
<revison>9714d9df4d409a4013acb6530ea3e3ce7b53acb5</revison>
|
112
|
+
<type></type>
|
113
|
+
<message>added .gitignore file</message>
|
114
|
+
</entry>
|
115
|
+
<entry>
|
116
|
+
<date>Sat Sep 06 12:58:25 -0400 2008</date>
|
117
|
+
<author> trans <transfire@gmail.com></author>
|
118
|
+
<revison>168a1faaf6148677bfdeec36793d4d141cf2a6d8</revison>
|
119
|
+
<type></type>
|
120
|
+
<message>reorganized project for reap changes</message>
|
121
|
+
</entry>
|
122
|
+
<entry>
|
123
|
+
<date>Thu Sep 04 17:03:44 -0400 2008</date>
|
124
|
+
<author> trans <transfire@gmail.com></author>
|
125
|
+
<revison>20c00238d1401c2b4385f0a6109c2c001b922008</revison>
|
126
|
+
<type>major</type>
|
127
|
+
<message>Started Repository. </message>
|
128
|
+
</entry>
|
129
|
+
</log>
|
@@ -0,0 +1,33 @@
|
|
1
|
+
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
|
2
|
+
|
3
|
+
<xsl:output cdata-section-elements="script"/>
|
4
|
+
|
5
|
+
<xsl:template match="/">
|
6
|
+
<html>
|
7
|
+
<head>
|
8
|
+
<title>Changelog</title>
|
9
|
+
<link REL='SHORTCUT ICON' HREF="../img/ruby-sm.png" />
|
10
|
+
<style>
|
11
|
+
td { font-family: sans-serif; padding: 0px 10px; }
|
12
|
+
</style>
|
13
|
+
</head>
|
14
|
+
<body>
|
15
|
+
<div class="container">
|
16
|
+
<h1>Changelog</h1>
|
17
|
+
<table style="width: 100%;">
|
18
|
+
<xsl:apply-templates />
|
19
|
+
</table>
|
20
|
+
</div>
|
21
|
+
</body>
|
22
|
+
</html>
|
23
|
+
</xsl:template>
|
24
|
+
|
25
|
+
<xsl:template match="entry">
|
26
|
+
<tr>
|
27
|
+
<td><b><pre><xsl:value-of select="msg"/></pre></b></td>
|
28
|
+
<td><xsl:value-of select="author"/></td>
|
29
|
+
<td><xsl:value-of select="date"/></td>
|
30
|
+
</tr>
|
31
|
+
</xsl:template>
|
32
|
+
|
33
|
+
</xsl:stylesheet>
|
data/doc/log/notes.xml
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
<notes>
|
2
|
+
<set label="FIXME">
|
3
|
+
<file src="lib/folio/minitar.rb">
|
4
|
+
<note line="421" type="FIXME">FIXME: what if an exception is raised in the block?</note>
|
5
|
+
<note line="458" type="FIXME">FIXME: what if an exception is raised in the block?</note>
|
6
|
+
</file>
|
7
|
+
</set>
|
8
|
+
<set label="TODO">
|
9
|
+
<file src="lib/folio/fileutils.rb">
|
10
|
+
<note line="10" type="TODO">TODO: Rename to linkstage or something less likely to name clash?</note>
|
11
|
+
<note line="22" type="TODO">TODO: dryrun test here or before folder creation?</note>
|
12
|
+
</file>
|
13
|
+
<file src="lib/folio/filetest.rb">
|
14
|
+
<note line="33" type="TODO">TODO: Make more robust. Probably needs to be fixed for Windows.</note>
|
15
|
+
<note line="52" type="TODO">TODO: Make more robust.</note>
|
16
|
+
</file>
|
17
|
+
<file src="lib/folio/fileobject.rb">
|
18
|
+
<note line="204" type="TODO">TODO: I don't like the name of this.</note>
|
19
|
+
</file>
|
20
|
+
<file src="lib/folio/document.rb">
|
21
|
+
<note line="40" type="TODO">TODO: how to handle unkinking (b/c file no longer exists)</note>
|
22
|
+
</file>
|
23
|
+
<file src="lib/folio/ziputils.rb">
|
24
|
+
<note line="7" type="TODO">TODO: Much of this shells out. It would be best to internalize.</note>
|
25
|
+
<note line="29" type="TODO">TODO: support gzip and bzip2 as well.</note>
|
26
|
+
<note line="141" type="TODO">TODO: Write unified untar_gzip function.</note>
|
27
|
+
</file>
|
28
|
+
<file src="lib/folio/shell.rb">
|
29
|
+
<note line="66" type="TODO">TODO: Should there be methods like this for each
|
30
|
+
type, and raise an error if not the right type?</note>
|
31
|
+
<note line="131" type="TODO">TODO: Ultimately merge #glob and #multiglob.</note>
|
32
|
+
<note line="196" type="TODO">TODO: Is #out_of_date? this the same as #uptodate?</note>
|
33
|
+
</file>
|
34
|
+
</set>
|
35
|
+
</notes>
|
data/doc/spec/index.html
ADDED
@@ -0,0 +1,552 @@
|
|
1
|
+
<html>
|
2
|
+
<head>
|
3
|
+
<title>Specifications</title>
|
4
|
+
|
5
|
+
<style>
|
6
|
+
#container{ margin: 0 auto; width: 800px; }
|
7
|
+
/* Debug borders */
|
8
|
+
p, li, dt, dd, div, pre, h1, h2, h3, h4, h5, h6 {
|
9
|
+
/*
|
10
|
+
border: 1px solid red;
|
11
|
+
*/
|
12
|
+
}
|
13
|
+
body { font-size: 0.9em; margin: 1em 5% 1em 5%; }
|
14
|
+
a { color: blue; text-decoration: underline; }
|
15
|
+
a:visited { color: fuchsia; }
|
16
|
+
em { font-style: italic; }
|
17
|
+
strong { font-weight: bold; }
|
18
|
+
tt { color: navy; }
|
19
|
+
h1, h2, h3, h4, h5, h6 {
|
20
|
+
color: #527bbd;
|
21
|
+
font-family: sans-serif;
|
22
|
+
margin-top: 1.2em;
|
23
|
+
margin-bottom: 0.5em;
|
24
|
+
line-height: 1.3;
|
25
|
+
}
|
26
|
+
h1 { border-bottom: 2px solid silver; }
|
27
|
+
h2 { border-bottom: 2px solid silver; padding-top: 0.5em; }
|
28
|
+
hr { border: 1px solid silver; }
|
29
|
+
p { color: #555;
|
30
|
+
text-align: justify;
|
31
|
+
margin-top: 0.5em;
|
32
|
+
margin-bottom: 0.5em;
|
33
|
+
line-height: 1.4em;
|
34
|
+
}
|
35
|
+
pre { padding: 10; margin: 0; }
|
36
|
+
|
37
|
+
span#author {
|
38
|
+
color: #527bbd;
|
39
|
+
font-family: sans-serif;
|
40
|
+
font-weight: bold;
|
41
|
+
font-size: 1.1em;
|
42
|
+
}
|
43
|
+
span#email {
|
44
|
+
}
|
45
|
+
span#revision {
|
46
|
+
font-family: sans-serif;
|
47
|
+
}
|
48
|
+
|
49
|
+
div#footer {
|
50
|
+
font-family: sans-serif;
|
51
|
+
font-size: small;
|
52
|
+
border-top: 2px solid silver;
|
53
|
+
padding-top: 0.5em;
|
54
|
+
margin-top: 4.0em;
|
55
|
+
}
|
56
|
+
|
57
|
+
div#footer-text {
|
58
|
+
float: left;
|
59
|
+
padding-bottom: 0.5em;
|
60
|
+
}
|
61
|
+
|
62
|
+
div#footer-badges {
|
63
|
+
float: right;
|
64
|
+
padding-bottom: 0.5em;
|
65
|
+
}
|
66
|
+
|
67
|
+
div.content { /* Block element content. */
|
68
|
+
padding: 0;
|
69
|
+
}
|
70
|
+
|
71
|
+
/* Block element titles. */
|
72
|
+
h1.title {
|
73
|
+
font-family: sans-serif;
|
74
|
+
font-weight: bold;
|
75
|
+
text-align: left;
|
76
|
+
font-size: 3em;
|
77
|
+
margin-top: 1.0em;
|
78
|
+
margin-bottom: 0.5em;
|
79
|
+
}
|
80
|
+
|
81
|
+
/* Block element titles. */
|
82
|
+
div.title, caption.title {
|
83
|
+
font-family: sans-serif;
|
84
|
+
font-weight: bold;
|
85
|
+
text-align: left;
|
86
|
+
margin-top: 1.0em;
|
87
|
+
margin-bottom: 0.5em;
|
88
|
+
}
|
89
|
+
div.title + * {
|
90
|
+
margin-top: 0;
|
91
|
+
}
|
92
|
+
|
93
|
+
td div.title:first-child {
|
94
|
+
margin-top: 0.0em;
|
95
|
+
}
|
96
|
+
div.content div.title:first-child {
|
97
|
+
margin-top: 0.0em;
|
98
|
+
}
|
99
|
+
div.content + div.title {
|
100
|
+
margin-top: 0.0em;
|
101
|
+
}
|
102
|
+
|
103
|
+
div.sidebarblock > div.content {
|
104
|
+
background: #ffffee;
|
105
|
+
border: 1px solid silver;
|
106
|
+
padding: 0.5em;
|
107
|
+
}
|
108
|
+
|
109
|
+
img { border-style: none; }
|
110
|
+
|
111
|
+
dl { margin-top: 0.8em; margin-bottom: 0.8em; }
|
112
|
+
dt { margin-top: 0.5em; margin-bottom: 0; font-style: italic; }
|
113
|
+
dd > *:first-child { margin-top: 0; }
|
114
|
+
ul, ol { list-style-position: outside; }
|
115
|
+
|
116
|
+
thead { font-family: sans-serif; font-weight: bold; }
|
117
|
+
tfoot { font-weight: bold; }
|
118
|
+
</style>
|
119
|
+
|
120
|
+
<!-- JQuery is needed -->
|
121
|
+
<script src="../assets/scripts/jquery.js" type="text/javascript" language="javascript"></script>
|
122
|
+
|
123
|
+
|
124
|
+
|
125
|
+
<link href="../assets/styles/spec.css" type="text/css" rel="stylesheet">
|
126
|
+
</head>
|
127
|
+
|
128
|
+
<body>
|
129
|
+
|
130
|
+
<!-- Side Table of Contents -->
|
131
|
+
<div id="sidebar" style="position: fixed; top: 10; right: 10; background: white;">
|
132
|
+
<a href="javascript: toc_toggle();">
|
133
|
+
<img src="img/icon/book.jpg" height="30px;" style="border: none;" alt="TOC" align="right"/>
|
134
|
+
</a>
|
135
|
+
|
136
|
+
<div id="toc_side" class="toc">
|
137
|
+
</div>
|
138
|
+
</div>
|
139
|
+
|
140
|
+
<div id="container">
|
141
|
+
<div id="header">
|
142
|
+
<img src="img/icon/book.jpg" align="left" style="padding-right: 10px;" alt=""/>
|
143
|
+
|
144
|
+
<h1 class="title">Specifications</h1>
|
145
|
+
|
146
|
+
<h1>Table of Contents</h1>
|
147
|
+
|
148
|
+
<div class="toc">
|
149
|
+
</div>
|
150
|
+
</div>
|
151
|
+
|
152
|
+
<div id="content">
|
153
|
+
<h1>Document Unit Testing</h1>
|
154
|
+
<p>
|
155
|
+
Load the Folio library.
|
156
|
+
</p>
|
157
|
+
<pre>
|
158
|
+
require 'folio'
|
159
|
+
</pre>
|
160
|
+
<p>
|
161
|
+
Instantiate document object.
|
162
|
+
</p>
|
163
|
+
<pre>
|
164
|
+
@foo = Folio.file('fixtures/foo.txt')
|
165
|
+
</pre>
|
166
|
+
<p>
|
167
|
+
Confirm it is a a document.
|
168
|
+
</p>
|
169
|
+
<pre>
|
170
|
+
@foo.assert.document?
|
171
|
+
</pre>
|
172
|
+
<p>
|
173
|
+
Confirm it is equal to another document initialized identically.
|
174
|
+
</p>
|
175
|
+
<pre>
|
176
|
+
@foo.assert == Folio.file('fixtures/foo.txt')
|
177
|
+
</pre>
|
178
|
+
<p>
|
179
|
+
Confirm it is equal to the same file initialized from a different working
|
180
|
+
directory.
|
181
|
+
</p>
|
182
|
+
<pre>
|
183
|
+
f = nil
|
184
|
+
Dir.chdir('fixtures') do
|
185
|
+
f = Folio.file('foo.txt')
|
186
|
+
end
|
187
|
+
@foo.assert == f
|
188
|
+
</pre>
|
189
|
+
<p>
|
190
|
+
Document can be read.
|
191
|
+
</p>
|
192
|
+
<pre>
|
193
|
+
@foo.read.assert == "THIS IS FOO!\n"
|
194
|
+
</pre>
|
195
|
+
<p>
|
196
|
+
The #readlines methods read the document into an array of lines.
|
197
|
+
</p>
|
198
|
+
<pre>
|
199
|
+
@foo.readlines.assert == ["THIS IS FOO!\n"]
|
200
|
+
</pre>
|
201
|
+
<p>
|
202
|
+
We can also open the document for reading using the more traditional open()
|
203
|
+
method.
|
204
|
+
</p>
|
205
|
+
<pre>
|
206
|
+
t = nil
|
207
|
+
@foo.open('r'){ |f| t = f.read }
|
208
|
+
t.assert == "THIS IS FOO!\n"
|
209
|
+
</pre>
|
210
|
+
<p>
|
211
|
+
The #parent method return the Directory object in which the document is
|
212
|
+
contained.
|
213
|
+
</p>
|
214
|
+
<pre>
|
215
|
+
@foo.parent.assert == Folio.file('fixtures')
|
216
|
+
</pre>
|
217
|
+
<p>
|
218
|
+
A document can be written to as well using the #write method.
|
219
|
+
</p>
|
220
|
+
<pre>
|
221
|
+
out = Folio.doc('fixtures/out.txt')
|
222
|
+
out.write('Hello')
|
223
|
+
File.read(out.to_s).assert == 'Hello'
|
224
|
+
</pre>
|
225
|
+
|
226
|
+
|
227
|
+
|
228
|
+
|
229
|
+
|
230
|
+
<h1>General Usage of Folio Link Object</h1>
|
231
|
+
<p>
|
232
|
+
Require the Folio library.
|
233
|
+
</p>
|
234
|
+
<pre>
|
235
|
+
require 'folio'
|
236
|
+
</pre>
|
237
|
+
<p>
|
238
|
+
Instantiate a soft link.
|
239
|
+
</p>
|
240
|
+
<pre>
|
241
|
+
@foo = Folio.file('fixtures/foo_softlink.txt')
|
242
|
+
</pre>
|
243
|
+
<p>
|
244
|
+
It is a link.
|
245
|
+
</p>
|
246
|
+
<pre>
|
247
|
+
@foo.link?.assert == true
|
248
|
+
</pre>
|
249
|
+
<p>
|
250
|
+
It is equal to a link defined identically.
|
251
|
+
</p>
|
252
|
+
<pre>
|
253
|
+
@foo.assert == Folio.file('fixtures/foo_softlink.txt')
|
254
|
+
</pre>
|
255
|
+
<p>
|
256
|
+
The link is not equal to the target document.
|
257
|
+
</p>
|
258
|
+
<pre>
|
259
|
+
@foo.assert! == Folio.file('fixtures/foo.txt')
|
260
|
+
</pre>
|
261
|
+
<p>
|
262
|
+
But it is equal to a same link instantiated from a differnt working
|
263
|
+
directory.
|
264
|
+
</p>
|
265
|
+
<pre>
|
266
|
+
f = nil
|
267
|
+
Dir.chdir('fixtures') do
|
268
|
+
f = Folio.file('foo_softlink.txt')
|
269
|
+
end
|
270
|
+
@foo.assert == f
|
271
|
+
</pre>
|
272
|
+
<p>
|
273
|
+
Reads the linked document correctly.
|
274
|
+
</p>
|
275
|
+
<pre>
|
276
|
+
@foo.read == "THIS IS FOO!"
|
277
|
+
</pre>
|
278
|
+
<p>
|
279
|
+
Opens the linked document for reading.
|
280
|
+
</p>
|
281
|
+
<pre>
|
282
|
+
t = nil
|
283
|
+
@foo.open('r'){ |f| t = f.read }
|
284
|
+
t.assert == "THIS IS FOO!\n"
|
285
|
+
</pre>
|
286
|
+
<p>
|
287
|
+
It provides the parent directory object.
|
288
|
+
</p>
|
289
|
+
<pre>
|
290
|
+
@foo.parent.assert == Folio.dir('fixtures')
|
291
|
+
</pre>
|
292
|
+
|
293
|
+
|
294
|
+
|
295
|
+
|
296
|
+
<h1>General Usage of the Folio Shell</h1>
|
297
|
+
<p>
|
298
|
+
Require the Folio library.
|
299
|
+
</p>
|
300
|
+
<pre>
|
301
|
+
require 'folio'
|
302
|
+
</pre>
|
303
|
+
<p>
|
304
|
+
Open a new Folio::Shell object.
|
305
|
+
</p>
|
306
|
+
<pre>
|
307
|
+
@c = Folio.shell('fixtures')
|
308
|
+
</pre>
|
309
|
+
<p>
|
310
|
+
Method #work returns current working directory.
|
311
|
+
</p>
|
312
|
+
<pre>
|
313
|
+
@c.work.assert == Folio.dir('fixtures')
|
314
|
+
</pre>
|
315
|
+
<p>
|
316
|
+
Method #to_s returns current working dirname.
|
317
|
+
</p>
|
318
|
+
<pre>
|
319
|
+
@c.to_s.assert == File.join(Dir.pwd, 'fixtures')
|
320
|
+
</pre>
|
321
|
+
<p>
|
322
|
+
Method #entries returns a list of names of the current directory content.
|
323
|
+
</p>
|
324
|
+
<pre>
|
325
|
+
@c.entries.sort.assert == ['foo.txt', 'foo_softlink.txt', 'out.txt']
|
326
|
+
</pre>
|
327
|
+
<p>
|
328
|
+
Method #files returns an array of file objects in the current directory.
|
329
|
+
</p>
|
330
|
+
<pre>
|
331
|
+
f = @c.files.to_a
|
332
|
+
f.size.assert == 3
|
333
|
+
f.assert.include?(Folio.file('fixtures/foo_softlink.txt'))
|
334
|
+
f.assert.include?(Folio.file('fixtures/foo.txt'))
|
335
|
+
</pre>
|
336
|
+
|
337
|
+
<h1>Problem Scenerios</h1>
|
338
|
+
<h2>Non-existant paths</h2>
|
339
|
+
<p>
|
340
|
+
If a path does not exist, how do we know if it is intended to be a file, or
|
341
|
+
directory, or what?
|
342
|
+
</p>
|
343
|
+
<pre>
|
344
|
+
d1 = dir('home/trans')
|
345
|
+
d2 = d1 / 'images'
|
346
|
+
</pre>
|
347
|
+
<p>
|
348
|
+
Optons for resolution include:
|
349
|
+
</p>
|
350
|
+
<ul>
|
351
|
+
<li>Do not support ambiguitous methods.
|
352
|
+
|
353
|
+
</li>
|
354
|
+
<li>Raise an error if non-existant.
|
355
|
+
|
356
|
+
</li>
|
357
|
+
<li>Default to a directory when ambiguious.
|
358
|
+
|
359
|
+
</li>
|
360
|
+
<li>Use a delegator.
|
361
|
+
|
362
|
+
</li>
|
363
|
+
</ul>
|
364
|
+
<p>
|
365
|
+
The first solution is the most straightforward. The second is reasonably
|
366
|
+
viable as well, but at least it provides some understanble use for such
|
367
|
+
methods.
|
368
|
+
</p>
|
369
|
+
<p>
|
370
|
+
The return value of the third feels to quirky. And the last is a complex
|
371
|
+
solution that effectively only leaves us with some sort of non-disk
|
372
|
+
Pathname object; a solution almost a quirky.
|
373
|
+
</p>
|
374
|
+
<h2>Removal of file-io object</h2>
|
375
|
+
<p>
|
376
|
+
If we delete a file object, then the object looses it’s reference.
|
377
|
+
This is especially problematic if we do not allow file objects to have
|
378
|
+
non-existant paths.
|
379
|
+
</p>
|
380
|
+
<pre>
|
381
|
+
d2 = d1.dir('images')
|
382
|
+
d2.rm_r
|
383
|
+
</pre>
|
384
|
+
<p>
|
385
|
+
Options for resolution:
|
386
|
+
</p>
|
387
|
+
<ul>
|
388
|
+
<li>Do not support removal methods.
|
389
|
+
|
390
|
+
</li>
|
391
|
+
<li>Allow non-existant paths.
|
392
|
+
|
393
|
+
</li>
|
394
|
+
<li>Use delegator.
|
395
|
+
|
396
|
+
</li>
|
397
|
+
</ul>
|
398
|
+
<p>
|
399
|
+
The first solution would mean using a parent directory object to delete
|
400
|
+
anything.
|
401
|
+
</p>
|
402
|
+
<pre>
|
403
|
+
f1 = file('/home/trans/.bashrc')
|
404
|
+
f1.rm # not allowed
|
405
|
+
f1.parent.rm(f1) # instead
|
406
|
+
</pre>
|
407
|
+
<p>
|
408
|
+
I do not like this option becuase it means a directory object would behave
|
409
|
+
substantially differnt from other file objects. That might not be so bad is
|
410
|
+
Shell and Directory could be one and the same, but methods like #ctime
|
411
|
+
would still clash.
|
412
|
+
</p>
|
413
|
+
<p>
|
414
|
+
The second option is the simplist. The file object simply takes on a
|
415
|
+
"virtual" state. This could lead to errors being thrown, but it
|
416
|
+
is not unacceptable.
|
417
|
+
</p>
|
418
|
+
<pre>
|
419
|
+
f1 = file('/home/trans/.bashrc')
|
420
|
+
f1.rm
|
421
|
+
f1.ctime # error
|
422
|
+
</pre>
|
423
|
+
<p>
|
424
|
+
The last solution creates an indirection for all file objects. Removing a
|
425
|
+
file would redelegate to a virtual pathname object. This is a more
|
426
|
+
complicated solution and is really no better than the previous solutution
|
427
|
+
—MethodMissing would be the error. A delegtor solution is a bit more
|
428
|
+
interesting when we consider virtual file objects that can mimic a file
|
429
|
+
system. However that could be a rather misleading redelgation.
|
430
|
+
</p>
|
431
|
+
<h2>Looking at the Lager Picture</h2>
|
432
|
+
<p>
|
433
|
+
Do we really need these objects? Isn’t the core idea the Folio Shell?
|
434
|
+
For the first issue, what is wrong with:
|
435
|
+
</p>
|
436
|
+
<pre>
|
437
|
+
s1 = shell('home/trans')
|
438
|
+
s2 = s1 / 'images'
|
439
|
+
</pre>
|
440
|
+
<p>
|
441
|
+
Which would clearly raise an error if it were not existant.
|
442
|
+
</p>
|
443
|
+
<p>
|
444
|
+
As for the second. While it might not be quite as concise, it fits the
|
445
|
+
shell prompt pattern:
|
446
|
+
</p>
|
447
|
+
<pre>
|
448
|
+
s1 = shell('/home/trans')
|
449
|
+
s1.rm('.bashrc')
|
450
|
+
</pre>
|
451
|
+
<p>
|
452
|
+
Yea, ok. However, while we could pass around shell objects as a form of
|
453
|
+
directory object, this would leave us no way to pass file objects.
|
454
|
+
</p>
|
455
|
+
<h2>Conclusion</h2>
|
456
|
+
<p>
|
457
|
+
It is fairly clear that the second solution to the second issue is the
|
458
|
+
clearest choice. And that Directory and Shell should in fact stay separate
|
459
|
+
objects. The "Larger Picture" should be the general pattern for
|
460
|
+
theses cases, however this ought not prevent the use of the file objects as
|
461
|
+
well.
|
462
|
+
</p>
|
463
|
+
<p>
|
464
|
+
As for the first issue, the first or second options the better choices. I
|
465
|
+
will probably raise the error.
|
466
|
+
</p>
|
467
|
+
|
468
|
+
|
469
|
+
</div>
|
470
|
+
</div>
|
471
|
+
|
472
|
+
</body>
|
473
|
+
|
474
|
+
</html>
|
475
|
+
|
476
|
+
<script src="../assets/scripts/spec.js" type="text/javascript" language="javascript"></script>
|
477
|
+
|
478
|
+
<script type="text/javascript" language="javascript">
|
479
|
+
/*****************************************************************
|
480
|
+
* $.toc()
|
481
|
+
* by rebecca murphey
|
482
|
+
* rmurphey gmail com
|
483
|
+
*
|
484
|
+
* This function is called on its own and takes as an argument
|
485
|
+
* a list of selectors with which it will build a table of
|
486
|
+
* contents.
|
487
|
+
*
|
488
|
+
* The first selector will make up the top level of the TOC;
|
489
|
+
* the second selector will make up the second level of the TOC;
|
490
|
+
* etc.
|
491
|
+
*
|
492
|
+
* This function returns a div containing nested unordered lists;
|
493
|
+
* each list item is linked to an anchor tag added before the item
|
494
|
+
* on the page.
|
495
|
+
*
|
496
|
+
* usage: $.toc('h1,h2,h3').prependTo('body');
|
497
|
+
************************************************************************/
|
498
|
+
(function($) {
|
499
|
+
$.toc = function(tocList) {
|
500
|
+
$(tocList).addClass('jquery-toc');
|
501
|
+
var tocListArray = tocList.split(',');
|
502
|
+
$.each(tocListArray, function(i,v) { tocListArray[i] = $.trim(v); });
|
503
|
+
var $elements = $('.jquery-toc');
|
504
|
+
$('body').append('<div></div>');
|
505
|
+
var $toc = $('body div:last');
|
506
|
+
var lastLevel = 1;
|
507
|
+
$toc.append('<ul class="jquery-toc-1"></ul>');
|
508
|
+
$elements.each(function() {
|
509
|
+
var $e = $(this);
|
510
|
+
var text = $e.text();
|
511
|
+
var anchor = text.replace(/ /g,'-');
|
512
|
+
$e.before('<a name="' + anchor + '"></a>');
|
513
|
+
var level;
|
514
|
+
$.each(tocListArray, function(i,v) {
|
515
|
+
if (v.match(' ')) {
|
516
|
+
var vArray = v.split(' ');
|
517
|
+
var e = vArray[vArray.length - 1];
|
518
|
+
} else { e = v; }
|
519
|
+
if ($e.is(e)) { level = i+1; }
|
520
|
+
});
|
521
|
+
var className = 'jquery-toc-' + level;
|
522
|
+
var li = '<li><a href="#' + anchor + '">' + text + '</a></li>';
|
523
|
+
if (level == lastLevel) {
|
524
|
+
$('ul.' + className + ':last',$toc).append(li);
|
525
|
+
} else if (level > lastLevel) {
|
526
|
+
var parentLevel = level - 1;
|
527
|
+
var parentClassName = 'jquery-toc-' + parentLevel;
|
528
|
+
$('ul.' + parentClassName + ':last',$toc).
|
529
|
+
append('<ul class="' + className + '"></ul>');
|
530
|
+
$('ul.' + className + ':last',$toc).append(li);
|
531
|
+
} else if (level < lastLevel) {
|
532
|
+
$('ul.' + className + ':last',$toc).append(li);
|
533
|
+
}
|
534
|
+
lastLevel = level;
|
535
|
+
});
|
536
|
+
var $toc_ul = $('ul.jquery-toc-1',$toc);
|
537
|
+
$toc.remove();
|
538
|
+
return($toc_ul);
|
539
|
+
}
|
540
|
+
})(jQuery);
|
541
|
+
</script>
|
542
|
+
|
543
|
+
<script>
|
544
|
+
function toc_toggle() {
|
545
|
+
$('#toc_side').toggle();
|
546
|
+
};
|
547
|
+
|
548
|
+
$.toc('#content h1,h2,h3,h4').appendTo('.toc');
|
549
|
+
|
550
|
+
toc_toggle();
|
551
|
+
</script>
|
552
|
+
|