gryphon_nest 4.1.0 → 4.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0d12483d4aed715c91f61d5a9979563fca19c11816367ed746688dd574f2389a
4
- data.tar.gz: bb86f4d32b8fc8508e76df99d7da05da883ab2c8abcb8cff6ddfd0742a513d09
3
+ metadata.gz: 455e829fa2827b15a7e0641049172d907615a4aa7bf5d29adefdb3440c71743e
4
+ data.tar.gz: 72a8c33e211645a385fb51c0581085159361e4c7d0dd62b1c284a7eb3e37cbc0
5
5
  SHA512:
6
- metadata.gz: 9d0fd32f0b95d06b21957abfe480bbc1e5ad49c160e98fb929c106d94f3da646dff0033c5207fb760975676c1a650b9c87c31844a8132bb73fa0f9971c92df13
7
- data.tar.gz: d110a25bd9513be044ac745cafd39600d096053d16e96968c2ace112cc6b7fa8ad675047eca2b30eaba34eead3da46d929d5dd6d89bd56191f34001287bd10b3
6
+ metadata.gz: b9c81a97e0bccc92c99cd1e7fd512b2e63899ab73b2de58f31a0161ad67246d27c1dc7f5fa2bc253fb4961ffa8047d79b56f26a45ca3f29b98bc5f33bdcb2c2e
7
+ data.tar.gz: 8db1246fd5023222581c26b408c98996ea935b159b1673d4b98f9cd07802c3d53109352f0f6230711260e5a4ba1f1d6b343e144e1d2e5a9e8ddddaa422fb36c1
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GryphonNest
4
+ # Wrapper class for operations performed on the layout.yaml file
5
+ class LayoutFile
6
+ # @param path [Pathname]
7
+ def initialize(path)
8
+ @path = path
9
+ @content = nil
10
+ @last_mtime = Time.now
11
+ end
12
+
13
+ # @return [Boolean]
14
+ def exist?
15
+ @path.exist?
16
+ end
17
+
18
+ # @return [Time]
19
+ def mtime
20
+ @path.mtime
21
+ end
22
+
23
+ # @return [String]
24
+ def content
25
+ mod_time = mtime
26
+
27
+ if @content.nil? || mod_time > @last_mtime
28
+ @content = @path.read
29
+ @last_mtime = mod_time
30
+ end
31
+
32
+ @content
33
+ end
34
+ end
35
+ end
@@ -8,8 +8,10 @@ module GryphonNest
8
8
  # Renders a Mustache template into a html file
9
9
  class MustacheProcessor
10
10
  # @param renderer [Renderers::MustacheRenderer]
11
- def initialize(renderer)
11
+ # @param layout_file [LayoutFile]
12
+ def initialize(renderer, layout_file)
12
13
  @renderer = renderer
14
+ @layout_file = layout_file
13
15
  end
14
16
 
15
17
  # @param src [Pathname]
@@ -17,8 +19,6 @@ module GryphonNest
17
19
  # @raise [Errors::YamlError]
18
20
  # @raise [Errors::ParseError]
19
21
  def process(src, dest)
20
- @layout ||= read_layout_file
21
-
22
22
  context = read_context(src)
23
23
  content = build_output(src, context)
24
24
  write_file(dest, content)
@@ -36,11 +36,21 @@ module GryphonNest
36
36
  path.join('index.html')
37
37
  end
38
38
 
39
- # @param _src [Pathname]
40
- # @param _dest [Pathname]
39
+ # @param src [Pathname]
40
+ # @param dest [Pathname]
41
41
  # @return [Boolean]
42
- def file_modified?(_src, _dest)
43
- true
42
+ def file_modified?(src, dest)
43
+ return true unless dest.exist?
44
+
45
+ mod_time = dest.mtime
46
+ return true if src.mtime > mod_time
47
+
48
+ path = context_file_name(src)
49
+ return true if path.exist? && path.mtime > mod_time
50
+
51
+ return false unless @layout_file.exist?
52
+
53
+ @layout_file.mtime > mod_time
44
54
  end
45
55
 
46
56
  private
@@ -49,25 +59,30 @@ module GryphonNest
49
59
  # @return [Hash]
50
60
  # @raise [Errors::YamlError]
51
61
  def read_context(src)
52
- path = src.sub(CONTENT_DIR, DATA_DIR).sub_ext('.yaml')
53
- YAML.safe_load_file(path, symbolize_names: true)
62
+ YAML.safe_load_file(context_file_name(src), symbolize_names: true)
54
63
  rescue IOError, Errno::ENOENT
55
64
  {}
56
65
  rescue Psych::SyntaxError => e
57
66
  raise Errors::YamlError, "Encountered error while reading context file. Reason: #{e.message}"
58
67
  end
59
68
 
69
+ # @param src [Pathname]
70
+ # @return [Pathname]
71
+ def context_file_name(src)
72
+ src.sub(CONTENT_DIR, DATA_DIR).sub_ext('.yaml')
73
+ end
74
+
60
75
  # @param file [Pathname]
61
76
  # @param context [Hash]
62
77
  # @return [String]
63
78
  # @raise [Errors::ParseError]
64
79
  def build_output(file, context)
65
80
  content =
66
- if @layout.empty?
67
- @renderer.render_file(file, context)
68
- else
81
+ if @layout_file.exist?
69
82
  context[:yield] = file.basename(TEMPLATE_EXT)
70
- @renderer.render(@layout, context)
83
+ @renderer.render(@layout_file.content, context)
84
+ else
85
+ @renderer.render_file(file, context)
71
86
  end
72
87
 
73
88
  HtmlBeautifier.beautify(content, stop_on_errors: true)
@@ -83,13 +98,6 @@ module GryphonNest
83
98
  path.dirname.mkpath
84
99
  path.write(content)
85
100
  end
86
-
87
- # @return [String]
88
- def read_layout_file
89
- File.read(LAYOUT_FILE)
90
- rescue IOError, Errno::ENOENT
91
- ''
92
- end
93
101
  end
94
102
  end
95
103
  end
@@ -12,9 +12,10 @@ module GryphonNest
12
12
  def create
13
13
  ProcessorRegistry.new do |reg|
14
14
  reg[TEMPLATE_EXT] = proc {
15
+ layout_file = LayoutFile.new(Pathname(LAYOUT_FILE))
15
16
  renderer = Renderers::MustacheRenderer.new
16
17
  renderer.template_path = CONTENT_DIR
17
- Processors::MustacheProcessor.new(renderer)
18
+ Processors::MustacheProcessor.new(renderer, layout_file)
18
19
  }
19
20
 
20
21
  sass_proc = proc { Processors::SassProcessor.new }
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GryphonNest
4
- VERSION = '4.1.0'
4
+ VERSION = '4.2.0'
5
5
  end
data/lib/gryphon_nest.rb CHANGED
@@ -8,6 +8,7 @@ require 'webrick'
8
8
  module GryphonNest
9
9
  autoload :Errors, 'gryphon_nest/errors'
10
10
  autoload :GzipCompressor, 'gryphon_nest/gzip_compressor'
11
+ autoload :LayoutFile, 'gryphon_nest/layout_file'
11
12
  autoload :Logging, 'gryphon_nest/logging'
12
13
  autoload :Processors, 'gryphon_nest/processors'
13
14
  autoload :Renderers, 'gryphon_nest/renderers'
@@ -29,18 +30,24 @@ module GryphonNest
29
30
  @logger = Logging.create
30
31
  @force = force
31
32
  @compressor = nil
33
+ @modifications = 0
32
34
  end
33
35
 
34
36
  # @raise [Errors::NotFoundError]
35
37
  def build
36
- raise Errors::NotFoundError, "Content directory doesn't exist in the current directory" unless Dir.exist?(CONTENT_DIR)
38
+ unless Dir.exist?(CONTENT_DIR)
39
+ raise Errors::NotFoundError, "Content directory doesn't exist in the current directory"
40
+ end
37
41
 
38
42
  Dir.mkdir(BUILD_DIR) unless Dir.exist?(BUILD_DIR)
39
43
 
40
- existing_files = glob("#{BUILD_DIR}/**/*").reject { |file| file.to_s.end_with?('.gz') }
41
- content_files = glob("#{CONTENT_DIR}/**/*")
44
+ existing_files = glob(BUILD_DIR, '[!.gz]')
45
+ content_files = glob(CONTENT_DIR)
42
46
  processed_files = content_files.collect { |src| process_file(src) }
43
- existing_files.difference(processed_files).each { |file| delete_file(file) }
47
+ files_to_delete = existing_files.difference(processed_files)
48
+ files_to_delete.each { |file| delete_file(file) }
49
+
50
+ @logger.info('No changes detected') if @modifications.zero? && files_to_delete.empty?
44
51
  end
45
52
 
46
53
  def clean
@@ -50,24 +57,15 @@ module GryphonNest
50
57
 
51
58
  def watch
52
59
  @logger.info('Watching for content changes')
53
- Listen.to(CONTENT_DIR, relative: true) do |modified, added, removed|
54
- modified.union(added).each do |file|
55
- path = Pathname(file)
56
- process_file(path)
57
- end
58
60
 
59
- removed.each do |file|
60
- path = Pathname(file)
61
- path = @processors[path.extname].dest_name(path)
62
- delete_file(path)
63
- end
64
- end.start
61
+ # Bypass modification checks, we already know the files been changed
62
+ @force = true
65
63
 
66
- Listen.to(DATA_DIR, relative: true) do |modified, added, removed|
67
- modified.union(added, removed).each do |file|
68
- path = Pathname(file)
69
- process_data_file(path)
70
- end
64
+ only = [/^#{CONTENT_DIR}/, /^#{DATA_DIR}/, /^#{LAYOUT_FILE}$/]
65
+ Listen.to('.', relative: true, only: only) do |modified, added, removed|
66
+ modified.union(added).each { |file| process_changes(file) }
67
+
68
+ removed.each { |file| process_changes(file, removal: true) }
71
69
  end.start
72
70
  end
73
71
 
@@ -89,6 +87,7 @@ module GryphonNest
89
87
  dest = processor.dest_name(src)
90
88
 
91
89
  if @force || processor.file_modified?(src, dest)
90
+ @modifications += 1
92
91
  msg = File.exist?(dest) ? 'Recreating' : 'Creating'
93
92
  @logger.info("#{msg} #{dest}")
94
93
  processor.process(src, dest)
@@ -111,6 +110,27 @@ module GryphonNest
111
110
  @compressor.compress(file)
112
111
  end
113
112
 
113
+ # @param src [String]
114
+ # @param removal [Boolean]
115
+ def process_changes(src, removal: false)
116
+ if src == LAYOUT_FILE
117
+ glob(CONTENT_DIR, TEMPLATE_EXT).each { |file| process_file(file) }
118
+ else
119
+ path = Pathname(src)
120
+
121
+ if src.start_with?(DATA_DIR)
122
+ process_data_file(path)
123
+ elsif removal
124
+ path = @processors[path.extname].dest_name(path)
125
+ delete_file(path)
126
+ else
127
+ process_file(path)
128
+ end
129
+ end
130
+ rescue StandardError => e
131
+ @logger.error(e.message)
132
+ end
133
+
114
134
  # @param src [Pathname]
115
135
  # @return [Pathname]
116
136
  def process_data_file(src)
@@ -121,23 +141,21 @@ module GryphonNest
121
141
  process_file(src)
122
142
  end
123
143
 
124
- # @params path [String]
144
+ # @params base [String]
145
+ # @params match [String]
125
146
  # @return [Array<Pathname>]
126
- def glob(path)
127
- Pathname.glob(path).reject(&:directory?)
147
+ def glob(base, match = '')
148
+ Pathname.glob("#{base}/**/*#{match}").reject(&:directory?)
128
149
  end
129
150
 
130
151
  # @param file [Pathname]
131
152
  def delete_file(file)
132
- @logger.info("Deleting #{file}")
133
- file.delete
134
-
135
- compressed = Pathname("#{file}.gz")
153
+ [file, Pathname("#{file}.gz")].each do |f|
154
+ next unless f.exist?
136
155
 
137
- return unless compressed.exist?
138
-
139
- @logger.info("Deleting #{compressed}")
140
- compressed.delete
156
+ @logger.info("Deleting #{f}")
157
+ f.delete
158
+ end
141
159
  end
142
160
  end
143
161
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gryphon_nest
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.1.0
4
+ version: 4.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Christopher Birmingham
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-06-24 00:00:00.000000000 Z
11
+ date: 2025-07-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: htmlbeautifier
@@ -122,6 +122,7 @@ files:
122
122
  - lib/gryphon_nest.rb
123
123
  - lib/gryphon_nest/errors.rb
124
124
  - lib/gryphon_nest/gzip_compressor.rb
125
+ - lib/gryphon_nest/layout_file.rb
125
126
  - lib/gryphon_nest/logging.rb
126
127
  - lib/gryphon_nest/processors.rb
127
128
  - lib/gryphon_nest/processors/asset_processor.rb