lifer 0.4.1 → 0.5.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: 0ce126108ec46665db3ad8337c07db1e11806bbb9792f5a86e5eed169925fe5d
4
- data.tar.gz: 90a6531804b57953fbd5da4d5b0488d6b9e98659111d4b5891aabc9907242ff3
3
+ metadata.gz: '008dbf536d2aa375839023322316ccc00216ea3d4c8eef88792e755f1f95d2ff'
4
+ data.tar.gz: 7fae8aee316e75f8f58b817041d94afead61361a110feaa8e15c1841ea97f26d
5
5
  SHA512:
6
- metadata.gz: 5d403fab16070747ccf5f5e756d135d0a30ebd955f3115f0cb75a549a61cb6affa8558fe17147a731f7ddee92dcc9484d529246353d0def6979ae7ebf004dd09
7
- data.tar.gz: cdbffa546204eea258e2488b765e393490103677d25754d8111b3de52429bf5e0a955f1d76e3034854319deb423befb8031120b8881d7acf9b65db1fd6ec855c
6
+ metadata.gz: 9b40732cb604bc0661bee53c3edf621d79c22822bb1fc7b8314e580eca9e2eafb09c04b842441812bc387942952f39c4adaf0068e66688a894f060b88a8ba8e8
7
+ data.tar.gz: f5dbd68e3d6b6267a8dc5c887220a37e71d851f40926b85a762b3c9bfe532f6cf9f9f7e6ac5f3389889be0ae9bc3cdc1b70b5efa4182d1cbc647d1a786779ede
data/CHANGELOG.md CHANGED
@@ -1,4 +1,9 @@
1
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.
2
7
 
3
8
  ## v0.4.1
4
9
 
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.1)
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
@@ -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.1"
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.1
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: