jekyll-plus 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +21 -21
  3. data/README.md +209 -77
  4. data/exe/jekyll+ +56 -0
  5. data/lib/jekyll-plus.rb +28 -2
  6. data/lib/jekyll-plus/version.rb +3 -3
  7. data/lib/jekyll/commands/extract_theme.rb +152 -0
  8. data/lib/jekyll/commands/new_site.rb +260 -0
  9. data/lib/jekyll/{templates/site_template/.gitignore → site_template/.gitignore.erb} +0 -0
  10. data/lib/jekyll/{templates/classic_template → site_template}/Gemfile.erb +9 -5
  11. data/lib/jekyll/{templates/site_template → site_template}/_config.yml.erb +15 -5
  12. data/lib/jekyll/{templates/site_template → site_template}/_posts/0000-00-00-welcome-to-jekyll.md.erb +2 -0
  13. data/lib/jekyll/{templates/site_template/about.md → site_template/about.md.erb} +4 -0
  14. data/lib/jekyll/{templates/site_template/index.md → site_template/index.html.erb} +1 -0
  15. data/lib/patches/idempotent_jekyll_config.rb +41 -0
  16. data/lib/patches/jekyll_watcher.rb +59 -0
  17. data/lib/patches/listen_windows_adapter.rb +8 -0
  18. data/lib/patches/mercenary_presenter.rb +38 -0
  19. metadata +46 -38
  20. data/lib/jekyll/commands/new.rb +0 -190
  21. data/lib/jekyll/templates/classic_template/_config.yml.erb +0 -37
  22. data/lib/jekyll/templates/classic_template/theme_folders/_includes/disqus_comments.html +0 -20
  23. data/lib/jekyll/templates/classic_template/theme_folders/_includes/footer.html +0 -46
  24. data/lib/jekyll/templates/classic_template/theme_folders/_includes/google-analytics.html +0 -11
  25. data/lib/jekyll/templates/classic_template/theme_folders/_includes/head.html +0 -16
  26. data/lib/jekyll/templates/classic_template/theme_folders/_includes/header.html +0 -27
  27. data/lib/jekyll/templates/classic_template/theme_folders/_includes/icon-github.html +0 -1
  28. data/lib/jekyll/templates/classic_template/theme_folders/_includes/icon-github.svg +0 -1
  29. data/lib/jekyll/templates/classic_template/theme_folders/_includes/icon-twitter.html +0 -1
  30. data/lib/jekyll/templates/classic_template/theme_folders/_includes/icon-twitter.svg +0 -1
  31. data/lib/jekyll/templates/classic_template/theme_folders/_layouts/default.html +0 -20
  32. data/lib/jekyll/templates/classic_template/theme_folders/_layouts/home.html +0 -25
  33. data/lib/jekyll/templates/classic_template/theme_folders/_layouts/page.html +0 -14
  34. data/lib/jekyll/templates/classic_template/theme_folders/_layouts/post.html +0 -18
  35. data/lib/jekyll/templates/classic_template/theme_folders/_sass/_base.scss +0 -198
  36. data/lib/jekyll/templates/classic_template/theme_folders/_sass/_layout.scss +0 -237
  37. data/lib/jekyll/templates/classic_template/theme_folders/_sass/_syntax-highlighting.scss +0 -71
  38. data/lib/jekyll/templates/classic_template/theme_folders/assets/main.scss +0 -47
  39. data/lib/jekyll/templates/site_template/Gemfile.erb +0 -24
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d61d7047840f274b66bfbae1c9e987cb304ba6fb
4
- data.tar.gz: c9bf197e497d800e3515a9d591e898cae0bf7b0f
3
+ metadata.gz: c81971827446233240473e8b39d503ed67d32c61
4
+ data.tar.gz: a1209f152c5aa9d54f2c4b5d398bd280c1059e3e
5
5
  SHA512:
6
- metadata.gz: ee0170d39c872f61bcd51b7bc4b3b835d595aec9fa90b2fcc54bd02f7f57421a4f851b1725cdc9021b8bf80d037289879c1cef406c80454511b158579cdc497c
7
- data.tar.gz: 15a4d19d35f2c921c33953ce77aee115515d76d6a44c2bf805de38fadc41f541705b393594a6bd56840c880a4afbabe275fe0c763c2c5025faf92c9e38e3d6b1
6
+ metadata.gz: 7d22a6ee2a5e95258cdec9cb0c11d9cbbeae831bed39b7c34dd859389188b38e8600908226f75e71aacfb398e75eba4373013a175617b8ddc27458d1e6b5f295
7
+ data.tar.gz: 6fcba5a1852e29870a6dbbf92dec32d6998de7932ea0972949e6230af7faf5a24766a45452ddfdeef7b9626fd4acd5984257b5c8099ffdc5fd1617849e3956c3
@@ -1,21 +1,21 @@
1
- The MIT License (MIT)
2
-
3
- Copyright (c) 2016 Ashwin Maroli
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in
13
- all copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- THE SOFTWARE.
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016-2017 Ashwin Maroli & Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md CHANGED
@@ -1,77 +1,209 @@
1
- # Jekyll-Plus
2
-
3
- [![Gem Version](https://img.shields.io/gem/v/jekyll-plus.svg)](https://rubygems.org/gems/jekyll-plus)
4
- [![Build Status](https://img.shields.io/travis/ashmaroli/jekyll-plus/master.svg?label=Build%20Status)][travis]
5
-
6
- [travis]: https://travis-ci.org/ashmaroli/jekyll-plus
7
-
8
- A ruby gem that modifies `jekyll new` command to add new switches: `--plus`, `--classic`, `--verbose`.
9
-
10
- ## Installation
11
-
12
- Simply run:
13
-
14
- $ gem install jekyll-plus
15
-
16
- Currently, to use this gem as intended, Jekyll's native `~/commands/new.rb` file requires to be slightly modified as shown below:
17
- ```diff
18
- # lib/jekyll/commands/new.rb
19
-
20
- def init_with_program(prog)
21
- prog.command(:new) do |c|
22
- c.syntax "new PATH"
23
- c.description "Creates a new Jekyll site scaffold in PATH"
24
-
25
- c.option "force", "--force", "Force creation even if PATH already exists"
26
- c.option "blank", "--blank", "Creates scaffolding but with empty files"
27
- c.option "skip-bundle", "--skip-bundle", "Skip 'bundle install'"
28
- + c.option "plus", "--plus", "Plus features"
29
- + c.option "classic", "--classic", "Classic Jekyll scaffolding"
30
- + c.option "verbose", "--verbose", "Output messages while creating"
31
-
32
- c.action do |args, options|
33
- + if options["plus"] || options["classic"] || options["verbose"]
34
- + External.require_with_graceful_fail "jekyll-plus"
35
- + end
36
- Jekyll::Commands::New.process(args, options)
37
- end
38
- end
39
- end
40
- ```
41
- ## Usage
42
-
43
- This gem provides three new switches to be used along with the `jekyll new` command.
44
-
45
- ### `--plus`
46
-
47
- This switch creates a new Jekyll site using ERB templates for `_config.yml` and `Gemfile` and additionally initializes the directory as a git repository.
48
- The config file in such sites will be **pre-populated** with information from the argument(s) passed to `jekyll new` and from the user's `.gitconfig` file. If the git-user-details have not been configured, placeholder text will be used instead.
49
-
50
- **Note:** `site.title` will be set with `capitalized` version of the project's directory-name.
51
- This switch has no effect when used alongside the `--blank` switch.
52
-
53
- ### `--classic`
54
-
55
- This switch creates a classic-style (pre-Jekyll-3.2) Jekyll site by including the `_layouts`, `_includes`, `_sass` at the root. The directory structure has been altered to be in sync with Jekyll v3.3 and hence you'll have a `Gemfile`, `css/main.scss` is now `assets/main.scss`, etc.
56
-
57
- A *Classic Site* will:
58
- - have `Gemfile` and `_config.yml` with the line containing `minima` commented out.
59
- - have `_layouts`, `_includes`, `_sass` and `assets` at root.
60
- - the contents of these directories, in sync (to be manually updated with patch releases) with the latest `master` branch from Minima Repo.
61
- - ***not*** have `site.email` and `site.author` pre-filled with info from user's `.gitconfig` or `site.title` pre-configured from the argument(s) passed.
62
- - ***not*** run `bundle install` automatically.
63
-
64
- **Note:** `--classic` dominates `--plus` and will create a *Classic Site* when the two switches are used together.
65
-
66
- ### `--verbose`
67
-
68
- This switch prints out messages as the new Jekyll site is being created. Can be used with `--blank`, `--plus` and `--classic`.
69
-
70
- ## Contributing
71
-
72
- Bug reports and pull requests are welcome on GitHub at https://github.com/ashmaroli/jekyll-plus. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
73
-
74
-
75
- ## License
76
-
77
- The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
1
+ # JekyllPlus
2
+
3
+ [![Gem Version](https://img.shields.io/gem/v/jekyll-plus.svg)](https://rubygems.org/gems/jekyll-plus)
4
+ [![Build Status](https://img.shields.io/travis/ashmaroli/jekyll-plus/master.svg?label=Build%20Status)][travis]
5
+
6
+ [travis]: https://travis-ci.org/ashmaroli/jekyll-plus
7
+
8
+ JekyllPlus is now a tool that simplifies the installation and usage of a Jekyll Site linked to a gem-based Jekyll Theme.
9
+ *Disclaimer: This plugin works best with gem-based themes that are [serve-ready packages](#gem-recommendation).*
10
+
11
+
12
+ ## Installation
13
+
14
+ Simply run:
15
+
16
+ $ gem install jekyll-plus
17
+
18
+
19
+ ## Usage
20
+
21
+ This gem installs an executable `jekyll+` that takes a couple of new commands to enrich the Jekyll experience.<br>
22
+ **Note:** Along with the following commands, all existing Jekyll Commands are available to be used with the executable.<br>
23
+ The new additions are :
24
+
25
+
26
+ ### `new-site`
27
+
28
+ ```
29
+ jekyll+ new-site -- Creates a custom Jekyll site scaffold in PATH
30
+
31
+ Usage:
32
+
33
+ jekyll+ new-site PATH
34
+
35
+ Options:
36
+ --classic Classic Jekyll scaffolding
37
+ --theme GEM-NAME Scaffold with a custom gem-based theme
38
+ --force Force creation even if PATH already exists
39
+ --verbose Output messages while creating
40
+
41
+ ```
42
+
43
+ #### Overview
44
+
45
+ `jekyll+ new-site` is very much like `jekyll new` in that it generates a static-site precursor to be processed into an HTML website. But its also very different in the sense that `new-site` **deviates from Jekyll's no-magic philosophy**
46
+
47
+ A default site generated by `new-site` will have the site's `title` configured based on the `PATH` argument supplied.
48
+
49
+ ```sh
50
+
51
+ $ jekyll+ new-site my blog
52
+ # => New jekyll site (titled) My Blog installed in ~/my blog.
53
+
54
+ ```
55
+
56
+ ```sh
57
+
58
+ $ jekyll+ new-site blogs/summer rain
59
+ # => New jekyll site (titled) Summer Rain installed in ~/blogs/summer rain.
60
+
61
+ ```
62
+ If the user has Git installed and configured on their system, another set of keys are automatically defined &mdash; `name:` and `email:`, both of which will now be populated with the corresponding Git credentials.
63
+
64
+ This auto-populate feature extends to sites generated with `--classic` and `--theme` switches **if the theme-gem doesn't bundle a `_config.yml` within it**.
65
+
66
+ --
67
+
68
+ The `--theme` switch is for those who have decided what **theme-gem** to use with their site.<br>
69
+ Simply provide the theme's `gem-name`.<br>
70
+ e.g. To install a site with the **gem-based version** of the popular theme [Minimal Mistakes](https://github.com/mmistakes/minimal-mistakes), (`minimal-mistakes-jekyll`), simply run
71
+
72
+ $ jekyll+ new-site awesome blog --theme minimal-mistakes-jekyll
73
+
74
+ If you have an older version of the theme-gem already installed on your system, then though a new site will be immediately installed at `./awesome blog`, with the `_config.yml` and `Gemfile` already set to use this theme, the downside is that you'll still have to manually download the Minimal-Mistakes-config-file from the theme repo to be *serve-ready*
75
+
76
+ But if you have installed the [**serve-ready**](#gem-recommendation) version of the theme-gem, then by simply running the command stated above, the new site installed at `./awesome blog` will have the minimum required elements to let you serve and preview the site immediately &mdash; a Minimal-Mistakes-config-file that has all the settings for your site and the associated template files.<br>
77
+ The data files need not be copied over to the `source` unless they need to be customized. Data files within the theme-gem will be read like the remaining template files via the built-in [`jekyll-data`](https://github.com/ashmaroli/jekyll-data) plugin.
78
+
79
+ If you dont have any version of the theme installed, then `new-site` will automatically run `bundle install` and install the latest version available if you're connected to the internet.
80
+
81
+ --
82
+
83
+ When the `--classic` switch is used, the generated site will contain all the directories expected in a Jekyll installation prior to Jekyll v3.2<br>
84
+ The `--classic` and `--theme` switch can be used together to install a classic-style site with the template files and directories extracted to your `source` from the theme-gem.
85
+
86
+
87
+ #### Key Points:
88
+
89
+ * `new-site` when passed without the `--classic` or the `--theme` switch doesn't run `bundle install` at the end.
90
+
91
+ * if either `--classic` or `--theme` is used, JekyllPlus will first check if the theme-gem (defaults to "minima") is installed in the system. If not found, then it'll initiate `bundle install` to install the theme-gem.
92
+
93
+ * the `--classic` switch will run the `extract-theme` command (described below) and copy the theme's template directories and files to the site's default `source` directory. Additionally, if the theme-gem has included a `_config.yml` within it, it will be copied over too, **replacing the one currently present at `source`.**
94
+
95
+ * the `--theme` switch will initialize a `Gemfile` and a `_config.yml` with the provided `GEM-NAME`. Additionally, this too will **replace the `_config.yml` at `source` if a namesake is present at the root of the theme-gem.**
96
+
97
+ --
98
+
99
+ ### `extract-theme`
100
+
101
+ ```
102
+ jekyll+ extract-theme -- Extract files and directories from theme-gem to source
103
+
104
+ Alias: extract
105
+
106
+ Usage:
107
+
108
+ jekyll+ extract-theme [DIR (or) FILE-PATH]
109
+ jekyll+ extract [DIR (or) FILE-PATH]
110
+
111
+ Options:
112
+ --force Force extraction even if file already exists
113
+ --list List the contents of the specified [DIR]
114
+ --lax Continue extraction process if a file doesn't exist
115
+ --quiet Swallow info messages while extracting
116
+ --verbose Additional info messages while extracting
117
+
118
+ ```
119
+ `extract-theme` or `extract` does just one thing &mdash; ***copy** files or entire directories from the configured theme-gem to the site's `source` directory.* You can *extract* any combination of files and directories *within the theme-gem* as long as you know their path, relative to the theme-gem.
120
+
121
+ **Example scenario: &mdash; Extracting the theme's layouts**
122
+
123
+ * Lets first inspect the contents of the `_layouts` directory.
124
+
125
+ ```sh
126
+ $ bundle exec jekyll+ extract-theme _layouts --list
127
+ # =>
128
+ Listing: Contents of '/_layouts' in theme gem...
129
+
130
+ * /_layouts/default.html
131
+ * /_layouts/home.html
132
+ * /_layouts/page.html
133
+ * /_layouts/post.html
134
+ ..done
135
+ ```
136
+
137
+ * Now I know what layouts are available. To *extract* the entire `_layouts` directory
138
+
139
+ ```sh
140
+ bundle exec jekyll+ extract-theme _layouts
141
+ ```
142
+
143
+ * Or, to simply *extract* the layouts for posts and pages:
144
+
145
+ ```sh
146
+ bundle exec jekyll+ extract-theme _layouts/page.html _layouts/post.html
147
+ ```
148
+
149
+ * To *extract* whatever is available under the `assets` directory and the `post.html` layout:
150
+
151
+ ```sh
152
+ bundle exec jekyll+ extract-theme assets _layouts/post.html
153
+ ```
154
+
155
+ * Any file within the theme-gem can be *extracted* to `source`.
156
+
157
+ ```sh
158
+ bundle exec jekyll+ extract-theme read-me.html
159
+ ```
160
+
161
+
162
+ ## Gem Recommendation
163
+
164
+ The only functional difference between `jekyll new` and **`jekyll+ new-site`** is that the latter's `--theme` and `--classic` switches revolve around a jekyll theme-gem (either the default theme-gem "minima" or the string passed to `--theme`.)
165
+
166
+ The following are a set of recommendations directed at theme-gem developers to make their themes **serve-ready**:
167
+
168
+ * **Serve-ready theme-gems contain all the minimum elements that are required to let the consumer easily preview their site by simply running `bundle exec jekyll+ serve`**
169
+
170
+ * If your theme is dependent on a custom **`_config.yml`** that declares necessary plugins and other settings, then please don't hesitate from bundling that file within your theme-gem. `jekyll+ new-site` will then automatically **replace** the **`_config.yml`** at `source` with your bundled file. **You just need to make sure that the `theme` key is properly defined.**
171
+
172
+ * If your theme-gem requires a set of data files that impart locale-configuration (they seldom require customization), bundle them into the gem. They will be *read-in* via the included [`jekyll-data`](https://github.com/ashmaroli/jekyll-data) plugin if the user decides to `build` their site locally using `jekyll+ build` or `jekyll+ serve`.
173
+
174
+ * If your theme-gem requires certain *customizable* `data files` to exist at `source`, again, pack in the `_data` directory. It can be easily sent to your user's `source` by having them simply run `jekyll+ extract-theme _data` or `jekyll+ extract _data`. Your theme's documentation may need to instruct the user to use that command.
175
+
176
+ * Except for `index.html`, files generated by `jekyll+ new-site` do not have the `layout:` key hard-coded in the FrontMatter and hence one can easily bootstrap a site with a theme-gem provided that the theme-gem's `_config.yml` has the **Front Matter Defaults** defined, for example:
177
+
178
+ ```yaml
179
+ defaults:
180
+ - scope:
181
+ path: ""
182
+ type: posts
183
+ values:
184
+ layout: post
185
+ - scope:
186
+ path: ""
187
+ type: pages
188
+ values:
189
+ layout: page
190
+ ```
191
+
192
+ * `index.html` will take on the values defined for `pages` and hence the `layout` is set to `home` by default.
193
+
194
+
195
+ ## Plugins & Patches
196
+
197
+ * Includes the [`jekyll-data`](https://github.com/ashmaroli/jekyll-data) plugin that enables reading of data files and `_config.yml` within the theme-gem.
198
+ * Includes patches to various modules and classes used by `Jekyll` adapted from certain existing pull-requests at their respective repos and will be altered / removed as required in future releases.
199
+ For details, please [refer this file](https://github.com/ashmaroli/jekyll-plus/blob/master/lib/jekyll-plus.rb#L9-L28).
200
+
201
+ ## Contributing
202
+
203
+ Bug reports and pull requests are welcome on GitHub at https://github.com/ashmaroli/jekyll-plus.<br>
204
+ This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
205
+
206
+
207
+ ## License
208
+
209
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
@@ -0,0 +1,56 @@
1
+ #!/usr/bin/env ruby
2
+ STDOUT.sync = true
3
+
4
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
5
+
6
+ require "jekyll-plus"
7
+ require "mercenary"
8
+
9
+ Jekyll::PluginManager.require_from_bundler
10
+
11
+ Jekyll::Deprecator.process(ARGV)
12
+
13
+ Mercenary.program(:"jekyll+") do |p|
14
+ p.version JekyllPlus::VERSION
15
+ p.description "JekyllPlus is a tool that simplifies the installation and usage" \
16
+ " of a Jekyll Site linked to a gem-based Jekyll Theme."
17
+ p.syntax "jekyll+ <subcommand> [options]"
18
+
19
+ p.option "source", "-s", "--source [DIR]", "Source directory (defaults to ./)"
20
+ p.option "destination", "-d", "--destination [DIR]",
21
+ "Destination directory (defaults to ./_site)"
22
+ p.option "safe", "--safe", "Safe mode (defaults to false)"
23
+ p.option "plugins_dir", "-p", "--plugins DIR1[,DIR2[,...]]", Array,
24
+ "Plugins directory (defaults to ./_plugins)"
25
+ p.option "layouts_dir", "--layouts DIR", String,
26
+ "Layouts directory (defaults to ./_layouts)"
27
+ p.option "profile", "--profile", "Generate a Liquid rendering profile"
28
+
29
+ Jekyll::External.require_if_present(Jekyll::External.blessed_gems) do |g|
30
+ cmd = g.split("-").last
31
+ p.command(cmd.to_sym) do |c|
32
+ c.syntax cmd
33
+ c.action do
34
+ Jekyll.logger.abort_with "You must install the '#{g}' gem" \
35
+ " to use the 'jekyll #{cmd}' command."
36
+ end
37
+ end
38
+ end
39
+
40
+ Jekyll::Command.subclasses.each { |c| c.init_with_program(p) }
41
+
42
+ p.action do |args, _|
43
+ if args.empty?
44
+ Jekyll.logger.error "A subcommand is required."
45
+ puts p
46
+ abort
47
+ else
48
+ subcommand = args.first
49
+ unless p.has_command? subcommand
50
+ Jekyll.logger.abort_with "FATAL: 'jekyll+ #{args.first}' could not" \
51
+ " be found. You may need to install the jekyll-#{args.first} gem" \
52
+ " or a related gem to be able to use this subcommand.".bold
53
+ end
54
+ end
55
+ end
56
+ end
@@ -1,2 +1,28 @@
1
- require "jekyll-plus/version"
2
- require_relative "jekyll/commands/new"
1
+ require "jekyll"
2
+ require "jekyll-plus/version"
3
+ require_relative "jekyll/commands/new_site"
4
+ require_relative "jekyll/commands/extract_theme"
5
+
6
+ # Plugins
7
+ require "jekyll-data" # read "_config.yml" and data files within a theme-gem
8
+
9
+ # ------------------------------ Temporary Patches ------------------------------
10
+ # TODO:
11
+ # - remove patch to Jekyll Configuration after jekyll/jekyll/pull/5487 is merged.
12
+ # - modify patch to Mercenary after jekyll/mercenary/pull/44 and
13
+ # jekyll/mercenary/pull/48 are merged.
14
+ # - remove patch to Jekyll::Watcher after jekyll/jekyll-watch/pull/42 is merged.
15
+ # - remove patch to Listen Adapter only if any issues regarding that crop up.
16
+
17
+ require_relative "patches/idempotent_jekyll_config"
18
+
19
+ require "mercenary"
20
+ require_relative "patches/mercenary_presenter"
21
+
22
+ require "jekyll-watch"
23
+ require_relative "patches/jekyll_watcher"
24
+
25
+ require "listen"
26
+ require_relative "patches/listen_windows_adapter"
27
+
28
+ # --------------------------- End of Temporary Patches ---------------------------
@@ -1,3 +1,3 @@
1
- module JekyllPlus
2
- VERSION = "0.1.0".freeze
3
- end
1
+ module JekyllPlus
2
+ VERSION = "0.2.0".freeze
3
+ end
@@ -0,0 +1,152 @@
1
+ module Jekyll
2
+ class Commands::ExtractTheme < Command
3
+ class << self
4
+ def init_with_program(prog)
5
+ prog.command(:"extract-theme") do |c|
6
+ c.syntax "extract-theme [DIR (or) FILE-PATH]"
7
+ c.description "Extract files and directories from theme-gem to Source"
8
+ c.alias :extract
9
+
10
+ c.option "force", "--force", "Force extraction even if file already exists"
11
+ c.option "list", "--list", "List the contents of the specified [DIR]"
12
+ c.option "lax", "--lax", "Continue extraction process if a file doesn't exist"
13
+ c.option "quiet", "--quiet", "Swallow info messages while extracting"
14
+ c.option "verbose", "--verbose", "Additional info messages while extracting"
15
+
16
+ c.action do |args, options|
17
+ if args.empty?
18
+ raise ArgumentError, "You must specify a theme directory or a file path."
19
+ end
20
+ process(args, options)
21
+ end
22
+ end
23
+ end
24
+
25
+ def process(args, options = {})
26
+ @quiet = options["quiet"]
27
+ @verbose = options["verbose"]
28
+
29
+ config = Jekyll.configuration(Configuration.new)
30
+ @source = config["source"]
31
+ @theme_dir = Site.new(config).theme.root
32
+
33
+ print "Source Directory:", @source
34
+ print "Theme Directory:", @theme_dir
35
+ verbose_print ""
36
+
37
+ # Substitute leading special-characters in an argument with an
38
+ # 'underscore' to disable extraction of files outside the theme-gem
39
+ # but allow extraction of theme directories with a leading underscore.
40
+ #
41
+ # Process each valid argument individually to enable extraction of
42
+ # multiple files or directories.
43
+ args.map { |i| i.sub(%r!\A\W!, "_") }.each do |arg|
44
+ initiate_extraction arg, options
45
+ end
46
+ Jekyll.logger.info "", "..done"
47
+ end
48
+
49
+ private
50
+
51
+ def initiate_extraction(path, options)
52
+ file_path = Jekyll.sanitized_path(@theme_dir, path)
53
+ if File.exist? file_path
54
+ extract_to_source file_path, options
55
+ else
56
+ error_msg = "'#{path}' could not be found at the root of your theme-gem."
57
+ if options["lax"]
58
+ Jekyll.logger.warn "", "#{error_msg} Proceeding anyways."
59
+ verbose_print ""
60
+ else
61
+ Jekyll.logger.abort_with "ERROR:", error_msg
62
+ end
63
+ end
64
+ end
65
+
66
+ def extract_to_source(path, options)
67
+ if File.directory?(path) && options["list"]
68
+ list_contents path
69
+ elsif File.directory? path
70
+ dir_path = File.expand_path(path.split("/").last, @source)
71
+ extract_directory dir_path, path, options
72
+ elsif !File.directory?(path) && options["list"]
73
+ Jekyll.logger.warn "Error:", relative_path(path)
74
+ Jekyll.logger.warn "", "The --list switch only works for directories"
75
+ else
76
+ dir_path = File.dirname(File.join(@source, relative_path(path)))
77
+ extract_file_with_directory dir_path, path, options
78
+ end
79
+ end
80
+
81
+ def list_contents(path)
82
+ print ""
83
+ print("Listing:",
84
+ "Contents of '#{relative_path(path)}' in theme gem...")
85
+ print ""
86
+ files_in(path).each do |file|
87
+ print "*", relative_path(file)
88
+ end
89
+ end
90
+
91
+ def extract_directory(dir_path, path, options)
92
+ if File.exist?(dir_path) && !options["force"]
93
+ already_exists_msg path
94
+ else
95
+ FileUtils.cp_r path, @source
96
+ directory = "#{relative_path(path).sub("/", "")} directory"
97
+ print "Extracting:", directory
98
+ verbose_print "", "-" * directory.length
99
+ files_in(path).each do |file|
100
+ verbose_print "", dir_content_path(path, file)
101
+ end
102
+ verbose_print ""
103
+ end
104
+ end
105
+
106
+ def extract_file_with_directory(dir_path, file_path, options)
107
+ FileUtils.mkdir_p dir_path unless File.directory? dir_path
108
+ file = file_path.split("/").last
109
+ if File.exist?(File.join(dir_path, file)) && !options["force"]
110
+ already_exists_msg file
111
+ else
112
+ FileUtils.cp_r file_path, dir_path
113
+ extraction_msg file_path
114
+ end
115
+ end
116
+
117
+ def files_in(dir_path)
118
+ Dir["#{dir_path}/**/*"].reject { |d| File.directory? d }
119
+ end
120
+
121
+ def relative_path(file)
122
+ file.sub(@theme_dir, "")
123
+ end
124
+
125
+ def dir_content_path(dir, file)
126
+ relative_path(file).sub("#{relative_path(dir)}/", " * ")
127
+ end
128
+
129
+ def extraction_msg(file)
130
+ print "Extracting:", relative_path(file)
131
+ end
132
+
133
+ def already_exists_msg(file)
134
+ Jekyll.logger.warn "Error:", "'#{relative_path(file)}' already exists " \
135
+ "at destination. Use --force to overwrite."
136
+ end
137
+
138
+ def print(topic, message = "")
139
+ unless @quiet
140
+ Jekyll.logger.info topic, message
141
+ end
142
+ end
143
+
144
+ # only with --verbose switch
145
+ def verbose_print(topic, message = "")
146
+ if @verbose
147
+ Jekyll.logger.info topic, message
148
+ end
149
+ end
150
+ end
151
+ end
152
+ end