fabula 0.4.2
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.
- checksums.yaml +7 -0
- data/LICENSE +1 -0
- data/README.md +178 -0
- data/README.md.erb +159 -0
- data/Rakefile +452 -0
- data/lib/fabula/_lib.rb +77 -0
- data/lib/fabula.rb +5 -0
- metadata +53 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 7c2e81e62282751f2e700fc7b654295a08718ceb72fed2fc2b92fca1055b0140
|
4
|
+
data.tar.gz: 6480bc710df19c5b24064b72705a2490aef57bd86340e8c9cfa6f4c7616464b1
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: dfe33d60e8ffc8a952c5f8aac67892fb6b2204b11b62d12422170cc23b7674d9d93fca3ed7d817c7f13f84aebcdb9580582b694eceb99874fb663a1cf42d321a
|
7
|
+
data.tar.gz: 840f7307f26bb60c010a4c9f4ffce8b08cbf12963e065a5bf6698adf67a32e80660a3e3ed2dabd35b3eaf39076a483688bb2997c7c3b4ab2633db44285a082e3
|
data/LICENSE
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Ruby
|
data/README.md
ADDED
@@ -0,0 +1,178 @@
|
|
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
|
+
|
160
|
+
SAMPLES
|
161
|
+
=======
|
162
|
+
#### <========< [samples/a.rb](https://github.com/ahoward/ro/blob/main/samples/a.rb) >========>
|
163
|
+
```sh
|
164
|
+
~ > cat samples/a.rb
|
165
|
+
```
|
166
|
+
```ruby
|
167
|
+
require 'ro'
|
168
|
+
|
169
|
+
p 42
|
170
|
+
```
|
171
|
+
|
172
|
+
```sh
|
173
|
+
~ > ruby samples/a.rb
|
174
|
+
```
|
175
|
+
```txt
|
176
|
+
42
|
177
|
+
```
|
178
|
+
|
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
ADDED
@@ -0,0 +1,452 @@
|
|
1
|
+
This.author = "Ara T. Howard"
|
2
|
+
This.email = "ara.t.howard@gmail.com"
|
3
|
+
This.github = "ahoward"
|
4
|
+
This.homepage = "https://github.com/#{ This.github }/#{ This.basename }"
|
5
|
+
This.repo = "https://github.com/#{ This.github }/#{ This.basename }"
|
6
|
+
|
7
|
+
task :license do
|
8
|
+
open('LICENSE', 'w'){|fd| fd.puts "Ruby"}
|
9
|
+
end
|
10
|
+
|
11
|
+
task :default do
|
12
|
+
puts((Rake::Task.tasks.map{|task| task.name.gsub(/::/,':')} - ['default']).sort)
|
13
|
+
end
|
14
|
+
|
15
|
+
task :test do
|
16
|
+
run_tests!
|
17
|
+
end
|
18
|
+
|
19
|
+
namespace :test do
|
20
|
+
task(:unit){ run_tests!(:unit) }
|
21
|
+
task(:functional){ run_tests!(:functional) }
|
22
|
+
task(:integration){ run_tests!(:integration) }
|
23
|
+
end
|
24
|
+
|
25
|
+
def run_tests!(which = nil)
|
26
|
+
which ||= '**'
|
27
|
+
test_dir = File.join(This.dir, "test")
|
28
|
+
test_glob ||= File.join(test_dir, "#{ which }/**_test.rb")
|
29
|
+
test_rbs = Dir.glob(test_glob).sort
|
30
|
+
|
31
|
+
div = ('=' * 119)
|
32
|
+
line = ('-' * 119)
|
33
|
+
|
34
|
+
test_rbs.each_with_index do |test_rb, index|
|
35
|
+
testno = index + 1
|
36
|
+
command = "#{ This.ruby } -w -I ./lib -I ./test/lib #{ test_rb }"
|
37
|
+
|
38
|
+
puts
|
39
|
+
say(div, :color => :cyan, :bold => true)
|
40
|
+
say("@#{ testno } => ", :bold => true, :method => :print)
|
41
|
+
say(command, :color => :cyan, :bold => true)
|
42
|
+
say(line, :color => :cyan, :bold => true)
|
43
|
+
|
44
|
+
system(command)
|
45
|
+
|
46
|
+
say(line, :color => :cyan, :bold => true)
|
47
|
+
|
48
|
+
status = $?.exitstatus
|
49
|
+
|
50
|
+
if status.zero?
|
51
|
+
say("@#{ testno } <= ", :bold => true, :color => :white, :method => :print)
|
52
|
+
say("SUCCESS", :color => :green, :bold => true)
|
53
|
+
else
|
54
|
+
say("@#{ testno } <= ", :bold => true, :color => :white, :method => :print)
|
55
|
+
say("FAILURE", :color => :red, :bold => true)
|
56
|
+
end
|
57
|
+
say(line, :color => :cyan, :bold => true)
|
58
|
+
|
59
|
+
exit(status) unless status.zero?
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
task :gemspec do
|
65
|
+
ignore_extensions = ['git', 'svn', 'tmp', /sw./, 'bak', 'gem']
|
66
|
+
ignore_directories = ['pkg']
|
67
|
+
ignore_files = ['test/log']
|
68
|
+
|
69
|
+
shiteless =
|
70
|
+
lambda do |list|
|
71
|
+
list.delete_if do |entry|
|
72
|
+
next unless test(?e, entry)
|
73
|
+
extension = File.basename(entry).split(%r/[.]/).last
|
74
|
+
ignore_extensions.any?{|ext| ext === extension}
|
75
|
+
end
|
76
|
+
|
77
|
+
list.delete_if do |entry|
|
78
|
+
next unless test(?d, entry)
|
79
|
+
dirname = File.expand_path(entry)
|
80
|
+
ignore_directories.any?{|dir| File.expand_path(dir) == dirname}
|
81
|
+
end
|
82
|
+
|
83
|
+
list.delete_if do |entry|
|
84
|
+
next unless test(?f, entry)
|
85
|
+
filename = File.expand_path(entry)
|
86
|
+
ignore_files.any?{|file| File.expand_path(file) == filename}
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
name = This.basename
|
91
|
+
object = This.object
|
92
|
+
version = This.version
|
93
|
+
files = shiteless[Dir::glob("**/**")]
|
94
|
+
executables = shiteless[Dir::glob("bin/*")].map{|exe| File.basename(exe)}
|
95
|
+
summary = Util.unindent(This.summary).strip
|
96
|
+
description = Util.unindent(This.description).strip
|
97
|
+
license = This.license.strip
|
98
|
+
|
99
|
+
if This.extensions.nil?
|
100
|
+
This.extensions = []
|
101
|
+
extensions = This.extensions
|
102
|
+
%w( Makefile configure extconf.rb ).each do |ext|
|
103
|
+
extensions << ext if File.exist?(ext)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
extensions = [extensions].flatten.compact
|
107
|
+
|
108
|
+
if This.dependencies.nil?
|
109
|
+
dependencies = []
|
110
|
+
else
|
111
|
+
case This.dependencies
|
112
|
+
when Hash
|
113
|
+
dependencies = This.dependencies.values
|
114
|
+
when Array
|
115
|
+
dependencies = This.dependencies
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
template =
|
120
|
+
if test(?e, 'gemspec.erb')
|
121
|
+
Template{ IO.read('gemspec.erb') }
|
122
|
+
else
|
123
|
+
Template {
|
124
|
+
<<-__
|
125
|
+
## <%= name %>.gemspec
|
126
|
+
#
|
127
|
+
|
128
|
+
Gem::Specification::new do |spec|
|
129
|
+
spec.name = <%= name.inspect %>
|
130
|
+
spec.version = <%= version.inspect %>
|
131
|
+
spec.required_ruby_version = '>= 3.0'
|
132
|
+
spec.platform = Gem::Platform::RUBY
|
133
|
+
spec.summary = <%= summary.inspect %>
|
134
|
+
spec.description = <%= description.inspect %>
|
135
|
+
spec.license = <%= license.inspect %>
|
136
|
+
|
137
|
+
spec.files =\n<%= files.sort.pretty_inspect %>
|
138
|
+
spec.executables = <%= executables.inspect %>
|
139
|
+
|
140
|
+
spec.require_path = "lib"
|
141
|
+
|
142
|
+
<% dependencies.each do |lib_version| %>
|
143
|
+
spec.add_dependency(*<%= Array(lib_version).flatten.inspect %>)
|
144
|
+
<% end %>
|
145
|
+
|
146
|
+
spec.extensions.push(*<%= extensions.inspect %>)
|
147
|
+
|
148
|
+
spec.author = <%= This.author.inspect %>
|
149
|
+
spec.email = <%= This.email.inspect %>
|
150
|
+
spec.homepage = <%= This.homepage.inspect %>
|
151
|
+
end
|
152
|
+
__
|
153
|
+
}
|
154
|
+
end
|
155
|
+
|
156
|
+
Fu.mkdir_p(This.pkgdir)
|
157
|
+
gemspec = "#{ name }.gemspec"
|
158
|
+
open(gemspec, "w"){|fd| fd.puts(template)}
|
159
|
+
This.gemspec = gemspec
|
160
|
+
end
|
161
|
+
|
162
|
+
task :gem => [:clean, :gemspec] do
|
163
|
+
Fu.mkdir_p(This.pkgdir)
|
164
|
+
before = Dir['*.gem']
|
165
|
+
cmd = "gem build #{ This.gemspec }"
|
166
|
+
`#{ cmd }`
|
167
|
+
after = Dir['*.gem']
|
168
|
+
gem = ((after - before).first || after.first) or abort('no gem!')
|
169
|
+
Fu.mv(gem, This.pkgdir)
|
170
|
+
This.gem = File.join(This.pkgdir, File.basename(gem))
|
171
|
+
end
|
172
|
+
|
173
|
+
task :README => [:readme]
|
174
|
+
|
175
|
+
task :readme do
|
176
|
+
samples = ''
|
177
|
+
prompt = '~ > '
|
178
|
+
lib = This.lib
|
179
|
+
version = This.version
|
180
|
+
|
181
|
+
Dir['sample*/**/**.rb'].sort.each do |sample|
|
182
|
+
link = "[#{ sample }](#{ This.repo }/blob/main/#{ sample })"
|
183
|
+
samples << " #### <========< #{ link } >========>\n"
|
184
|
+
|
185
|
+
cmd = "cat #{ sample }"
|
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"
|
194
|
+
|
195
|
+
cmd = "ruby #{ sample }"
|
196
|
+
samples << "```sh\n"
|
197
|
+
samples << Util.indent(prompt + cmd, 2) << "\n"
|
198
|
+
samples << "```\n"
|
199
|
+
|
200
|
+
cmd = "ruby -e'STDOUT.sync=true; exec %(ruby -I ./lib #{ sample })'"
|
201
|
+
oe = `#{ cmd } 2>&1`
|
202
|
+
samples << "```txt\n"
|
203
|
+
samples << Util.indent(oe, 4) << "\n"
|
204
|
+
samples << "```\n"
|
205
|
+
|
206
|
+
samples << "\n"
|
207
|
+
end
|
208
|
+
|
209
|
+
This.samples = samples
|
210
|
+
|
211
|
+
template =
|
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') }
|
217
|
+
else
|
218
|
+
Template {
|
219
|
+
<<-__
|
220
|
+
NAME
|
221
|
+
#{ lib }
|
222
|
+
|
223
|
+
DESCRIPTION
|
224
|
+
|
225
|
+
INSTALL
|
226
|
+
gem install #{ lib }
|
227
|
+
|
228
|
+
SAMPLES
|
229
|
+
#{ samples }
|
230
|
+
__
|
231
|
+
}
|
232
|
+
end
|
233
|
+
|
234
|
+
IO.binwrite('README.md', template)
|
235
|
+
end
|
236
|
+
|
237
|
+
task :clean do
|
238
|
+
Dir[File.join(This.pkgdir, '**/**')].each{|entry| Fu.rm_rf(entry)}
|
239
|
+
end
|
240
|
+
|
241
|
+
task :release => [:dist, :gem] do
|
242
|
+
gems = Dir[File.join(This.pkgdir, '*.gem')].flatten
|
243
|
+
abort "which one? : #{ gems.inspect }" if gems.size > 1
|
244
|
+
abort "no gems?" if gems.size < 1
|
245
|
+
|
246
|
+
cmd = "gem push #{ This.gem }"
|
247
|
+
puts cmd
|
248
|
+
puts
|
249
|
+
system(cmd)
|
250
|
+
abort("cmd(#{ cmd }) failed with (#{ $?.inspect })") unless $?.exitstatus.zero?
|
251
|
+
end
|
252
|
+
|
253
|
+
|
254
|
+
|
255
|
+
|
256
|
+
|
257
|
+
BEGIN {
|
258
|
+
# support for this rakefile
|
259
|
+
#
|
260
|
+
$VERBOSE = nil
|
261
|
+
|
262
|
+
require 'ostruct'
|
263
|
+
require 'erb'
|
264
|
+
require 'fileutils'
|
265
|
+
require 'rbconfig'
|
266
|
+
require 'pp'
|
267
|
+
|
268
|
+
# fu shortcut!
|
269
|
+
#
|
270
|
+
Fu = FileUtils
|
271
|
+
|
272
|
+
# guess a bunch of stuff about this rakefile/environment based on the
|
273
|
+
#
|
274
|
+
This = OpenStruct.new
|
275
|
+
|
276
|
+
This.file = File.expand_path(__FILE__)
|
277
|
+
This.dir = File.dirname(This.file)
|
278
|
+
This.pkgdir = File.join(This.dir, 'pkg')
|
279
|
+
This.basename = File.basename(This.dir)
|
280
|
+
|
281
|
+
# load actual shit _lib
|
282
|
+
#
|
283
|
+
_libpath = ["./lib/#{ This.basename }/_lib.rb", "./lib/#{ This.basename }.rb"]
|
284
|
+
_lib = _libpath.detect{|l| test(?s, l)}
|
285
|
+
|
286
|
+
abort "could not find a _lib in ./lib/ via #{ _libpath.join(':') }" unless _lib
|
287
|
+
|
288
|
+
This._lib = _lib
|
289
|
+
require This._lib
|
290
|
+
|
291
|
+
# extract the name from the _lib
|
292
|
+
#
|
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
|
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
|
308
|
+
|
309
|
+
# now, fully grok This
|
310
|
+
#
|
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
|
317
|
+
|
318
|
+
# discover full path to this ruby executable
|
319
|
+
#
|
320
|
+
c = RbConfig::CONFIG
|
321
|
+
bindir = c["bindir"] || c['BINDIR']
|
322
|
+
ruby_install_name = c['ruby_install_name'] || c['RUBY_INSTALL_NAME'] || 'ruby'
|
323
|
+
ruby_ext = c['EXEEXT'] || ''
|
324
|
+
ruby = File.join(bindir, (ruby_install_name + ruby_ext))
|
325
|
+
This.ruby = ruby
|
326
|
+
|
327
|
+
# some utils, alwayze teh utils...
|
328
|
+
#
|
329
|
+
module Util
|
330
|
+
def indent(s, n = 2)
|
331
|
+
s = unindent(s)
|
332
|
+
ws = ' ' * n
|
333
|
+
s.gsub(%r/^/, ws)
|
334
|
+
end
|
335
|
+
|
336
|
+
def unindent(s)
|
337
|
+
indent = nil
|
338
|
+
s.each_line do |line|
|
339
|
+
next if line =~ %r/^\s*$/
|
340
|
+
indent = line[%r/^\s*/] and break
|
341
|
+
end
|
342
|
+
unindented = indent ? s.gsub(%r/^#{ indent }/, "") : s
|
343
|
+
unindented.strip
|
344
|
+
end
|
345
|
+
extend self
|
346
|
+
end
|
347
|
+
|
348
|
+
# template support
|
349
|
+
#
|
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
|
360
|
+
def initialize(&block)
|
361
|
+
@block = block
|
362
|
+
@template = block.call.to_s
|
363
|
+
end
|
364
|
+
def expand(b=nil)
|
365
|
+
ERB.new(Util.unindent(@template), trim_mode: '%<>-').result((b||@block).binding)
|
366
|
+
end
|
367
|
+
alias_method 'to_s', 'expand'
|
368
|
+
end
|
369
|
+
def Template(*args, &block) Template.new(*args, &block) end
|
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
|
+
|
399
|
+
# colored console output support
|
400
|
+
#
|
401
|
+
This.ansi = {
|
402
|
+
:clear => "\e[0m",
|
403
|
+
:reset => "\e[0m",
|
404
|
+
:erase_line => "\e[K",
|
405
|
+
:erase_char => "\e[P",
|
406
|
+
:bold => "\e[1m",
|
407
|
+
:dark => "\e[2m",
|
408
|
+
:underline => "\e[4m",
|
409
|
+
:underscore => "\e[4m",
|
410
|
+
:blink => "\e[5m",
|
411
|
+
:reverse => "\e[7m",
|
412
|
+
:concealed => "\e[8m",
|
413
|
+
:black => "\e[30m",
|
414
|
+
:red => "\e[31m",
|
415
|
+
:green => "\e[32m",
|
416
|
+
:yellow => "\e[33m",
|
417
|
+
:blue => "\e[34m",
|
418
|
+
:magenta => "\e[35m",
|
419
|
+
:cyan => "\e[36m",
|
420
|
+
:white => "\e[37m",
|
421
|
+
:on_black => "\e[40m",
|
422
|
+
:on_red => "\e[41m",
|
423
|
+
:on_green => "\e[42m",
|
424
|
+
:on_yellow => "\e[43m",
|
425
|
+
:on_blue => "\e[44m",
|
426
|
+
:on_magenta => "\e[45m",
|
427
|
+
:on_cyan => "\e[46m",
|
428
|
+
:on_white => "\e[47m"
|
429
|
+
}
|
430
|
+
def say(phrase, *args)
|
431
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
432
|
+
options[:color] = args.shift.to_s.to_sym unless args.empty?
|
433
|
+
keys = options.keys
|
434
|
+
keys.each{|key| options[key.to_s.to_sym] = options.delete(key)}
|
435
|
+
|
436
|
+
color = options[:color]
|
437
|
+
bold = options.has_key?(:bold)
|
438
|
+
|
439
|
+
parts = [phrase]
|
440
|
+
parts.unshift(This.ansi[color]) if color
|
441
|
+
parts.unshift(This.ansi[:bold]) if bold
|
442
|
+
parts.push(This.ansi[:clear]) if parts.size > 1
|
443
|
+
|
444
|
+
method = options[:method] || :puts
|
445
|
+
|
446
|
+
Kernel.send(method, parts.join)
|
447
|
+
end
|
448
|
+
|
449
|
+
# always run out of the project dir
|
450
|
+
#
|
451
|
+
Dir.chdir(This.dir)
|
452
|
+
}
|
data/lib/fabula/_lib.rb
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
module Fabula
|
2
|
+
VERSION = '0.4.2' unless defined?(VERSION)
|
3
|
+
|
4
|
+
class << self
|
5
|
+
def version
|
6
|
+
VERSION
|
7
|
+
end
|
8
|
+
|
9
|
+
def repo
|
10
|
+
'https://github.com/ahoward/fabula'
|
11
|
+
end
|
12
|
+
|
13
|
+
def summary
|
14
|
+
<<~____
|
15
|
+
the static site builder you always dreamed of
|
16
|
+
____
|
17
|
+
end
|
18
|
+
|
19
|
+
def description
|
20
|
+
<<~____
|
21
|
+
fabula is a an super small, super fast, static site generator with everything
|
22
|
+
to need to build and host content driven websites. combined with github
|
23
|
+
pages, it offers a complete solution for headless cms, https, super fast
|
24
|
+
hosting, editorial workflows, and clever image handling with no frameworks and
|
25
|
+
an extremely small codebase.
|
26
|
+
____
|
27
|
+
end
|
28
|
+
|
29
|
+
def libs
|
30
|
+
%w[
|
31
|
+
]
|
32
|
+
end
|
33
|
+
|
34
|
+
def dependencies
|
35
|
+
{
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
def libdir(*args, &block)
|
40
|
+
@libdir ||= File.dirname(File.expand_path(__FILE__))
|
41
|
+
args.empty? ? @libdir : File.join(@libdir, *args)
|
42
|
+
ensure
|
43
|
+
if block
|
44
|
+
begin
|
45
|
+
$LOAD_PATH.unshift(@libdir)
|
46
|
+
block.call
|
47
|
+
ensure
|
48
|
+
$LOAD_PATH.shift
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def load(*libs)
|
54
|
+
libs = libs.join(' ').scan(/[^\s+]+/)
|
55
|
+
libdir { libs.each { |lib| Kernel.load(lib) } }
|
56
|
+
end
|
57
|
+
|
58
|
+
def load_dependencies!
|
59
|
+
libs.each do |lib|
|
60
|
+
require lib
|
61
|
+
end
|
62
|
+
|
63
|
+
begin
|
64
|
+
require 'rubygems'
|
65
|
+
rescue LoadError
|
66
|
+
nil
|
67
|
+
end
|
68
|
+
|
69
|
+
has_rubygems = defined?(gem)
|
70
|
+
|
71
|
+
dependencies.each do |lib, dependency|
|
72
|
+
gem(*dependency) if has_rubygems
|
73
|
+
require(lib)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
data/lib/fabula.rb
ADDED
metadata
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fabula
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.4.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ara T. Howard
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2025-01-01 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: |-
|
14
|
+
fabula is a an super small, super fast, static site generator with everything
|
15
|
+
to need to build and host content driven websites. combined with github
|
16
|
+
pages, it offers a complete solution for headless cms, https, super fast
|
17
|
+
hosting, editorial workflows, and clever image handling with no frameworks and
|
18
|
+
an extremely small codebase.
|
19
|
+
email: ara.t.howard@gmail.com
|
20
|
+
executables: []
|
21
|
+
extensions: []
|
22
|
+
extra_rdoc_files: []
|
23
|
+
files:
|
24
|
+
- LICENSE
|
25
|
+
- README.md
|
26
|
+
- README.md.erb
|
27
|
+
- Rakefile
|
28
|
+
- lib/fabula.rb
|
29
|
+
- lib/fabula/_lib.rb
|
30
|
+
homepage: https://github.com/ahoward/fabula
|
31
|
+
licenses:
|
32
|
+
- Ruby
|
33
|
+
metadata: {}
|
34
|
+
post_install_message:
|
35
|
+
rdoc_options: []
|
36
|
+
require_paths:
|
37
|
+
- lib
|
38
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
39
|
+
requirements:
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: '3.0'
|
43
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
requirements: []
|
49
|
+
rubygems_version: 3.5.16
|
50
|
+
signing_key:
|
51
|
+
specification_version: 4
|
52
|
+
summary: the static site builder you always dreamed of
|
53
|
+
test_files: []
|