flora 0.10.0 → 0.12.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f445572c3d4330b5d1e8f3d6ce42ef45cd11053e17cceee1cbcd0d8860430d2b
4
- data.tar.gz: a02c49517eed09e56f8fcba6586646f4b566d78405fe78b61157c75aec8feb53
3
+ metadata.gz: a11f85e869328faff7d9244556f4b6c27ea30460c1ecbb9a691737d10f24daaa
4
+ data.tar.gz: 7a43d4c8821ce2e8d6899cdae404bb47a1db66c54032ac5cbc123e18cee394af
5
5
  SHA512:
6
- metadata.gz: 41e4980576a56a14e468b8d63bcf5cc344ca5ae54525c3676f8ec3a08d5049803fd22848cf0bd9b2472da3f87f2b587fc1773833c96d6d9ca3e0cf0070295469
7
- data.tar.gz: 55f9466b3b93a5d39021403f9874b65cca0250dc47e68d353de8da7569edd71da9e9883c9b8268206cb3a01563bef161d246792410eb0781e76713e7ac0f8a59
6
+ metadata.gz: fc3287be925560cb0ee03df33c04d8cb2de6a811345dc75385359afa94236a5500cac5c5a969b50bfb66b44117d4266e986fd86f624d84e38a83c995ffa503f0
7
+ data.tar.gz: 4eae0b7459aad9100e813ab916be76ef9c7c0aac7d814ac9524e358a98a06a6fb83f4e869f1bfccca426c2af3c3376cc405d93e3a8fe55950054b5f3a2992dd2
data/lib/flora/app.rb CHANGED
@@ -12,14 +12,15 @@ class Flora::App
12
12
  @app = app
13
13
  @dir = Pathname.new(dir)
14
14
  @flora = flora
15
- @last_built = Time.at(0)
15
+ @@last_built ||= Time.at(0)
16
16
  end
17
17
 
18
18
 
19
19
  def call(env)
20
20
  if should_rebuild?
21
+ @flora.reload_project
21
22
  @flora.build(OUT_DIR)
22
- @last_built = Time.now.utc
23
+ @@last_built = Time.now.utc
23
24
  # TODO: also trigger a reload in the browser
24
25
  end
25
26
 
@@ -33,7 +34,7 @@ class Flora::App
33
34
  # TODO: this is probably slow. I'm sure there's an easier kqueue-esq way
34
35
  # of doing this.
35
36
  @dir.find do |file|
36
- return true if file.stat.mtime > @last_built
37
+ return true if file.stat.mtime > @@last_built
37
38
  end
38
39
 
39
40
  false
@@ -42,22 +43,6 @@ class Flora::App
42
43
  end
43
44
 
44
45
 
45
- class Reloader
46
-
47
- def initialize(app, flora)
48
- @app = app
49
- @flora = flora
50
- end
51
-
52
- def call(env)
53
- @flora.reload_project
54
-
55
- @app.call(env)
56
- end
57
-
58
- end
59
-
60
-
61
46
  # UGLY. Is there a better way to do this?
62
47
  class StaticWithoutHtml
63
48
 
@@ -84,7 +69,6 @@ class Flora::App
84
69
 
85
70
  Rack::Builder.new do
86
71
  use Rebuilder, path, flora
87
- use Reloader, flora
88
72
  use StaticWithoutHtml, OUT_DIR
89
73
  use Rack::Static, urls: [''], root: OUT_DIR, index: 'index.html'
90
74
 
data/lib/flora/config.rb CHANGED
@@ -14,7 +14,7 @@ class Flora::Config
14
14
 
15
15
 
16
16
  def extend_view(mod)
17
- Kernel.prepend(mod)
17
+ Kernel.include(mod)
18
18
  end
19
19
 
20
20
 
data/lib/flora/factory.rb CHANGED
@@ -1,9 +1,10 @@
1
1
  # Factories assemble Projects into Websites.
2
2
  class Flora::Factory
3
3
 
4
- def initialize(project, config)
4
+ def initialize(project, config, logger)
5
5
  @project = project
6
6
  @config = config
7
+ @logger = logger
7
8
  end
8
9
 
9
10
 
@@ -15,6 +16,8 @@ class Flora::Factory
15
16
  out_filename = out_dir.join(blueprint.page_name)
16
17
  FileUtils.mkdir_p(out_filename.dirname) unless out_filename.dirname.exist?
17
18
  out_filename.write(blueprint.render)
19
+
20
+ @logger.debug("[Flora] #{blueprint.file} => #{out_filename}")
18
21
  end
19
22
  end
20
23
 
@@ -18,7 +18,7 @@ class Flora::Plugins::Blog::Post
18
18
 
19
19
 
20
20
  def date
21
- @frontmatter['date']
21
+ @frontmatter['date'].to_time
22
22
  end
23
23
 
24
24
 
@@ -13,10 +13,67 @@ module Flora::Plugins::Blog
13
13
  @post = Post.new(file, project.dir)
14
14
  end
15
15
 
16
+ end
17
+
18
+
19
+ class Feed
20
+
21
+ def initialize(posts, config)
22
+ @posts = posts
23
+ @config = config
24
+ end
25
+
26
+
27
+ def render
28
+ builder = Nokogiri::XML::Builder.new do |xml|
29
+ xml.feed(xmlns: 'http://www.w3.org/2005/Atom') do
30
+ xml.generator('Flora')
31
+ nokogiri_tag(xml, :title, @config.blog[:title])
32
+ xml.updated(last_updated.iso8601)
33
+ nokogiri_tag(xml, :link, href: @config.blog[:url])
34
+ xml.id(@config.blog[:url])
35
+ xml.author do
36
+ xml.name(@config.blog[:author])
37
+ end
38
+
39
+ @posts.each { to_entry(xml, it) }
40
+ end
41
+ end
42
+
43
+ builder.to_xml
44
+ end
45
+
16
46
 
17
47
  private
18
48
 
19
- def render_tree
49
+ def full_url(post)
50
+ @config.blog[:url] + post.url
51
+ end
52
+
53
+
54
+ def last_updated
55
+ @posts[0].date
56
+ end
57
+
58
+
59
+ def to_entry(xml, post)
60
+ xml.entry do
61
+ xml.id(full_url(post))
62
+ nokogiri_tag(xml, :title, post.title)
63
+ # TODO: actually support published vs updated.
64
+ xml.updated(post.date.iso8601)
65
+ xml.published(post.date.iso8601)
66
+ nokogiri_tag(xml, :link, rel: 'alternate', href: full_url(post))
67
+ end
68
+ end
69
+
70
+
71
+
72
+ # Nokogiri's builder uses method_missing, and some of Lilac's tags are
73
+ # named the same as some of the Atom tags we want to use which causes
74
+ # conflicts. Use this method to get around that!
75
+ def nokogiri_tag(xml, tag, *args, **opts, &block)
76
+ xml.method_missing(tag, *args, **opts, &block)
20
77
  end
21
78
 
22
79
  end
@@ -39,4 +96,27 @@ module Flora::Plugins::Blog
39
96
 
40
97
  end
41
98
 
99
+
100
+ module FactoryMethods
101
+
102
+ def assemble(out_dir)
103
+ super
104
+
105
+ feed = Feed.new(@project.posts, @config)
106
+ out_dir.join('feed.xml').write(feed.render)
107
+ end
108
+
109
+ end
110
+
111
+
112
+ module Config
113
+
114
+ def self.included(base)
115
+ base.class_eval do
116
+ attr_accessor(:blog)
117
+ end
118
+ end
119
+
120
+ end
121
+
42
122
  end
data/lib/flora/project.rb CHANGED
@@ -14,14 +14,18 @@ class Flora::Project
14
14
  @dir = dir
15
15
  @loader = loader
16
16
  @config = config
17
+ @mutex = Mutex.new
17
18
 
18
19
  @blueprints = find_blueprints
19
20
  end
20
21
 
21
22
 
22
23
  def reload
23
- @loader.reload
24
- @blueprints = find_blueprints
24
+ # `flora serve` can sometimes hit this multiple times and cause errors.
25
+ @mutex.synchronize do
26
+ @loader.reload
27
+ @blueprints = find_blueprints
28
+ end
25
29
  end
26
30
 
27
31
 
@@ -46,8 +50,4 @@ class Flora::Project
46
50
  blueprints
47
51
  end
48
52
 
49
-
50
- def has_supporting_code?
51
- end
52
-
53
53
  end
data/lib/flora/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  class Flora
2
- VERSION = '0.10.0'
2
+ VERSION = '0.12.0'
3
3
  end
data/lib/flora.rb CHANGED
@@ -2,20 +2,26 @@ require 'zeitwerk'
2
2
  require 'nokogiri'
3
3
  require 'kramdown'
4
4
  require 'fileutils'
5
+ require 'logger'
5
6
 
6
7
  loader = Zeitwerk::Loader.for_gem(warn_on_extra_files: false)
7
8
  loader.setup
8
9
 
9
10
  class Flora
10
11
 
12
+ attr_writer(:logger)
13
+
14
+
11
15
  def initialize(dir)
12
16
  dir = Pathname.new(dir)
13
17
 
18
+ @logger = Logger.new(STDOUT, level: ENV['FLORA_LOG'] || 'info')
19
+
14
20
  # Inject Lilac into the Kernel so it's available everywhere. Just
15
21
  # instance_eval isn't enough because it'll be missing in lib/ code.
16
22
  #
17
23
  # TODO: is there a less disruptive way to do this?
18
- Kernel.prepend(Flora::Lilac)
24
+ Kernel.include(Flora::Lilac)
19
25
 
20
26
  # The classes that are pluggable get their own instances to avoid conflicting
21
27
  # with other instances of Flora in the same process. This is mostly for the
@@ -34,17 +40,23 @@ class Flora
34
40
 
35
41
  @config = @config_class.new(dir.join('_config.rb'), self)
36
42
  @project = @project_class.new(dir, @project_loader, @config)
37
- @factory = @factory_class.new(@project, @config)
43
+ @factory = @factory_class.new(@project, @config, @logger)
38
44
  end
39
45
 
40
46
 
41
47
  def build(out)
42
- @factory.assemble(Pathname.new(out))
48
+ duration = bench do
49
+ @factory.assemble(Pathname.new(out))
50
+ end
51
+ @logger.info("[Flora] Built project (#{duration}s)")
43
52
  end
44
53
 
45
54
 
46
55
  def reload_project
47
- @project.reload
56
+ duration = bench do
57
+ @project.reload
58
+ end
59
+ @logger.info("[Flora] Reloaded project (#{duration}s)")
48
60
  end
49
61
 
50
62
 
@@ -58,6 +70,15 @@ class Flora
58
70
  Flora::Project::Blueprint.include(mod::BlueprintMethods) if defined?(mod::BlueprintMethods)
59
71
  end
60
72
 
73
+
74
+ private
75
+
76
+ def bench
77
+ now = Time.now.utc
78
+ yield
79
+ Time.now.utc - now
80
+ end
81
+
61
82
  end
62
83
 
63
84
  # Built-in Blueprints need to be explicitly loaded or else they won't show up
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flora
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.0
4
+ version: 0.12.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nick Vladimiroff
@@ -121,6 +121,20 @@ dependencies:
121
121
  - - ">="
122
122
  - !ruby/object:Gem::Version
123
123
  version: '0'
124
+ - !ruby/object:Gem::Dependency
125
+ name: logger
126
+ requirement: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - ">="
129
+ - !ruby/object:Gem::Version
130
+ version: '0'
131
+ type: :runtime
132
+ prerelease: false
133
+ version_requirements: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ version: '0'
124
138
  email:
125
139
  - nickvladimiroff@hey.com
126
140
  executables: