net-ssh 0.5.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.
Files changed (179) hide show
  1. data/doc/LICENSE-BSD +27 -0
  2. data/doc/LICENSE-GPL +280 -0
  3. data/doc/LICENSE-RUBY +56 -0
  4. data/doc/README +13 -0
  5. data/doc/manual-html/chapter-1.html +333 -0
  6. data/doc/manual-html/chapter-2.html +455 -0
  7. data/doc/manual-html/chapter-3.html +413 -0
  8. data/doc/manual-html/chapter-4.html +353 -0
  9. data/doc/manual-html/chapter-5.html +393 -0
  10. data/doc/manual-html/chapter-6.html +296 -0
  11. data/doc/manual-html/index.html +217 -0
  12. data/doc/manual-html/manual.css +192 -0
  13. data/doc/manual/chapter.erb +18 -0
  14. data/doc/manual/example.erb +18 -0
  15. data/doc/manual/index.erb +29 -0
  16. data/doc/manual/manual.css +192 -0
  17. data/doc/manual/manual.rb +240 -0
  18. data/doc/manual/manual.yml +67 -0
  19. data/doc/manual/page.erb +87 -0
  20. data/doc/manual/parts/channels_callbacks.txt +32 -0
  21. data/doc/manual/parts/channels_loop.txt +14 -0
  22. data/doc/manual/parts/channels_open.txt +20 -0
  23. data/doc/manual/parts/channels_operations.txt +15 -0
  24. data/doc/manual/parts/channels_types.txt +3 -0
  25. data/doc/manual/parts/channels_what_are.txt +7 -0
  26. data/doc/manual/parts/exec_channels.txt +28 -0
  27. data/doc/manual/parts/exec_open.txt +51 -0
  28. data/doc/manual/parts/exec_popen3.txt +35 -0
  29. data/doc/manual/parts/forward_direct.txt +37 -0
  30. data/doc/manual/parts/forward_handlers.txt +16 -0
  31. data/doc/manual/parts/forward_intro.txt +18 -0
  32. data/doc/manual/parts/forward_local.txt +18 -0
  33. data/doc/manual/parts/forward_remote.txt +14 -0
  34. data/doc/manual/parts/intro_author.txt +1 -0
  35. data/doc/manual/parts/intro_getting.txt +39 -0
  36. data/doc/manual/parts/intro_license.txt +6 -0
  37. data/doc/manual/parts/intro_support.txt +7 -0
  38. data/doc/manual/parts/intro_what_is.txt +7 -0
  39. data/doc/manual/parts/intro_what_is_not.txt +3 -0
  40. data/doc/manual/parts/proxy_http.txt +52 -0
  41. data/doc/manual/parts/proxy_intro.txt +1 -0
  42. data/doc/manual/parts/proxy_socks.txt +23 -0
  43. data/doc/manual/parts/session_key.txt +66 -0
  44. data/doc/manual/parts/session_options.txt +42 -0
  45. data/doc/manual/parts/session_session.txt +14 -0
  46. data/doc/manual/parts/session_start.txt +49 -0
  47. data/doc/manual/tutorial.erb +30 -0
  48. data/examples/channel-demo.rb +81 -0
  49. data/examples/port-forward.rb +51 -0
  50. data/examples/process-demo.rb +91 -0
  51. data/examples/remote-net-port-forward.rb +45 -0
  52. data/examples/remote-port-forward.rb +80 -0
  53. data/examples/tail-demo.rb +49 -0
  54. data/lib/net/ssh.rb +52 -0
  55. data/lib/net/ssh/connection/channel.rb +411 -0
  56. data/lib/net/ssh/connection/constants.rb +47 -0
  57. data/lib/net/ssh/connection/driver.rb +343 -0
  58. data/lib/net/ssh/connection/services.rb +72 -0
  59. data/lib/net/ssh/connection/term.rb +90 -0
  60. data/lib/net/ssh/errors.rb +27 -0
  61. data/lib/net/ssh/proxy/errors.rb +34 -0
  62. data/lib/net/ssh/proxy/http.rb +126 -0
  63. data/lib/net/ssh/proxy/socks4.rb +83 -0
  64. data/lib/net/ssh/proxy/socks5.rb +160 -0
  65. data/lib/net/ssh/service/forward/driver.rb +319 -0
  66. data/lib/net/ssh/service/forward/local-network-handler.rb +74 -0
  67. data/lib/net/ssh/service/forward/remote-network-handler.rb +81 -0
  68. data/lib/net/ssh/service/forward/services.rb +76 -0
  69. data/lib/net/ssh/service/process/driver.rb +153 -0
  70. data/lib/net/ssh/service/process/open.rb +193 -0
  71. data/lib/net/ssh/service/process/popen3.rb +160 -0
  72. data/lib/net/ssh/service/process/services.rb +66 -0
  73. data/lib/net/ssh/service/services.rb +44 -0
  74. data/lib/net/ssh/session.rb +242 -0
  75. data/lib/net/ssh/transport/algorithm-negotiator.rb +267 -0
  76. data/lib/net/ssh/transport/compress/compressor.rb +53 -0
  77. data/lib/net/ssh/transport/compress/decompressor.rb +53 -0
  78. data/lib/net/ssh/transport/compress/none-compressor.rb +39 -0
  79. data/lib/net/ssh/transport/compress/none-decompressor.rb +39 -0
  80. data/lib/net/ssh/transport/compress/services.rb +68 -0
  81. data/lib/net/ssh/transport/compress/zlib-compressor.rb +60 -0
  82. data/lib/net/ssh/transport/compress/zlib-decompressor.rb +52 -0
  83. data/lib/net/ssh/transport/constants.rb +66 -0
  84. data/lib/net/ssh/transport/errors.rb +47 -0
  85. data/lib/net/ssh/transport/identity-cipher.rb +61 -0
  86. data/lib/net/ssh/transport/kex/dh-gex.rb +106 -0
  87. data/lib/net/ssh/transport/kex/dh.rb +231 -0
  88. data/lib/net/ssh/transport/kex/services.rb +60 -0
  89. data/lib/net/ssh/transport/ossl/buffer-factory.rb +52 -0
  90. data/lib/net/ssh/transport/ossl/buffer.rb +87 -0
  91. data/lib/net/ssh/transport/ossl/cipher-factory.rb +98 -0
  92. data/lib/net/ssh/transport/ossl/digest-factory.rb +51 -0
  93. data/lib/net/ssh/transport/ossl/hmac-factory.rb +71 -0
  94. data/lib/net/ssh/transport/ossl/hmac/hmac.rb +62 -0
  95. data/lib/net/ssh/transport/ossl/hmac/md5-96.rb +44 -0
  96. data/lib/net/ssh/transport/ossl/hmac/md5.rb +46 -0
  97. data/lib/net/ssh/transport/ossl/hmac/none.rb +46 -0
  98. data/lib/net/ssh/transport/ossl/hmac/services.rb +68 -0
  99. data/lib/net/ssh/transport/ossl/hmac/sha1-96.rb +44 -0
  100. data/lib/net/ssh/transport/ossl/hmac/sha1.rb +45 -0
  101. data/lib/net/ssh/transport/ossl/key-factory.rb +113 -0
  102. data/lib/net/ssh/transport/ossl/services.rb +149 -0
  103. data/lib/net/ssh/transport/packet-stream.rb +210 -0
  104. data/lib/net/ssh/transport/services.rb +146 -0
  105. data/lib/net/ssh/transport/session.rb +296 -0
  106. data/lib/net/ssh/transport/version-negotiator.rb +73 -0
  107. data/lib/net/ssh/userauth/agent.rb +218 -0
  108. data/lib/net/ssh/userauth/constants.rb +35 -0
  109. data/lib/net/ssh/userauth/driver.rb +176 -0
  110. data/lib/net/ssh/userauth/methods/hostbased.rb +119 -0
  111. data/lib/net/ssh/userauth/methods/password.rb +70 -0
  112. data/lib/net/ssh/userauth/methods/publickey.rb +137 -0
  113. data/lib/net/ssh/userauth/methods/services.rb +63 -0
  114. data/lib/net/ssh/userauth/services.rb +126 -0
  115. data/lib/net/ssh/userauth/userkeys.rb +258 -0
  116. data/lib/net/ssh/util/buffer.rb +274 -0
  117. data/lib/net/ssh/util/openssl.rb +146 -0
  118. data/lib/net/ssh/util/prompter.rb +73 -0
  119. data/lib/net/ssh/version.rb +29 -0
  120. data/test/ALL-TESTS.rb +21 -0
  121. data/test/connection/tc_channel.rb +136 -0
  122. data/test/connection/tc_driver.rb +287 -0
  123. data/test/connection/tc_integration.rb +85 -0
  124. data/test/proxy/tc_http.rb +209 -0
  125. data/test/proxy/tc_socks4.rb +148 -0
  126. data/test/proxy/tc_socks5.rb +214 -0
  127. data/test/service/forward/tc_driver.rb +289 -0
  128. data/test/service/forward/tc_local_network_handler.rb +123 -0
  129. data/test/service/forward/tc_remote_network_handler.rb +108 -0
  130. data/test/service/process/tc_driver.rb +79 -0
  131. data/test/service/process/tc_integration.rb +117 -0
  132. data/test/service/process/tc_open.rb +179 -0
  133. data/test/service/process/tc_popen3.rb +164 -0
  134. data/test/tc_integration.rb +79 -0
  135. data/test/transport/compress/tc_none_compress.rb +41 -0
  136. data/test/transport/compress/tc_none_decompress.rb +45 -0
  137. data/test/transport/compress/tc_zlib_compress.rb +61 -0
  138. data/test/transport/compress/tc_zlib_decompress.rb +48 -0
  139. data/test/transport/kex/tc_dh.rb +304 -0
  140. data/test/transport/kex/tc_dh_gex.rb +70 -0
  141. data/test/transport/ossl/fixtures/dsa-encrypted +15 -0
  142. data/test/transport/ossl/fixtures/dsa-encrypted-bad +15 -0
  143. data/test/transport/ossl/fixtures/dsa-unencrypted +12 -0
  144. data/test/transport/ossl/fixtures/dsa-unencrypted-bad +12 -0
  145. data/test/transport/ossl/fixtures/dsa-unencrypted.pub +1 -0
  146. data/test/transport/ossl/fixtures/not-a-private-key +4 -0
  147. data/test/transport/ossl/fixtures/not-supported +2 -0
  148. data/test/transport/ossl/fixtures/rsa-encrypted +18 -0
  149. data/test/transport/ossl/fixtures/rsa-encrypted-bad +18 -0
  150. data/test/transport/ossl/fixtures/rsa-unencrypted +15 -0
  151. data/test/transport/ossl/fixtures/rsa-unencrypted-bad +15 -0
  152. data/test/transport/ossl/fixtures/rsa-unencrypted.pub +1 -0
  153. data/test/transport/ossl/hmac/tc_hmac.rb +58 -0
  154. data/test/transport/ossl/hmac/tc_md5.rb +50 -0
  155. data/test/transport/ossl/hmac/tc_md5_96.rb +50 -0
  156. data/test/transport/ossl/hmac/tc_none.rb +50 -0
  157. data/test/transport/ossl/hmac/tc_sha1.rb +50 -0
  158. data/test/transport/ossl/hmac/tc_sha1_96.rb +50 -0
  159. data/test/transport/ossl/tc_buffer.rb +97 -0
  160. data/test/transport/ossl/tc_buffer_factory.rb +67 -0
  161. data/test/transport/ossl/tc_cipher_factory.rb +84 -0
  162. data/test/transport/ossl/tc_digest_factory.rb +39 -0
  163. data/test/transport/ossl/tc_hmac_factory.rb +72 -0
  164. data/test/transport/ossl/tc_key_factory.rb +199 -0
  165. data/test/transport/tc_algorithm_negotiator.rb +169 -0
  166. data/test/transport/tc_identity_cipher.rb +52 -0
  167. data/test/transport/tc_integration.rb +110 -0
  168. data/test/transport/tc_packet_stream.rb +183 -0
  169. data/test/transport/tc_session.rb +283 -0
  170. data/test/transport/tc_version_negotiator.rb +86 -0
  171. data/test/userauth/methods/tc_hostbased.rb +136 -0
  172. data/test/userauth/methods/tc_password.rb +89 -0
  173. data/test/userauth/methods/tc_publickey.rb +167 -0
  174. data/test/userauth/tc_agent.rb +223 -0
  175. data/test/userauth/tc_driver.rb +190 -0
  176. data/test/userauth/tc_integration.rb +81 -0
  177. data/test/userauth/tc_userkeys.rb +265 -0
  178. data/test/util/tc_buffer.rb +217 -0
  179. metadata +256 -0
@@ -0,0 +1,29 @@
1
+ <p class="product-manual">Product Manual</p>
2
+
3
+ <p align="center">
4
+ <img src="<%= manual.product.logo %>"
5
+ alt="<%= manual.product.name %>: <%= manual.product.tagline %>" />
6
+ </p>
7
+
8
+ <p align="center">
9
+ <% manual.product.urls.each do |item| %>
10
+ <%= item.keys.first %>: <a href="<%= item.values.first %>"><%= item.values.first %></a><br />
11
+ <% end %>
12
+ </p>
13
+
14
+ <% if manual.recent_updates && manual.recent_updates.length > 0 %>
15
+ <p align="center"><strong>Recent Updates to This Manual</strong></p>
16
+ <table border='0' cellpadding='0' cellspacing='0' align='center'><tr><td>
17
+ <ul>
18
+ <% manual.recent_updates.each do |update| %>
19
+ <li><%= update %></li>
20
+ <% end %>
21
+ </ul>
22
+ </table>
23
+ <% end %>
24
+
25
+ <p class="copyright">
26
+ Copyright &copy; <%= manual.meta.copyright %>
27
+ <%= manual.meta.author %>
28
+ (<a href="mailto:<%= manual.meta.email %>"><%= manual.meta.email %></a>)
29
+ </p>
@@ -0,0 +1,192 @@
1
+ body {
2
+ background: #FFF;
3
+ font-family: sans-serif;
4
+ color: #000;
5
+ margin: 0px;
6
+ }
7
+
8
+ a {
9
+ color: #00F;
10
+ text-decoration: none;
11
+ }
12
+
13
+ a:hover {
14
+ text-decoration: underline;
15
+ }
16
+
17
+ .product-manual {
18
+ text-align: center;
19
+ font-size: x-large;
20
+ font-variant: small-caps;
21
+ font-weight: bold;
22
+ color: #005;
23
+ }
24
+
25
+ .copyright {
26
+ text-align: center;
27
+ font-size: small;
28
+ font-style: italic;
29
+ color: #005;
30
+ margin-top: 1in;
31
+ }
32
+
33
+ #banner {
34
+ background: #005;
35
+ color: #FFF;
36
+ border-bottom: 1px solid #000;
37
+ padding-top: 0.5em;
38
+ padding-bottom: 0.5em;
39
+ padding-left: 1em;
40
+ margin-bottom: 1em;
41
+ }
42
+
43
+ #banner .title {
44
+ font-size: x-large;
45
+ }
46
+
47
+ #banner .title:first-letter {
48
+ font-size: 250%;
49
+ font-weight: normal;
50
+ float: left;
51
+ margin-top: -7px;
52
+ margin-bottom: -7px;
53
+ }
54
+
55
+ #banner .product {
56
+ font-weight: bold;
57
+ color: #FF7;
58
+ letter-spacing: 0.5em;
59
+ }
60
+
61
+ #banner .tagline {
62
+ font-style: italic;
63
+ font-size: large;
64
+ letter-spacing: 0.1em;
65
+ color: #FFF;
66
+ }
67
+
68
+ #banner .info {
69
+ color: white;
70
+ font-size: small;
71
+ padding-right: 1em;
72
+ }
73
+
74
+ #content {
75
+ margin-left: 0cm;
76
+ margin-right: 1cm;
77
+ }
78
+
79
+ #navigation {
80
+ font-size: x-small;
81
+ border-right: 2px groove black;
82
+ border-top: 2px groove black;
83
+ margin-right: 1em;
84
+ width: 200px;
85
+ height: 100%;
86
+ background: #FFD;
87
+ }
88
+
89
+ #navigation ul, #navigation ol {
90
+ margin-left: 1.2em;
91
+ padding-left: 1.2em;
92
+ }
93
+
94
+ #navigation .license {
95
+ font-size: x-small;
96
+ text-align: center;
97
+ border-top: 1px dashed #005;
98
+ margin-top: 2em;
99
+ padding: 1em;
100
+ }
101
+
102
+ .section {
103
+ margin-bottom: 1em;
104
+ }
105
+
106
+ .section p {
107
+ text-align: justify;
108
+ }
109
+
110
+ #content pre {
111
+ background: #FFE;
112
+ border: 1px dotted #AAA;
113
+ padding: 1em;
114
+ }
115
+
116
+ #content h1 {
117
+ background: #005;
118
+ color: #FFF;
119
+ font-size: x-large;
120
+ font-weight: bold;
121
+ font-variant: small-caps;
122
+ padding: 0.5em;
123
+ border: 1px solid #000;
124
+ margin-top: 0px;
125
+ margin-bottom: 1em;
126
+ }
127
+
128
+ #content h2 {
129
+ background: #005;
130
+ color: #FFF;
131
+ font-size: large;
132
+ font-weight: bold;
133
+ font-variant: small-caps;
134
+ padding: 0.25em;
135
+ padding-left: 0.5em;
136
+ border: 1px solid #000;
137
+ margin-bottom: 1em;
138
+ }
139
+
140
+ #content h3 {
141
+ background: #FFD;
142
+ color: #000;
143
+ font-size: normal;
144
+ font-weight: bold;
145
+ font-variant: small-caps;
146
+ padding: 0.25em;
147
+ padding-left: 0.5em;
148
+ border: 1px dotted #000;
149
+ margin-bottom: 1em;
150
+ }
151
+
152
+ #content h4 {
153
+ background: #FFE;
154
+ color: #000;
155
+ font-size: normal;
156
+ font-weight: bold;
157
+ font-variant: small-caps;
158
+ padding: 0.25em;
159
+ padding-left: 0.5em;
160
+ border: 1px dotted #777;
161
+ margin-bottom: 1em;
162
+ }
163
+
164
+ #navigation h1 {
165
+ margin: 0px;
166
+ padding: 1em;
167
+ color: #005;
168
+ background: transparent;
169
+ font-weight: bold;
170
+ font-size: 150%;
171
+ font-variant: small-caps;
172
+ text-align: center;
173
+ }
174
+
175
+ #navigation h2 {
176
+ margin: 0px;
177
+ margin-bottom: 1em;
178
+ padding: 0.5em;
179
+ border-top: 1px dashed #005;
180
+ border-bottom: 1px dashed #005;
181
+ color: #005;
182
+ background: transparent;
183
+ font-weight: bold;
184
+ font-size: 125%;
185
+ font-variant: small-caps;
186
+ text-align: center;
187
+ }
188
+
189
+ table.list td {
190
+ border-bottom: 1px dotted #005;
191
+ padding-bottom: 5px;
192
+ }
@@ -0,0 +1,240 @@
1
+ # --------------------------------------------------------------------------
2
+ # Portions of this code were taken from the "poignant.rb" script created
3
+ # by whytheluckystiff, which generates "Why's (Poignant) Guide to Ruby".
4
+ # The original script may be obtained from the poignant CVS repository,
5
+ # at http://poignant.rubyforge.org.
6
+ #
7
+ # This script is distributed under the by-sa/1.0 Creative Commons license.
8
+ # --------------------------------------------------------------------------
9
+
10
+ require 'erb'
11
+ require 'fileutils'
12
+ require 'yaml'
13
+ require 'redcloth'
14
+
15
+ module Needle
16
+ module Manual
17
+
18
+ class Manual
19
+ attr_accessor :product, :meta, :chapters, :tutorials, :examples, :recent_updates
20
+
21
+ def Manual.load( file_name )
22
+ File.open( file_name ) { |file| YAML.load( file ) }
23
+ end
24
+ end
25
+
26
+ class Meta
27
+ attr_accessor :copyright, :author, :email
28
+ end
29
+
30
+ class Product
31
+ attr_accessor :name, :tagline, :version, :logo, :urls, :project
32
+ end
33
+
34
+ class Sidebar
35
+ attr_accessor :title, :content
36
+ end
37
+
38
+ class Chapter
39
+ attr_accessor :index, :title, :sections
40
+
41
+ def initialize( index, title, sections )
42
+ @index = index
43
+ @title = title
44
+
45
+ section_index = 0
46
+ @sections = ( sections || [] ).collect do |section|
47
+ section_index += 1
48
+ if section.respond_to? :keys
49
+ Section.new( section_index, section.keys.first, section.values.first )
50
+ else
51
+ section_index -= 1
52
+ Section.new( section_index, nil, section )
53
+ end
54
+ end
55
+ end
56
+
57
+ def page_title
58
+ "Chapter #{index}: #{title}"
59
+ end
60
+ end
61
+
62
+ class Tutorial
63
+ attr_accessor :index, :title, :brief, :intro, :steps, :summary
64
+
65
+ def initialize( index, title, brief, intro, steps, summary )
66
+ @index = index
67
+ @title = title
68
+ @brief = RedCloth.new( brief )
69
+ @intro = RedCloth.new( intro ) if intro
70
+ @summary = RedCloth.new( summary ) if summary
71
+ @steps = steps.map { |step| RedCloth.new( step ) }
72
+ end
73
+
74
+ def page_title
75
+ "Tutorial #{index}: #{title}"
76
+ end
77
+ end
78
+
79
+ class Example
80
+ attr_accessor :index, :title, :brief, :intro, :design, :implementation, :summary
81
+
82
+ def initialize( index, title, brief, intro, design, implementation, summary )
83
+ @index = index
84
+ @title = title
85
+ @brief = RedCloth.new( brief )
86
+ @intro = RedCloth.new( intro )
87
+ @design = RedCloth.new( design )
88
+ @implementation = RedCloth.new( implementation )
89
+ @summary = RedCloth.new( summary )
90
+ end
91
+
92
+ def page_title
93
+ "Example #{index}: #{title}"
94
+ end
95
+ end
96
+
97
+ class Section
98
+ attr_accessor :index, :title, :content
99
+
100
+ def initialize( index, title, content )
101
+ @index = index
102
+ @title = RedCloth.new( title ).to_html.gsub( %r{</?p>}, "" ) if title
103
+ @content = RedCloth.new( content || "" )
104
+ end
105
+ end
106
+
107
+ YAML.add_private_type( 'file' ) { |type_id, value| File.read( value ) rescue "" }
108
+ YAML.add_private_type( 'eval' ) { |type_id, value| eval( value ) }
109
+
110
+ YAML.add_domain_type( 'jamisbuck.org,2004', 'manual' ) do |taguri, val|
111
+ index = 0
112
+
113
+ val['chapters'].collect! do |chapter|
114
+ index += 1
115
+ Chapter.new( index, chapter.keys.first, chapter.values.first )
116
+ end
117
+
118
+ index = 0
119
+ ( val['tutorials'] ||= [] ).collect! do |tutorial|
120
+ index += 1
121
+ content = tutorial.values.first
122
+ Tutorial.new( index, tutorial.keys.first, content['brief'], content['intro'],
123
+ content['steps'], content['summary'] )
124
+ end
125
+
126
+ index = 0
127
+ ( val['examples'] ||= [] ).collect! do |example|
128
+ index += 1
129
+ content = example.values.first
130
+ Example.new( index, example.keys.first, content['brief'], content['intro'], content['design'],
131
+ content['implementation'], content['summary'] )
132
+ end
133
+
134
+ YAML.object_maker( Manual, val )
135
+ end
136
+
137
+ YAML.add_domain_type( 'jamisbuck.org,2004', 'meta' ) do |taguri, val|
138
+ YAML.object_maker( Meta, val )
139
+ end
140
+
141
+ YAML.add_domain_type( 'jamisbuck.org,2004', 'product' ) do |taguri, val|
142
+ version = val["version"]
143
+ if version.respond_to?( :type_id )
144
+ if version.type_id == "version"
145
+ if version.value =~ %r{(.*)/(.*)}
146
+ require_file, constant = $1, $2
147
+ else
148
+ constant = version.value
149
+ end
150
+
151
+ require require_file if require_file
152
+ val["version"] = eval(constant)
153
+ else
154
+ raise "Unexpected type: #{val.type_id}"
155
+ end
156
+ end
157
+ YAML.object_maker( Product, val )
158
+ end
159
+
160
+ YAML.add_domain_type( 'jamisbuck.org,2004', 'sidebar' ) do |taguri, val|
161
+ YAML.object_maker( Sidebar,
162
+ 'title' => val.keys.first,
163
+ 'content'=> RedCloth.new( val.values.first ) )
164
+ end
165
+
166
+ end
167
+ end
168
+
169
+ if __FILE__ == $0
170
+
171
+ def log_action( action )
172
+ $stderr.puts action
173
+ end
174
+
175
+ unless ( output_path = ARGV[0] )
176
+ $stderr.puts "Usage: #{$0} [/path/to/save/html]"
177
+ exit
178
+ end
179
+
180
+ Dir.mkdir output_path rescue nil
181
+
182
+ log_action "Loading manual.yml..."
183
+ manual = Needle::Manual::Manual.load( 'manual.yml' )
184
+
185
+ # force these to be defined at the TOPLEVEL_BINDING
186
+ object = nil
187
+ guts = nil
188
+
189
+ page = File.open( "page.erb" ) { |file| ERB.new( file.read ) }
190
+ page.filename = "page.erb"
191
+
192
+ template = File.open( "index.erb" ) { |file| ERB.new( file.read ) }
193
+ template.filename = "index.erb"
194
+
195
+ File.open( File.join( output_path, "index.html" ), "w" ) do |file|
196
+ guts = template.result
197
+ file << page.result
198
+ end
199
+
200
+ template = File.open( "chapter.erb" ) { |file| ERB.new( file.read ) }
201
+ template.filename = "chapter.erb"
202
+
203
+ manual.chapters.each do |object|
204
+ log_action "Processing chapter ##{object.index}..."
205
+ File.open( File.join( output_path, "chapter-#{object.index}.html" ), "w" ) do |file|
206
+ guts = template.result
207
+ file << page.result
208
+ end
209
+ end
210
+
211
+ template = File.open( "tutorial.erb" ) { |file| ERB.new( file.read ) }
212
+ template.filename = "tutorial.erb"
213
+
214
+ manual.tutorials.each do |object|
215
+ log_action "Processing tutorial ##{object.index}..."
216
+ File.open( File.join( output_path, "tutorial-#{object.index}.html" ), "w" ) do |file|
217
+ guts = template.result
218
+ file << page.result
219
+ end
220
+ end
221
+
222
+ # template = File.open( "example.erb" ) { |file| ERB.new( file.read ) }
223
+ # template.filename = "example.erb"
224
+
225
+ # manual.examples.each do |object|
226
+ # log_action "Processing example ##{object.index}..."
227
+ # File.open( File.join( output_path, "example-#{object.index}.html" ), "w" ) do |file|
228
+ # guts = template.result
229
+ # file << page.result
230
+ # end
231
+ # end
232
+
233
+ log_action "Copying style sheets..."
234
+ FileUtils.cp Dir["*.css"], output_path
235
+
236
+ log_action "Copying images..."
237
+ FileUtils.cp Dir["img/*.jpg"], output_path
238
+
239
+ log_action "Done!"
240
+ end