ro 1.4.6 → 4.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.
Files changed (157) hide show
  1. checksums.yaml +6 -14
  2. data/Gemfile +2 -0
  3. data/Gemfile.lock +64 -0
  4. data/LICENSE +1 -0
  5. data/README.md +276 -105
  6. data/README.md.erb +159 -0
  7. data/Rakefile +129 -78
  8. data/bin/ro +241 -68
  9. data/lib/ro/_lib.rb +107 -0
  10. data/lib/ro/asset.rb +55 -0
  11. data/lib/ro/collection/list.rb +23 -0
  12. data/lib/ro/collection.rb +211 -0
  13. data/lib/ro/config.rb +72 -0
  14. data/lib/ro/error.rb +11 -0
  15. data/lib/ro/html.rb +23 -0
  16. data/lib/ro/html_safe.rb +143 -0
  17. data/lib/ro/klass.rb +25 -0
  18. data/lib/ro/methods.rb +295 -0
  19. data/lib/ro/model.rb +83 -114
  20. data/lib/ro/node.rb +209 -349
  21. data/lib/ro/pagination.rb +7 -4
  22. data/lib/ro/path.rb +229 -0
  23. data/lib/ro/root.rb +52 -31
  24. data/lib/ro/script/builder.rb +221 -0
  25. data/lib/ro/script/console.rb +47 -0
  26. data/lib/ro/script/server.rb +76 -0
  27. data/lib/ro/script.rb +189 -0
  28. data/lib/ro/slug.rb +19 -18
  29. data/lib/ro/template/rouge_formatter.rb +42 -0
  30. data/lib/ro/template.rb +145 -51
  31. data/lib/ro/text.rb +120 -0
  32. data/lib/ro.rb +89 -317
  33. data/public/api/ro/index-1.json +1065 -0
  34. data/public/api/ro/index.json +1055 -0
  35. data/public/api/ro/nerd/fastest-possible-embeddings/index.json +90 -0
  36. data/public/api/ro/nerd/ima/index.json +49 -0
  37. data/public/api/ro/nerd/index/index.json +74 -0
  38. data/public/api/ro/nerd/index-1.json +204 -0
  39. data/public/api/ro/nerd/index.json +194 -0
  40. data/public/api/ro/pages/about/index.json +60 -0
  41. data/public/api/ro/pages/contact/index.json +50 -0
  42. data/public/api/ro/pages/cv/index.json +49 -0
  43. data/public/api/ro/pages/disco/index.json +117 -0
  44. data/public/api/ro/pages/index/index.json +30 -0
  45. data/public/api/ro/pages/index-1.json +366 -0
  46. data/public/api/ro/pages/index.json +356 -0
  47. data/public/api/ro/pages/jess/index.json +62 -0
  48. data/public/api/ro/pages/now/index.json +43 -0
  49. data/public/api/ro/posts/almost-died-in-an-ice-cave/index.json +265 -0
  50. data/public/api/ro/posts/facebook-and-global-extremism/index.json +90 -0
  51. data/public/api/ro/posts/index-1.json +527 -0
  52. data/public/api/ro/posts/index.json +517 -0
  53. data/public/api/ro/posts/lemmings-considered-harmful/index.json +49 -0
  54. data/public/api/ro/posts/lost-in-the-desert/index.json +49 -0
  55. data/public/api/ro/posts/mission/index.json +49 -0
  56. data/public/api/ro/posts/return-your-laptop/index.json +61 -0
  57. data/public/ro/nerd/fastest-possible-embeddings/assets/giraffe.jpeg +0 -0
  58. data/public/ro/nerd/fastest-possible-embeddings/assets/let-me-in.jpg +0 -0
  59. data/public/ro/nerd/fastest-possible-embeddings/assets/src/fastembed.js +70 -0
  60. data/public/ro/nerd/fastest-possible-embeddings/assets/src/fastembed.rs +68 -0
  61. data/public/ro/nerd/fastest-possible-embeddings/assets/terminal.jpg +0 -0
  62. data/public/ro/nerd/fastest-possible-embeddings/attributes.yml +7 -0
  63. data/public/ro/nerd/fastest-possible-embeddings/body.md +266 -0
  64. data/public/ro/nerd/ima/assets/og.jpeg +0 -0
  65. data/public/ro/nerd/ima/attributes.yml +8 -0
  66. data/public/ro/nerd/ima/body.md +22 -0
  67. data/public/ro/nerd/index/assets/giraffe.jpeg +0 -0
  68. data/public/ro/nerd/index/assets/let-me-in.jpg +0 -0
  69. data/public/ro/nerd/index/assets/terminal.jpg +0 -0
  70. data/public/ro/nerd/index/attributes.yml +7 -0
  71. data/public/ro/nerd/index/body.md +130 -0
  72. data/public/ro/pages/about/assets/og.jpeg +0 -0
  73. data/public/ro/pages/about/assets/speak-english-pulp-fiction.gif +0 -0
  74. data/public/ro/pages/about/body.md +40 -0
  75. data/public/ro/pages/contact/assets/giraffe.jpeg +0 -0
  76. data/public/ro/pages/contact/attributes.yml +7 -0
  77. data/public/ro/pages/contact/body.md +9 -0
  78. data/public/ro/pages/cv/assets/ara.jpg +0 -0
  79. data/public/ro/pages/cv/attributes.yml +6 -0
  80. data/public/ro/pages/cv/body.md +122 -0
  81. data/public/ro/pages/disco/assets/disco.jpg +0 -0
  82. data/public/ro/pages/disco/assets/disco.png +0 -0
  83. data/public/ro/pages/disco/assets/speak-english-pulp-fiction.gif +0 -0
  84. data/public/ro/pages/disco/assets/src/environment.md +2354 -0
  85. data/public/ro/pages/disco/assets/src/fortune-500.md +2518 -0
  86. data/public/ro/pages/disco/assets/src/greed.md +2703 -0
  87. data/public/ro/pages/disco/assets/src/up-at-night.md +2337 -0
  88. data/public/ro/pages/disco/attributes.yml +9 -0
  89. data/public/ro/pages/disco/body.md +99 -0
  90. data/public/ro/pages/disco/samples/environment.md +2354 -0
  91. data/public/ro/pages/disco/samples/fortune-500.md +2518 -0
  92. data/public/ro/pages/disco/samples/greed.md +2703 -0
  93. data/public/ro/pages/disco/samples/up-at-night.md +2337 -0
  94. data/public/ro/pages/index/attributes.yml +1 -0
  95. data/public/ro/pages/index/body.md +15 -0
  96. data/public/ro/pages/jess/assets/og.jpg +0 -0
  97. data/public/ro/pages/jess/assets/speak-english-pulp-fiction.gif +0 -0
  98. data/public/ro/pages/jess/attributes.yml +7 -0
  99. data/public/ro/pages/jess/body.md +3 -0
  100. data/public/ro/pages/now/assets/speak-english-pulp-fiction.gif +0 -0
  101. data/public/ro/pages/now/attributes.yml +1 -0
  102. data/public/ro/pages/now/body.md +24 -0
  103. data/public/ro/posts/almost-died-in-an-ice-cave/assets/image1.png +0 -0
  104. data/public/ro/posts/almost-died-in-an-ice-cave/assets/image10.png +0 -0
  105. data/public/ro/posts/almost-died-in-an-ice-cave/assets/image11.png +0 -0
  106. data/public/ro/posts/almost-died-in-an-ice-cave/assets/image12.png +0 -0
  107. data/public/ro/posts/almost-died-in-an-ice-cave/assets/image13.png +0 -0
  108. data/public/ro/posts/almost-died-in-an-ice-cave/assets/image14.png +0 -0
  109. data/public/ro/posts/almost-died-in-an-ice-cave/assets/image15.png +0 -0
  110. data/public/ro/posts/almost-died-in-an-ice-cave/assets/image2.png +0 -0
  111. data/public/ro/posts/almost-died-in-an-ice-cave/assets/image3.png +0 -0
  112. data/public/ro/posts/almost-died-in-an-ice-cave/assets/image4.png +0 -0
  113. data/public/ro/posts/almost-died-in-an-ice-cave/assets/image5.png +0 -0
  114. data/public/ro/posts/almost-died-in-an-ice-cave/assets/image6.png +0 -0
  115. data/public/ro/posts/almost-died-in-an-ice-cave/assets/image7.png +0 -0
  116. data/public/ro/posts/almost-died-in-an-ice-cave/assets/image8.png +0 -0
  117. data/public/ro/posts/almost-died-in-an-ice-cave/assets/image9.png +0 -0
  118. data/public/ro/posts/almost-died-in-an-ice-cave/assets/josh-pointing.jpg +0 -0
  119. data/public/ro/posts/almost-died-in-an-ice-cave/assets/levi-rawr.png +0 -0
  120. data/public/ro/posts/almost-died-in-an-ice-cave/assets/og.jpg +0 -0
  121. data/public/ro/posts/almost-died-in-an-ice-cave/assets/purple-heart.jpg +0 -0
  122. data/public/ro/posts/almost-died-in-an-ice-cave/attributes.yml +6 -0
  123. data/public/ro/posts/almost-died-in-an-ice-cave/body.md +419 -0
  124. data/public/ro/posts/facebook-and-global-extremism/assets/background.html +125 -0
  125. data/public/ro/posts/facebook-and-global-extremism/assets/background.md +95 -0
  126. data/public/ro/posts/facebook-and-global-extremism/assets/og.jpg +0 -0
  127. data/public/ro/posts/facebook-and-global-extremism/assets/prompt.txt +122 -0
  128. data/public/ro/posts/facebook-and-global-extremism/assets/results.md +183 -0
  129. data/public/ro/posts/facebook-and-global-extremism/assets/survey.txt +190 -0
  130. data/public/ro/posts/facebook-and-global-extremism/attributes.yml +7 -0
  131. data/public/ro/posts/facebook-and-global-extremism/body.md +393 -0
  132. data/public/ro/posts/lemmings-considered-harmful/assets/lemming.jpeg +0 -0
  133. data/public/ro/posts/lemmings-considered-harmful/attributes.yml +6 -0
  134. data/public/ro/posts/lemmings-considered-harmful/body.md +43 -0
  135. data/public/ro/posts/lost-in-the-desert/assets/og.jpg +0 -0
  136. data/public/ro/posts/lost-in-the-desert/attributes.yml +6 -0
  137. data/public/ro/posts/lost-in-the-desert/body.md +7 -0
  138. data/public/ro/posts/mission/assets/og.jpg +0 -0
  139. data/public/ro/posts/mission/attributes.yml +6 -0
  140. data/public/ro/posts/mission/body.md +4 -0
  141. data/public/ro/posts/return-your-laptop/assets/og.jpg +0 -0
  142. data/public/ro/posts/return-your-laptop/assets/return-your-laptop.png +0 -0
  143. data/public/ro/posts/return-your-laptop/attributes.yml +6 -0
  144. data/public/ro/posts/return-your-laptop/body.md +58 -0
  145. data/ro.gemspec +217 -28
  146. data/scripts/speedtest.rb +324 -0
  147. data/tmp/gem-details.oe +0 -0
  148. metadata +214 -74
  149. data/TODO.md +0 -50
  150. data/lib/ro/blankslate.rb +0 -7
  151. data/lib/ro/cache.rb +0 -26
  152. data/lib/ro/git.rb +0 -374
  153. data/lib/ro/initializers/env.rb +0 -5
  154. data/lib/ro/initializers/tilt.rb +0 -104
  155. data/lib/ro/lock.rb +0 -53
  156. data/lib/ro/node/list.rb +0 -142
  157. data/notes/ara.txt +0 -215
data/README.md.erb ADDED
@@ -0,0 +1,159 @@
1
+ NAME
2
+ ====
3
+
4
+ `ro`
5
+
6
+ INSTALL
7
+ =======
8
+
9
+ as a gem
10
+
11
+ ```sh
12
+ ~> gem install ro
13
+ ```
14
+
15
+
16
+ SYNOPSIS
17
+ ========
18
+
19
+ keep all your content in git as god intended.
20
+
21
+ even images.
22
+
23
+ fuck wordpress.
24
+
25
+ # TL;DR;
26
+
27
+ `ro` is the world's tiniest, simplest, zero-config, and most bestest headless CMS.
28
+
29
+ it keeps your content in an on disk bundle that will make sense to an 11 year
30
+
31
+ it depends on nothing but GitHub itself for the storage, management, and
32
+ delivery of rich web content and assets.
33
+
34
+ ## Storage
35
+
36
+ `ro` keeps your structured web content in a super sane structure, that keeps
37
+ assets close to its related content, allows for structured data to be kept
38
+ along side markdown/html content, and which supports source code as a first
39
+ class citizen.
40
+
41
+ For example, given:
42
+
43
+ ```sh
44
+ ~> tree ro/data
45
+
46
+ # ro/data
47
+ # └── posts
48
+ # ├── first-post
49
+ # │   ├── attributes.yml
50
+ # │   └── body.md
51
+ # │   ├── blurb.erb.md
52
+ # │   ├── assets
53
+ # │   │   ├── foo.jpg
54
+ ```
55
+
56
+ `ro` will provide an interface logically consistent with:
57
+
58
+ ```ruby
59
+ node.attributes #=> any/all the data loaded from 'attributes.yml'
60
+ node.attributes.body #=> an HTML representation of 'body.md'
61
+ node.attributes.blurb #=> an HTML representation of 'blurb.md'
62
+ node.attributes.assets #=> list of assets with url and path info
63
+ ```
64
+
65
+ To learn more, clone this repo, `bundle install`, and fire up a console to
66
+ check play with this idea:
67
+
68
+ eg: [given this node](https://github.com/ahoward/ro/tree/main/ro/data/posts/first-post)
69
+
70
+ ```ruby
71
+ ~> ro console
72
+
73
+ ro[./ro/data]:001:0> ro.posts.first_post.title
74
+ => "First Post"
75
+
76
+ ro[./ro/data]:002:0> ro.collections.posts.first_post.assets.first.url
77
+ => "/ro/posts/first-post/assets/foo.jpg"
78
+
79
+ ro[./ro/data]:003:0> ro.collections.posts.first_post.body.slice(0,42)
80
+ => "<div class='ro markdown'>\n <ul>\n <li>one"
81
+ ```
82
+
83
+
84
+ ## Management
85
+
86
+ Managing `ro` is as simple as using the built-in GitHub Markdown editor. The
87
+ file system layout, which supports relative asset urls, means the built-in
88
+ editor preview renders just fine. Of course, you are free to manage content
89
+ programatically as well. Either way, updates to the the content will result
90
+ in an automated API build of a static API which is then deployed to GitHub
91
+ Pages.
92
+
93
+ This is made possible by certain design decisions `ro` has made, specifically
94
+ allowing assets/ to be stored and rendered relative to their parent content.
95
+
96
+ Of course, you have all the power of `git` so other methods of managing the
97
+ content are available, programtic, locally in vs-code, etc. You have lots of
98
+ simply options, none of which require drivers or databases, and all of which
99
+ provide perfect history over your valuable web content and assets.
100
+
101
+ A word on managing assets, if you plan to have many large images, you probably
102
+ want to enable GitLFS on your content repository, `ro` plays perfectly with
103
+ it.
104
+
105
+
106
+ ## Delivery
107
+
108
+ Delivery of `ro` content, to remote clients, is via http+json. To output your
109
+ content as json, you simply need to run
110
+
111
+ ```sh
112
+ ~> ro build
113
+
114
+ ro.build: public/ro -> public/api/ro
115
+ ro.build: public/api/ro/posts/first_post/index.json
116
+ ro.build: public/api/ro/posts/second_post/index.json
117
+ ro.build: public/api/ro/posts/third_post/index.json
118
+ ro.build: public/api/ro/posts/index/0.json
119
+ ro.build: public/api/ro/posts/index.json
120
+ ro.build: public/api/ro/index/0.json
121
+ ro.build: public/api/ro/index.json
122
+ ro.build: public/api/ro/index.html
123
+ ro.build: public/ro -> public/api/ro in 0.08s
124
+
125
+ ```
126
+
127
+ During the build, assets are expanded to be the full URL of the final
128
+ deployment destination. This is done via the RO_URL environment variable, and
129
+ automatically with a pre-build GitHub Action that will deploy your content via
130
+ GitHub Pages. See
131
+ https://github.com/ahoward/ro/blob/main/.github/workflows/gh-pages.yml#L55 for
132
+ more details.
133
+
134
+ You can view sample output from this Action, deployed to GH Pages here: https://ahoward.github.io/ro
135
+
136
+
137
+
138
+ # USAGE
139
+
140
+ #### WRITE-ME // #TODO
141
+
142
+ ## API // Javascript
143
+
144
+ #### WRITE-ME // #TODO
145
+
146
+ ## CLI
147
+
148
+ #### WRITE-ME // #TODO
149
+
150
+ ## Programatic // Ruby
151
+
152
+ #### WRITE-ME // #TODO
153
+
154
+ ## Via Repository
155
+
156
+ #### WRITE-ME // #TODO
157
+
158
+ - note on http vs https
159
+
data/Rakefile CHANGED
@@ -1,8 +1,12 @@
1
- This.rubyforge_project = 'codeforpeople'
2
1
  This.author = "Ara T. Howard"
3
2
  This.email = "ara.t.howard@gmail.com"
4
- This.homepage = "https://github.com/ahoward/#{ This.lib }"
3
+ This.github = "ahoward"
4
+ This.homepage = "https://github.com/#{ This.github }/#{ This.basename }"
5
+ This.repo = "https://github.com/#{ This.github }/#{ This.basename }"
5
6
 
7
+ task :license do
8
+ open('LICENSE', 'w'){|fd| fd.puts "Ruby"}
9
+ end
6
10
 
7
11
  task :default do
8
12
  puts((Rake::Task.tasks.map{|task| task.name.gsub(/::/,':')} - ['default']).sort)
@@ -29,7 +33,7 @@ def run_tests!(which = nil)
29
33
 
30
34
  test_rbs.each_with_index do |test_rb, index|
31
35
  testno = index + 1
32
- command = "#{ File.basename(This.ruby) } -I ./lib -I ./test/lib #{ test_rb }"
36
+ command = "#{ This.ruby } -w -I ./lib -I ./test/lib #{ test_rb }"
33
37
 
34
38
  puts
35
39
  say(div, :color => :cyan, :bold => true)
@@ -59,8 +63,8 @@ end
59
63
 
60
64
  task :gemspec do
61
65
  ignore_extensions = ['git', 'svn', 'tmp', /sw./, 'bak', 'gem']
62
- ignore_directories = ['pkg', 'db']
63
- ignore_files = ['test/log', 'test/db.yml', 'a.rb', 'b.rb'] + Dir['db/*'] + %w'db'
66
+ ignore_directories = ['pkg']
67
+ ignore_files = ['test/log']
64
68
 
65
69
  shiteless =
66
70
  lambda do |list|
@@ -69,11 +73,13 @@ task :gemspec do
69
73
  extension = File.basename(entry).split(%r/[.]/).last
70
74
  ignore_extensions.any?{|ext| ext === extension}
71
75
  end
76
+
72
77
  list.delete_if do |entry|
73
78
  next unless test(?d, entry)
74
79
  dirname = File.expand_path(entry)
75
80
  ignore_directories.any?{|dir| File.expand_path(dir) == dirname}
76
81
  end
82
+
77
83
  list.delete_if do |entry|
78
84
  next unless test(?f, entry)
79
85
  filename = File.expand_path(entry)
@@ -81,36 +87,24 @@ task :gemspec do
81
87
  end
82
88
  end
83
89
 
84
- lib = This.lib
90
+ name = This.basename
85
91
  object = This.object
86
92
  version = This.version
87
- files = shiteless[Dir::glob("**/**")].select{|path| test(?f, path)}
93
+ files = shiteless[Dir::glob("**/**")]
88
94
  executables = shiteless[Dir::glob("bin/*")].map{|exe| File.basename(exe)}
89
- #has_rdoc = true #File.exist?('doc')
90
- test_files = test(?e, "test/#{ lib }.rb") ? "test/#{ lib }.rb" : nil
91
- summary = object.respond_to?(:summary) ? object.summary : "summary: #{ lib } kicks the ass"
92
- description = object.respond_to?(:description) ? object.description : "description: #{ lib } kicks the ass"
93
- license = object.respond_to?(:license) ? object.license : nil
94
-
95
- if license.nil?
96
- license =
97
- begin
98
- IO.binread('LICENSE')
99
- rescue
100
- "Same As Ruby's"
101
- end
102
- end
95
+ summary = Util.unindent(This.summary).strip
96
+ description = Util.unindent(This.description).strip
97
+ license = This.license.strip
103
98
 
104
99
  if This.extensions.nil?
105
100
  This.extensions = []
106
101
  extensions = This.extensions
107
102
  %w( Makefile configure extconf.rb ).each do |ext|
108
- extensions << ext if File.exists?(ext)
103
+ extensions << ext if File.exist?(ext)
109
104
  end
110
105
  end
111
106
  extensions = [extensions].flatten.compact
112
107
 
113
- # TODO
114
108
  if This.dependencies.nil?
115
109
  dependencies = []
116
110
  else
@@ -128,14 +122,15 @@ task :gemspec do
128
122
  else
129
123
  Template {
130
124
  <<-__
131
- ## <%= lib %>.gemspec
125
+ ## <%= name %>.gemspec
132
126
  #
133
127
 
134
128
  Gem::Specification::new do |spec|
135
- spec.name = <%= lib.inspect %>
129
+ spec.name = <%= name.inspect %>
136
130
  spec.version = <%= version.inspect %>
131
+ spec.required_ruby_version = '>= 3.0'
137
132
  spec.platform = Gem::Platform::RUBY
138
- spec.summary = <%= lib.inspect %>
133
+ spec.summary = <%= summary.inspect %>
139
134
  spec.description = <%= description.inspect %>
140
135
  spec.license = <%= license.inspect %>
141
136
 
@@ -144,15 +139,12 @@ task :gemspec do
144
139
 
145
140
  spec.require_path = "lib"
146
141
 
147
- spec.test_files = <%= test_files.inspect %>
148
-
149
142
  <% dependencies.each do |lib_version| %>
150
143
  spec.add_dependency(*<%= Array(lib_version).flatten.inspect %>)
151
144
  <% end %>
152
145
 
153
146
  spec.extensions.push(*<%= extensions.inspect %>)
154
147
 
155
- spec.rubyforge_project = <%= This.rubyforge_project.inspect %>
156
148
  spec.author = <%= This.author.inspect %>
157
149
  spec.email = <%= This.email.inspect %>
158
150
  spec.homepage = <%= This.homepage.inspect %>
@@ -162,7 +154,7 @@ task :gemspec do
162
154
  end
163
155
 
164
156
  Fu.mkdir_p(This.pkgdir)
165
- gemspec = "#{ lib }.gemspec"
157
+ gemspec = "#{ name }.gemspec"
166
158
  open(gemspec, "w"){|fd| fd.puts(template)}
167
159
  This.gemspec = gemspec
168
160
  end
@@ -178,29 +170,50 @@ task :gem => [:clean, :gemspec] do
178
170
  This.gem = File.join(This.pkgdir, File.basename(gem))
179
171
  end
180
172
 
173
+ task :README => [:readme]
174
+
181
175
  task :readme do
182
176
  samples = ''
183
177
  prompt = '~ > '
184
178
  lib = This.lib
185
179
  version = This.version
186
180
 
187
- Dir['sample*/*'].sort.each do |sample|
188
- samples << "\n" << " <========< #{ sample } >========>" << "\n\n"
181
+ Dir['sample*/**/**.rb'].sort.each do |sample|
182
+ link = "[#{ sample }](#{ This.repo }/blob/main/#{ sample })"
183
+ samples << " #### <========< #{ link } >========>\n"
189
184
 
190
185
  cmd = "cat #{ sample }"
191
- samples << Util.indent(prompt + cmd, 2) << "\n\n"
192
- samples << Util.indent(`#{ cmd }`, 4) << "\n"
186
+ samples << "```sh\n"
187
+ samples << Util.indent(prompt + cmd, 2) << "\n"
188
+ samples << "```\n"
189
+ samples << "```ruby\n"
190
+ samples << Util.indent(IO.binread(sample), 4) << "\n"
191
+ samples << "```\n"
192
+
193
+ samples << "\n"
193
194
 
194
195
  cmd = "ruby #{ sample }"
195
- samples << Util.indent(prompt + cmd, 2) << "\n\n"
196
+ samples << "```sh\n"
197
+ samples << Util.indent(prompt + cmd, 2) << "\n"
198
+ samples << "```\n"
196
199
 
197
200
  cmd = "ruby -e'STDOUT.sync=true; exec %(ruby -I ./lib #{ sample })'"
198
- samples << Util.indent(`#{ cmd } 2>&1`, 4) << "\n"
201
+ oe = `#{ cmd } 2>&1`
202
+ samples << "```txt\n"
203
+ samples << Util.indent(oe, 4) << "\n"
204
+ samples << "```\n"
205
+
206
+ samples << "\n"
199
207
  end
200
208
 
209
+ This.samples = samples
210
+
201
211
  template =
202
- if test(?e, 'readme.erb')
203
- Template{ IO.read('readme.erb') }
212
+ case
213
+ when test(?e, 'README.md.erb')
214
+ Template{ IO.read('README.md.erb') }
215
+ when test(?e, 'README.erb')
216
+ Template{ IO.read('README.erb') }
204
217
  else
205
218
  Template {
206
219
  <<-__
@@ -218,31 +231,23 @@ task :readme do
218
231
  }
219
232
  end
220
233
 
221
- open("README", "w"){|fd| fd.puts template}
234
+ IO.binwrite('README.md', template)
222
235
  end
223
236
 
224
-
225
237
  task :clean do
226
238
  Dir[File.join(This.pkgdir, '**/**')].each{|entry| Fu.rm_rf(entry)}
227
239
  end
228
240
 
229
-
230
- task :release => [:clean, :gemspec, :gem] do
241
+ task :release => [:dist, :gem] do
231
242
  gems = Dir[File.join(This.pkgdir, '*.gem')].flatten
232
- raise "which one? : #{ gems.inspect }" if gems.size > 1
233
- raise "no gems?" if gems.size < 1
243
+ abort "which one? : #{ gems.inspect }" if gems.size > 1
244
+ abort "no gems?" if gems.size < 1
234
245
 
235
246
  cmd = "gem push #{ This.gem }"
236
247
  puts cmd
237
248
  puts
238
249
  system(cmd)
239
250
  abort("cmd(#{ cmd }) failed with (#{ $?.inspect })") unless $?.exitstatus.zero?
240
-
241
- cmd = "rubyforge login && rubyforge add_release #{ This.rubyforge_project } #{ This.lib } #{ This.version } #{ This.gem }"
242
- puts cmd
243
- puts
244
- system(cmd)
245
- abort("cmd(#{ cmd }) failed with (#{ $?.inspect })") unless $?.exitstatus.zero?
246
251
  end
247
252
 
248
253
 
@@ -260,58 +265,66 @@ BEGIN {
260
265
  require 'rbconfig'
261
266
  require 'pp'
262
267
 
263
- # fu shortcut
268
+ # fu shortcut!
264
269
  #
265
270
  Fu = FileUtils
266
271
 
267
- # cache a bunch of stuff about this rakefile/environment
272
+ # guess a bunch of stuff about this rakefile/environment based on the
268
273
  #
269
274
  This = OpenStruct.new
270
275
 
271
276
  This.file = File.expand_path(__FILE__)
272
277
  This.dir = File.dirname(This.file)
273
278
  This.pkgdir = File.join(This.dir, 'pkg')
279
+ This.basename = File.basename(This.dir)
274
280
 
275
- # grok lib
281
+ # load actual shit _lib
276
282
  #
277
- lib = ENV['LIB']
278
- unless lib
279
- lib = File.basename(Dir.pwd).sub(/[-].*$/, '')
280
- end
281
- This.lib = lib
283
+ _libpath = ["./lib/#{ This.basename }/_lib.rb", "./lib/#{ This.basename }.rb"]
284
+ _lib = _libpath.detect{|l| test(?s, l)}
282
285
 
283
- # grok version
284
- #
285
- version = ENV['VERSION']
286
- unless version
287
- require "./lib/#{ This.lib }"
288
- This.name = lib.capitalize
289
- This.object = eval(This.name)
290
- version = This.object.send(:version)
291
- end
292
- This.version = version
286
+ abort "could not find a _lib in ./lib/ via #{ _libpath.join(':') }" unless _lib
287
+
288
+ This._lib = _lib
289
+ require This._lib
293
290
 
294
- # see if dependencies are export by the module
291
+ # extract the name from the _lib
295
292
  #
296
- if This.object.respond_to?(:dependencies)
297
- This.dependencies = This.object.dependencies
293
+ lines = IO.binread(This._lib).split("\n")
294
+ re = %r`\A \s* (module|class) \s+ ([^\s]+) \s* \z`iomx
295
+ name = nil
296
+ lines.each do |line|
297
+ match = line.match(re)
298
+ if match
299
+ name = match.to_a.last
300
+ break
301
+ end
298
302
  end
303
+ unless name
304
+ abort "could not extract `name` from #{ This._lib }"
305
+ end
306
+ This.name = name
307
+ This.basename = This.name.downcase
299
308
 
300
- # we need to know the name of the lib an it's version
309
+ # now, fully grok This
301
310
  #
302
- abort('no lib') unless This.lib
303
- abort('no version') unless This.version
311
+ This.object = eval(This.name)
312
+ This.version = This.object.version
313
+ This.dependencies = This.object.dependencies
314
+ This.summary = This.object.summary
315
+ This.description = This.object.respond_to?(:description) ? This.object.description : This.summary
316
+ This.license = This.object.respond_to?(:license) ? This.object.license : IO.binread('LICENSE').strip
304
317
 
305
318
  # discover full path to this ruby executable
306
319
  #
307
- c = Config::CONFIG
320
+ c = RbConfig::CONFIG
308
321
  bindir = c["bindir"] || c['BINDIR']
309
322
  ruby_install_name = c['ruby_install_name'] || c['RUBY_INSTALL_NAME'] || 'ruby'
310
323
  ruby_ext = c['EXEEXT'] || ''
311
324
  ruby = File.join(bindir, (ruby_install_name + ruby_ext))
312
325
  This.ruby = ruby
313
326
 
314
- # some utils
327
+ # some utils, alwayze teh utils...
315
328
  #
316
329
  module Util
317
330
  def indent(s, n = 2)
@@ -326,7 +339,8 @@ BEGIN {
326
339
  next if line =~ %r/^\s*$/
327
340
  indent = line[%r/^\s*/] and break
328
341
  end
329
- indent ? s.gsub(%r/^#{ indent }/, "") : s
342
+ unindented = indent ? s.gsub(%r/^#{ indent }/, "") : s
343
+ unindented.strip
330
344
  end
331
345
  extend self
332
346
  end
@@ -334,17 +348,54 @@ BEGIN {
334
348
  # template support
335
349
  #
336
350
  class Template
351
+ def Template.indent(string, n = 2)
352
+ string = string.to_s
353
+ n = n.to_i
354
+ padding = (42 - 10).chr * n
355
+ initial = %r/^#{ Regexp.escape(padding) }/
356
+ #require 'debug'
357
+ #binding.break
358
+ Util.indent(string, n).sub(initial, '')
359
+ end
337
360
  def initialize(&block)
338
361
  @block = block
339
362
  @template = block.call.to_s
340
363
  end
341
364
  def expand(b=nil)
342
- ERB.new(Util.unindent(@template)).result((b||@block).binding)
365
+ ERB.new(Util.unindent(@template), trim_mode: '%<>-').result((b||@block).binding)
343
366
  end
344
367
  alias_method 'to_s', 'expand'
345
368
  end
346
369
  def Template(*args, &block) Template.new(*args, &block) end
347
370
 
371
+ # os / platform support
372
+ #
373
+ module Platform
374
+ def Platform.windows?
375
+ (/cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM) != nil
376
+ end
377
+
378
+ def Platform.darwin?
379
+ (/darwin/ =~ RUBY_PLATFORM) != nil
380
+ end
381
+
382
+ def Platform.mac?
383
+ Platform.darwin?
384
+ end
385
+
386
+ def Platform.unix?
387
+ !Platform.windows?
388
+ end
389
+
390
+ def Platform.linux?
391
+ Platform.unix? and not Platform.darwin?
392
+ end
393
+
394
+ def Platform.jruby?
395
+ RUBY_ENGINE == 'jruby'
396
+ end
397
+ end
398
+
348
399
  # colored console output support
349
400
  #
350
401
  This.ansi = {