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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f0e20dc4cac02d09e72094542c9b723b2b6af0ee
4
- data.tar.gz: c405bf6eb3312c99c234a5efaa0fdb5257c8788b
3
+ metadata.gz: b3e1eb8424b81b08cb185b26e80273a94ff027f5
4
+ data.tar.gz: eb0dbd0f3a65fbd4ce2ab8b5e8aacc48158ee03c
5
5
  SHA512:
6
- metadata.gz: b6e966358fe33155bed90bead4ca941d3de8dd612b8069ba699fa852941de7ff44e7116626999e1a368c0adda7435ced90462b63554878fe42c6f0295bda8862
7
- data.tar.gz: 0827edc6fdd1d45682c0f9a22cac978fd7b8f1e6e69c50b6b3deae01f587411a1d0e559a1c3a18c37a37cf0a2a8dc5bd4b8cd10802742d0d9a92e5cf39053e3c
6
+ metadata.gz: fc9abaedb2d419a05eb69b45e14702e88438162df849749daa1b968b3617a6f271e5a4c89985a65adcf0c2ec2bebf5dc32298940bf9ac9e2bde95637eb8dd8e3
7
+ data.tar.gz: 814114a8a51a3e298687569cc7effde92cfb872304761633cf0df035c06f71734a7b4f6e672c009c0333627f2ea18f79c8cfc0147eb06b3bfb53806efda4f1cb
@@ -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
@@ -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
- alterant: app.vomit(:alterant),
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
@@ -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 "version", "Print version"
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
@@ -5,6 +5,7 @@ require "munge/cli/commands/init"
5
5
  require "munge/cli/commands/build"
6
6
  require "munge/cli/commands/view"
7
7
  require "munge/cli/commands/server"
8
+ require "munge/cli/commands/update"
8
9
  require "munge/cli/dispatch"
9
10
 
10
11
  require "munge/formatters/default"
@@ -2,17 +2,8 @@ module Munge
2
2
  module Formatters
3
3
  class Dots
4
4
  def initialize
5
- @counts = {
6
- new: 0,
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].push(relpath)
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 = block.call
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
- block.call
15
+ yield
16
16
  end
17
17
  end
18
18
 
@@ -2,11 +2,11 @@ module Munge
2
2
  module Helpers
3
3
  module Find
4
4
  def items
5
- @items
5
+ system.items
6
6
  end
7
7
 
8
8
  def layouts
9
- @layouts
9
+ system.layouts
10
10
  end
11
11
  end
12
12
  end
@@ -1,33 +1,28 @@
1
1
  module Munge
2
2
  module Helpers
3
3
  module Link
4
- def path_to(item)
5
- @router.route(item)
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(item, text = nil, opts = {})
9
- link = path_to(item)
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
- optstr = opts.map { |key, val| %(#{key}="#{val}") }
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
- parts.join
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
- .inject(content) do |memo, engine|
31
- options = @tilt_options[engine]
32
- template = engine.new(template_name, options) { memo }
33
-
34
- if inner
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.inject(@global_data) do |merged, datum|
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
- @layouts[item_or_string]
70
+ system.layouts[item_or_string]
78
71
  else
79
72
  item_or_string
80
73
  end
@@ -32,7 +32,7 @@ module Munge
32
32
  end
33
33
 
34
34
  def h(string)
35
- CGI.escape_html(string)
35
+ CGI.escape_html(string.to_s)
36
36
  end
37
37
  end
38
38
  end
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
- if File.dirname(@relpath) == "."
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
- File.basename(@relpath)
36
+ Munge::Util::Path.basename(@relpath)
38
37
  end
39
38
 
39
+ # @return [String] filename before the first "."
40
40
  def basename
41
- filename.split(".").first
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
- filename.split(".")[1..-1]
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 === @relpath
81
+ Munge::Util::BooleanRegex.match?(regexp, @relpath)
69
82
  end
70
83
 
71
- # do not query with slashes
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 === @route
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:, alterant:, writer:, formatter:, verbosity:, destination:)
3
+ def initialize(items:, router:, processor:, writer:, formatter:, verbosity:, destination:)
4
4
  @items = items
5
5
  @router = router
6
- @alterant = alterant
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 = @alterant.transform(item)
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
- def push(virtual_item)
34
- key = virtual_item.id
35
- @items[key] = virtual_item
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
- found_item = @items[id]
40
-
41
- if found_item.nil?
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 = compute_file_type(relpath)
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
- type = compute_file_type(relpath)
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
- if type == :text
34
- parsed = ContentParser.new(content)
35
-
36
- build(
37
- relpath: relpath,
38
- content: parsed.content,
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 compute_file_type(abspath)
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 Alterant
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
- # name should be snake_case Symbol
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
- .inject(item.content) do |content, params|
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, alterant)
8
- @item = item
9
- @alterant = alterant
7
+ def initialize(item, processor)
8
+ @item = item
9
+ @processor = processor
10
10
  end
11
11
 
12
12
  def compiled_content
13
- @compiled_content ||= @alterant.transform(@item)
13
+ @compiled_content ||= @processor.transform(@item)
14
14
  end
15
15
 
16
16
  def_delegators :@item, *%i(type relpath id frontmatter stat layout)
@@ -1,9 +1,9 @@
1
1
  module Munge
2
2
  class System
3
3
  class Router
4
- def initialize(alterant:)
4
+ def initialize(processor:)
5
5
  @registries = { route: [], filepath: [] }
6
- @alterant = alterant
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, @alterant)
38
+ itemish = Itemish.new(item, @processor)
39
39
 
40
40
  @registries[method_name]
41
41
  .select { |router| router.type == method_name }
42
- .inject(initial_route || item.route) do |route, router|
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
- source_path = File.expand_path(config[:source], root_path)
6
- layouts_path = File.expand_path(config[:layouts], root_path)
7
- data_path = File.expand_path(config[:data], root_path)
4
+ @root_path = root_path
5
+ @config = config
6
+ end
8
7
 
9
- @global_data = YAML.load_file(data_path) || {}
8
+ def items
9
+ return @items if @items
10
10
 
11
- @config = config
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
- @layouts =
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
- @alterant =
38
- Alterant.new
44
+ def processor
45
+ @processor ||= Processor.new
46
+ end
39
47
 
40
- @router =
48
+ def router
49
+ @router ||=
41
50
  Router.new(
42
- alterant: @alterant
51
+ processor: processor
43
52
  )
44
53
  end
45
- # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
46
54
 
47
- attr_accessor :alterant
48
- attr_accessor :config
49
- attr_accessor :global_data
50
- attr_accessor :router
51
- attr_accessor :items
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(scope)
5
- @pristine_scope = scope
6
- @registry = []
7
- @demands = Hash.new { Hash.new }
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 = @pristine_scope.dup
16
- scope.instance_variable_set(:@renderer, @renderer)
17
- dirty_scope = extend_with_helpers(scope)
18
- dirty_scope.instance_variable_set(:@tilt_options, @demands)
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
- private
29
+ class Scope
30
+ def initialize(system, tilt_options)
31
+ @system = system
32
+ @tilt_options = tilt_options
33
+ end
31
34
 
32
- def extend_with_helpers(scope)
33
- @registry
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
@@ -0,0 +1,13 @@
1
+ module Munge
2
+ module Util
3
+ class BooleanRegex
4
+ def self.match?(pattern, string)
5
+ if pattern =~ string
6
+ true
7
+ else
8
+ false
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -2,26 +2,29 @@ module Munge
2
2
  module Util
3
3
  class Path
4
4
  def self.dirname(path)
5
- path_parts = path.split("/")
6
- path_parts[0..-2].join("/")
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
- basename = File.basename(path)
11
- basename_parts = basename.split(".")
13
+ filename = basename(path)
14
+ filename_parts = filename.split(".")
12
15
 
13
- if basename_parts.length > 1
14
- basename_parts[-1]
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
- basename = File.basename(path)
22
- basename_parts = basename.split(".")
24
+ filename = basename(path)
25
+ filename_parts = filename.split(".")
23
26
 
24
- basename_parts[1..-1]
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
- basename = File.basename(path)
33
- basename_parts = basename.split(".")
35
+ filename = basename(path)
36
+ filename_parts = filename.split(".")
34
37
 
35
- basename_parts[0] || ""
38
+ filename_parts[0] || ""
36
39
  end
37
40
 
38
41
  def self.path_no_extension(path)
data/lib/munge/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Munge
2
- VERSION = "0.11.1".freeze
2
+ VERSION = "0.12.0".freeze
3
3
  end
@@ -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
 
@@ -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/alterant"
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
@@ -8,4 +8,4 @@ tilt_transformer.register(Munge::Helpers::AssetPaths)
8
8
  tilt_transformer.register(Munge::Helpers::AssetTags)
9
9
  tilt_transformer.register(AssetRoots)
10
10
 
11
- system.alterant.register(tilt_transformer)
11
+ system.processor.register(tilt_transformer)
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.11.1
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-06-09 00:00:00.000000000 Z
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
- description: Documentation for this release is located in https://github.com/zachahn/munge/blob/v0.11.1/README.md
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: