lifer 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a217d32a3f6c4df0f7048d805e620929ab8f38144587843d452b7384fb70a221
4
- data.tar.gz: 4e9e38b37aa953832cfefde1f0d5d467278c75ce50825251d032f551b7789573
3
+ metadata.gz: '008dbf536d2aa375839023322316ccc00216ea3d4c8eef88792e755f1f95d2ff'
4
+ data.tar.gz: 7fae8aee316e75f8f58b817041d94afead61361a110feaa8e15c1841ea97f26d
5
5
  SHA512:
6
- metadata.gz: 7fe48ea2e1ab8d3715c93af0fa71fca53db5820ad51b83f7c506562bee14a6ec8ed06c2a8b4886c62c37933e141c10d8a97b443acee6daa3a9f28580aa4ac21f
7
- data.tar.gz: dc39315e31d0fb0129b6fe53a403ac8d721e8bc48e350f4227f9086d2c18742dd09596013fd5e138544fcdb9dd6283594f2b542d9e015a867532090a398f3838
6
+ metadata.gz: 9b40732cb604bc0661bee53c3edf621d79c22822bb1fc7b8314e580eca9e2eafb09c04b842441812bc387942952f39c4adaf0068e66688a894f060b88a8ba8e8
7
+ data.tar.gz: f5dbd68e3d6b6267a8dc5c887220a37e71d851f40926b85a762b3c9bfe532f6cf9f9f7e6ac5f3389889be0ae9bc3cdc1b70b5efa4182d1cbc647d1a786779ede
data/CHANGELOG.md CHANGED
@@ -1,3 +1,15 @@
1
+ ## Next
2
+ ## v0.5.0
3
+
4
+ This release refactors all of our builders to use parallelization, meaning that
5
+ `lifer build` process should be faster. It should be much faster for larger
6
+ projects. I'm using the `parallel` gem for parallelization at this time.
7
+
8
+ ## v0.4.1
9
+
10
+ Resolves a bug where Liquid templates using the `{% layout %}` tag were not able
11
+ to render partials.
12
+
1
13
  ## v0.4.0
2
14
 
3
15
  This release locks the `liquid` dependency to Liquid 5.6 or greater. Liquid 5.6
data/Gemfile CHANGED
@@ -9,6 +9,7 @@ gem "bump"
9
9
  gem "capybara"
10
10
 
11
11
  gem "debug", ">= 1.0.0"
12
+ gem "nokogiri"
12
13
  gem "rake", "~> 13.0"
13
14
  gem "rspec", "~> 3.0"
14
15
  gem "parallel_tests"
data/Gemfile.lock CHANGED
@@ -1,11 +1,12 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- lifer (0.4.0)
4
+ lifer (0.5.0)
5
5
  i18n (< 2)
6
6
  kramdown (~> 2.4)
7
7
  liquid (~> 5.6, < 6)
8
8
  listen (< 4)
9
+ parallel (~> 1.26, < 2)
9
10
  puma (< 7)
10
11
  rack (< 4)
11
12
  rss
@@ -83,7 +84,7 @@ GEM
83
84
  regexp_parser (2.9.2)
84
85
  reline (0.5.10)
85
86
  io-console (~> 0.5)
86
- rexml (3.4.0)
87
+ rexml (3.4.1)
87
88
  rspec (3.13.0)
88
89
  rspec-core (~> 3.13.0)
89
90
  rspec-expectations (~> 3.13.0)
data/README.md CHANGED
@@ -87,6 +87,21 @@ suite can run on your machine:
87
87
  $ bundle install
88
88
  $ bundle exec rspec
89
89
 
90
+ ### Releases
91
+
92
+ We use the Bump gem to manage releases. Before releasing a version of Lifer:
93
+
94
+ 1. Ensure unreleased changes have entries in the CHANGELOG file.
95
+ 2. Ensure all tests pass locally.
96
+
97
+ Then use Bump to perform release chores and create a version tag:
98
+
99
+ $ bundle exec bump <minor|patch> --tag --changelog --edit-changelog
100
+ $ git push origin <new_version>
101
+
102
+ (Where `new_version` is the version you intend to release. For example:
103
+ `v1.2.3`.)
104
+
90
105
  ## Contributing
91
106
 
92
107
  I'm not currently accepting unsolicited contributions to Lifer. I'm still
@@ -50,8 +50,8 @@ class Lifer::Builder::HTML::FromLiquid
50
50
  .gsub(/\{%\s*#{tag_name}.+%\}/, "")
51
51
 
52
52
  content_with_layout = Liquid::Template
53
- .parse(current_layout_file, error_mode: :strict)
54
- .render(document_context, render_options)
53
+ .parse(current_layout_file, **parse_options)
54
+ .render(document_context, **render_options)
55
55
 
56
56
  Liquid::Template
57
57
  .parse(
@@ -54,12 +54,8 @@ class Lifer::Builder::HTML < Lifer::Builder
54
54
  # @return [void]
55
55
  def execute
56
56
  Lifer.collections(without_selections: true).each do |collection|
57
- collection.entries.each do |entry|
58
- next unless entry.class.output_extension == :html
59
-
60
- generate_output_directories_for entry
61
- generate_output_file_for entry
62
- end
57
+ generate_output_directories_for collection
58
+ generate_output_entries_for collection
63
59
  end
64
60
  end
65
61
 
@@ -75,24 +71,39 @@ class Lifer::Builder::HTML < Lifer::Builder
75
71
  end
76
72
 
77
73
  # @private
78
- # For the given entry, ensure all of the paths to the file exist so the file
79
- # can be safely written to.
74
+ # For the given collection, ensure all required directories and
75
+ # subdirectories exist so the entry output can be safely written to.
80
76
  #
81
- # @param entry [Lifer::Entry] An entry.
82
- # @return [Array<String>] An array containing the directories that were just
83
- # created (or already existed).
84
- def generate_output_directories_for(entry)
85
- dirname = Pathname File.dirname(output_file entry)
86
- FileUtils.mkdir_p dirname unless Dir.exist?(dirname)
77
+ # @param entry [Lifer::Collection] A collection.
78
+ # @return [void]
79
+ def generate_output_directories_for(collection)
80
+ directories = collection.entries
81
+ .map { |entry| File.dirname(output_file entry) }
82
+ .uniq
83
+
84
+ Lifer::Utilities.parallelized(directories) do |directory|
85
+ FileUtils.mkdir_p directory unless Dir.exist?(directory)
86
+ end
87
+ end
88
+
89
+ def generate_output_entries_for(collection)
90
+ Lifer::Utilities.parallelized(collection.entries) do |entry|
91
+ generate_output_file_for entry
92
+ end
87
93
  end
88
94
 
89
95
  # @private
90
96
  # For the given entry, generate the production entry.
91
97
  #
92
98
  # @param entry [Lifer::Entry] An entry.
93
- # @return [Integer] The length of the written file. We should not care about
94
- # this return value.
99
+ # @raise [StandardError] If the file already exists, we kill the program. The
100
+ # end user needs to ensure there are no entry conflicts.
101
+ # @return [Integer, NilClass] The length of the written file, or nil if the
102
+ # entry cannot be output to HTML. We should not care about this return
103
+ # value.
95
104
  def generate_output_file_for(entry)
105
+ return unless entry.class.output_extension == :html
106
+
96
107
  relative_path = output_file entry
97
108
  absolute_path = File.join(Lifer.output_directory, relative_path)
98
109
 
@@ -117,12 +128,11 @@ class Lifer::Builder::HTML < Lifer::Builder
117
128
  when /.*\.liquid$/ then FromLiquid
118
129
  else
119
130
  file = entry.collection.setting(:layout_file)
120
- puts I18n.t(
131
+ raise I18n.t(
121
132
  "builder.html.no_builder_error",
122
133
  file:,
123
134
  type: File.extname(file)
124
135
  )
125
- exit
126
136
  end
127
137
  end
128
138
 
@@ -27,7 +27,7 @@ class Lifer::Builder::RSS < Lifer::Builder
27
27
  #
28
28
  # @return [void]
29
29
  def execute
30
- collections_with_feeds.each do |collection|
30
+ Lifer::Utilities.parallelized collections_with_feeds do |collection|
31
31
  next unless (filename = output_filename(collection))
32
32
 
33
33
  FileUtils.mkdir_p File.dirname(filename)
@@ -26,20 +26,8 @@ class Lifer::Builder::TXT < Lifer::Builder
26
26
  # @return [void]
27
27
  def execute
28
28
  Lifer.collections(without_selections: true).each do |collection|
29
- collection.entries.each do |entry|
30
- next unless entry.class.output_extension == :txt
31
-
32
- relative_path = output_file entry
33
- absolute_path = File.join(Lifer.output_directory, relative_path)
34
-
35
- FileUtils.mkdir_p File.dirname(relative_path)
36
-
37
- if File.exist?(absolute_path)
38
- raise I18n.t("builder.file_conflict_error", path: absolute_path)
39
- end
40
-
41
- File.open(relative_path, "w") { |file| file.write entry.full_text }
42
- end
29
+ generate_output_directories_for collection
30
+ generate_output_entries_for collection
43
31
  end
44
32
  end
45
33
 
@@ -51,6 +39,37 @@ class Lifer::Builder::TXT < Lifer::Builder
51
39
  @root = root
52
40
  end
53
41
 
42
+ def generate_output_directories_for(collection)
43
+ directories = collection.entries
44
+ .map { |entry| File.dirname(output_file entry) }
45
+ .uniq
46
+
47
+ Lifer::Utilities.parallelized(directories) do |directory|
48
+ FileUtils.mkdir_p directory unless Dir.exist?(directory)
49
+ end
50
+ end
51
+
52
+ def generate_output_entries_for(collection)
53
+ Lifer::Utilities.parallelized(collection.entries) do |entry|
54
+ generate_output_file_for entry
55
+ end
56
+ end
57
+
58
+ def generate_output_file_for(entry)
59
+ return unless entry.class.output_extension == :txt
60
+
61
+ relative_path = output_file entry
62
+ absolute_path = File.join(Lifer.output_directory, relative_path)
63
+
64
+ FileUtils.mkdir_p File.dirname(relative_path)
65
+
66
+ if File.exist?(absolute_path)
67
+ raise I18n.t("builder.file_conflict_error", path: absolute_path)
68
+ end
69
+
70
+ File.open(relative_path, "w") { |file| file.write entry.full_text }
71
+ end
72
+
54
73
  def output_file(entry)
55
74
  Lifer::URIStrategy
56
75
  .find(entry.collection.setting :uri_strategy)
@@ -1,3 +1,5 @@
1
+ require "parallel"
2
+
1
3
  # A module namespace for any weird utilities that are used pseudo-globally.
2
4
  # Ensure that these are actually useful globally, though. :-)
3
5
  #
@@ -66,6 +68,29 @@ module Lifer::Utilities
66
68
  # @return [String] The kabab-cased output.
67
69
  def handleize(string) = parameterize(string, separator: "-")
68
70
 
71
+ # Parallelize and fan out a collection of work in child processes. If any of
72
+ # the child processes results in an error, we raise it and halt the program.
73
+ #
74
+ # @param collection [Array] A collection to operate on.
75
+ # @yield [Object] A function to transform each collection item (in
76
+ # parallel).
77
+ # @raise [Exception] Any exception thrown by a child process.
78
+ # @return [Array] The mapped results of the operation.
79
+ def parallelized(collection, &block)
80
+ results = Parallel.map(collection) do |collection_item|
81
+ begin
82
+ yield collection_item
83
+ rescue => error
84
+ error
85
+ end
86
+ end
87
+
88
+ first_error = results.detect { _1.is_a? Exception }
89
+ raise first_error if first_error
90
+
91
+ results
92
+ end
93
+
69
94
  # Given a hash, take all of its keys (and sub-keys) and convert them into
70
95
  # strings.
71
96
  #
data/lib/lifer/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Lifer
2
- VERSION = "0.4.0"
2
+ VERSION = "0.5.0"
3
3
  end
data/lifer.gemspec CHANGED
@@ -37,10 +37,8 @@ Gem::Specification.new do |spec|
37
37
  spec.add_dependency "kramdown", "~> 2.4"
38
38
  spec.add_dependency "liquid", ["~> 5.6", "< 6"]
39
39
  spec.add_dependency "listen", "< 4"
40
+ spec.add_dependency "parallel", ["~> 1.26", "< 2"]
40
41
  spec.add_dependency "puma", "< 7"
41
42
  spec.add_dependency "rack", "< 4"
42
43
  spec.add_dependency "rss"
43
-
44
- spec.add_development_dependency "debug"
45
- spec.add_development_dependency "nokogiri"
46
44
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lifer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - benjamin wil
@@ -73,69 +73,61 @@ dependencies:
73
73
  - !ruby/object:Gem::Version
74
74
  version: '4'
75
75
  - !ruby/object:Gem::Dependency
76
- name: puma
76
+ name: parallel
77
77
  requirement: !ruby/object:Gem::Requirement
78
78
  requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '1.26'
79
82
  - - "<"
80
83
  - !ruby/object:Gem::Version
81
- version: '7'
84
+ version: '2'
82
85
  type: :runtime
83
86
  prerelease: false
84
87
  version_requirements: !ruby/object:Gem::Requirement
85
88
  requirements:
89
+ - - "~>"
90
+ - !ruby/object:Gem::Version
91
+ version: '1.26'
86
92
  - - "<"
87
93
  - !ruby/object:Gem::Version
88
- version: '7'
94
+ version: '2'
89
95
  - !ruby/object:Gem::Dependency
90
- name: rack
96
+ name: puma
91
97
  requirement: !ruby/object:Gem::Requirement
92
98
  requirements:
93
99
  - - "<"
94
100
  - !ruby/object:Gem::Version
95
- version: '4'
101
+ version: '7'
96
102
  type: :runtime
97
103
  prerelease: false
98
104
  version_requirements: !ruby/object:Gem::Requirement
99
105
  requirements:
100
106
  - - "<"
101
107
  - !ruby/object:Gem::Version
102
- version: '4'
108
+ version: '7'
103
109
  - !ruby/object:Gem::Dependency
104
- name: rss
110
+ name: rack
105
111
  requirement: !ruby/object:Gem::Requirement
106
112
  requirements:
107
- - - ">="
113
+ - - "<"
108
114
  - !ruby/object:Gem::Version
109
- version: '0'
115
+ version: '4'
110
116
  type: :runtime
111
117
  prerelease: false
112
118
  version_requirements: !ruby/object:Gem::Requirement
113
119
  requirements:
114
- - - ">="
115
- - !ruby/object:Gem::Version
116
- version: '0'
117
- - !ruby/object:Gem::Dependency
118
- name: debug
119
- requirement: !ruby/object:Gem::Requirement
120
- requirements:
121
- - - ">="
122
- - !ruby/object:Gem::Version
123
- version: '0'
124
- type: :development
125
- prerelease: false
126
- version_requirements: !ruby/object:Gem::Requirement
127
- requirements:
128
- - - ">="
120
+ - - "<"
129
121
  - !ruby/object:Gem::Version
130
- version: '0'
122
+ version: '4'
131
123
  - !ruby/object:Gem::Dependency
132
- name: nokogiri
124
+ name: rss
133
125
  requirement: !ruby/object:Gem::Requirement
134
126
  requirements:
135
127
  - - ">="
136
128
  - !ruby/object:Gem::Version
137
129
  version: '0'
138
- type: :development
130
+ type: :runtime
139
131
  prerelease: false
140
132
  version_requirements: !ruby/object:Gem::Requirement
141
133
  requirements: