lifer 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/main.yml +1 -1
  3. data/.gitignore +1 -0
  4. data/CHANGELOG.md +26 -0
  5. data/Gemfile +9 -0
  6. data/Gemfile.lock +110 -25
  7. data/LICENSE +18 -0
  8. data/README.md +79 -14
  9. data/Rakefile +2 -4
  10. data/bin/lifer +4 -2
  11. data/lib/lifer/brain.rb +171 -21
  12. data/lib/lifer/builder/html/from_erb.rb +92 -0
  13. data/lib/lifer/builder/html/from_liquid/drops/collection_drop.rb +40 -0
  14. data/lib/lifer/builder/html/from_liquid/drops/collections_drop.rb +40 -0
  15. data/lib/lifer/builder/html/from_liquid/drops/entry_drop.rb +63 -0
  16. data/lib/lifer/builder/html/from_liquid/drops/frontmatter_drop.rb +45 -0
  17. data/lib/lifer/builder/html/from_liquid/drops/settings_drop.rb +42 -0
  18. data/lib/lifer/builder/html/from_liquid/drops.rb +15 -0
  19. data/lib/lifer/builder/html/from_liquid/filters.rb +27 -0
  20. data/lib/lifer/builder/html/from_liquid/layout_tag.rb +67 -0
  21. data/lib/lifer/builder/html/from_liquid.rb +116 -0
  22. data/lib/lifer/builder/html.rb +107 -51
  23. data/lib/lifer/builder/rss.rb +113 -0
  24. data/lib/lifer/builder/txt.rb +60 -0
  25. data/lib/lifer/builder.rb +100 -1
  26. data/lib/lifer/cli.rb +105 -0
  27. data/lib/lifer/collection.rb +87 -8
  28. data/lib/lifer/config.rb +159 -31
  29. data/lib/lifer/dev/response.rb +61 -0
  30. data/lib/lifer/dev/router.rb +44 -0
  31. data/lib/lifer/dev/server.rb +97 -0
  32. data/lib/lifer/entry/html.rb +39 -0
  33. data/lib/lifer/entry/markdown.rb +162 -0
  34. data/lib/lifer/entry/txt.rb +41 -0
  35. data/lib/lifer/entry.rb +142 -41
  36. data/lib/lifer/message.rb +58 -0
  37. data/lib/lifer/selection/all_markdown.rb +16 -0
  38. data/lib/lifer/selection/included_in_feeds.rb +15 -0
  39. data/lib/lifer/selection.rb +79 -0
  40. data/lib/lifer/shared/finder_methods.rb +35 -0
  41. data/lib/lifer/shared.rb +6 -0
  42. data/lib/lifer/templates/cli.txt.erb +10 -0
  43. data/lib/lifer/templates/config.yaml +77 -0
  44. data/lib/lifer/templates/its-a-living.png +0 -0
  45. data/lib/lifer/templates/layout.html.erb +1 -1
  46. data/lib/lifer/uri_strategy/pretty.rb +14 -6
  47. data/lib/lifer/uri_strategy/pretty_root.rb +24 -0
  48. data/lib/lifer/uri_strategy/pretty_yyyy_mm_dd.rb +32 -0
  49. data/lib/lifer/uri_strategy/root.rb +17 -0
  50. data/lib/lifer/uri_strategy/simple.rb +10 -6
  51. data/lib/lifer/uri_strategy.rb +46 -6
  52. data/lib/lifer/utilities.rb +117 -0
  53. data/lib/lifer/version.rb +3 -0
  54. data/lib/lifer.rb +130 -23
  55. data/lifer.gemspec +12 -6
  56. data/locales/en.yml +54 -0
  57. metadata +142 -9
  58. data/lib/lifer/layout.rb +0 -25
  59. data/lib/lifer/templates/config +0 -4
  60. data/lib/lifer/uri_strategy/base.rb +0 -15
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c5891938dbf0269f6cf30b14cd14130025b2214e0b03b6c756d48efa1abf8ae3
4
- data.tar.gz: a6bb29832ac1e2ccde939d17f6c84643c5d8f3544d0cda7f407a696d642836e7
3
+ metadata.gz: 5b5555d8af73f17e139a069f5b18b104c7938cf8089525ecd3d27b703d388d64
4
+ data.tar.gz: 83ed1f8052bb3f7e241276ca2e7354f870429e5fd5ff5a5a2a97c36d1d756c4c
5
5
  SHA512:
6
- metadata.gz: 6cd12ec2588d1afc192352219a98e04672ce721069160bc5b3f0db5e2c91998a156318d30ee7a3299d062f32127b0cf9cc9d7eea7ece320212627c3e27344d91
7
- data.tar.gz: 1506e4a3bf8957dce6dbacccf25d75a52edf710c886a8955b979dede89b698dfc8f0a8dd1571fa6275ad8737ad0cdc2e9897503b16bb848bcaef2027ddfb8fcf
6
+ metadata.gz: b79197172aedc215a7d1acab9665406e5065b0aa32451ca5b76d89742021660f87c6ab6366edb581ab2477ad400a3a741468480d5a428cab1113544e11485c3a
7
+ data.tar.gz: e09e4484fb63f9b093b7a03ddff94ee49e0dc7c3bca1fe68e316540c9a02f4561f215f7c32bb77e842c83d1e63f30d57d252569218b8d2eddf2aa8823ce06d15
@@ -11,7 +11,7 @@ jobs:
11
11
  - name: Set up Ruby
12
12
  uses: ruby/setup-ruby@v1
13
13
  with:
14
- ruby-version: 3.1.2
14
+ ruby-version: 3.3.4
15
15
  bundler-cache: true
16
16
  - name: Run the default task
17
17
  run: bundle exec rake
data/.gitignore CHANGED
@@ -11,3 +11,4 @@ lifer*.gem
11
11
 
12
12
  # Temp files.
13
13
  /tmp/
14
+ /doc/
data/CHANGELOG.md ADDED
@@ -0,0 +1,26 @@
1
+ ## v0.3.0
2
+
3
+ This version marks the first version of Lifer that is kind of usable. The README
4
+ currently describes the big picture best. But I can that as of this version,
5
+ I've documented all of the public interfaces and added a good number of `FIXME`
6
+ comments to indicate functionality that _works_ but isn't quite where I want it
7
+ to be long term.
8
+
9
+ To manually test everything, I took my legacy Jekyll-based static site and
10
+ successfully ported it to Lifer.
11
+
12
+ The biggest thorn in my side is the Liquid rendering implementation. It works,
13
+ but the amount of trouble it was, and the not-very-serious way Liquid reports
14
+ rendering issues after build time, makes me think that this will come back to
15
+ haunt me.
16
+
17
+ Special thanks to [Chris][1] for helping me with some loading issues and
18
+ [Madeline][2] for helping me diagnose some disgusting Liquid template rendering
19
+ issues.
20
+
21
+ [1]: https://github.com/forkata
22
+ [2]: https://github.com/madelinecollier
23
+
24
+ ## v0.2.0
25
+
26
+ ![It's a living](lib/lifer/templates/its-a-living.png)
data/Gemfile CHANGED
@@ -4,5 +4,14 @@ source "https://rubygems.org"
4
4
 
5
5
  gemspec
6
6
 
7
+ gem "bump"
8
+
9
+ gem "capybara"
10
+
11
+ gem "debug", ">= 1.0.0"
7
12
  gem "rake", "~> 13.0"
8
13
  gem "rspec", "~> 3.0"
14
+ gem "parallel_tests"
15
+ gem "ruby-lsp"
16
+
17
+ gem "yard"
data/Gemfile.lock CHANGED
@@ -1,48 +1,133 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- lifer (0.1.0)
4
+ lifer (0.3.0)
5
+ i18n (< 2)
5
6
  kramdown (~> 2.4)
7
+ liquid (< 6)
8
+ listen (< 4)
9
+ puma (< 7)
10
+ rack (< 4)
11
+ rss
6
12
 
7
13
  GEM
8
14
  remote: https://rubygems.org/
9
15
  specs:
10
- debug (1.6.2)
11
- irb (>= 1.3.6)
12
- reline (>= 0.3.1)
13
- diff-lcs (1.5.0)
14
- io-console (0.5.11)
15
- irb (1.4.1)
16
- reline (>= 0.3.0)
17
- kramdown (2.4.0)
18
- rexml
19
- rake (13.0.6)
20
- reline (0.3.1)
16
+ addressable (2.8.7)
17
+ public_suffix (>= 2.0.2, < 7.0)
18
+ bigdecimal (3.1.9)
19
+ bump (0.10.0)
20
+ capybara (3.40.0)
21
+ addressable
22
+ matrix
23
+ mini_mime (>= 0.1.3)
24
+ nokogiri (~> 1.11)
25
+ rack (>= 1.6.0)
26
+ rack-test (>= 0.6.3)
27
+ regexp_parser (>= 1.5, < 3.0)
28
+ xpath (~> 3.2)
29
+ concurrent-ruby (1.3.4)
30
+ debug (1.9.2)
31
+ irb (~> 1.10)
32
+ reline (>= 0.3.8)
33
+ diff-lcs (1.5.1)
34
+ ffi (1.17.1-arm64-darwin)
35
+ ffi (1.17.1-x86_64-darwin)
36
+ ffi (1.17.1-x86_64-linux-gnu)
37
+ i18n (1.14.6)
38
+ concurrent-ruby (~> 1.0)
39
+ io-console (0.7.2)
40
+ irb (1.14.0)
41
+ rdoc (>= 4.0.0)
42
+ reline (>= 0.4.2)
43
+ kramdown (2.5.1)
44
+ rexml (>= 3.3.9)
45
+ language_server-protocol (3.17.0.3)
46
+ liquid (5.6.0)
47
+ bigdecimal
48
+ strscan
49
+ listen (3.9.0)
50
+ rb-fsevent (~> 0.10, >= 0.10.3)
51
+ rb-inotify (~> 0.9, >= 0.9.10)
52
+ logger (1.6.1)
53
+ matrix (0.4.2)
54
+ mini_mime (1.1.5)
55
+ nio4r (2.7.4)
56
+ nokogiri (1.16.7-arm64-darwin)
57
+ racc (~> 1.4)
58
+ nokogiri (1.16.7-x86_64-darwin)
59
+ racc (~> 1.4)
60
+ nokogiri (1.16.7-x86_64-linux)
61
+ racc (~> 1.4)
62
+ parallel (1.26.3)
63
+ parallel_tests (4.7.2)
64
+ parallel
65
+ prism (1.0.0)
66
+ psych (5.1.2)
67
+ stringio
68
+ public_suffix (6.0.1)
69
+ puma (6.5.0)
70
+ nio4r (~> 2.0)
71
+ racc (1.8.1)
72
+ rack (3.1.7)
73
+ rack-test (2.1.0)
74
+ rack (>= 1.3)
75
+ rake (13.2.1)
76
+ rb-fsevent (0.11.2)
77
+ rb-inotify (0.11.1)
78
+ ffi (~> 1.0)
79
+ rbs (3.5.3)
80
+ logger
81
+ rdoc (6.7.0)
82
+ psych (>= 4.0.0)
83
+ regexp_parser (2.9.2)
84
+ reline (0.5.10)
21
85
  io-console (~> 0.5)
22
- rexml (3.2.5)
23
- rspec (3.11.0)
24
- rspec-core (~> 3.11.0)
25
- rspec-expectations (~> 3.11.0)
26
- rspec-mocks (~> 3.11.0)
27
- rspec-core (3.11.0)
28
- rspec-support (~> 3.11.0)
29
- rspec-expectations (3.11.0)
86
+ rexml (3.4.0)
87
+ rspec (3.13.0)
88
+ rspec-core (~> 3.13.0)
89
+ rspec-expectations (~> 3.13.0)
90
+ rspec-mocks (~> 3.13.0)
91
+ rspec-core (3.13.1)
92
+ rspec-support (~> 3.13.0)
93
+ rspec-expectations (3.13.3)
30
94
  diff-lcs (>= 1.2.0, < 2.0)
31
- rspec-support (~> 3.11.0)
32
- rspec-mocks (3.11.1)
95
+ rspec-support (~> 3.13.0)
96
+ rspec-mocks (3.13.1)
33
97
  diff-lcs (>= 1.2.0, < 2.0)
34
- rspec-support (~> 3.11.0)
35
- rspec-support (3.11.0)
98
+ rspec-support (~> 3.13.0)
99
+ rspec-support (3.13.1)
100
+ rss (0.3.1)
101
+ rexml
102
+ ruby-lsp (0.17.17)
103
+ language_server-protocol (~> 3.17.0)
104
+ prism (~> 1.0)
105
+ rbs (>= 3, < 4)
106
+ sorbet-runtime (>= 0.5.10782)
107
+ sorbet-runtime (0.5.11558)
108
+ stringio (3.1.1)
109
+ strscan (3.1.2)
110
+ xpath (3.2.0)
111
+ nokogiri (~> 1.8)
112
+ yard (0.9.37)
36
113
 
37
114
  PLATFORMS
115
+ arm64-darwin-22
38
116
  x86_64-darwin-21
117
+ x86_64-darwin-22
39
118
  x86_64-linux
40
119
 
41
120
  DEPENDENCIES
42
- debug
121
+ bump
122
+ capybara
123
+ debug (>= 1.0.0)
43
124
  lifer!
125
+ nokogiri
126
+ parallel_tests
44
127
  rake (~> 13.0)
45
128
  rspec (~> 3.0)
129
+ ruby-lsp
130
+ yard
46
131
 
47
132
  BUNDLED WITH
48
133
  2.3.21
data/LICENSE ADDED
@@ -0,0 +1,18 @@
1
+ Copyright 2024 benjamin wil
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
4
+ this software and associated documentation files (the “Software”), to deal in
5
+ the Software without restriction, including without limitation the rights to
6
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7
+ the Software, and to permit persons to whom the Software is furnished to do so,
8
+ subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
15
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -1,35 +1,100 @@
1
1
  # Lifer
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/lifer`. To experiment with that code, run `bin/console` for an interactive prompt.
3
+ Lifer is an extensible static site generator. Out of the box, it provides a
4
+ classic static site generation experience, complete with RSS feeds, ERB template
5
+ rendering, and Liquid template rendering. Unlike other Ruby-based static site
6
+ generators, Lifer encourages you to bring your own asset pipeline and configure
7
+ it as a pre-build step.
4
8
 
5
- TODO: Delete this and the text above, and describe your gem
9
+ _Lifer is currently in pre-release. Features are incomplete. Your mileage may
10
+ vary._
11
+
12
+ **What's with the name?** Lifer aims to be easy to maintain for the lifetime of
13
+ your static site by requiring few dependencies and being very extensible by the
14
+ end user. There is no need for plugins in the form of separate Ruby gems. The
15
+ generator should also "breathe life" into your project because it's so easy to
16
+ use (🤞).
17
+
18
+ ## Features
19
+
20
+ Here's a short overview of Lifer's flagship features.
21
+
22
+ ### Bring your own asset pipeline
23
+
24
+ Whether you want to compile assets with Ruby-based tools, JavaScript-based
25
+ tools, or other tools, Lifer is okay with that. As long as those tools come with
26
+ a commandline interface, Lifer can shell out to those tools as a prebuild step.
27
+
28
+ The tradeoff here is that your templates will not be asset aware, meaning asset
29
+ fingerprinting and complex asset locating isn't really possible at this time. If
30
+ you need features like that, consider other static site generators or consider
31
+ *not* using a static site generator.
32
+
33
+ ### Collections and selections
34
+
35
+ If you have multiple collections of entries that must be output in different
36
+ ways, Lifer can help you do this. While every entry can only belong to a single
37
+ collection, you can create your own "selections" filter to group entries across
38
+ collections.
39
+
40
+ ### Extensibility
41
+
42
+ Lifer autoloads any Ruby files included in the root of your project
43
+ automatically. This lets you specify your own custom output builders, feed
44
+ formats, and meta-collections of entries.
45
+
46
+ ### Development server
47
+
48
+ Need to preview your static site before your build it on your production server?
49
+ No problem. Just use the Lifer commandline interface to start a development
50
+ server at `http://localhost:9292`:
51
+
52
+ $ lifer serve
53
+
54
+ The development server is not very sophisticated and can still be improved. But
55
+ for previewing new entries? It works just fine.
6
56
 
7
57
  ## Installation
8
58
 
9
- Add this line to your application's Gemfile:
59
+ _This installation guide assumes you already have Ruby 3 installed on your
60
+ system._
61
+
62
+ I recommend installing Lifer via Bundler. In the root directory of your static
63
+ site source, add a Gemfile if one doesn't exist already:
64
+
65
+ $ bundle init
66
+
67
+ In the Gemfile, add the `lifer` gem:
10
68
 
11
69
  ```ruby
12
- gem 'lifer'
70
+ gem "lifer", "<= 1"
13
71
  ```
14
72
 
15
73
  And then execute:
16
74
 
17
75
  $ bundle install
18
76
 
19
- Or install it yourself as:
20
-
21
- $ gem install lifer
77
+ ## Development
22
78
 
23
- ## Usage
79
+ _This development guide assumes you already have Ruby 3 installed on your
80
+ system._
24
81
 
25
- TODO: Write usage instructions here
82
+ Clone this repository, install dependencies via Bundler, and ensure the test
83
+ suite can run on your machine:
26
84
 
27
- ## Development
85
+ $ git clone https://github.com/benjaminwil/lifer lifer
86
+ $ cd lifer
87
+ $ bundle install
88
+ $ bundle exec rspec
28
89
 
29
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
90
+ ## Contributing
30
91
 
31
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
92
+ I'm not currently accepting unsolicited contributions to Lifer. I'm still
93
+ figuring out what the shape of this project is.
32
94
 
33
- ## Contributing
95
+ If you encounter bugs, please open an issue.
34
96
 
35
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/lifer.
97
+ If you have ideas for improving existing functionality or adding *missing*
98
+ functionality, please open an issue. Maybe there is room for you to contribute,
99
+ but I don't want you to waste your time preparing a merge request that I won't
100
+ accept.
data/Rakefile CHANGED
@@ -1,8 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "bundler/gem_tasks"
4
- require "rspec/core/rake_task"
4
+ require "parallel_tests/tasks"
5
5
 
6
- RSpec::Core::RakeTask.new(:spec)
7
-
8
- task default: :spec
6
+ task default: :"parallel:spec"
data/bin/lifer CHANGED
@@ -1,6 +1,8 @@
1
1
  #!/usr/bin/env -S ruby -Eutf-8
2
2
 
3
3
  require "bundler/setup"
4
- require_relative "../lib/lifer"
5
4
 
6
- Lifer.build
5
+ require "lifer"
6
+ require "lifer/cli"
7
+
8
+ Lifer::CLI.start!
data/lib/lifer/brain.rb CHANGED
@@ -1,45 +1,195 @@
1
+ require "fileutils"
2
+
3
+ require_relative "config"
4
+
5
+ # The brain is the object that keeps track of all essential information about
6
+ # the current Lifer project. Usually this information will be consumed via the
7
+ # `Lifer` module methods.
8
+ #
1
9
  class Lifer::Brain
10
+ # The default configuration file URI.
11
+ #
12
+ DEFAULT_CONFIG_FILE_URI = ".config/lifer.yaml"
13
+
2
14
  attr_reader :root
3
15
 
4
16
  class << self
5
- def init(root: Dir.pwd)
6
- new(root: root)
7
- end
17
+ # The preferred initializer for the single `Lifer::Brain` object that
18
+ # represents the user's Lifer project.
19
+ #
20
+ # @param root [String] The root Lifer project directory.
21
+ # @param config_file [String] A path to the correct Lifer config file. If
22
+ # left empty, the brain uses the one at the default path or the one
23
+ # bundled with the gem.
24
+ # @return [Lifer::Brain] The brain object for the current Lifer project.
25
+ def init(root: Dir.pwd, config_file: nil) = new(root:, config_file:)
8
26
  end
9
27
 
10
- def build!
11
- Lifer::Builder::HTML.execute(root: root)
28
+ # Destroy any existing build output and then build the Lifer project with all
29
+ # configured `Lifer::Builder`s.
30
+ #
31
+ # @param environment [Symbol] The current Lifer environment.
32
+ # @return [void] This builds the Lifer site to the configured output
33
+ # directory.
34
+ def build!(environment: :build)
35
+ brainwash!
36
+
37
+ prebuild_steps =
38
+ case setting(:global, :prebuild)
39
+ when Array, NilClass then setting(:global, :prebuild)
40
+ when Hash then setting(:global, :prebuild, environment)
41
+ end
42
+
43
+ builder_list =
44
+ case setting(:global, :build)
45
+ when Array, NilClass then setting(:global, :build)
46
+ when Hash then setting(:global, :build, environment)
47
+ end
48
+
49
+ Lifer::Builder.prebuild!(*prebuild_steps, root:)
50
+ Lifer::Builder.build!(*builder_list, root:)
12
51
  end
13
52
 
53
+ # Returns all collections and selections within the Lifer root.
54
+ #
55
+ # Collections only exist if they're explicitly configured in a configuration
56
+ # file and they match a subdirectory within the root.
57
+ #
58
+ # Selections, on the other hand, reorganize entries from literal collections.
59
+ # For example, a user could collect all of their entries that were authored
60
+ # by Harry B. Cutler.
61
+ #
62
+ # Every Lifer build contains at least one collection. (That collection is
63
+ # `:root`.)
64
+ #
65
+ # @return [Array<Lifer::Collection>] All the collections for the current Lifer
66
+ # project.
14
67
  def collections
15
- @collections ||=
68
+ @collections ||= generate_collections + generate_selections
69
+ end
70
+
71
+ # Returns the Lifer project's configuration object.
72
+ #
73
+ # @return [Lifer::Config] The Lifer configuration object.
74
+ def config = (@config ||= Lifer::Config.build file: config_file_location)
75
+
76
+ # Returns all entries that have been added to the manifest. If all is working
77
+ # as intended, this should be every entry ever generated.
78
+ #
79
+ # @return [Set<Lifer::Entry>] All entries that currently exist.
80
+ def entry_manifest = (@entry_manifest ||= Set.new)
81
+
82
+ # A manifest of all Lifer project entries.
83
+ #
84
+ # @return [Set<Lifer::Entry>] A set of all entries.
85
+ def manifest = (@manifest ||= Set.new)
86
+
87
+ # Returns the build directory for the Lifer project's build output.
88
+ #
89
+ # @return [String] The Lifer build directory.
90
+ def output_directory
91
+ @output_directory ||=
16
92
  begin
17
- collection_map =
18
- config.collections.map { |collection_name|
19
- [collection_name, "#{root}/#{collection_name}"]
20
- }.to_h.merge!({root: root})
21
-
22
- collection_map.map { |name, dir|
23
- Lifer::Collection.generate(name: name, directory: dir)
24
- }
93
+ dir = "%s/%s" % [root, setting(:global, :output_directory)]
94
+
95
+ return Pathname(dir) if Dir.exist? dir
96
+
97
+ Dir.mkdir(dir)
98
+ Pathname(dir)
25
99
  end
26
100
  end
27
101
 
28
- def config
29
- @config ||= Lifer::Config.build(file: config_file_location)
102
+ # The user can bring their own Ruby files to be read by Lifer. This ensures
103
+ # they are loaded before the build starts.
104
+ #
105
+ # Note that the user's Bundler path may be in scope, so we need to skip
106
+ # those Ruby files.
107
+ #
108
+ # @return [void]
109
+ def require_user_provided_ruby_files!
110
+ return if root.include? Lifer.gem_root
111
+
112
+ rb_files = Dir.glob("#{root}/**/*.rb", File::FNM_DOTMATCH)
113
+
114
+ if Bundler.bundle_path.to_s.include? root
115
+ rb_files -=
116
+ Dir.glob("#{Bundler.bundle_path}/**/*.rb", File::FNM_DOTMATCH)
117
+ end
118
+
119
+ rb_files.each do |rb_file|
120
+ load rb_file
121
+ end
30
122
  end
31
123
 
32
- def manifest
33
- @manifest ||= Set.new
124
+ # Given the tree of a setting name, and the setting scope, returns the setting
125
+ # value. If the in-scope collection does not have a configured setting, this
126
+ # method will return fallback settings (unless `:strict` is `true`).
127
+ #
128
+ # Example usage:
129
+ #
130
+ # setting(:my, :great, :setting)
131
+ #
132
+ # @overload setting(path, ..., collection: nil, strict: false)
133
+ # @param name [Symbol] A key in the tree to a setting value.
134
+ # @param ... [Symbol] Any additional keys in the tree.
135
+ # @param collection [Lifer::Collection] The collection to scope the result
136
+ # to.
137
+ # @param strict [boolean] If true, do not return fallback setting values.
138
+ # @return [Array, String] The value of the requested setting.
139
+ def setting(*name, collection: nil, strict: false)
140
+ config.setting *name, collection_name: collection&.name, strict: strict
34
141
  end
35
142
 
36
143
  private
37
144
 
38
- def initialize(root:)
145
+ attr_reader :config_file_location
146
+
147
+ def initialize(root:, config_file:)
39
148
  @root = root
149
+ @config_file_location = build_config_file_location(config_file)
40
150
  end
41
151
 
42
- def config_file_location
43
- File.join(root, ".config", "lifer.yaml")
152
+ def brainwash!
153
+ FileUtils.rm_r output_directory
154
+ FileUtils.mkdir_p output_directory
155
+ end
156
+
157
+ def build_config_file_location(path)
158
+ return File.join(root, DEFAULT_CONFIG_FILE_URI) if path.nil?
159
+
160
+ path.start_with?("/") ? path : File.join(root, path)
161
+ end
162
+
163
+ # FIXME:
164
+ # Do collections work with sub-subdirectories? For example, what if the
165
+ # configured collection maps to a directory:
166
+ #
167
+ # subdirectory_one/sub_subdirectory_one
168
+ #
169
+ # @return [Set<Lifer::Collection>]
170
+ def generate_collections
171
+ config.collectionables
172
+ .map { |collection_name| [collection_name, "#{root}/#{collection_name}"] }
173
+ .to_h
174
+ .merge!({root: root})
175
+ .map { |collection_name, directory|
176
+ Lifer::Collection.generate name: collection_name, directory: directory
177
+ }
178
+ .to_set
179
+ end
180
+
181
+ # @private
182
+ # Requires user-provided selection classes (classes that subclass
183
+ # `Lifer::Selection` and implement an `#entries` method) so that users can
184
+ # bring their own pseudo-collections of entries.
185
+ #
186
+ # @return [Set<Lifer::Selection>]
187
+ def generate_selections
188
+ return [] if config.file.to_s.include? Lifer.gem_root
189
+
190
+ config.setting(:selections).map { |selection_name|
191
+ klass = Lifer::Utilities.classify selection_name
192
+ klass.generate
193
+ }.to_set
44
194
  end
45
195
  end