munge 0.11.1 → 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 +4 -4
- data/lib/munge/application.rb +18 -0
- data/lib/munge/bootloader.rb +3 -0
- data/lib/munge/cli/commands/build.rb +6 -1
- data/lib/munge/cli/commands/update.rb +24 -0
- data/lib/munge/cli/commands/view.rb +5 -0
- data/lib/munge/cli/dispatch.rb +9 -1
- data/lib/munge/cli.rb +1 -0
- data/lib/munge/formatters/dots.rb +3 -12
- data/lib/munge/go/sass.rb +13 -0
- data/lib/munge/helpers/capture.rb +2 -2
- data/lib/munge/helpers/find.rb +2 -2
- data/lib/munge/helpers/link.rb +13 -18
- data/lib/munge/helpers/rendering.rb +8 -15
- data/lib/munge/helpers/tag.rb +1 -1
- data/lib/munge/init.rb +7 -0
- data/lib/munge/item.rb +37 -11
- data/lib/munge/runner.rb +3 -3
- data/lib/munge/system/collection.rb +27 -8
- data/lib/munge/system/item_factory.rb +28 -20
- data/lib/munge/system/{alterant.rb → processor.rb} +13 -3
- data/lib/munge/system/readers/filesystem.rb +4 -0
- data/lib/munge/system/router/itemish.rb +4 -4
- data/lib/munge/system/router.rb +4 -4
- data/lib/munge/system.rb +36 -25
- data/lib/munge/transformers/tilt_transformer.rb +15 -13
- data/lib/munge/util/boolean_regex.rb +13 -0
- data/lib/munge/util/path.rb +15 -12
- data/lib/munge/version.rb +1 -1
- data/lib/munge/write_manager.rb +5 -0
- data/lib/munge/writers/filesystem.rb +7 -0
- data/lib/munge/writers/noop.rb +5 -0
- data/lib/munge.rb +2 -1
- data/munge.gemspec +5 -0
- data/seeds/config/view_helpers.rb +1 -1
- metadata +41 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b3e1eb8424b81b08cb185b26e80273a94ff027f5
|
4
|
+
data.tar.gz: eb0dbd0f3a65fbd4ce2ab8b5e8aacc48158ee03c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fc9abaedb2d419a05eb69b45e14702e88438162df849749daa1b968b3617a6f271e5a4c89985a65adcf0c2ec2bebf5dc32298940bf9ac9e2bde95637eb8dd8e3
|
7
|
+
data.tar.gz: 814114a8a51a3e298687569cc7effde92cfb872304761633cf0df035c06f71734a7b4f6e672c009c0333627f2ea18f79c8cfc0147eb06b3bfb53806efda4f1cb
|
data/lib/munge/application.rb
CHANGED
@@ -1,31 +1,49 @@
|
|
1
1
|
module Munge
|
2
|
+
# This class is one of the main interfaces users would interact with. This
|
3
|
+
# provides methods to create and iterate through items.
|
2
4
|
class Application
|
3
5
|
def initialize(system)
|
4
6
|
@system = system
|
5
7
|
end
|
6
8
|
|
9
|
+
# @return [Array<Item>]
|
7
10
|
def items
|
8
11
|
@system.items
|
9
12
|
end
|
10
13
|
|
14
|
+
# @return [Array<Item>]
|
11
15
|
def nonrouted
|
12
16
|
items.select { |item| item.route.nil? }
|
13
17
|
end
|
14
18
|
|
19
|
+
# @return [Array<Item>]
|
15
20
|
def routed
|
16
21
|
items.select(&:route)
|
17
22
|
end
|
18
23
|
|
24
|
+
# Builds an Item
|
25
|
+
#
|
26
|
+
# @return [Item]
|
19
27
|
def build_virtual_item(relpath, content, **frontmatter)
|
20
28
|
@system.items.build(relpath: relpath, content: content, frontmatter: frontmatter)
|
21
29
|
end
|
22
30
|
|
31
|
+
# Creates an Item and inserts it into the registry of Items.
|
32
|
+
#
|
33
|
+
# @see #build_virtual_item
|
34
|
+
# @param relpath [String]
|
35
|
+
# @param content [String]
|
36
|
+
# @param frontmatter [Hash]
|
37
|
+
# @return [Array<Item>]
|
23
38
|
def create(*args)
|
24
39
|
item = build_virtual_item(*args)
|
25
40
|
@system.items.push(item)
|
26
41
|
[item]
|
27
42
|
end
|
28
43
|
|
44
|
+
# Returns parts of System
|
45
|
+
#
|
46
|
+
# @private
|
29
47
|
def vomit(component_name)
|
30
48
|
@system.public_send(component_name)
|
31
49
|
end
|
data/lib/munge/bootloader.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
module Munge
|
2
|
+
# This class is useful for loading the application.
|
2
3
|
class Bootloader
|
4
|
+
# @param root_path [String] Absolute path to munge directory
|
3
5
|
def initialize(root_path:)
|
4
6
|
@root_path = root_path
|
5
7
|
@config_path = File.join(root_path, "config.yml")
|
@@ -8,6 +10,7 @@ module Munge
|
|
8
10
|
@config = Munge::Util::Config.read(@config_path)
|
9
11
|
end
|
10
12
|
|
13
|
+
# @return [Munge::Init]
|
11
14
|
def init
|
12
15
|
@init ||=
|
13
16
|
Init.new(
|
@@ -1,7 +1,12 @@
|
|
1
1
|
module Munge
|
2
2
|
module Cli
|
3
3
|
module Commands
|
4
|
+
# This class is used by the CLI to build and calculate output
|
4
5
|
class Build
|
6
|
+
# @param bootloader [Munge::Bootloader]
|
7
|
+
# @param dry_run [true, false]
|
8
|
+
# @param reporter [Munge::Reporters]
|
9
|
+
# @param build_root [String, nil]
|
5
10
|
def initialize(bootloader, dry_run:, reporter:, verbosity:, build_root: nil)
|
6
11
|
destination_root = bootloader.root_path
|
7
12
|
config = bootloader.config
|
@@ -12,7 +17,7 @@ module Munge
|
|
12
17
|
Munge::Runner.new(
|
13
18
|
items: app.vomit(:items),
|
14
19
|
router: app.vomit(:router),
|
15
|
-
|
20
|
+
processor: app.vomit(:processor),
|
16
21
|
writer: writer(dry_run),
|
17
22
|
formatter: formatter(reporter),
|
18
23
|
verbosity: verbosity.to_sym,
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Munge
|
2
|
+
module Cli
|
3
|
+
module Commands
|
4
|
+
class Update
|
5
|
+
include Thor::Base
|
6
|
+
include Thor::Actions
|
7
|
+
|
8
|
+
def self.source_root
|
9
|
+
File.expand_path("../../../../../seeds", __FILE__)
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(_bootloader, path)
|
13
|
+
self.options = {}
|
14
|
+
self.destination_root = File.expand_path(path)
|
15
|
+
end
|
16
|
+
|
17
|
+
def call
|
18
|
+
directory("config", File.expand_path("config", destination_root))
|
19
|
+
copy_file("setup.rb")
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -27,7 +27,12 @@ require "rack"
|
|
27
27
|
module Munge
|
28
28
|
module Cli
|
29
29
|
module Commands
|
30
|
+
# This class starts up a webserver useful for development
|
30
31
|
class View
|
32
|
+
# @param bootloader [Munge::Bootloader]
|
33
|
+
# @param host [String]
|
34
|
+
# @param port [Numeric]
|
35
|
+
# @param build_root [String, nil]
|
31
36
|
def initialize(bootloader, host:, port:, build_root: nil)
|
32
37
|
config = bootloader.config
|
33
38
|
@host = host
|
data/lib/munge/cli/dispatch.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
module Munge
|
2
2
|
module Cli
|
3
|
+
# This class directs commandline flags to appropriate classes
|
3
4
|
class Dispatch < Thor
|
4
5
|
desc "init PATH", "Create new site at PATH"
|
5
6
|
def init(path)
|
@@ -33,7 +34,14 @@ module Munge
|
|
33
34
|
Commands::Server.new(bootloader).call
|
34
35
|
end
|
35
36
|
|
36
|
-
desc "
|
37
|
+
desc "update", "Use with caution: override local configs with pristine version (useful after bumping version in Gemfile)"
|
38
|
+
def update
|
39
|
+
ENV["MUNGE_ENV"] ||= "development"
|
40
|
+
|
41
|
+
Commands::Update.new(bootloader, current_working_directory).call
|
42
|
+
end
|
43
|
+
|
44
|
+
desc "version", "Print version (v#{Munge::VERSION})"
|
37
45
|
map %w(-v --version) => "version"
|
38
46
|
def version
|
39
47
|
puts "munge #{Munge::VERSION}"
|
data/lib/munge/cli.rb
CHANGED
@@ -2,17 +2,8 @@ module Munge
|
|
2
2
|
module Formatters
|
3
3
|
class Dots
|
4
4
|
def initialize
|
5
|
-
@counts = {
|
6
|
-
|
7
|
-
changed: 0,
|
8
|
-
identical: 0
|
9
|
-
}
|
10
|
-
|
11
|
-
@relpaths = {
|
12
|
-
new: [],
|
13
|
-
changed: [],
|
14
|
-
identical: []
|
15
|
-
}
|
5
|
+
@counts = Hash.new { 0 }
|
6
|
+
@relpaths = Hash.new { [] }
|
16
7
|
|
17
8
|
@dots = {
|
18
9
|
new: Rainbow("W").green,
|
@@ -29,7 +20,7 @@ module Munge
|
|
29
20
|
@counts[write_status] += 1
|
30
21
|
|
31
22
|
if should_print
|
32
|
-
@relpaths[write_status]
|
23
|
+
@relpaths[write_status] += [relpath]
|
33
24
|
end
|
34
25
|
|
35
26
|
print @dots[write_status]
|
data/lib/munge/go/sass.rb
CHANGED
@@ -5,10 +5,19 @@ module Munge
|
|
5
5
|
module Go
|
6
6
|
module_function
|
7
7
|
|
8
|
+
# Appends a path to Sass's load paths. To append multiple paths, call the
|
9
|
+
# function multiple times.
|
10
|
+
#
|
11
|
+
# @param paths [Array<String>, String] path or components of path
|
12
|
+
# @return [void]
|
8
13
|
def add_sass_load_path!(*paths)
|
9
14
|
Sass.load_paths << File.join(*paths)
|
10
15
|
end
|
11
16
|
|
17
|
+
# Sets {Munge::System} for use with plugins
|
18
|
+
#
|
19
|
+
# @param system [Munge::System]
|
20
|
+
# @return [void]
|
12
21
|
# rubocop:disable Style/AccessorMethodName
|
13
22
|
def set_sass_system!(system)
|
14
23
|
Sass::Script::Functions.send(:define_method, :system) do
|
@@ -17,6 +26,10 @@ module Munge
|
|
17
26
|
end
|
18
27
|
# rubocop:enable Style/AccessorMethodName
|
19
28
|
|
29
|
+
# Includes methods into Sass functions scope
|
30
|
+
#
|
31
|
+
# @param asset_roots [Module]
|
32
|
+
# @return [void]
|
20
33
|
def add_sass_functions!(asset_roots)
|
21
34
|
Sass::Script::Functions.send(:include, asset_roots)
|
22
35
|
end
|
@@ -6,13 +6,13 @@ module Munge
|
|
6
6
|
original_erbout = block.binding.local_variable_get(:_erbout)
|
7
7
|
block.binding.local_variable_set(:_erbout, "")
|
8
8
|
|
9
|
-
captured_text =
|
9
|
+
captured_text = yield
|
10
10
|
|
11
11
|
block.binding.local_variable_set(:_erbout, original_erbout)
|
12
12
|
|
13
13
|
captured_text
|
14
14
|
else
|
15
|
-
|
15
|
+
yield
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
data/lib/munge/helpers/find.rb
CHANGED
data/lib/munge/helpers/link.rb
CHANGED
@@ -1,33 +1,28 @@
|
|
1
1
|
module Munge
|
2
2
|
module Helpers
|
3
3
|
module Link
|
4
|
-
def path_to(
|
5
|
-
|
4
|
+
def path_to(itemish)
|
5
|
+
item =
|
6
|
+
if item.is_a?(String)
|
7
|
+
system.items[itemish]
|
8
|
+
else
|
9
|
+
itemish
|
10
|
+
end
|
11
|
+
|
12
|
+
system.router.route(item)
|
6
13
|
end
|
7
14
|
|
8
|
-
def link_to(
|
9
|
-
link = path_to(
|
15
|
+
def link_to(itemish, text = nil, opts = {})
|
16
|
+
link = path_to(itemish)
|
10
17
|
|
11
18
|
if text.is_a?(Hash)
|
12
19
|
opts = text
|
13
20
|
text = nil
|
14
21
|
end
|
15
22
|
|
16
|
-
|
17
|
-
|
18
|
-
parts =
|
19
|
-
[
|
20
|
-
[
|
21
|
-
"<a",
|
22
|
-
%(href="#{link}"),
|
23
|
-
optstr
|
24
|
-
].flatten.join(" "),
|
25
|
-
">",
|
26
|
-
text || link,
|
27
|
-
"</a>"
|
28
|
-
]
|
23
|
+
href_with_options = { href: link }.merge(opts)
|
29
24
|
|
30
|
-
|
25
|
+
content_tag(:a, text || link, href_with_options)
|
31
26
|
end
|
32
27
|
end
|
33
28
|
end
|
@@ -27,15 +27,11 @@ module Munge
|
|
27
27
|
|
28
28
|
output =
|
29
29
|
engines
|
30
|
-
.
|
31
|
-
options =
|
32
|
-
template = engine.new(template_name, options) {
|
33
|
-
|
34
|
-
|
35
|
-
template.render(self, data) { inner }
|
36
|
-
else
|
37
|
-
template.render(self, data)
|
38
|
-
end
|
30
|
+
.reduce(content) do |memoized_content, engine|
|
31
|
+
options = tilt_options[engine]
|
32
|
+
template = engine.new(template_name, options) { memoized_content }
|
33
|
+
|
34
|
+
template.render(self, data) { inner }
|
39
35
|
end
|
40
36
|
|
41
37
|
if block_given?
|
@@ -62,19 +58,16 @@ module Munge
|
|
62
58
|
|
63
59
|
def merged_data(*data)
|
64
60
|
hash_with_string_and_symbol_keys =
|
65
|
-
data.
|
61
|
+
data.reduce(system.global_data) do |merged, datum|
|
66
62
|
merged.merge(datum)
|
67
63
|
end
|
68
64
|
|
69
|
-
hash_with_string_and_symbol_keys
|
70
|
-
.each_with_object({}) do |(key, value), memo|
|
71
|
-
memo[key.to_sym] = value
|
72
|
-
end
|
65
|
+
Munge::Util::SymbolHash.deep_convert(hash_with_string_and_symbol_keys)
|
73
66
|
end
|
74
67
|
|
75
68
|
def resolve_layout(item_or_string)
|
76
69
|
if item_or_string.is_a?(String)
|
77
|
-
|
70
|
+
system.layouts[item_or_string]
|
78
71
|
else
|
79
72
|
item_or_string
|
80
73
|
end
|
data/lib/munge/helpers/tag.rb
CHANGED
data/lib/munge/init.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
module Munge
|
2
|
+
# This class loads the user rules, as well as provides some useful methods
|
3
|
+
# for setup.
|
2
4
|
class Init
|
5
|
+
# Initializing loads up the user's `setup.rb` and `rules.rb`.
|
3
6
|
def initialize(root_path:,
|
4
7
|
config:,
|
5
8
|
setup_path:,
|
@@ -21,10 +24,14 @@ module Munge
|
|
21
24
|
@app.items.freeze
|
22
25
|
end
|
23
26
|
|
27
|
+
# @return [String] path to user's `config/` directory
|
24
28
|
def config_path
|
25
29
|
File.join(root_path, "config")
|
26
30
|
end
|
27
31
|
|
32
|
+
# Loads file into current scope. Similar to `load "filename.rb"`
|
33
|
+
#
|
34
|
+
# @return [void]
|
28
35
|
def import(file_path)
|
29
36
|
absolute_file_path = File.expand_path(file_path, root_path)
|
30
37
|
contents = File.read(absolute_file_path)
|
data/lib/munge/item.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
module Munge
|
2
|
+
# Items are the core data object for building and manipulating pages.
|
2
3
|
class Item
|
3
4
|
def initialize(type:,
|
4
5
|
relpath:,
|
@@ -25,63 +26,88 @@ module Munge
|
|
25
26
|
|
26
27
|
attr_reader :layout, :transforms
|
27
28
|
|
29
|
+
# @return [String] dirname without leading "."
|
28
30
|
def dirname
|
29
|
-
|
30
|
-
""
|
31
|
-
else
|
32
|
-
File.dirname(@relpath)
|
33
|
-
end
|
31
|
+
Munge::Util::Path.dirname(@relpath)
|
34
32
|
end
|
35
33
|
|
34
|
+
# @return [String] filename
|
36
35
|
def filename
|
37
|
-
|
36
|
+
Munge::Util::Path.basename(@relpath)
|
38
37
|
end
|
39
38
|
|
39
|
+
# @return [String] filename before the first "."
|
40
40
|
def basename
|
41
|
-
|
41
|
+
Munge::Util::Path.basename_no_extension(@relpath)
|
42
42
|
end
|
43
43
|
|
44
|
+
# @return [Array<String>] extensions (everything following the first ".")
|
44
45
|
def extensions
|
45
|
-
|
46
|
+
Munge::Util::Path.extnames(@relpath)
|
46
47
|
end
|
47
48
|
|
49
|
+
# @param key [String]
|
48
50
|
def [](key)
|
49
51
|
@frontmatter[key]
|
50
52
|
end
|
51
53
|
|
54
|
+
# @param key [String]
|
52
55
|
def []=(key, value)
|
53
56
|
@frontmatter[key] = value
|
54
57
|
end
|
55
58
|
|
59
|
+
# @param new_route [String] the compiled route to this item
|
60
|
+
# @return [String] sanitized version of input
|
56
61
|
def route=(new_route)
|
57
62
|
@route = remove_surrounding_slashes(new_route)
|
58
63
|
end
|
59
64
|
|
65
|
+
# @return [String, nil] absolute route to this item, if set
|
60
66
|
def route
|
61
67
|
if @route
|
62
68
|
"/#{@route}"
|
63
69
|
end
|
64
70
|
end
|
65
71
|
|
72
|
+
# Runs a regex match to see if item was found in the specified directory.
|
73
|
+
# Do not query with any slashes. Each argument will automatically be joined
|
74
|
+
# by slashes. Note though that the string will be converted into a regex.
|
75
|
+
#
|
76
|
+
# @param *subdir_patterns [Array<String>]
|
77
|
+
# @return [true, false] whether or not this item was found in specified
|
78
|
+
# subdirectory
|
66
79
|
def relpath?(*subdir_patterns)
|
67
80
|
regexp = generate_regex(subdir_patterns)
|
68
|
-
regexp
|
81
|
+
Munge::Util::BooleanRegex.match?(regexp, @relpath)
|
69
82
|
end
|
70
83
|
|
71
|
-
#
|
84
|
+
# Runs a regex match to see if the item matches a route. See #relpath?
|
85
|
+
#
|
86
|
+
# @param *subdir_patterns [Array<String>]
|
87
|
+
# @return [true, false] whether or not this route belongs to specified
|
88
|
+
# subdirectory
|
72
89
|
def route?(*subdir_patterns)
|
73
90
|
regexp = generate_regex(subdir_patterns)
|
74
|
-
regexp
|
91
|
+
Munge::Util::BooleanRegex.match?(regexp, @route)
|
75
92
|
end
|
76
93
|
|
94
|
+
# @param new_layout [String] layout to apply onto this item
|
95
|
+
# @return [String] sanitized version of the input
|
77
96
|
def layout=(new_layout)
|
78
97
|
@layout = remove_surrounding_slashes(new_layout)
|
79
98
|
end
|
80
99
|
|
100
|
+
# @param transformer [Symbol] name of transformer to apply onto item when
|
101
|
+
# building
|
102
|
+
# @param *args
|
103
|
+
# @return [void]
|
81
104
|
def transform(transformer = :tilt, *args)
|
82
105
|
@transforms.push([transformer, args])
|
83
106
|
end
|
84
107
|
|
108
|
+
# Deep freeze. Freezes all instance variables as well as itself.
|
109
|
+
#
|
110
|
+
# @return [void]
|
85
111
|
def freeze
|
86
112
|
freeze_all_instance_variables
|
87
113
|
|
data/lib/munge/runner.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
module Munge
|
2
2
|
class Runner
|
3
|
-
def initialize(items:, router:,
|
3
|
+
def initialize(items:, router:, processor:, writer:, formatter:, verbosity:, destination:)
|
4
4
|
@items = items
|
5
5
|
@router = router
|
6
|
-
@
|
6
|
+
@processor = processor
|
7
7
|
@writer = writer
|
8
8
|
@reporter = Munge::Reporter.new(formatter: formatter, verbosity: verbosity)
|
9
9
|
@write_manager = Munge::WriteManager.new(driver: File)
|
@@ -25,7 +25,7 @@ module Munge
|
|
25
25
|
def render_and_write(item)
|
26
26
|
relpath = @router.filepath(item)
|
27
27
|
abspath = File.join(@destination, relpath)
|
28
|
-
content = @
|
28
|
+
content = @processor.transform(item)
|
29
29
|
|
30
30
|
write_status = @write_manager.status(abspath, content)
|
31
31
|
|
@@ -1,8 +1,11 @@
|
|
1
1
|
module Munge
|
2
2
|
class System
|
3
|
+
# This class is effectively an Array of Items
|
3
4
|
class Collection
|
4
5
|
include Enumerable
|
5
6
|
|
7
|
+
# @param [System::ItemFactory] item_factory
|
8
|
+
# @param [Array<Hash>] items
|
6
9
|
def initialize(item_factory:,
|
7
10
|
items:)
|
8
11
|
@item_factory = item_factory
|
@@ -14,14 +17,25 @@ module Munge
|
|
14
17
|
.to_h
|
15
18
|
end
|
16
19
|
|
20
|
+
# @see System::ItemFactory#build
|
21
|
+
# @param relpath [String]
|
22
|
+
# @param content [String]
|
23
|
+
# @param frontmatter [Hash]
|
24
|
+
# @param stat [File::Stat]
|
17
25
|
def build(**args)
|
18
26
|
@item_factory.build(**prune_args(args))
|
19
27
|
end
|
20
28
|
|
29
|
+
# @see System::ItemFactory#parse
|
30
|
+
# @param relpath [String]
|
31
|
+
# @param content [String]
|
32
|
+
# @param stat [File::Stat]
|
21
33
|
def parse(**args)
|
22
34
|
@item_factory.parse(**prune_args(args))
|
23
35
|
end
|
24
36
|
|
37
|
+
# @yield [Item]
|
38
|
+
# @return [Enumerator]
|
25
39
|
def each
|
26
40
|
return enum_for(:each) unless block_given?
|
27
41
|
|
@@ -30,19 +44,24 @@ module Munge
|
|
30
44
|
end
|
31
45
|
end
|
32
46
|
|
33
|
-
|
34
|
-
|
35
|
-
|
47
|
+
# @param item [Item]
|
48
|
+
# @return [void]
|
49
|
+
def push(item)
|
50
|
+
if @items.key?(item.id)
|
51
|
+
raise "item with id `#{item.id}` already exists"
|
52
|
+
else
|
53
|
+
@items[item.id] = item
|
54
|
+
end
|
36
55
|
end
|
37
56
|
|
57
|
+
# @param id [String] ID of item
|
58
|
+
# @return [Item]
|
38
59
|
def [](id)
|
39
|
-
|
40
|
-
|
41
|
-
|
60
|
+
if @items.key?(id)
|
61
|
+
@items[id]
|
62
|
+
else
|
42
63
|
raise "item not found (#{id})"
|
43
64
|
end
|
44
|
-
|
45
|
-
found_item
|
46
65
|
end
|
47
66
|
|
48
67
|
def freeze
|
@@ -1,17 +1,25 @@
|
|
1
1
|
module Munge
|
2
2
|
class System
|
3
3
|
class ItemFactory
|
4
|
+
# @param text_extensions [Array<String>]
|
5
|
+
# @param ignore_extensions [Array<String>] Strings are converted to regex
|
4
6
|
def initialize(text_extensions:,
|
5
7
|
ignore_extensions:)
|
6
8
|
@text_extensions = Set.new(text_extensions)
|
7
9
|
@item_identifier = ItemIdentifier.new(remove_extensions: ignore_extensions)
|
8
10
|
end
|
9
11
|
|
12
|
+
# Builds an Item
|
13
|
+
#
|
14
|
+
# @param relpath [String]
|
15
|
+
# @param content [String]
|
16
|
+
# @param frontmatter [Hash]
|
17
|
+
# @param stat [File::Stat]
|
10
18
|
def build(relpath:,
|
11
19
|
content:,
|
12
20
|
frontmatter: {},
|
13
21
|
stat: nil)
|
14
|
-
type =
|
22
|
+
type = item_file_type(relpath)
|
15
23
|
|
16
24
|
id = @item_identifier.call(relpath)
|
17
25
|
|
@@ -25,28 +33,28 @@ module Munge
|
|
25
33
|
)
|
26
34
|
end
|
27
35
|
|
36
|
+
# Parses frontmatter and builds an Item, given a text string
|
37
|
+
#
|
38
|
+
# @param relpath [String]
|
39
|
+
# @param content [String]
|
40
|
+
# @param stat [File::Stat]
|
28
41
|
def parse(relpath:,
|
29
42
|
content:,
|
30
43
|
stat: nil)
|
31
|
-
|
44
|
+
normalized_content, normalized_frontmatter =
|
45
|
+
if item_file_type(relpath) == :text
|
46
|
+
parsed = ContentParser.new(content)
|
47
|
+
[parsed.content, parsed.frontmatter]
|
48
|
+
else
|
49
|
+
[content, {}]
|
50
|
+
end
|
32
51
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
frontmatter: parsed.frontmatter,
|
40
|
-
stat: stat
|
41
|
-
)
|
42
|
-
else
|
43
|
-
build(
|
44
|
-
relpath: relpath,
|
45
|
-
content: content,
|
46
|
-
frontmatter: {},
|
47
|
-
stat: stat
|
48
|
-
)
|
49
|
-
end
|
52
|
+
build(
|
53
|
+
relpath: relpath,
|
54
|
+
content: normalized_content,
|
55
|
+
frontmatter: normalized_frontmatter,
|
56
|
+
stat: stat
|
57
|
+
)
|
50
58
|
end
|
51
59
|
|
52
60
|
private
|
@@ -56,7 +64,7 @@ module Munge
|
|
56
64
|
Set.new(extensions)
|
57
65
|
end
|
58
66
|
|
59
|
-
def
|
67
|
+
def item_file_type(abspath)
|
60
68
|
exts = file_extensions(abspath)
|
61
69
|
|
62
70
|
if exts.intersect?(@text_extensions)
|
@@ -1,15 +1,22 @@
|
|
1
1
|
module Munge
|
2
2
|
class System
|
3
|
-
class
|
3
|
+
class Processor
|
4
4
|
def initialize
|
5
5
|
@registry = {}
|
6
6
|
end
|
7
7
|
|
8
|
+
# Register tranformer
|
9
|
+
#
|
10
|
+
# @see Munge::Transformers::Tilt
|
8
11
|
def register(transformer)
|
9
12
|
register_manually(transformer.name, transformer)
|
10
13
|
end
|
11
14
|
|
12
|
-
#
|
15
|
+
# Register transformer manually
|
16
|
+
#
|
17
|
+
# @see Munge::Transformers::Tilt
|
18
|
+
# @param name [Symbol] Snake case name
|
19
|
+
# @param transformer [#call]
|
13
20
|
def register_manually(name, transformer)
|
14
21
|
if @registry.key?(name)
|
15
22
|
raise "already registered transformer `#{name}`"
|
@@ -18,10 +25,13 @@ module Munge
|
|
18
25
|
end
|
19
26
|
end
|
20
27
|
|
28
|
+
# Transforms the given item's content
|
29
|
+
#
|
30
|
+
# @param item [Item]
|
21
31
|
def transform(item)
|
22
32
|
item.transforms
|
23
33
|
.map { |name, args| [get_transformer(name), args] }
|
24
|
-
.
|
34
|
+
.reduce(item.content) do |content, params|
|
25
35
|
transformer, args = params
|
26
36
|
|
27
37
|
transformer.call(item, content, *args)
|
@@ -1,13 +1,17 @@
|
|
1
1
|
module Munge
|
2
2
|
class System
|
3
3
|
module Readers
|
4
|
+
# Enumerable list of {Munge::Item}s
|
4
5
|
class Filesystem
|
5
6
|
include Enumerable
|
6
7
|
|
8
|
+
# @param source_path [String]
|
7
9
|
def initialize(source_path)
|
8
10
|
@source_path = source_path
|
9
11
|
end
|
10
12
|
|
13
|
+
# @yield [Item]
|
14
|
+
# @return [Enumerator]
|
11
15
|
def each
|
12
16
|
return enum_for(:each) unless block_given?
|
13
17
|
|
@@ -4,13 +4,13 @@ module Munge
|
|
4
4
|
class Itemish
|
5
5
|
extend Forwardable
|
6
6
|
|
7
|
-
def initialize(item,
|
8
|
-
@item
|
9
|
-
@
|
7
|
+
def initialize(item, processor)
|
8
|
+
@item = item
|
9
|
+
@processor = processor
|
10
10
|
end
|
11
11
|
|
12
12
|
def compiled_content
|
13
|
-
@compiled_content ||= @
|
13
|
+
@compiled_content ||= @processor.transform(@item)
|
14
14
|
end
|
15
15
|
|
16
16
|
def_delegators :@item, *%i(type relpath id frontmatter stat layout)
|
data/lib/munge/system/router.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
module Munge
|
2
2
|
class System
|
3
3
|
class Router
|
4
|
-
def initialize(
|
4
|
+
def initialize(processor:)
|
5
5
|
@registries = { route: [], filepath: [] }
|
6
|
-
@
|
6
|
+
@processor = processor
|
7
7
|
end
|
8
8
|
|
9
9
|
def register(router)
|
@@ -35,11 +35,11 @@ module Munge
|
|
35
35
|
raise "item `#{item.relpath}` has no route"
|
36
36
|
end
|
37
37
|
|
38
|
-
itemish = Itemish.new(item, @
|
38
|
+
itemish = Itemish.new(item, @processor)
|
39
39
|
|
40
40
|
@registries[method_name]
|
41
41
|
.select { |router| router.type == method_name }
|
42
|
-
.
|
42
|
+
.reduce(initial_route || item.route) do |route, router|
|
43
43
|
if router.match?(route, itemish)
|
44
44
|
router.call(route, itemish)
|
45
45
|
else
|
data/lib/munge/system.rb
CHANGED
@@ -1,25 +1,19 @@
|
|
1
1
|
module Munge
|
2
2
|
class System
|
3
|
-
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
4
3
|
def initialize(root_path, config)
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
@root_path = root_path
|
5
|
+
@config = config
|
6
|
+
end
|
8
7
|
|
9
|
-
|
8
|
+
def items
|
9
|
+
return @items if @items
|
10
10
|
|
11
|
-
|
11
|
+
source_path = File.expand_path(@config[:source], @root_path)
|
12
12
|
|
13
13
|
source_item_factory =
|
14
14
|
ItemFactory.new(
|
15
|
-
text_extensions: config[:text_extensions] + config[:bintext_extensions],
|
16
|
-
ignore_extensions: config[:dynamic_extensions]
|
17
|
-
)
|
18
|
-
|
19
|
-
layouts_item_factory =
|
20
|
-
ItemFactory.new(
|
21
|
-
text_extensions: config[:text_extensions] + config[:bintext_extensions],
|
22
|
-
ignore_extensions: %w(.+)
|
15
|
+
text_extensions: @config[:text_extensions] + @config[:bintext_extensions],
|
16
|
+
ignore_extensions: @config[:dynamic_extensions]
|
23
17
|
)
|
24
18
|
|
25
19
|
@items =
|
@@ -27,27 +21,44 @@ module Munge
|
|
27
21
|
item_factory: source_item_factory,
|
28
22
|
items: Readers::Filesystem.new(source_path)
|
29
23
|
)
|
24
|
+
end
|
25
|
+
|
26
|
+
def layouts
|
27
|
+
return @layouts if @layouts
|
28
|
+
|
29
|
+
layouts_path = File.expand_path(@config[:layouts], @root_path)
|
30
30
|
|
31
|
-
|
31
|
+
layouts_item_factory =
|
32
|
+
ItemFactory.new(
|
33
|
+
text_extensions: @config[:text_extensions] + @config[:bintext_extensions],
|
34
|
+
ignore_extensions: %w(.+)
|
35
|
+
)
|
36
|
+
|
37
|
+
@layouts ||=
|
32
38
|
Collection.new(
|
33
39
|
item_factory: layouts_item_factory,
|
34
40
|
items: Readers::Filesystem.new(layouts_path)
|
35
41
|
)
|
42
|
+
end
|
36
43
|
|
37
|
-
|
38
|
-
|
44
|
+
def processor
|
45
|
+
@processor ||= Processor.new
|
46
|
+
end
|
39
47
|
|
40
|
-
|
48
|
+
def router
|
49
|
+
@router ||=
|
41
50
|
Router.new(
|
42
|
-
|
51
|
+
processor: processor
|
43
52
|
)
|
44
53
|
end
|
45
|
-
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
46
54
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
55
|
+
def global_data
|
56
|
+
return @global_data if @global_data
|
57
|
+
|
58
|
+
data_path = File.expand_path(@config[:data], @root_path)
|
59
|
+
@global_data = YAML.load_file(data_path) || {}
|
60
|
+
end
|
61
|
+
|
62
|
+
attr_reader :config
|
52
63
|
end
|
53
64
|
end
|
@@ -1,10 +1,10 @@
|
|
1
1
|
module Munge
|
2
2
|
module Transformers
|
3
3
|
class TiltTransformer
|
4
|
-
def initialize(
|
5
|
-
@
|
6
|
-
@registry
|
7
|
-
@demands
|
4
|
+
def initialize(system)
|
5
|
+
@system = system
|
6
|
+
@registry = []
|
7
|
+
@demands = Hash.new { Hash.new }
|
8
8
|
end
|
9
9
|
|
10
10
|
def name
|
@@ -12,11 +12,10 @@ module Munge
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def call(item, content = nil, renderer = nil)
|
15
|
-
scope = @
|
16
|
-
scope.
|
17
|
-
|
18
|
-
|
19
|
-
dirty_scope.render_with_layout(item, content_engines: renderer, content_override: content)
|
15
|
+
scope = Scope.new(@system.clone, @demands)
|
16
|
+
@registry.each { |helpers| scope.extend(helpers) }
|
17
|
+
|
18
|
+
scope.render_with_layout(item, content_engines: renderer, content_override: content)
|
20
19
|
end
|
21
20
|
|
22
21
|
def register(helper)
|
@@ -27,11 +26,14 @@ module Munge
|
|
27
26
|
@demands[tilt_template] = @demands[tilt_template].merge(options)
|
28
27
|
end
|
29
28
|
|
30
|
-
|
29
|
+
class Scope
|
30
|
+
def initialize(system, tilt_options)
|
31
|
+
@system = system
|
32
|
+
@tilt_options = tilt_options
|
33
|
+
end
|
31
34
|
|
32
|
-
|
33
|
-
|
34
|
-
.inject(scope) { |a, e| a.extend(e) }
|
35
|
+
attr_reader :system
|
36
|
+
attr_reader :tilt_options
|
35
37
|
end
|
36
38
|
end
|
37
39
|
end
|
data/lib/munge/util/path.rb
CHANGED
@@ -2,26 +2,29 @@ module Munge
|
|
2
2
|
module Util
|
3
3
|
class Path
|
4
4
|
def self.dirname(path)
|
5
|
-
|
6
|
-
|
5
|
+
if File.dirname(path) == "."
|
6
|
+
""
|
7
|
+
else
|
8
|
+
File.dirname(path)
|
9
|
+
end
|
7
10
|
end
|
8
11
|
|
9
12
|
def self.extname(path)
|
10
|
-
|
11
|
-
|
13
|
+
filename = basename(path)
|
14
|
+
filename_parts = filename.split(".")
|
12
15
|
|
13
|
-
if
|
14
|
-
|
16
|
+
if filename_parts.length > 1
|
17
|
+
filename_parts[-1]
|
15
18
|
else
|
16
19
|
""
|
17
20
|
end
|
18
21
|
end
|
19
22
|
|
20
23
|
def self.extnames(path)
|
21
|
-
|
22
|
-
|
24
|
+
filename = basename(path)
|
25
|
+
filename_parts = filename.split(".")
|
23
26
|
|
24
|
-
|
27
|
+
filename_parts[1..-1]
|
25
28
|
end
|
26
29
|
|
27
30
|
def self.basename(path)
|
@@ -29,10 +32,10 @@ module Munge
|
|
29
32
|
end
|
30
33
|
|
31
34
|
def self.basename_no_extension(path)
|
32
|
-
|
33
|
-
|
35
|
+
filename = basename(path)
|
36
|
+
filename_parts = filename.split(".")
|
34
37
|
|
35
|
-
|
38
|
+
filename_parts[0] || ""
|
36
39
|
end
|
37
40
|
|
38
41
|
def self.path_no_extension(path)
|
data/lib/munge/version.rb
CHANGED
data/lib/munge/write_manager.rb
CHANGED
@@ -1,10 +1,15 @@
|
|
1
1
|
module Munge
|
2
|
+
# This class decides whether an item needs to be written.
|
2
3
|
class WriteManager
|
4
|
+
# @param driver [#exist?, #read]
|
3
5
|
def initialize(driver:)
|
4
6
|
@driver = driver
|
5
7
|
@write_paths = []
|
6
8
|
end
|
7
9
|
|
10
|
+
# @param path [String] absolute path to file
|
11
|
+
# @param content [String] new content of file
|
12
|
+
# @return [Symbol] `:double_write_error`, `:identical`, `:different`
|
8
13
|
def status(path, content)
|
9
14
|
if @write_paths.include?(path)
|
10
15
|
return :double_write_error
|
@@ -1,6 +1,13 @@
|
|
1
1
|
module Munge
|
2
2
|
module Writers
|
3
|
+
# Filesystem driver for writing files. These drivers can be defined however
|
4
|
+
# you wish, as long as the `#write` method accepts an abspath and content.
|
3
5
|
class Filesystem
|
6
|
+
# Writes content to abspath. Nonexistent directories will be created
|
7
|
+
# automatically.
|
8
|
+
#
|
9
|
+
# @param abspath [String]
|
10
|
+
# @param content [String]
|
4
11
|
def write(abspath, content)
|
5
12
|
FileUtils.mkdir_p(File.dirname(abspath))
|
6
13
|
|
data/lib/munge/writers/noop.rb
CHANGED
@@ -1,6 +1,11 @@
|
|
1
1
|
module Munge
|
2
2
|
module Writers
|
3
|
+
# NoOp driver for writing files. This is used to compute dry-runs.
|
3
4
|
class Noop
|
5
|
+
# Pretends to write, but actually does nothing
|
6
|
+
#
|
7
|
+
# @param _abspath [String]
|
8
|
+
# @param _content [String]
|
4
9
|
def write(_abspath, _content)
|
5
10
|
end
|
6
11
|
end
|
data/lib/munge.rb
CHANGED
@@ -19,6 +19,7 @@ require "munge/item"
|
|
19
19
|
require "munge/util/path"
|
20
20
|
require "munge/util/symbol_hash"
|
21
21
|
require "munge/util/config"
|
22
|
+
require "munge/util/boolean_regex"
|
22
23
|
require "munge/system/router"
|
23
24
|
require "munge/system/router/itemish"
|
24
25
|
require "munge/system/item_factory"
|
@@ -26,7 +27,7 @@ require "munge/system/item_factory/content_parser"
|
|
26
27
|
require "munge/system/item_factory/item_identifier"
|
27
28
|
require "munge/system/collection"
|
28
29
|
require "munge/system/readers/filesystem"
|
29
|
-
require "munge/system/
|
30
|
+
require "munge/system/processor"
|
30
31
|
require "munge/system"
|
31
32
|
require "munge/writers/filesystem"
|
32
33
|
require "munge/writers/noop"
|
data/munge.gemspec
CHANGED
@@ -36,6 +36,7 @@ Gem::Specification.new do |spec|
|
|
36
36
|
spec.add_development_dependency "timecop", "~> 0.8"
|
37
37
|
spec.add_development_dependency "codeclimate-test-reporter", "~> 0.4"
|
38
38
|
spec.add_development_dependency "simplecov", "~> 0.10"
|
39
|
+
spec.add_development_dependency "yard", "~> 0.9.0"
|
39
40
|
|
40
41
|
spec.add_runtime_dependency "adsf", "~> 1.2"
|
41
42
|
spec.add_runtime_dependency "listen", "~> 3.0", "< 3.1"
|
@@ -43,4 +44,8 @@ Gem::Specification.new do |spec|
|
|
43
44
|
spec.add_runtime_dependency "rainbow", ">= 1.99.1", "< 3.0"
|
44
45
|
spec.add_runtime_dependency "tilt", "~> 2.0"
|
45
46
|
spec.add_runtime_dependency "sass", "~> 3.4"
|
47
|
+
|
48
|
+
if Gem::Version.new(RUBY_VERSION) < Gem::Version.new("2.3")
|
49
|
+
spec.add_runtime_dependency "rack", ">= 1.0", "< 2.0"
|
50
|
+
end
|
46
51
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: munge
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.12.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Zach Ahn
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-07-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -178,6 +178,20 @@ dependencies:
|
|
178
178
|
- - "~>"
|
179
179
|
- !ruby/object:Gem::Version
|
180
180
|
version: '0.10'
|
181
|
+
- !ruby/object:Gem::Dependency
|
182
|
+
name: yard
|
183
|
+
requirement: !ruby/object:Gem::Requirement
|
184
|
+
requirements:
|
185
|
+
- - "~>"
|
186
|
+
- !ruby/object:Gem::Version
|
187
|
+
version: 0.9.0
|
188
|
+
type: :development
|
189
|
+
prerelease: false
|
190
|
+
version_requirements: !ruby/object:Gem::Requirement
|
191
|
+
requirements:
|
192
|
+
- - "~>"
|
193
|
+
- !ruby/object:Gem::Version
|
194
|
+
version: 0.9.0
|
181
195
|
- !ruby/object:Gem::Dependency
|
182
196
|
name: adsf
|
183
197
|
requirement: !ruby/object:Gem::Requirement
|
@@ -274,7 +288,27 @@ dependencies:
|
|
274
288
|
- - "~>"
|
275
289
|
- !ruby/object:Gem::Version
|
276
290
|
version: '3.4'
|
277
|
-
|
291
|
+
- !ruby/object:Gem::Dependency
|
292
|
+
name: rack
|
293
|
+
requirement: !ruby/object:Gem::Requirement
|
294
|
+
requirements:
|
295
|
+
- - ">="
|
296
|
+
- !ruby/object:Gem::Version
|
297
|
+
version: '1.0'
|
298
|
+
- - "<"
|
299
|
+
- !ruby/object:Gem::Version
|
300
|
+
version: '2.0'
|
301
|
+
type: :runtime
|
302
|
+
prerelease: false
|
303
|
+
version_requirements: !ruby/object:Gem::Requirement
|
304
|
+
requirements:
|
305
|
+
- - ">="
|
306
|
+
- !ruby/object:Gem::Version
|
307
|
+
version: '1.0'
|
308
|
+
- - "<"
|
309
|
+
- !ruby/object:Gem::Version
|
310
|
+
version: '2.0'
|
311
|
+
description: Documentation for this release is located in https://github.com/zachahn/munge/blob/v0.12.0/README.md
|
278
312
|
email:
|
279
313
|
- zach.ahn@gmail.com
|
280
314
|
executables:
|
@@ -293,6 +327,7 @@ files:
|
|
293
327
|
- lib/munge/cli/commands/build.rb
|
294
328
|
- lib/munge/cli/commands/init.rb
|
295
329
|
- lib/munge/cli/commands/server.rb
|
330
|
+
- lib/munge/cli/commands/update.rb
|
296
331
|
- lib/munge/cli/commands/view.rb
|
297
332
|
- lib/munge/cli/dispatch.rb
|
298
333
|
- lib/munge/formatters/default.rb
|
@@ -315,15 +350,16 @@ files:
|
|
315
350
|
- lib/munge/routers/remove_index_basename.rb
|
316
351
|
- lib/munge/runner.rb
|
317
352
|
- lib/munge/system.rb
|
318
|
-
- lib/munge/system/alterant.rb
|
319
353
|
- lib/munge/system/collection.rb
|
320
354
|
- lib/munge/system/item_factory.rb
|
321
355
|
- lib/munge/system/item_factory/content_parser.rb
|
322
356
|
- lib/munge/system/item_factory/item_identifier.rb
|
357
|
+
- lib/munge/system/processor.rb
|
323
358
|
- lib/munge/system/readers/filesystem.rb
|
324
359
|
- lib/munge/system/router.rb
|
325
360
|
- lib/munge/system/router/itemish.rb
|
326
361
|
- lib/munge/transformers/tilt_transformer.rb
|
362
|
+
- lib/munge/util/boolean_regex.rb
|
327
363
|
- lib/munge/util/config.rb
|
328
364
|
- lib/munge/util/path.rb
|
329
365
|
- lib/munge/util/symbol_hash.rb
|
@@ -376,3 +412,4 @@ signing_key:
|
|
376
412
|
specification_version: 4
|
377
413
|
summary: Static site generator aiming to simplify complex build rules
|
378
414
|
test_files: []
|
415
|
+
has_rdoc:
|