Skip to content

Commit 6d8fbe2

Browse files
committed
Merge pull request #2 from BennyHallett/commands
2 parents 223e9c9 + 660ec9a commit 6d8fbe2

File tree

6 files changed

+353
-0
lines changed

6 files changed

+353
-0
lines changed

lib/jekyll/commands/draft.rb

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
module Jekyll
2+
module Commands
3+
class Draft < Command
4+
def self.init_with_program(prog)
5+
prog.command(:draft) do |c|
6+
c.syntax 'draft NAME'
7+
c.description 'Creates a new draft post with the given NAME'
8+
9+
c.option 'type', '-t TYPE', '--type TYPE', 'Specify the content type'
10+
c.option 'layout', '-l LAYOUT', '--layout LAYOUT', 'Specify the post layout'
11+
c.option 'force', '-f', '--force', 'Overwrite a draft if it already exists'
12+
13+
c.action do |args, options|
14+
Jekyll::Commands::Draft.process(args, options)
15+
end
16+
end
17+
end
18+
19+
def self.process(args, options = {})
20+
raise ArgumentError.new('You must specify a name.') if args.empty?
21+
22+
type = options["type"].nil? ? "markdown" : options["type"]
23+
layout = options["layout"].nil? ? "post" : options["layout"]
24+
25+
title = args.shift
26+
name = title.gsub(' ', '-').downcase
27+
28+
draft_path = draft_name(name, type)
29+
30+
raise ArgumentError.new("A draft already exists at ./#{draft_path}") if File.exist?(draft_path) and !options["force"]
31+
32+
File.open(draft_path, "w") do |f|
33+
f.puts(front_matter(layout, title))
34+
end
35+
36+
puts "New draft created at ./#{draft_path}.\n"
37+
end
38+
# Internal: Gets the filename of the draft to be created
39+
#
40+
# Returns the filename of the draft, as a String
41+
def self.draft_name(name, ext='markdown')
42+
"_drafts/#{name}.#{ext}"
43+
end
44+
45+
def self.front_matter(layout, title)
46+
"---
47+
layout: #{layout}
48+
title: #{title}
49+
---"
50+
end
51+
end
52+
end
53+
end

lib/jekyll/commands/post.rb

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
module Jekyll
2+
module Commands
3+
class Post < Command
4+
def self.init_with_program(prog)
5+
prog.command(:post) do |c|
6+
c.syntax 'post NAME'
7+
c.description 'Creates a new post with the given NAME'
8+
9+
c.option 'type', '-t TYPE', '--type TYPE', 'Specify the content type'
10+
c.option 'layout', '-t LAYOUT', '--layout LAYOUT', 'Specify the post layout'
11+
c.option 'date', '-d DATE', '--date DATE', 'Specify the post date'
12+
c.option 'force', '-f', '--force', 'Overwrite a post if it already exists'
13+
14+
c.action do |args, options|
15+
Jekyll::Commands::Post.process(args, options)
16+
end
17+
end
18+
end
19+
20+
def self.process(args, options = {})
21+
raise ArgumentError.new('You must specify a name.') if args.empty?
22+
23+
type = options["type"].nil? ? "markdown" : options["type"]
24+
layout = options["layout"].nil? ? "post" : options["layout"]
25+
26+
date = options["date"].nil? ? Time.now : DateTime.parse(options["date"])
27+
28+
title = args.shift
29+
name = title.gsub(' ', '-').downcase
30+
31+
post_path = file_name(name, type, date)
32+
33+
raise ArgumentError.new("A post already exists at ./#{post_path}") if File.exist?(post_path) and !options["force"]
34+
35+
File.open(post_path, "w") do |f|
36+
f.puts(front_matter(layout, title))
37+
end
38+
39+
puts "New post created at ./#{post_path}.\n"
40+
end
41+
# Internal: Gets the filename of the draft to be created
42+
#
43+
# Returns the filename of the draft, as a String
44+
def self.file_name(name, ext, date)
45+
"_posts/#{date.strftime('%Y-%m-%d')}-#{name}.#{ext}"
46+
end
47+
48+
def self.front_matter(layout, title)
49+
"---
50+
layout: #{layout}
51+
title: #{title}
52+
---"
53+
end
54+
end
55+
end
56+
end

lib/jekyll/commands/publish.rb

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
module Jekyll
2+
module Commands
3+
class Publish < Command
4+
def self.init_with_program(prog)
5+
prog.command(:publish) do |c|
6+
c.syntax 'publish NAME'
7+
c.description 'Moves a draft into the _posts directory and sets the date'
8+
9+
c.option 'date', '-d DATE', '--date DATE', 'Specify the post date'
10+
11+
c.action do |args, options|
12+
Jekyll::Commands::Publish.process(args, options)
13+
end
14+
end
15+
end
16+
17+
def self.process(args, options = {})
18+
raise ArgumentError.new('You must specify a name.') if args.empty?
19+
20+
date = options["date"].nil? ? Date.today : Date.parse(options["date"])
21+
file = args.shift
22+
23+
post_path = post_name(date, file)
24+
FileUtils.mv(draft_name(file), post_path)
25+
26+
puts "Draft #{file} was published to ./#{post_path}"
27+
end
28+
29+
# Internal: Gets the filename of the post to be created
30+
#
31+
# Returns the filename of the post, as a String
32+
def self.post_name(date, name)
33+
"_posts/#{date.strftime('%Y-%m-%d')}-#{name}"
34+
end
35+
36+
def self.draft_name(name)
37+
"_drafts/#{name}"
38+
end
39+
40+
end
41+
end
42+
end

test/test_draft_command.rb

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
require 'helper'
2+
require 'jekyll/commands/draft'
3+
4+
class TestDraftCommand < Test::Unit::TestCase
5+
6+
context 'when no flags are given' do
7+
setup do
8+
@name = 'A test post'
9+
@args = [@name]
10+
@drafts_dir = '_drafts'
11+
@path = File.join(@drafts_dir, 'a-test-post.markdown')
12+
stub(Jekyll).configuration { Jekyll::Configuration::DEFAULTS }
13+
@site = Site.new(Jekyll.configuration)
14+
FileUtils.mkdir @drafts_dir
15+
end
16+
17+
teardown do
18+
FileUtils.rm_r @drafts_dir
19+
end
20+
21+
should 'create a new draft post' do
22+
assert !File.exist?(@path)
23+
capture_stdout { Jekyll::Commands::Draft.process(@args) }
24+
assert File.exist?(@path)
25+
end
26+
27+
should 'write a success message' do
28+
output = capture_stdout { Jekyll::Commands::Draft.process(@args) }
29+
success_message = "New draft created at ./#{@path}.\n"
30+
assert_equal success_message, output
31+
end
32+
end
33+
34+
context 'when the draft already exists' do
35+
setup do
36+
@name = 'An existing draft'
37+
@args = [@name]
38+
@drafts_dir = '_drafts'
39+
@path = File.join(@drafts_dir, 'an-existing-draft.markdown')
40+
stub(Jekyll).configuration { Jekyll::Configuration::DEFAULTS }
41+
@site = Site.new(Jekyll.configuration)
42+
FileUtils.mkdir @drafts_dir
43+
FileUtils.touch @path
44+
end
45+
46+
teardown do
47+
FileUtils.rm_r @drafts_dir
48+
end
49+
50+
should 'raise an ArgumentError' do
51+
exception = assert_raise ArgumentError do
52+
capture_stdout { Jekyll::Commands::Draft.process(@args) }
53+
end
54+
assert_equal "A draft already exists at ./#{@path}", exception.message
55+
end
56+
57+
should 'overwrite the existing draft if --force is given' do
58+
capture_stdout { Jekyll::Commands::Draft.process(@args, { "force" => true }) }
59+
assert File.readlines(@path).grep(/layout: post/).any?
60+
end
61+
62+
end
63+
64+
context 'when no args are given' do
65+
setup do
66+
@empty_args = []
67+
end
68+
69+
should 'raise an ArgumentError' do
70+
exception = assert_raise ArgumentError do
71+
Jekyll::Commands::Draft.process(@empty_args)
72+
end
73+
assert_equal 'You must specify a name.', exception.message
74+
end
75+
end
76+
77+
end

test/test_post_command.rb

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
require 'helper'
2+
require 'jekyll/commands/post'
3+
4+
class TestPostCommand < Test::Unit::TestCase
5+
6+
context 'when no flags are given' do
7+
setup do
8+
@name = 'A test post'
9+
@args = [@name]
10+
@posts_dir = '_posts'
11+
@path = File.join(@posts_dir, "#{Time.now.strftime('%Y-%m-%d')}-a-test-post.markdown")
12+
FileUtils.mkdir @posts_dir
13+
end
14+
15+
teardown do
16+
FileUtils.rm_r @posts_dir
17+
end
18+
19+
should 'create a new post' do
20+
assert !File.exist?(@path)
21+
capture_stdout { Jekyll::Commands::Post.process(@args) }
22+
assert File.exist?(@path)
23+
end
24+
25+
should 'write a success message' do
26+
output = capture_stdout { Jekyll::Commands::Post.process(@args) }
27+
success_message = "New post created at ./#{@path}.\n"
28+
assert_equal success_message, output
29+
end
30+
end
31+
32+
context 'when the post already exists' do
33+
setup do
34+
@name = 'An existing post'
35+
@args = [@name]
36+
@posts_dir = '_posts'
37+
@path = File.join(@posts_dir, "#{Time.now.strftime('%Y-%m-%d')}-an-existing-post.markdown")
38+
FileUtils.mkdir @posts_dir
39+
FileUtils.touch @path
40+
end
41+
42+
teardown do
43+
FileUtils.rm_r @posts_dir
44+
end
45+
46+
should 'raise an ArgumentError' do
47+
exception = assert_raise ArgumentError do
48+
capture_stdout { Jekyll::Commands::Post.process(@args) }
49+
end
50+
assert_equal "A post already exists at ./#{@path}", exception.message
51+
end
52+
53+
should 'overwrite the existing post if --force is given' do
54+
capture_stdout { Jekyll::Commands::Post.process(@args, { "force" => true }) }
55+
assert File.readlines(@path).grep(/layout: post/).any?
56+
end
57+
58+
end
59+
60+
context 'when no args are given' do
61+
setup do
62+
@empty_args = []
63+
end
64+
65+
should 'raise an ArgumentError' do
66+
exception = assert_raise ArgumentError do
67+
Jekyll::Commands::Post.process(@empty_args)
68+
end
69+
assert_equal 'You must specify a name.', exception.message
70+
end
71+
end
72+
73+
end

test/test_publish.rb

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
require 'helper'
2+
require 'date'
3+
require 'jekyll/commands/publish'
4+
5+
class TestPublishCommand < Test::Unit::TestCase
6+
7+
context 'when no flags are given' do
8+
setup do
9+
@name = 'a-test-post.markdown'
10+
@args = [@name]
11+
@drafts_dir = '_drafts'
12+
@posts_dir = '_posts'
13+
@draft_path = File.join(@drafts_dir, 'a-test-post.markdown')
14+
@post_path = File.join(@posts_dir, "#{Time.now.strftime('%Y-%m-%d')}-#{@name}")
15+
FileUtils.mkdir @drafts_dir
16+
FileUtils.mkdir @posts_dir
17+
FileUtils.touch @draft_path
18+
end
19+
20+
teardown do
21+
FileUtils.rm_r @drafts_dir
22+
FileUtils.rm_r @posts_dir
23+
end
24+
25+
should 'publish a draft post' do
26+
assert !File.exist?(@post_path), 'Post already exists'
27+
assert File.exist?(@draft_path), 'Draft does not exist'
28+
capture_stdout { Jekyll::Commands::Publish.process(@args) }
29+
assert File.exist?(@post_path), 'Post does not exist'
30+
end
31+
32+
should 'write a success message' do
33+
output = capture_stdout { Jekyll::Commands::Publish.process(@args) }
34+
success_message = "Draft #{@name} was published to ./#{@post_path}\n"
35+
assert_equal success_message, output
36+
end
37+
end
38+
39+
context 'when no args are given' do
40+
setup do
41+
@empty_args = []
42+
end
43+
44+
should 'raise an ArgumentError' do
45+
exception = assert_raise ArgumentError do
46+
Jekyll::Commands::Publish.process(@empty_args)
47+
end
48+
assert_equal 'You must specify a name.', exception.message
49+
end
50+
end
51+
52+
end

0 commit comments

Comments
 (0)