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
@@ -0,0 +1,260 @@
1
+ require "erb"
2
+
3
+ module Jekyll
4
+ class Commands::NewSite < Command
5
+ class << self
6
+ def init_with_program(prog)
7
+ prog.command(:"new-site") do |c|
8
+ c.syntax "new-site PATH"
9
+ c.description "Creates a custom Jekyll site scaffold in PATH"
10
+
11
+ c.option "classic", "--classic", "Classic Jekyll scaffolding"
12
+ c.option "theme", "--theme GEM-NAME", "Scaffold with a custom gem-based theme"
13
+ c.option "force", "--force", "Force creation even if PATH already exists"
14
+ c.option "verbose", "--verbose", "Output messages while creating"
15
+
16
+ c.action do |args, options|
17
+ raise ArgumentError, "You must specify a path." if args.empty?
18
+ process(args, options)
19
+ end
20
+ end
21
+ end
22
+
23
+ def process(args, options = {})
24
+ site_path = File.expand_path(args.join(" "), Dir.pwd)
25
+ FileUtils.mkdir_p site_path
26
+ if existing_source_location?(site_path, options)
27
+ Jekyll.logger.abort_with "Conflict:", "#{site_path} exists and is not empty."
28
+ end
29
+
30
+ initialize_git site_path if git_installed?
31
+ create_variables_from(args, options)
32
+
33
+ create_site site_path, options
34
+ end
35
+
36
+ #
37
+ # private methods
38
+ #
39
+
40
+ private
41
+
42
+ # join the arguments given, with a whitespace; replace backslashes, if any
43
+ # with a forward slash; split the string into an array again and select the
44
+ # last entry.
45
+ # Further split the entry along a single whitespace, and map to a new array
46
+ # after capitalizing the split-entries. Join them again with a whitespace
47
+ # to form the final title string.
48
+ def extract_title_from(args)
49
+ a = args.join(" ").tr("\\", "/").split("/").last
50
+ a.split.map(&:capitalize).join(" ")
51
+ end
52
+
53
+ def create_variables_from(args, options)
54
+ @verbose = options["verbose"]
55
+
56
+ @theme = options["theme"] ? options["theme"] : "minima"
57
+ @name = user_name
58
+ @email = user_email
59
+
60
+ # extract capitalized blog title from the argument(s) when a 'path'
61
+ # to the new site has been provided.
62
+ # e.g. jekyll new work/blogs/exploring ruby would install a blog
63
+ # titled 'Exploring Ruby' at path ~/work/blogs/exploring ruby
64
+ @title = extract_title_from(args)
65
+ end
66
+
67
+ def create_site(path, options)
68
+ add_foundation_files path
69
+ create_scaffold_at path
70
+
71
+ if options["classic"]
72
+ bundle_unless_theme_installed path
73
+ extract_templates_and_config path
74
+ elsif options["theme"]
75
+ bundle_unless_theme_installed path
76
+ extract_theme_config path
77
+ end
78
+
79
+ success_message path, options
80
+ end
81
+
82
+ def add_foundation_files(path)
83
+ print_header "Creating:", "Foundation files"
84
+ process_template_for "Gemfile", site_template, path
85
+ process_template_for "_config.yml", site_template, path
86
+ verbose_print ""
87
+ end
88
+
89
+ def create_scaffold_at(path)
90
+ print_header "Creating:", "Scaffold files"
91
+ FileUtils.mkdir_p(File.expand_path("_posts", path))
92
+
93
+ pages = %w(index.html about.md)
94
+ pages << ".gitignore"
95
+ pages.each do |page|
96
+ write_file(page, erb_render("#{page}.erb", site_template), path)
97
+ end
98
+ write_file(welcome_post, erb_render(scaffold_path, site_template), path)
99
+ verbose_print ""
100
+ end
101
+
102
+ def extract_templates_and_config(path)
103
+ print_header(
104
+ "Extracting:",
105
+ "Templates and _config.yml from #{@theme.cyan} if available..",
106
+ "="
107
+ )
108
+ package = %w(_layouts _includes _sass _data assets _config.yml)
109
+ package << extraction_opts
110
+
111
+ Dir.chdir(path) do
112
+ bundle_extract package
113
+ end
114
+ end
115
+
116
+ def extract_theme_config(path)
117
+ print_header(
118
+ "Extracting:",
119
+ "_config.yml from theme-gem if available..",
120
+ "="
121
+ )
122
+ package = %w(_config.yml)
123
+ package << extraction_opts
124
+
125
+ Dir.chdir(path) do
126
+ bundle_extract package
127
+ end
128
+ end
129
+
130
+ def bundle_extract(package)
131
+ system("bundle", "exec", "jekyll+ extract #{package.join(" ")}")
132
+ end
133
+
134
+ def extraction_opts
135
+ @verbose ? "--force --lax --verbose" : "--force --lax --quiet"
136
+ end
137
+
138
+ def success_message(path, options)
139
+ print_info ""
140
+ if options["classic"]
141
+ print_info "A classic-style jekyll site installed in #{path.cyan}."
142
+
143
+ elsif options["theme"]
144
+ print_info "New #{@theme.cyan} themed jekyll site installed in #{path.cyan}."
145
+
146
+ else
147
+ print_info "New jekyll site #{@title.cyan} installed in #{path.cyan}."
148
+ end
149
+ end
150
+
151
+ def bundle_unless_theme_installed(path)
152
+ print_info "Checking:", "Local theme installation..."
153
+ Gem::Specification.find_by_name(@theme)
154
+ theme_installed_msg
155
+ print_info ""
156
+ rescue Gem::LoadError
157
+ Jekyll.logger.error "Jekyll+:", "Theme #{@theme.inspect} could not be found."
158
+ bundle_install path
159
+ print_info ""
160
+ end
161
+
162
+ def bundle_install(path)
163
+ print_info "Jekyll+:", "Running bundle install in #{path.cyan}..."
164
+ Dir.chdir(path) do
165
+ process, output = Utils::Exec.run("bundle", "install")
166
+ report = output.to_s.each_line.map(&:strip)
167
+ print_info "Bundler:", report.first
168
+ report[1..-1].each { |line| print_info "", line }
169
+ raise SystemExit unless process.success?
170
+ end
171
+ end
172
+
173
+ def theme_installed_msg
174
+ print_info "", "#{@theme.inspect} local installation found." \
175
+ " Bundle install skipped".green
176
+ end
177
+
178
+ #
179
+
180
+ def process_template_for(file, source, destination)
181
+ verbose_print "", File.join(destination, file)
182
+ File.open(File.join(destination, file), "w") do |f|
183
+ f.write(
184
+ erb_render("#{file}.erb", source)
185
+ )
186
+ end
187
+ end
188
+
189
+ def write_file(filename, contents, path)
190
+ full_path = File.expand_path(filename, path)
191
+ verbose_print "", full_path
192
+ File.write(full_path, contents)
193
+ end
194
+
195
+ def erb_render(filename, source)
196
+ ERB.new(
197
+ File.read(File.expand_path(filename, source)), 0, "<>"
198
+ ).result(binding)
199
+ end
200
+
201
+ def welcome_post
202
+ "_posts/#{Time.now.strftime("%Y-%m-%d")}-welcome-to-jekyll.md"
203
+ end
204
+
205
+ def site_template
206
+ File.expand_path("../site_template", File.dirname(__FILE__))
207
+ end
208
+
209
+ def scaffold_path
210
+ "_posts/0000-00-00-welcome-to-jekyll.md.erb"
211
+ end
212
+
213
+ #
214
+
215
+ def existing_source_location?(path, options)
216
+ !options["force"] && !Dir["#{path}/**/*"].empty?
217
+ end
218
+
219
+ #
220
+
221
+ def git_installed?
222
+ process, _output = Utils::Exec.run("git", "--version")
223
+ process.success?
224
+ end
225
+
226
+ def initialize_git(path)
227
+ verbose_print "Initialising:", File.join(path, ".git")
228
+ Dir.chdir(path) { `git init` }
229
+ end
230
+
231
+ def user_name
232
+ name ||= `git config user.name`.chomp
233
+ name.empty? ? "Github User" : name
234
+ end
235
+
236
+ def user_email
237
+ email ||= `git config user.email`.chomp
238
+ email.empty? ? "your-email@domain.com" : email
239
+ end
240
+
241
+ #
242
+
243
+ def print_info(topic, message = "")
244
+ Jekyll.logger.info topic, message
245
+ end
246
+
247
+ # only with --verbose switch
248
+ def verbose_print(topic, message = "")
249
+ if @verbose
250
+ Jekyll.logger.info topic, message
251
+ end
252
+ end
253
+
254
+ def print_header(topic, message, style = "-")
255
+ print_info topic, message
256
+ verbose_print "", style * message.length
257
+ end
258
+ end
259
+ end
260
+ end
@@ -11,10 +11,11 @@ ruby "<%= RUBY_VERSION %>"
11
11
  # Happy Jekylling!
12
12
  gem "jekyll", "~> <%= Jekyll::VERSION %>"
13
13
 
14
- # This is the default theme for new Jekyll sites. You may uncomment the line
15
- # below and change to any other theme-gem. Don't forget to run `bundle install`
16
- # again after you change the setting.
17
- # gem "minima"
14
+ # The theme-gem for your site.
15
+ gem <%= @theme.inspect %><% if @theme == "minima" %>, "~> 2.0"
16
+ <% elsif @theme == "test-theme" %>, path: File.expand_path("../../../test/fixtures/test-theme", File.dirname(__FILE__))
17
+ <% end %>
18
+
18
19
 
19
20
  # If you want to use GitHub Pages, remove the "gem "jekyll"" above and
20
21
  # uncomment the line below. To upgrade, run `bundle update github-pages`.
@@ -22,5 +23,8 @@ gem "jekyll", "~> <%= Jekyll::VERSION %>"
22
23
 
23
24
  # If you have any plugins, put them here!
24
25
  group :jekyll_plugins do
25
- gem "jekyll-feed", "~> 0.6"
26
+ <% if @theme == "minima" %>
27
+ gem "jekyll-feed", "~> 0.8"
28
+ <% end %>
29
+ gem "jekyll-plus" # Required to use the jekyll+ executable to build / serve your site
26
30
  end
@@ -14,11 +14,11 @@
14
14
  # You can create any custom variable you would like, and they will be accessible
15
15
  # in the templates via {{ site.myvariable }}.
16
16
 
17
- title: <%= @blog_title %>
18
- author: <%= @user_name %>
19
- email: <%= @user_email %>
17
+ title: <%= @title %>
18
+ name: <%= @name %>
19
+ email: <%= @email %>
20
20
  # the ">" below means to ignore newlines until "baseurl:"
21
- description: >
21
+ description: > #
22
22
  Write an awesome description for your new site here. You can edit this
23
23
  line in _config.yml. It will appear in your document head meta (for
24
24
  Google search results) and in your feed.xml site description.
@@ -29,9 +29,19 @@ github_username: jekyll
29
29
 
30
30
  # Build settings
31
31
  markdown: kramdown
32
- theme: minima
32
+ theme: <%= @theme %>
33
+ <% if @theme == "minima" %>
33
34
  gems:
34
35
  - jekyll-feed
36
+ <% end %>
37
+ # Exclude from processing.
38
+ # The following items will not be processed, by default. Create a custom list
39
+ # to override the default setting.
35
40
  exclude:
36
41
  - Gemfile
37
42
  - Gemfile.lock
43
+ - node_modules
44
+ - vendor/bundle/
45
+ - vendor/cache/
46
+ - vendor/gems/
47
+ - vendor/ruby/
@@ -1,5 +1,7 @@
1
1
  ---
2
+ <% if @theme == "minima" %>
2
3
  layout: post
4
+ <% end %>
3
5
  title: "Welcome to Jekyll!"
4
6
  date: <%= Time.now.strftime('%Y-%m-%d %H:%M:%S %z') %>
5
7
  categories: jekyll update
@@ -1,11 +1,14 @@
1
1
  ---
2
+ <% if @theme == "minima" %>
2
3
  layout: page
4
+ <% end %>
3
5
  title: About
4
6
  permalink: /about/
5
7
  ---
6
8
 
7
9
  This is the base Jekyll theme. You can find out more info about customizing your Jekyll theme, as well as basic Jekyll usage documentation at [jekyllrb.com](http://jekyllrb.com/)
8
10
 
11
+ <% if @theme == "minima" %>
9
12
  You can find the source code for the Jekyll new theme at:
10
13
  {% include icon-github.html username="jekyll" %} /
11
14
  [minima](https://github.com/jekyll/minima)
@@ -13,3 +16,4 @@ You can find the source code for the Jekyll new theme at:
13
16
  You can find the source code for Jekyll at
14
17
  {% include icon-github.html username="jekyll" %} /
15
18
  [jekyll](https://github.com/jekyll/jekyll)
19
+ <% end %>
@@ -2,5 +2,6 @@
2
2
  # You don't need to edit this file, it's empty on purpose.
3
3
  # Edit theme's home layout instead if you wanna make some changes
4
4
  # See: https://jekyllrb.com/docs/themes/#overriding-theme-defaults
5
+
5
6
  layout: home
6
7
  ---
@@ -0,0 +1,41 @@
1
+ module Jekyll
2
+ class Command
3
+ def self.configuration_from_options(options)
4
+ return options if options.is_a?(Jekyll::Configuration)
5
+ Jekyll.configuration(options)
6
+ end
7
+ end
8
+
9
+ module Commands
10
+ class Serve < Command
11
+ class << self
12
+ def init_with_program(prog)
13
+ prog.command(:serve) do |cmd|
14
+ cmd.description "Serve your site locally"
15
+ cmd.syntax "serve [options]"
16
+ cmd.alias :server
17
+ cmd.alias :s
18
+
19
+ add_build_options(cmd)
20
+ COMMAND_OPTIONS.each do |key, val|
21
+ cmd.option key, *val
22
+ end
23
+
24
+ cmd.action do |_, opts|
25
+ opts["serving"] = true
26
+ opts["watch" ] = true unless opts.key?("watch")
27
+
28
+ config = configuration_from_options(opts)
29
+ if Jekyll.env == "development"
30
+ config["url"] = default_url(config)
31
+ end
32
+
33
+ Build.process(config)
34
+ Serve.process(config)
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,59 @@
1
+ require "listen"
2
+
3
+ module Jekyll
4
+ module Watcher
5
+ extend self
6
+
7
+ # Returns nothing.
8
+ def watch(options, site = nil)
9
+ ENV["LISTEN_GEM_DEBUGGING"] ||= "1" if options["verbose"]
10
+
11
+ site ||= Jekyll::Site.new(options)
12
+ listener = build_listener(site, options)
13
+ listener.start
14
+
15
+ Jekyll.logger.info "Auto-regeneration:", "#{"enabled".green} for #{options["source"]}"
16
+
17
+ unless options["serving"]
18
+ trap("INT") do
19
+ listener.stop
20
+ puts " Halting auto-regeneration."
21
+ exit 0
22
+ end
23
+
24
+ sleep_forever
25
+ end
26
+ rescue ThreadError
27
+ # You pressed Ctrl-C, oh my!
28
+ end
29
+
30
+ def listen_handler(site)
31
+ proc do |modified, added, removed|
32
+ t = Time.now
33
+ c = modified + added + removed
34
+ n = c.length
35
+ Jekyll.logger.info("Regenerating:",
36
+ "#{n} file(s) changed at #{t.strftime("%Y-%m-%d %H:%M:%S")} ")
37
+ relative_paths = c.map { |p| site.in_source_dir(p) }
38
+ relative_paths.each { |file| Jekyll.logger.info "", file.cyan }
39
+ process site, t
40
+ end
41
+ end
42
+
43
+ private
44
+
45
+ def process(site, time)
46
+ site.process
47
+ Jekyll.logger.info "", "...done in #{Time.now - time} seconds.".green
48
+ print_clear_line
49
+ rescue => e
50
+ Jekyll.logger.warn "Error:", e.message
51
+ Jekyll.logger.warn "Error:", "Run jekyll build --trace for more information."
52
+ print_clear_line
53
+ end
54
+
55
+ def print_clear_line
56
+ Jekyll.logger.info ""
57
+ end
58
+ end
59
+ end