ro 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- Y2M5NmE2YmY3ZDgyYWFhNzZhMzE3MzFmOTgzNmJkNGE4YmM1M2U3Ng==
4
+ YzI0NGMwM2VlMDE4OWU1NzkzN2ZkZThlYTJiNTM4YjU1YjJiYmMzOQ==
5
5
  data.tar.gz: !binary |-
6
- ZWMxMzRkMWJhNmZlYmJkMTk4ODAzNjRhOTgxZGIxNWZhMjFkNjE0NQ==
6
+ Y2Q1ODc5M2MxZWJmNTIzODdkNGM5NzVhYmQzZjQ1OGE3MDM3YTkwNQ==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- MTgyNDczMDY4ZjY1YTE0Nzg2MmZjN2RlYzU1NzdhNjVjNzY1YzE0NjA1ZGNl
10
- OTNlMjQyODc1MGQyZGViMDA4MWFkN2ViNzRiM2ViODdiODYwY2ZiNTZhN2Vh
11
- ZGUxOTU0YzZkMGUxNWFmNmY2ZTBiOWY3YWQxODg5OWFmZWE1NmE=
9
+ N2Y0ZDI3YWQxMTlhNGQyNzRiNWI3NGI3NGIxODgxZjE0OTdkNjM5NTFlNjdk
10
+ YTI1MjM1MTc4ZDk0MDYyZThlM2FkNTc1M2QyYjg3MWUyZTlkYzA2N2VhODQ3
11
+ M2Q4N2U1YWEzMzZmNTQ1MDE1OWFlYmE1M2FlMzJhNGFkOTA2NGM=
12
12
  data.tar.gz: !binary |-
13
- N2JlYmYwOGJhYTlhYzY2YWI4ZDJkNzQ4MWY2OWE1NmE0YWVlMjllODZiNjEx
14
- ZTI0OTQyNjkxNDVjMTBiZjc3ZmFhZDYyMjllMzkwYmU4OTQzNTY3NDVkMjQ4
15
- MTJmNjM4ZThiOTQ4Mzk5MTliNTdmOGUxN2E5OTcxMzBiOTgyODQ=
13
+ MTE3ZWQyMTA4M2RjMDgxY2E3ZGM5MjhlZDA3NmE4MWFmZjk2NDQ5MzdjNjNm
14
+ YzU5NmYxNjFkMzRlYmE3OWE0NWVhNDQ4MjA3M2ZiYzRkMzk4NDAzODI4MTE0
15
+ NThmYThmNmUyNjY0ODI4NzgxMDUzNDQzZWFhZDZkODNlYTI5MjU=
data/README.md CHANGED
@@ -4,24 +4,81 @@ NAME
4
4
  ro
5
5
 
6
6
 
7
- SYNOPSIS
7
+ TL;DR
8
8
  --------
9
9
 
10
- RTFC
10
+ <pre>
11
+
12
+ ro
13
+ ├── people
14
+ │   ├── ara
15
+ │   │   ├── assets
16
+ │   │   │   ├── ara-glacier.jpg
17
+ │   │   │   └── source
18
+ │   │   │   └── a.rb
19
+ │   │   ├── attributes.yml
20
+ │   │   └── bio.md.erb
21
+ │   └── noah
22
+ │   └── attributes.yml
23
+ └── posts
24
+ ├── foobar
25
+ ├── hello-world
26
+ │   ├── attributes.yml
27
+ │   └── body.md
28
+ └── second-awesome-post
29
+ ├── attributes.yml
30
+ └── body.md
31
+
32
+ </pre>
33
+
34
+
35
+ ```ruby
36
+
37
+ ro.people #=> all people nodes
38
+ ro[:people] #=> same thing
39
+
40
+ ro.people.ara #=> data for the person named 'ara'
41
+ ro[:people][:ara] #=> same thing
42
+
43
+
44
+ ro.people.ara.first_name #=> give you *one* guess ;-) !
11
45
 
46
+ ro.people.ara.url_for('ara-glacier.jpg') #=> external, timestamped, url for this asset
47
+
48
+ ro.people.ara.source('a.rb') #=> syntax highlighted source yo!
49
+
50
+ ro.posts.find('second-awesome-post').body #=> html-z yo
51
+
52
+
53
+ ```
54
+
55
+ ```bash
56
+
57
+ ### CHECK IT OUT!
58
+
59
+ ~ > git clone https://github.com/ahoward/ro.git
60
+ ~ > cd ro
61
+ ~> ./bin/ro console
62
+
63
+ ```
12
64
 
13
65
  DESCRIPTION
14
66
  -----------
15
67
 
16
68
  ro is library for managing your site's content in git, as god intended.
17
69
 
18
- more details coming soon...
70
+ it features:
71
+
72
+ - super fast loading via a robust caching/promise strategy
73
+ - *all* teh templates supported via tilt (https://github.com/rtomayko/tilt)
74
+ - the awesomest markdown ever, with syntax highlighting and even erb evaluation
75
+ - an awesome command line tool for introspecting your data (./ro console)
19
76
 
20
77
 
21
78
  INSTALL
22
79
  -------
23
80
 
24
- gem install ro (coming soon)
81
+ gem install ro
25
82
 
26
83
 
27
84
  DOCS
data/bin/ro ADDED
@@ -0,0 +1,92 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ Main {
4
+
5
+ option('--root', '-r'){
6
+ argument :required
7
+ }
8
+
9
+ mode(:console){
10
+ def run
11
+ if params['root'].given?
12
+ Ro.root = params['root'].value
13
+ end
14
+
15
+ basename = File.basename(Ro.root)
16
+
17
+ ARGV.clear
18
+ require 'irb'
19
+
20
+ Kernel.module_eval do
21
+ def reload!
22
+ Object.send(:remove_const, :Ro)
23
+ load "#{ $libdir }/ro.rb"
24
+ "#{ $libdir }/ro.rb"
25
+ end
26
+ end
27
+
28
+ $HACK = IRB.method(:load_modules)
29
+
30
+ def IRB.load_modules
31
+ $HACK.call()
32
+
33
+ basename = File.basename(Ro.root)
34
+
35
+ IRB.conf[:PROMPT][:RO] = {
36
+ :PROMPT_I=>"Ro(./#{ basename }):%03n:%i> ",
37
+ :PROMPT_N=>"Ro(./#{ basename }):%03n:%i> ",
38
+ :PROMPT_S=>"Ro(./#{ basename }):%03n:%i%l ",
39
+ :PROMPT_C=>"Ro(./#{ basename }):%03n:%i* ",
40
+ :RETURN=>"=> %s\n"
41
+ }
42
+
43
+ IRB.conf[:PROMPT_MODE] = :RO
44
+ IRB.conf[:AUTO_INDENT] = true
45
+ end
46
+
47
+
48
+ ::IRB.start
49
+ end
50
+
51
+ =begin
52
+ module Console
53
+ def reload!
54
+ Object.send(:remove_const, :Ro)
55
+ load "#{ $libdir }/ro.rb"
56
+ "#{ $libdir }/ro.rb"
57
+ end
58
+ end
59
+ =end
60
+
61
+ class Console < Ro::BlankSlate
62
+ def initialize(nodes)
63
+ @nodes = nodes
64
+ end
65
+
66
+ def binding
67
+ Kernel.binding
68
+ end
69
+
70
+ def reload!
71
+ Object.send(:remove_const, :Ro)
72
+ load "#{ $libdir }/ro.rb"
73
+ "#{ $libdir }/ro.rb"
74
+ end
75
+
76
+ def method_missing(method, *args, &block)
77
+ @nodes.send(method, *args, &block)
78
+ end
79
+ end
80
+ }
81
+
82
+ }
83
+
84
+ BEGIN {
85
+ require 'main'
86
+
87
+ $bindir = File.dirname(__FILE__)
88
+ $libdir = File.expand_path("#{ $bindir }/../lib/")
89
+
90
+ require "#{ $libdir }/ro.rb"
91
+ }
92
+
data/lib/ro.rb CHANGED
@@ -5,10 +5,12 @@
5
5
  require 'yaml'
6
6
  require 'digest/md5'
7
7
  require 'logger'
8
+ require 'erb'
9
+ require 'cgi'
8
10
 
9
11
  #
10
12
  module Ro
11
- Version = '1.0.0' unless defined?(Version)
13
+ Version = '1.1.0' unless defined?(Version)
12
14
 
13
15
  def version
14
16
  Ro::Version
@@ -82,13 +84,15 @@
82
84
  Root.new(
83
85
  case
84
86
  when defined?(Rails.root)
85
- Rails.root.to_s
87
+ root = Rails.root.to_s
88
+ File.join(root, 'public', 'ro')
86
89
 
87
90
  when defined?(Middleman::Application)
88
- Middleman::Application.server.root.to_s
91
+ root = Middleman::Application.server.root.to_s
92
+ File.join(root, 'source', 'ro')
89
93
 
90
94
  else
91
- "./ro"
95
+ ENV['RO_ROOT'] || "./ro"
92
96
  end
93
97
  )
94
98
  }
@@ -101,6 +105,14 @@
101
105
  nil
102
106
  }
103
107
 
108
+ Fattr(:mount){
109
+ '/ro'
110
+ }
111
+
112
+ Fattr(:asset_host){
113
+ nil
114
+ }
115
+
104
116
  def Ro.nodes(*args, &block)
105
117
  root.nodes(*args, &block)
106
118
  end
@@ -108,7 +120,7 @@
108
120
  def Ro.relative_path(path, *args)
109
121
  options = Map.options_for!(args)
110
122
  path = File.expand_path(String(path))
111
- relative = File.expand_path(String(args.shift || options[:relative] || options[:to]))
123
+ relative = File.expand_path(String(args.shift || options[:relative] || options[:to]) || options[:from])
112
124
  Pathname.new(path).relative_path_from(Pathname.new(relative)).to_s
113
125
  end
114
126
 
@@ -154,6 +166,83 @@
154
166
  args.push(options)
155
167
  Slug.for(*args, &block)
156
168
  end
169
+
170
+ def Ro.erb(content, node = nil)
171
+ binding =
172
+ case node
173
+ when Binding
174
+ node
175
+ when Node
176
+ node._binding
177
+ when nil
178
+ nil
179
+ else
180
+ instance_eval{ Kernel.binding }
181
+ end
182
+
183
+ ERB.new(content.to_s).result(binding)
184
+ end
185
+
186
+ def Ro.render(*args, &block)
187
+ Template.render(*args, &block)
188
+ end
189
+
190
+ def Ro.render_source(*args, &block)
191
+ Template.render_source(*args, &block)
192
+ end
193
+
194
+ def Ro.paths_for(*args)
195
+ path = args.flatten.compact.join('/')
196
+ path.gsub!(%r|[.]+/|, '/')
197
+ path.squeeze!('/')
198
+ path.sub!(%r|^/|, '')
199
+ path.sub!(%r|/$|, '')
200
+ paths = path.split('/')
201
+ end
202
+
203
+ def Ro.absolute_path_for(*args)
204
+ path = ('/' + paths_for(*args).join('/')).squeeze('/')
205
+ path unless path.empty?
206
+ end
207
+
208
+ def Ro.relative_path_for(*args)
209
+ path = absolute_path_for(*args).sub(%r{^/+}, '')
210
+ path unless path.empty?
211
+ end
212
+
213
+ def Ro.normalize_path(arg, *args)
214
+ absolute_path_for(arg, *args)
215
+ end
216
+
217
+ def Ro.query_string_for(hash, options = {})
218
+ options = Map.for(options)
219
+ escape = options.has_key?(:escape) ? options[:escape] : true
220
+ pairs = []
221
+ esc = escape ? proc{|v| CGI.escape(v.to_s)} : proc{|v| v.to_s}
222
+ hash.each do |key, values|
223
+ key = key.to_s
224
+ values = [values].flatten
225
+ values.each do |value|
226
+ value = value.to_s
227
+ if value.empty?
228
+ pairs << [ esc[key] ]
229
+ else
230
+ pairs << [ esc[key], esc[value] ].join('=')
231
+ end
232
+ end
233
+ end
234
+ pairs.replace pairs.sort_by{|pair| pair.size}
235
+ pairs.join('&')
236
+ end
237
+
238
+ def Ro.realpath(path)
239
+ begin
240
+ Pathname.new(path.to_s).expand_path.realpath.to_s
241
+ rescue Object
242
+ File.expand_path(path.to_s)
243
+ end
244
+ end
245
+
157
246
  end
158
247
 
159
248
  #
@@ -171,7 +260,6 @@
171
260
 
172
261
  slug.rb
173
262
  blankslate.rb
174
- util.rb
175
263
 
176
264
  root.rb
177
265
 
@@ -12,8 +12,8 @@ module Ro
12
12
  @type = File.basename(File.dirname(@path))
13
13
  @root = Ro::Root.new(File.dirname(File.dirname(@path)))
14
14
  @loaded = false
15
- @attributes = nil
16
- @in_method_missing = false
15
+ @loading = false
16
+ @attributes = Map.new
17
17
  end
18
18
 
19
19
  def id
@@ -25,30 +25,104 @@ module Ro
25
25
  end
26
26
 
27
27
  def inspect
28
- #"#{ self.class.name }(#{ type }/#{ name })"
29
28
  identifier
30
29
  end
31
30
 
32
31
  def to_s
33
- inpsect
32
+ inspect
34
33
  end
35
34
 
36
35
  def basename
37
36
  name
38
37
  end
39
38
 
39
+ def node
40
+ self
41
+ end
42
+
43
+ def get(*args)
44
+ attributes.get(*args)
45
+ end
46
+
47
+ def [](*args)
48
+ attributes.get(*args)
49
+ end
50
+
51
+ def asset_path(*args, &block)
52
+ File.join(relative_path, 'assets')
53
+ end
54
+
55
+ def url_for(*args, &block)
56
+ options = Map.options_for!(args)
57
+
58
+ cache_buster = options.delete('_') != false
59
+
60
+ path_info = Ro.relative_path_for(args)
61
+
62
+ path = File.join(@path.to_s, 'assets', path_info)
63
+
64
+ globs =
65
+ [
66
+ File.join(@path.to_s, 'assets', "#{ path_info }"),
67
+ File.join(@path.to_s, 'assets', "#{ path_info }*"),
68
+ File.join(@path.to_s, 'assets', "**/#{ path_info }")
69
+ ]
70
+
71
+ candidates = globs.map{|glob| Dir.glob(glob)}.flatten.compact.uniq
72
+
73
+ case candidates.size
74
+ when 0
75
+ raise ArgumentError.new("no asset matching #{ globs.inspect }")
76
+ when 1
77
+ path = candidates.first
78
+
79
+ path_info = path.gsub(/^#{ Regexp.escape(Ro.root) }/, '')
80
+
81
+ if cache_buster
82
+ timestamp = File.stat(path).mtime.to_i
83
+ options['_'] = timestamp
84
+ end
85
+ else
86
+ raise ArgumentError.new("too many assets (#{ candidates.inspect }) matching #{ globs.inspect }")
87
+ end
88
+
89
+ url = File.join(Ro.mount, path_info)
90
+
91
+ if options.empty?
92
+ url
93
+ else
94
+ query_string = Ro.query_string_for(options)
95
+ "#{ url }?#{ query_string }"
96
+ end
97
+ end
98
+
99
+ def source_for(*args)
100
+ key = Ro.relative_path_for(:assets, :source, args).split('/')
101
+ get(key)
102
+ end
103
+
104
+ def mount(*args)
105
+ path_info = Ro.absolute_path_for(Ro.mount, relative_path)
106
+ [Ro.asset_host, path_info].compact.join('/')
107
+ end
108
+
109
+ def relative_path
110
+ re = /^#{ Regexp.escape(Ro.root) }/
111
+ @path.to_s.gsub(re, '')
112
+ end
113
+
40
114
  def method_missing(method, *args, &block)
41
- Ro.log "Ro::Node(#{ identifier })#method_missing(#{ method.inspect }, #{ args.inspect })"
115
+ super if method.to_s == 'to_ary'
42
116
 
43
- in_method_missing = !!@in_method_missing
117
+ Ro.log "Ro::Node(#{ identifier })#method_missing(#{ method.inspect }, #{ args.inspect })"
44
118
 
45
- return super if in_method_missing
119
+ key = method.to_s
46
120
 
47
- @in_method_missing = true
121
+ if @attributes.has_key?(key)
122
+ return @attributes[key]
123
+ end
48
124
 
49
125
  _load do
50
- key = method.to_s
51
-
52
126
  return(
53
127
  if @attributes.has_key?(key)
54
128
  @attributes[key]
@@ -57,14 +131,12 @@ module Ro
57
131
  end
58
132
  )
59
133
  end
60
- ensure
61
- @in_method_missing = in_method_missing
62
134
  end
63
135
 
64
136
  def attributes
65
137
  _load{ @attributes }
66
138
  end
67
-
139
+
68
140
  def instance_eval(*args, &block)
69
141
  _load{ super }
70
142
  end
@@ -108,43 +180,15 @@ module Ro
108
180
  }
109
181
  end
110
182
 
111
- class Related
112
- fattr :attributes
113
-
114
- def initialize(attributes)
115
- @attributes = attributes
116
- end
117
-
118
- def all
119
- related = @attributes.get(:related) || Map.new
120
- names = related.keys
121
- self[names]
122
- end
123
-
124
- def [](name)
125
- name = File.basename(name.to_s)
126
-
127
- value = @attributes.get(:related, name)
128
-
129
- type, names =
130
- case value
131
- when Hash
132
- value.to_a.first
133
- else
134
- [name, value]
135
- end
136
-
137
- names = Array(names).flatten.compact.uniq
138
-
139
- list = ro[type]
140
-
141
- list.where(*names)
142
- end
143
- end
144
-
145
183
  def _load(&block)
146
184
  unless @loaded
185
+ if @loading
186
+ return(block ? block.call : :loading)
187
+ end
188
+
189
+ @loading = true
147
190
  @loaded = _load_from_cache_or_disk
191
+ @loading = false
148
192
  end
149
193
 
150
194
  block ? block.call : @loaded
@@ -157,16 +201,23 @@ module Ro
157
201
 
158
202
  if cached
159
203
  Ro.log "loading #{ identifier } from cache"
204
+
160
205
  @attributes = Map.new.update(cached)
161
- :cache
206
+
207
+ return :cache
162
208
  else
163
209
  Ro.log "loading #{ identifier } from disk"
210
+
164
211
  @attributes = Map.new
212
+
165
213
  _load_attributes_yml
166
- #_load_attribute_templates
167
- #_load_sources
214
+ _load_attribute_files
215
+ _load_sources
216
+ _load_urls
217
+
168
218
  Ro.cache.write(cache_key, @attributes)
169
- :disk
219
+
220
+ return :disk
170
221
  end
171
222
  end
172
223
 
@@ -175,10 +226,73 @@ module Ro
175
226
  buf = IO.binread(_attributes_yml)
176
227
  data = YAML.load(buf)
177
228
  data = data.is_a?(Hash) ? data : {'_' => data}
229
+
178
230
  @attributes.update(data)
231
+
232
+ %w( assets ).each do |key|
233
+ raise ArgumentError.new("attributes.yml may not contain the key '#{ key }'") if @attributes.has_key?(key)
234
+ end
235
+
236
+ @attributes
237
+ end
238
+ end
239
+
240
+ def _load_attribute_files
241
+ glob = File.join(@path, '*')
242
+ node = self
243
+
244
+ Dir.glob(glob) do |path|
245
+ next if test(?d, path)
246
+
247
+ basename = File.basename(path)
248
+ key, ext = basename.split('.', 2)
249
+
250
+ next if basename == 'attributes.yml'
251
+
252
+ value = Ro.render(path, node)
253
+ @attributes.set(key => value)
254
+ end
255
+ end
256
+
257
+ def _load_sources
258
+ glob = File.join(@path, 'assets/source/*')
259
+ node = self
260
+
261
+ Dir.glob(glob) do |path|
262
+ next if test(?d, path)
263
+
264
+ basename = File.basename(path)
265
+ key, ext = basename.split('.', 2)
266
+
267
+ next if basename == 'attributes.yml'
268
+
269
+ value = Ro.render_source(path, node)
270
+ @attributes.set([:assets, :source, basename] => value)
179
271
  end
180
272
  end
181
273
 
274
+ def _load_urls
275
+ glob = File.join(@path, 'assets/**/**')
276
+ node = self
277
+
278
+ Dir.glob(glob) do |path|
279
+ next if test(?d, path)
280
+
281
+ relative_path = Ro.relative_path(path, :to => "#{ @path }/assets")
282
+
283
+ url = url_for(relative_path)
284
+ key = relative_path.split('/')
285
+
286
+ key.unshift('urls')
287
+
288
+ @attributes.set(key => url)
289
+ end
290
+ end
291
+
292
+ def _binding
293
+ Kernel.binding
294
+ end
295
+
182
296
  def _cache_key
183
297
  glob = File.join(@path, '**/**')
184
298
 
@@ -106,13 +106,7 @@ module Ro
106
106
  def method_missing(method, *args, &block)
107
107
  Ro.log "Ro::List(#{ identifier })#method_missing(#{ method.inspect }, #{ args.inspect })"
108
108
 
109
- in_method_missing = !!@in_method_missing
110
-
111
- return super if in_method_missing
112
-
113
- @in_method_missing = true
114
-
115
- if @scope.nil?
109
+ if @type.nil?
116
110
  type = method.to_s
117
111
  list = self[type]
118
112
  super unless list
@@ -122,8 +116,14 @@ module Ro
122
116
  node = self[name]
123
117
  node.nil? ? super : node
124
118
  end
125
- ensure
126
- @in_method_missing = in_method_missing
119
+ end
120
+
121
+ def binding
122
+ Kernel.binding
123
+ end
124
+
125
+ def _binding
126
+ Kernel.binding
127
127
  end
128
128
  end
129
129
  end
@@ -1,10 +1,10 @@
1
1
  module Ro
2
2
  class Root < ::String
3
3
  def initialize(root)
4
- super(Util.realpath(root.to_s))
4
+ super(Ro.realpath(root.to_s))
5
5
  ensure
6
6
  raise ArgumentError.new("root=#{ root.inspect }") if root.nil?
7
- raise ArgumentError.new("root=#{ root.inpsect }") unless test(?d, root)
7
+ raise ArgumentError.new("root=#{ root.inspect }") unless test(?d, root)
8
8
  end
9
9
 
10
10
  def root
@@ -1,5 +1,61 @@
1
1
  module Ro
2
2
  class Template
3
+ def Template.render(path, node = nil)
4
+ parts = File.basename(path).split('.')
5
+ base = parts.shift
6
+ exts = parts.reverse
7
+
8
+ content = IO.binread(path).force_encoding('utf-8')
9
+
10
+ loop do
11
+ break if exts.empty?
12
+ ext = exts.shift
13
+
14
+ case ext.to_s.downcase
15
+ when 'erb', 'eruby'
16
+ content = Ro.erb(content, node)
17
+ when 'yml'
18
+ content = YAML.load(content)
19
+ else
20
+ tilt = Tilt[ext].new{ content }
21
+ content = tilt.render(node)
22
+ end
23
+ end
24
+
25
+ content
26
+ end
27
+
28
+ def Template.render_source(path, node = nil)
29
+ parts = File.basename(path).split('.')
30
+ base = parts.shift
31
+ exts = parts.reverse
32
+
33
+ content = IO.binread(path).force_encoding('utf-8')
34
+
35
+ loop do
36
+ break if exts.empty?
37
+ ext = exts.shift
38
+
39
+ if exts.empty?
40
+ code = content
41
+ language = ext
42
+ content = ::Pygments.highlight(code, :lexer => language, :options => {:encoding => 'utf-8'})
43
+ else
44
+ case ext.to_s.downcase
45
+ when 'erb', 'eruby'
46
+ content = Ro.erb(content, node)
47
+ when 'yml'
48
+ content = YAML.load(content)
49
+ else
50
+ tilt = Tilt[ext].new{ content }
51
+ content = tilt.render(node)
52
+ end
53
+ end
54
+ end
55
+
56
+ content
57
+ end
58
+
3
59
  fattr :path
4
60
 
5
61
  def initialize(path)
@@ -1,17 +1,27 @@
1
1
  todo:
2
- - need source file loading
2
+ - helper/model extension
3
3
 
4
- - need asset/url_for management
4
+ Ro.helper(:posts) do
5
+ end
5
6
 
6
- - ./bin/ro shell
7
- - binding of all nodes?
7
+ Ro.model(:posts) do
8
+ end
8
9
 
9
- - a real live test suite
10
+ Post = Ro.model(:posts)
10
11
 
12
+ Post.class_eval do
13
+ end
11
14
 
15
+ - a real live test suite
12
16
 
13
17
 
14
18
  done:
19
+ - load all asset urls
20
+ - asset loading and url generation
21
+ - ./bin/ro shell
22
+ - binding of all nodes?
23
+ - need source file loading
24
+ - attribute templates
15
25
  - need relationships
16
26
  - ro.posts.related
17
27
  - ro.posts.related.tags
data/ro.gemspec CHANGED
@@ -3,7 +3,7 @@
3
3
 
4
4
  Gem::Specification::new do |spec|
5
5
  spec.name = "ro"
6
- spec.version = "1.0.0"
6
+ spec.version = "1.1.0"
7
7
  spec.platform = Gem::Platform::RUBY
8
8
  spec.summary = "ro"
9
9
  spec.description = "description: ro kicks the ass"
@@ -15,6 +15,8 @@ Gem::Specification::new do |spec|
15
15
  "=p",
16
16
  "README.md",
17
17
  "Rakefile",
18
+ "bin",
19
+ "bin/ro",
18
20
  "lib",
19
21
  "lib/co",
20
22
  "lib/co/db.rb",
@@ -28,9 +30,7 @@ Gem::Specification::new do |spec|
28
30
  "lib/ro/blankslate.rb",
29
31
  "lib/ro/cache.rb",
30
32
  "lib/ro/db",
31
- "lib/ro/db.rb",
32
33
  "lib/ro/db/collection",
33
- "lib/ro/db/collection.rb",
34
34
  "lib/ro/initializers",
35
35
  "lib/ro/initializers/env.rb",
36
36
  "lib/ro/initializers/tilt.rb",
@@ -40,20 +40,29 @@ Gem::Specification::new do |spec|
40
40
  "lib/ro/root.rb",
41
41
  "lib/ro/slug.rb",
42
42
  "lib/ro/template.rb",
43
- "lib/ro/util.rb",
44
43
  "notes",
45
44
  "notes/ara.txt",
46
45
  "ro",
47
46
  "ro.gemspec",
48
47
  "ro/people",
49
48
  "ro/people/ara",
49
+ "ro/people/ara/assets",
50
+ "ro/people/ara/assets/ara-glacier.jpg",
51
+ "ro/people/ara/assets/source",
52
+ "ro/people/ara/assets/source/a.rb",
50
53
  "ro/people/ara/attributes.yml",
54
+ "ro/people/ara/bio.md.erb",
55
+ "ro/people/noah",
56
+ "ro/people/noah/attributes.yml",
51
57
  "ro/posts",
52
- "ro/posts/foobar",
53
58
  "ro/posts/hello-world",
54
- "ro/posts/hello-world/attributes.yml"]
59
+ "ro/posts/hello-world/attributes.yml",
60
+ "ro/posts/hello-world/body.md",
61
+ "ro/posts/second-awesome-post",
62
+ "ro/posts/second-awesome-post/attributes.yml",
63
+ "ro/posts/second-awesome-post/body.md"]
55
64
 
56
- spec.executables = []
65
+ spec.executables = ["ro"]
57
66
 
58
67
  spec.require_path = "lib"
59
68
 
@@ -0,0 +1,5 @@
1
+ class C
2
+ @x = 42
3
+
4
+ A = 42.0
5
+ end
@@ -2,10 +2,11 @@ first_name: Ara
2
2
 
3
3
  last_name: Howard
4
4
 
5
+
5
6
  related:
6
7
  posts:
7
8
  - hello-world
8
9
 
9
- sample_posts:
10
+ featured_posts:
10
11
  posts:
11
- - hello-world
12
+ - second-awesome-post
@@ -0,0 +1,18 @@
1
+ * one
2
+ * two
3
+ * three
4
+
5
+
6
+ pretty syntax highlighting
7
+
8
+
9
+ ```ruby
10
+
11
+ @a = 42
12
+
13
+
14
+ ```
15
+
16
+ <%= first_name %>
17
+
18
+ <%= url_for('ara-glacier') %>
@@ -0,0 +1,5 @@
1
+
2
+ first_name: Noah
3
+
4
+ last_name: Larson
5
+
@@ -0,0 +1,3 @@
1
+ * we
2
+ * use
3
+ * markdown because it is _awesome_
@@ -0,0 +1 @@
1
+ title: Secondu
@@ -0,0 +1,3 @@
1
+ and this my friend
2
+
3
+ is just _awesome_
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ro
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ara T. Howard
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-10-28 00:00:00.000000000 Z
11
+ date: 2013-10-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: map
@@ -96,7 +96,8 @@ dependencies:
96
96
  version: 2.1.0
97
97
  description: ! 'description: ro kicks the ass'
98
98
  email: ara.t.howard@gmail.com
99
- executables: []
99
+ executables:
100
+ - ro
100
101
  extensions: []
101
102
  extra_rdoc_files: []
102
103
  files:
@@ -104,6 +105,7 @@ files:
104
105
  - ':w'
105
106
  - README.md
106
107
  - Rakefile
108
+ - bin/ro
107
109
  - lib/co/db.rb
108
110
  - lib/co/node.rb
109
111
  - lib/co/node/list.rb
@@ -111,8 +113,6 @@ files:
111
113
  - lib/ro.rb
112
114
  - lib/ro/blankslate.rb
113
115
  - lib/ro/cache.rb
114
- - lib/ro/db.rb
115
- - lib/ro/db/collection.rb
116
116
  - lib/ro/initializers/env.rb
117
117
  - lib/ro/initializers/tilt.rb
118
118
  - lib/ro/node.rb
@@ -120,12 +120,17 @@ files:
120
120
  - lib/ro/root.rb
121
121
  - lib/ro/slug.rb
122
122
  - lib/ro/template.rb
123
- - lib/ro/util.rb
124
123
  - notes/ara.txt
125
124
  - ro.gemspec
125
+ - ro/people/ara/assets/ara-glacier.jpg
126
+ - ro/people/ara/assets/source/a.rb
126
127
  - ro/people/ara/attributes.yml
127
- - ro/posts/foobar
128
+ - ro/people/ara/bio.md.erb
129
+ - ro/people/noah/attributes.yml
128
130
  - ro/posts/hello-world/attributes.yml
131
+ - ro/posts/hello-world/body.md
132
+ - ro/posts/second-awesome-post/attributes.yml
133
+ - ro/posts/second-awesome-post/body.md
129
134
  homepage: https://github.com/ahoward/ro
130
135
  licenses:
131
136
  - Same As Ruby's
@@ -1,29 +0,0 @@
1
- module Ro
2
- class Db
3
- fattr :root
4
-
5
- def initialize(*args, &block)
6
- options = Map.options_for!(args)
7
-
8
- @root = String(args.shift || options[:root] || Ro.root)
9
- end
10
-
11
- def collections
12
- @collections ||= Collection::List.new
13
-
14
- Dir.glob(glob){|path| @collections.add(path)}
15
-
16
- @collections
17
- end
18
-
19
- def glob
20
- File.join(root, '*')
21
- end
22
-
23
- def nodes(*args, &block)
24
- collections.map do |collection|
25
- collection.nodes(*args, &block)
26
- end.flatten
27
- end
28
- end
29
- end
@@ -1,46 +0,0 @@
1
- module Ro
2
- class Db
3
- class Collection
4
- class List < ::Array
5
- def add(path)
6
- name = File.basename(path.to_s)
7
-
8
- unless any?{|c| c.name == name }
9
- collection = Collection.new(path)
10
- push(collection)
11
- sort!{|a,b| a.name <=> b.name}
12
- end
13
- end
14
- end
15
-
16
- fattr :path
17
-
18
- def initialize(path)
19
- @path = Util.realpath(path)
20
- end
21
-
22
- def basename
23
- File.basename(@path)
24
- end
25
-
26
- def name
27
- basename
28
- end
29
-
30
- def dirname
31
- File.dirname(@path)
32
- end
33
-
34
- def glob
35
- File.join(@path, '*')
36
- end
37
-
38
- def nodes
39
- Dir.glob(glob).map do |path|
40
- next unless test(?d, path)
41
- Ro::Node.new(path)
42
- end
43
- end
44
- end
45
- end
46
- end
@@ -1,13 +0,0 @@
1
- module Ro
2
- module Util
3
- def realpath(path)
4
- begin
5
- Pathname.new(path.to_s).expand_path.realpath.to_s
6
- rescue Object
7
- File.expand_path(path.to_s)
8
- end
9
- end
10
-
11
- extend(self)
12
- end
13
- end
File without changes