bunto 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.markdown +59 -0
- data/bin/bunto +51 -0
- data/lib/bunto.rb +179 -0
- data/lib/bunto/cleaner.rb +105 -0
- data/lib/bunto/collection.rb +205 -0
- data/lib/bunto/command.rb +65 -0
- data/lib/bunto/commands/build.rb +77 -0
- data/lib/bunto/commands/clean.rb +42 -0
- data/lib/bunto/commands/doctor.rb +114 -0
- data/lib/bunto/commands/help.rb +31 -0
- data/lib/bunto/commands/new.rb +82 -0
- data/lib/bunto/commands/serve.rb +204 -0
- data/lib/bunto/commands/serve/servlet.rb +61 -0
- data/lib/bunto/configuration.rb +323 -0
- data/lib/bunto/converter.rb +48 -0
- data/lib/bunto/converters/identity.rb +21 -0
- data/lib/bunto/converters/markdown.rb +92 -0
- data/lib/bunto/converters/markdown/kramdown_parser.rb +117 -0
- data/lib/bunto/converters/markdown/rdiscount_parser.rb +33 -0
- data/lib/bunto/converters/markdown/redcarpet_parser.rb +102 -0
- data/lib/bunto/converters/smartypants.rb +34 -0
- data/lib/bunto/convertible.rb +297 -0
- data/lib/bunto/deprecator.rb +46 -0
- data/lib/bunto/document.rb +444 -0
- data/lib/bunto/drops/bunto_drop.rb +21 -0
- data/lib/bunto/drops/collection_drop.rb +22 -0
- data/lib/bunto/drops/document_drop.rb +27 -0
- data/lib/bunto/drops/drop.rb +176 -0
- data/lib/bunto/drops/site_drop.rb +38 -0
- data/lib/bunto/drops/unified_payload_drop.rb +25 -0
- data/lib/bunto/drops/url_drop.rb +83 -0
- data/lib/bunto/entry_filter.rb +72 -0
- data/lib/bunto/errors.rb +10 -0
- data/lib/bunto/excerpt.rb +127 -0
- data/lib/bunto/external.rb +59 -0
- data/lib/bunto/filters.rb +367 -0
- data/lib/bunto/frontmatter_defaults.rb +188 -0
- data/lib/bunto/generator.rb +3 -0
- data/lib/bunto/hooks.rb +101 -0
- data/lib/bunto/layout.rb +49 -0
- data/lib/bunto/liquid_extensions.rb +22 -0
- data/lib/bunto/liquid_renderer.rb +39 -0
- data/lib/bunto/liquid_renderer/file.rb +50 -0
- data/lib/bunto/liquid_renderer/table.rb +94 -0
- data/lib/bunto/log_adapter.rb +115 -0
- data/lib/bunto/mime.types +800 -0
- data/lib/bunto/page.rb +180 -0
- data/lib/bunto/plugin.rb +96 -0
- data/lib/bunto/plugin_manager.rb +95 -0
- data/lib/bunto/post.rb +329 -0
- data/lib/bunto/publisher.rb +21 -0
- data/lib/bunto/reader.rb +126 -0
- data/lib/bunto/readers/collection_reader.rb +20 -0
- data/lib/bunto/readers/data_reader.rb +69 -0
- data/lib/bunto/readers/layout_reader.rb +53 -0
- data/lib/bunto/readers/page_reader.rb +21 -0
- data/lib/bunto/readers/post_reader.rb +62 -0
- data/lib/bunto/readers/static_file_reader.rb +21 -0
- data/lib/bunto/regenerator.rb +175 -0
- data/lib/bunto/related_posts.rb +56 -0
- data/lib/bunto/renderer.rb +191 -0
- data/lib/bunto/site.rb +391 -0
- data/lib/bunto/static_file.rb +141 -0
- data/lib/bunto/stevenson.rb +58 -0
- data/lib/bunto/tags/highlight.rb +122 -0
- data/lib/bunto/tags/include.rb +190 -0
- data/lib/bunto/tags/post_url.rb +88 -0
- data/lib/bunto/url.rb +136 -0
- data/lib/bunto/utils.rb +287 -0
- data/lib/bunto/utils/ansi.rb +59 -0
- data/lib/bunto/utils/platforms.rb +30 -0
- data/lib/bunto/version.rb +3 -0
- data/lib/site_template/.gitignore +3 -0
- data/lib/site_template/_config.yml +21 -0
- data/lib/site_template/_includes/footer.html +38 -0
- data/lib/site_template/_includes/head.html +12 -0
- data/lib/site_template/_includes/header.html +27 -0
- data/lib/site_template/_includes/icon-github.html +1 -0
- data/lib/site_template/_includes/icon-github.svg +1 -0
- data/lib/site_template/_includes/icon-twitter.html +1 -0
- data/lib/site_template/_includes/icon-twitter.svg +1 -0
- data/lib/site_template/_layouts/default.html +20 -0
- data/lib/site_template/_layouts/page.html +14 -0
- data/lib/site_template/_layouts/post.html +15 -0
- data/lib/site_template/_posts/0000-00-00-welcome-to-bunto.markdown.erb +25 -0
- data/lib/site_template/_sass/_base.scss +206 -0
- data/lib/site_template/_sass/_layout.scss +242 -0
- data/lib/site_template/_sass/_syntax-highlighting.scss +71 -0
- data/lib/site_template/about.md +15 -0
- data/lib/site_template/css/main.scss +53 -0
- data/lib/site_template/feed.xml +30 -0
- data/lib/site_template/index.html +23 -0
- metadata +252 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: db4d93530a7eb0e73c615ce0699607440a4dfc3c
|
4
|
+
data.tar.gz: 3817cf82a033d008dad8a0438ddcf303a6d71c16
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b19c626c0e74905faddc592b4c6b832d77c2a65d14dafab7ebd81af6ae77763abf1790555c049685b25df402efb2ab7ab26e83c214755c960ff8395776ae7d57
|
7
|
+
data.tar.gz: aae78e9d6637ac07b5b12f5fa7bc508bf79ef4cc59ec24266b2de8b0cbb5295da8664c0e4dfee1475a2437b77fe73e4f9da0c5ae317310f32cca158ef7fbc6dd
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2014-present Suriyaa Kudo
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.markdown
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
# ![Bunto](https://cloud.githubusercontent.com/assets/5073946/9288138/f4335fee-4337-11e5-9a28-068900097035.png)
|
2
|
+
|
3
|
+
|
4
|
+
> **Bunto** is a Web Application Framework which can be used as a simple, static site generator for personal, project, or organization sites.
|
5
|
+
|
6
|
+
[![Gem Version](https://img.shields.io/gem/v/bunto.svg)][ruby-gems]
|
7
|
+
[![Build Status](https://travis-ci.org/bunto/bunto.svg?branch=ruby)][travis]
|
8
|
+
<!--
|
9
|
+
[![Test Coverage](https://codeclimate.com/github/bunto/bunto/badges/coverage.svg)][coverage]
|
10
|
+
[![Code Climate](https://codeclimate.com/github/bunto/bunto/badges/gpa.svg)][codeclimate]
|
11
|
+
[![Dependency Status](https://gemnasium.com/bunto/bunto.svg)][gemnasium]
|
12
|
+
[![Security](https://hakiri.io/github/bunto/bunto/ruby.svg)][hakiri]
|
13
|
+
-->
|
14
|
+
|
15
|
+
[ruby-gems]: https://rubygems.org/gems/bunto
|
16
|
+
<!--
|
17
|
+
[gemnasium]: https://gemnasium.com/bunto/bunto
|
18
|
+
[codeclimate]: https://codeclimate.com/github/bunto/bunto
|
19
|
+
[coverage]: https://codeclimate.com/github/bunto/bunto/coverage
|
20
|
+
[hakiri]: https://hakiri.io/github/bunto/bunto/ruby
|
21
|
+
-->
|
22
|
+
[travis]: https://travis-ci.org/bunto/bunto
|
23
|
+
|
24
|
+
By Suriyaa Kudo, Tom Preston-Werner and many [awesome contributors](https://github.com/bunto/bunto/graphs/contributors)!
|
25
|
+
|
26
|
+
Bunto is a Web Application Framework and can be used as a static site generator perfect for personal, project, or organization sites. Think of it like a file-based CMS, without all the complexity. Bunto takes your content, renders HTML and CSS templates, and spits out a complete, static website ready to be served by Apache, hostSE, Nginx or another web server. Bunto is the engine behind [GitHub Pages](http://pages.github.com), which you can use to host sites right from your GitHub repositories.
|
27
|
+
|
28
|
+
## Getting Started
|
29
|
+
|
30
|
+
* [Install](https://bunto.github.io/bunto/docs/installation/) the gem
|
31
|
+
* Read up about its [Usage](https://bunto.github.io/docs/usage/) and [Configuration](https://bunto.github.io/docs/configuration/)
|
32
|
+
* Take a gander at some existing [Sites](https://wiki.github.com/bunto/bunto/sites)
|
33
|
+
* Fork and [Contribute](https://bunto.github.io/docs/contributing/) your own modifications
|
34
|
+
* Have questions? Check out our official forum community [Bunto Talk](https://bunto.github.io/talk/) or [`#bunto` on irc.freenode.net](https://botbot.me/freenode/bunto/)
|
35
|
+
|
36
|
+
## Code of Conduct
|
37
|
+
|
38
|
+
In order to have a more open and welcoming community, Bunto adheres to a
|
39
|
+
[code of conduct](CONDUCT.md) adapted from the Ruby on Rails code of
|
40
|
+
conduct.
|
41
|
+
|
42
|
+
Please adhere to this code of conduct in any interactions you have in the
|
43
|
+
Bunto community. It is strictly enforced on all official Bunto
|
44
|
+
repositories, websites, and resources. If you encounter someone violating
|
45
|
+
these terms, please let a maintainer (@SuriyaaKudoIsc) know
|
46
|
+
and we will address it as soon as possible.
|
47
|
+
|
48
|
+
## Diving In
|
49
|
+
|
50
|
+
* [Migrate](http://bunto.github.io/import/docs/home/) from your previous system
|
51
|
+
* Learn how the [YAML Front Matter](https://bunto.github.io/docs/frontmatter/) works
|
52
|
+
* Put information on your site with [Variables](https://bunto.github.io/docs/variables/)
|
53
|
+
* Customize the [Permalinks](https://bunto.github.io/docs/permalinks/) your posts are generated with
|
54
|
+
* Use the built-in [Liquid Extensions](https://bunto.github.io/docs/templates/) to make your life easier
|
55
|
+
* Use custom [Plugins](https://bunto.github.io/docs/plugins/) to generate content specific to your site
|
56
|
+
|
57
|
+
## License
|
58
|
+
|
59
|
+
See [LICENSE](https://github.com/bunto/bunto/blob/master/LICENSE).
|
data/bin/bunto
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
STDOUT.sync = true
|
3
|
+
|
4
|
+
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), *%w( .. lib ))
|
5
|
+
|
6
|
+
require 'bunto'
|
7
|
+
require 'mercenary'
|
8
|
+
|
9
|
+
Bunto::PluginManager.require_from_bundler
|
10
|
+
|
11
|
+
Bunto::Deprecator.process(ARGV)
|
12
|
+
|
13
|
+
Mercenary.program(:bunto) do |p|
|
14
|
+
p.version Bunto::VERSION
|
15
|
+
p.description 'Bunto is a static site generator in Ruby'
|
16
|
+
p.syntax 'bunto <subcommand> [options]'
|
17
|
+
|
18
|
+
p.option 'source', '-s', '--source [DIR]', 'Source directory (defaults to ./)'
|
19
|
+
p.option 'destination', '-d', '--destination [DIR]', 'Destination directory (defaults to ./_site)'
|
20
|
+
p.option 'safe', '--safe', 'Safe mode (defaults to false)'
|
21
|
+
p.option 'plugins_dir', '-p', '--plugins PLUGINS_DIR1[,PLUGINS_DIR2[,...]]', Array, 'Plugins directory (defaults to ./_plugins)'
|
22
|
+
p.option 'layouts_dir', '--layouts DIR', String, 'Layouts directory (defaults to ./_layouts)'
|
23
|
+
p.option 'profile', '--profile', 'Generate a Liquid rendering profile'
|
24
|
+
|
25
|
+
Bunto::External.require_if_present(Bunto::External.blessed_gems) do |g|
|
26
|
+
cmd = g.split('-').last
|
27
|
+
p.command(cmd.to_sym) do |c|
|
28
|
+
c.syntax cmd
|
29
|
+
c.action do
|
30
|
+
Bunto.logger.abort_with "You must install the '#{g}' gem to use the 'bunto #{cmd}' command."
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
Bunto::Command.subclasses.each { |c| c.init_with_program(p) }
|
36
|
+
|
37
|
+
p.action do |args, _|
|
38
|
+
if args.empty?
|
39
|
+
Bunto.logger.error "A subcommand is required."
|
40
|
+
puts p
|
41
|
+
abort
|
42
|
+
else
|
43
|
+
subcommand = args.first
|
44
|
+
unless p.has_command? subcommand
|
45
|
+
Bunto.logger.abort_with "fatal: 'bunto #{args.first}' could not" \
|
46
|
+
" be found. You may need to install the bunto-#{args.first} gem" \
|
47
|
+
" or a related gem to be able to use this subcommand."
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/lib/bunto.rb
ADDED
@@ -0,0 +1,179 @@
|
|
1
|
+
$LOAD_PATH.unshift File.dirname(__FILE__) # For use/testing when no gem is installed
|
2
|
+
|
3
|
+
# Require all of the Ruby files in the given directory.
|
4
|
+
#
|
5
|
+
# path - The String relative path from here to the directory.
|
6
|
+
#
|
7
|
+
# Returns nothing.
|
8
|
+
def require_all(path)
|
9
|
+
glob = File.join(File.dirname(__FILE__), path, '*.rb')
|
10
|
+
Dir[glob].each do |f|
|
11
|
+
require f
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
# rubygems
|
16
|
+
require 'rubygems'
|
17
|
+
|
18
|
+
# stdlib
|
19
|
+
require 'forwardable'
|
20
|
+
require 'fileutils'
|
21
|
+
require 'time'
|
22
|
+
require 'English'
|
23
|
+
require 'pathname'
|
24
|
+
require 'logger'
|
25
|
+
require 'set'
|
26
|
+
|
27
|
+
# 3rd party
|
28
|
+
require 'safe_yaml/load'
|
29
|
+
require 'liquid'
|
30
|
+
require 'kramdown'
|
31
|
+
require 'colorator'
|
32
|
+
|
33
|
+
SafeYAML::OPTIONS[:suppress_warnings] = true
|
34
|
+
|
35
|
+
module Bunto
|
36
|
+
# internal requires
|
37
|
+
autoload :Cleaner, 'bunto/cleaner'
|
38
|
+
autoload :Collection, 'bunto/collection'
|
39
|
+
autoload :Configuration, 'bunto/configuration'
|
40
|
+
autoload :Convertible, 'bunto/convertible'
|
41
|
+
autoload :Deprecator, 'bunto/deprecator'
|
42
|
+
autoload :Document, 'bunto/document'
|
43
|
+
autoload :Draft, 'bunto/draft'
|
44
|
+
autoload :EntryFilter, 'bunto/entry_filter'
|
45
|
+
autoload :Errors, 'bunto/errors'
|
46
|
+
autoload :Excerpt, 'bunto/excerpt'
|
47
|
+
autoload :External, 'bunto/external'
|
48
|
+
autoload :Filters, 'bunto/filters'
|
49
|
+
autoload :FrontmatterDefaults, 'bunto/frontmatter_defaults'
|
50
|
+
autoload :Hooks, 'bunto/hooks'
|
51
|
+
autoload :Layout, 'bunto/layout'
|
52
|
+
autoload :CollectionReader, 'bunto/readers/collection_reader'
|
53
|
+
autoload :DataReader, 'bunto/readers/data_reader'
|
54
|
+
autoload :LayoutReader, 'bunto/readers/layout_reader'
|
55
|
+
autoload :PostReader, 'bunto/readers/post_reader'
|
56
|
+
autoload :PageReader, 'bunto/readers/page_reader'
|
57
|
+
autoload :StaticFileReader, 'bunto/readers/static_file_reader'
|
58
|
+
autoload :LogAdapter, 'bunto/log_adapter'
|
59
|
+
autoload :Page, 'bunto/page'
|
60
|
+
autoload :PluginManager, 'bunto/plugin_manager'
|
61
|
+
autoload :Publisher, 'bunto/publisher'
|
62
|
+
autoload :Reader, 'bunto/reader'
|
63
|
+
autoload :Regenerator, 'bunto/regenerator'
|
64
|
+
autoload :RelatedPosts, 'bunto/related_posts'
|
65
|
+
autoload :Renderer, 'bunto/renderer'
|
66
|
+
autoload :LiquidRenderer, 'bunto/liquid_renderer'
|
67
|
+
autoload :Site, 'bunto/site'
|
68
|
+
autoload :StaticFile, 'bunto/static_file'
|
69
|
+
autoload :Stevenson, 'bunto/stevenson'
|
70
|
+
autoload :URL, 'bunto/url'
|
71
|
+
autoload :Utils, 'bunto/utils'
|
72
|
+
autoload :VERSION, 'bunto/version'
|
73
|
+
|
74
|
+
# extensions
|
75
|
+
require 'bunto/plugin'
|
76
|
+
require 'bunto/converter'
|
77
|
+
require 'bunto/generator'
|
78
|
+
require 'bunto/command'
|
79
|
+
require 'bunto/liquid_extensions'
|
80
|
+
|
81
|
+
class << self
|
82
|
+
# Public: Tells you which Bunto environment you are building in so you can skip tasks
|
83
|
+
# if you need to. This is useful when doing expensive compression tasks on css and
|
84
|
+
# images and allows you to skip that when working in development.
|
85
|
+
|
86
|
+
def env
|
87
|
+
ENV["BUNTO_ENV"] || "development"
|
88
|
+
end
|
89
|
+
|
90
|
+
# Public: Generate a Bunto configuration Hash by merging the default
|
91
|
+
# options with anything in _config.yml, and adding the given options on top.
|
92
|
+
#
|
93
|
+
# override - A Hash of config directives that override any options in both
|
94
|
+
# the defaults and the config file. See Bunto::Configuration::DEFAULTS for a
|
95
|
+
# list of option names and their defaults.
|
96
|
+
#
|
97
|
+
# Returns the final configuration Hash.
|
98
|
+
def configuration(override = {})
|
99
|
+
config = Configuration[Configuration::DEFAULTS]
|
100
|
+
override = Configuration[override].stringify_keys
|
101
|
+
unless override.delete('skip_config_files')
|
102
|
+
config = config.read_config_files(config.config_files(override))
|
103
|
+
end
|
104
|
+
|
105
|
+
# Merge DEFAULTS < _config.yml < override
|
106
|
+
config = Utils.deep_merge_hashes(config, override).stringify_keys
|
107
|
+
set_timezone(config['timezone']) if config['timezone']
|
108
|
+
|
109
|
+
config
|
110
|
+
end
|
111
|
+
|
112
|
+
# Public: Set the TZ environment variable to use the timezone specified
|
113
|
+
#
|
114
|
+
# timezone - the IANA Time Zone
|
115
|
+
#
|
116
|
+
# Returns nothing
|
117
|
+
def set_timezone(timezone)
|
118
|
+
ENV['TZ'] = timezone
|
119
|
+
end
|
120
|
+
|
121
|
+
# Public: Fetch the logger instance for this Bunto process.
|
122
|
+
#
|
123
|
+
# Returns the LogAdapter instance.
|
124
|
+
def logger
|
125
|
+
@logger ||= LogAdapter.new(Stevenson.new, (ENV["BUNTO_LOG_LEVEL"] || :info).to_sym)
|
126
|
+
end
|
127
|
+
|
128
|
+
# Public: Set the log writer.
|
129
|
+
# New log writer must respond to the same methods
|
130
|
+
# as Ruby's interal Logger.
|
131
|
+
#
|
132
|
+
# writer - the new Logger-compatible log transport
|
133
|
+
#
|
134
|
+
# Returns the new logger.
|
135
|
+
def logger=(writer)
|
136
|
+
@logger = LogAdapter.new(writer, (ENV["BUNTO_LOG_LEVEL"] || :info).to_sym)
|
137
|
+
end
|
138
|
+
|
139
|
+
# Public: An array of sites
|
140
|
+
#
|
141
|
+
# Returns the Bunto sites created.
|
142
|
+
def sites
|
143
|
+
@sites ||= []
|
144
|
+
end
|
145
|
+
|
146
|
+
# Public: Ensures the questionable path is prefixed with the base directory
|
147
|
+
# and prepends the questionable path with the base directory if false.
|
148
|
+
#
|
149
|
+
# base_directory - the directory with which to prefix the questionable path
|
150
|
+
# questionable_path - the path we're unsure about, and want prefixed
|
151
|
+
#
|
152
|
+
# Returns the sanitized path.
|
153
|
+
def sanitized_path(base_directory, questionable_path)
|
154
|
+
return base_directory if base_directory.eql?(questionable_path)
|
155
|
+
|
156
|
+
clean_path = File.expand_path(questionable_path, "/")
|
157
|
+
clean_path = clean_path.sub(/\A\w\:\//, '/')
|
158
|
+
|
159
|
+
if clean_path.start_with?(base_directory.sub(/\A\w\:\//, '/'))
|
160
|
+
clean_path
|
161
|
+
else
|
162
|
+
File.join(base_directory, clean_path)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
# Conditional optimizations
|
167
|
+
Bunto::External.require_if_present('liquid-c')
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
require "bunto/drops/drop"
|
172
|
+
require_all 'bunto/commands'
|
173
|
+
require_all 'bunto/converters'
|
174
|
+
require_all 'bunto/converters/markdown'
|
175
|
+
require_all 'bunto/drops'
|
176
|
+
require_all 'bunto/generators'
|
177
|
+
require_all 'bunto/tags'
|
178
|
+
|
179
|
+
require 'bunto-sass-converter'
|
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'set'
|
2
|
+
|
3
|
+
module Bunto
|
4
|
+
# Handles the cleanup of a site's destination before it is built.
|
5
|
+
class Cleaner
|
6
|
+
HIDDEN_FILE_REGEX = /\/\.{1,2}$/
|
7
|
+
attr_reader :site
|
8
|
+
|
9
|
+
def initialize(site)
|
10
|
+
@site = site
|
11
|
+
end
|
12
|
+
|
13
|
+
# Cleans up the site's destination directory
|
14
|
+
def cleanup!
|
15
|
+
FileUtils.rm_rf(obsolete_files)
|
16
|
+
FileUtils.rm_rf(metadata_file) unless @site.incremental?
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
# Private: The list of files and directories to be deleted during cleanup process
|
22
|
+
#
|
23
|
+
# Returns an Array of the file and directory paths
|
24
|
+
def obsolete_files
|
25
|
+
(existing_files - new_files - new_dirs + replaced_files).to_a
|
26
|
+
end
|
27
|
+
|
28
|
+
# Private: The metadata file storing dependency tree and build history
|
29
|
+
#
|
30
|
+
# Returns an Array with the metdata file as the only item
|
31
|
+
def metadata_file
|
32
|
+
[site.regenerator.metadata_file]
|
33
|
+
end
|
34
|
+
|
35
|
+
# Private: The list of existing files, apart from those included in keep_files and hidden files.
|
36
|
+
#
|
37
|
+
# Returns a Set with the file paths
|
38
|
+
def existing_files
|
39
|
+
files = Set.new
|
40
|
+
regex = keep_file_regex
|
41
|
+
dirs = keep_dirs
|
42
|
+
|
43
|
+
Utils.safe_glob(site.in_dest_dir, ["**", "*"], File::FNM_DOTMATCH).each do |file|
|
44
|
+
next if file =~ HIDDEN_FILE_REGEX || file =~ regex || dirs.include?(file)
|
45
|
+
files << file
|
46
|
+
end
|
47
|
+
|
48
|
+
files
|
49
|
+
end
|
50
|
+
|
51
|
+
# Private: The list of files to be created when site is built.
|
52
|
+
#
|
53
|
+
# Returns a Set with the file paths
|
54
|
+
def new_files
|
55
|
+
files = Set.new
|
56
|
+
site.each_site_file { |item| files << item.destination(site.dest) }
|
57
|
+
files
|
58
|
+
end
|
59
|
+
|
60
|
+
# Private: The list of directories to be created when site is built.
|
61
|
+
# These are the parent directories of the files in #new_files.
|
62
|
+
#
|
63
|
+
# Returns a Set with the directory paths
|
64
|
+
def new_dirs
|
65
|
+
new_files.map { |file| parent_dirs(file) }.flatten.to_set
|
66
|
+
end
|
67
|
+
|
68
|
+
# Private: The list of parent directories of a given file
|
69
|
+
#
|
70
|
+
# Returns an Array with the directory paths
|
71
|
+
def parent_dirs(file)
|
72
|
+
parent_dir = File.dirname(file)
|
73
|
+
if parent_dir == site.dest
|
74
|
+
[]
|
75
|
+
else
|
76
|
+
[parent_dir] + parent_dirs(parent_dir)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# Private: The list of existing files that will be replaced by a directory during build
|
81
|
+
#
|
82
|
+
# Returns a Set with the file paths
|
83
|
+
def replaced_files
|
84
|
+
new_dirs.select { |dir| File.file?(dir) }.to_set
|
85
|
+
end
|
86
|
+
|
87
|
+
# Private: The list of directories that need to be kept because they are parent directories
|
88
|
+
# of files specified in keep_files
|
89
|
+
#
|
90
|
+
# Returns a Set with the directory paths
|
91
|
+
def keep_dirs
|
92
|
+
site.keep_files.map { |file| parent_dirs(site.in_dest_dir(file)) }.flatten.to_set
|
93
|
+
end
|
94
|
+
|
95
|
+
# Private: Creates a regular expression from the config's keep_files array
|
96
|
+
#
|
97
|
+
# Examples
|
98
|
+
# ['.git','.svn'] creates the following regex: /\/(\.git|\/.svn)/
|
99
|
+
#
|
100
|
+
# Returns the regular expression
|
101
|
+
def keep_file_regex
|
102
|
+
Regexp.union(site.keep_files)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,205 @@
|
|
1
|
+
module Bunto
|
2
|
+
class Collection
|
3
|
+
attr_reader :site, :label, :metadata
|
4
|
+
attr_writer :docs
|
5
|
+
|
6
|
+
# Create a new Collection.
|
7
|
+
#
|
8
|
+
# site - the site to which this collection belongs.
|
9
|
+
# label - the name of the collection
|
10
|
+
#
|
11
|
+
# Returns nothing.
|
12
|
+
def initialize(site, label)
|
13
|
+
@site = site
|
14
|
+
@label = sanitize_label(label)
|
15
|
+
@metadata = extract_metadata
|
16
|
+
end
|
17
|
+
|
18
|
+
# Fetch the Documents in this collection.
|
19
|
+
# Defaults to an empty array if no documents have been read in.
|
20
|
+
#
|
21
|
+
# Returns an array of Bunto::Document objects.
|
22
|
+
def docs
|
23
|
+
@docs ||= []
|
24
|
+
end
|
25
|
+
|
26
|
+
# Override of normal respond_to? to match method_missing's logic for
|
27
|
+
# looking in @data.
|
28
|
+
def respond_to?(method, include_private = false)
|
29
|
+
docs.respond_to?(method.to_sym, include_private) || super
|
30
|
+
end
|
31
|
+
|
32
|
+
# Override of method_missing to check in @data for the key.
|
33
|
+
def method_missing(method, *args, &blck)
|
34
|
+
if docs.respond_to?(method.to_sym)
|
35
|
+
Bunto.logger.warn "Deprecation:", "#{label}.#{method} should be changed to #{label}.docs.#{method}."
|
36
|
+
Bunto.logger.warn "", "Called by #{caller.first}."
|
37
|
+
docs.public_send(method.to_sym, *args, &blck)
|
38
|
+
else
|
39
|
+
super
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Fetch the static files in this collection.
|
44
|
+
# Defaults to an empty array if no static files have been read in.
|
45
|
+
#
|
46
|
+
# Returns an array of Bunto::StaticFile objects.
|
47
|
+
def files
|
48
|
+
@files ||= []
|
49
|
+
end
|
50
|
+
|
51
|
+
# Read the allowed documents into the collection's array of docs.
|
52
|
+
#
|
53
|
+
# Returns the sorted array of docs.
|
54
|
+
def read
|
55
|
+
filtered_entries.each do |file_path|
|
56
|
+
full_path = collection_dir(file_path)
|
57
|
+
next if File.directory?(full_path)
|
58
|
+
if Utils.has_yaml_header? full_path
|
59
|
+
doc = Bunto::Document.new(full_path, { :site => site, :collection => self })
|
60
|
+
doc.read
|
61
|
+
if site.publisher.publish?(doc) || !write?
|
62
|
+
docs << doc
|
63
|
+
else
|
64
|
+
Bunto.logger.debug "Skipped From Publishing:", doc.relative_path
|
65
|
+
end
|
66
|
+
else
|
67
|
+
relative_dir = Bunto.sanitized_path(relative_directory, File.dirname(file_path)).chomp("/.")
|
68
|
+
files << StaticFile.new(site, site.source, relative_dir, File.basename(full_path), self)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
docs.sort!
|
72
|
+
end
|
73
|
+
|
74
|
+
# All the entries in this collection.
|
75
|
+
#
|
76
|
+
# Returns an Array of file paths to the documents in this collection
|
77
|
+
# relative to the collection's directory
|
78
|
+
def entries
|
79
|
+
return [] unless exists?
|
80
|
+
@entries ||=
|
81
|
+
Utils.safe_glob(collection_dir, ["**", "*.*"]).map do |entry|
|
82
|
+
entry["#{collection_dir}/"] = ''
|
83
|
+
entry
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
# Filtered version of the entries in this collection.
|
88
|
+
# See `Bunto::EntryFilter#filter` for more information.
|
89
|
+
#
|
90
|
+
# Returns a list of filtered entry paths.
|
91
|
+
def filtered_entries
|
92
|
+
return [] unless exists?
|
93
|
+
@filtered_entries ||=
|
94
|
+
Dir.chdir(directory) do
|
95
|
+
entry_filter.filter(entries).reject do |f|
|
96
|
+
path = collection_dir(f)
|
97
|
+
File.directory?(path) || (File.symlink?(f) && site.safe)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# The directory for this Collection, relative to the site source.
|
103
|
+
#
|
104
|
+
# Returns a String containing the directory name where the collection
|
105
|
+
# is stored on the filesystem.
|
106
|
+
def relative_directory
|
107
|
+
@relative_directory ||= "_#{label}"
|
108
|
+
end
|
109
|
+
|
110
|
+
# The full path to the directory containing the collection.
|
111
|
+
#
|
112
|
+
# Returns a String containing th directory name where the collection
|
113
|
+
# is stored on the filesystem.
|
114
|
+
def directory
|
115
|
+
@directory ||= site.in_source_dir(relative_directory)
|
116
|
+
end
|
117
|
+
|
118
|
+
# The full path to the directory containing the collection, with
|
119
|
+
# optional subpaths.
|
120
|
+
#
|
121
|
+
# *files - (optional) any other path pieces relative to the
|
122
|
+
# directory to append to the path
|
123
|
+
#
|
124
|
+
# Returns a String containing th directory name where the collection
|
125
|
+
# is stored on the filesystem.
|
126
|
+
def collection_dir(*files)
|
127
|
+
return directory if files.empty?
|
128
|
+
site.in_source_dir(relative_directory, *files)
|
129
|
+
end
|
130
|
+
|
131
|
+
# Checks whether the directory "exists" for this collection.
|
132
|
+
# The directory must exist on the filesystem and must not be a symlink
|
133
|
+
# if in safe mode.
|
134
|
+
#
|
135
|
+
# Returns false if the directory doesn't exist or if it's a symlink
|
136
|
+
# and we're in safe mode.
|
137
|
+
def exists?
|
138
|
+
File.directory?(directory) && !(File.symlink?(directory) && site.safe)
|
139
|
+
end
|
140
|
+
|
141
|
+
# The entry filter for this collection.
|
142
|
+
# Creates an instance of Bunto::EntryFilter.
|
143
|
+
#
|
144
|
+
# Returns the instance of Bunto::EntryFilter for this collection.
|
145
|
+
def entry_filter
|
146
|
+
@entry_filter ||= Bunto::EntryFilter.new(site, relative_directory)
|
147
|
+
end
|
148
|
+
|
149
|
+
# An inspect string.
|
150
|
+
#
|
151
|
+
# Returns the inspect string
|
152
|
+
def inspect
|
153
|
+
"#<Bunto::Collection @label=#{label} docs=#{docs}>"
|
154
|
+
end
|
155
|
+
|
156
|
+
# Produce a sanitized label name
|
157
|
+
# Label names may not contain anything but alphanumeric characters,
|
158
|
+
# underscores, and hyphens.
|
159
|
+
#
|
160
|
+
# label - the possibly-unsafe label
|
161
|
+
#
|
162
|
+
# Returns a sanitized version of the label.
|
163
|
+
def sanitize_label(label)
|
164
|
+
label.gsub(/[^a-z0-9_\-\.]/i, '')
|
165
|
+
end
|
166
|
+
|
167
|
+
# Produce a representation of this Collection for use in Liquid.
|
168
|
+
# Exposes two attributes:
|
169
|
+
# - label
|
170
|
+
# - docs
|
171
|
+
#
|
172
|
+
# Returns a representation of this collection for use in Liquid.
|
173
|
+
def to_liquid
|
174
|
+
Drops::CollectionDrop.new self
|
175
|
+
end
|
176
|
+
|
177
|
+
# Whether the collection's documents ought to be written as individual
|
178
|
+
# files in the output.
|
179
|
+
#
|
180
|
+
# Returns true if the 'write' metadata is true, false otherwise.
|
181
|
+
def write?
|
182
|
+
!!metadata.fetch('output', false)
|
183
|
+
end
|
184
|
+
|
185
|
+
# The URL template to render collection's documents at.
|
186
|
+
#
|
187
|
+
# Returns the URL template to render collection's documents at.
|
188
|
+
def url_template
|
189
|
+
@url_template ||= metadata.fetch('permalink') do
|
190
|
+
Utils.add_permalink_suffix("/:collection/:path", site.permalink_style)
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
# Extract options for this collection from the site configuration.
|
195
|
+
#
|
196
|
+
# Returns the metadata for this collection
|
197
|
+
def extract_metadata
|
198
|
+
if site.config['collections'].is_a?(Hash)
|
199
|
+
site.config['collections'][label] || {}
|
200
|
+
else
|
201
|
+
{}
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|