Skip to content

Commit b67e0c7

Browse files
committed
Add unpublish command
1 parent 8dbf1e8 commit b67e0c7

File tree

3 files changed

+149
-1
lines changed

3 files changed

+149
-1
lines changed

lib/jekyll-compose.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,6 @@ module Compose
1111
end
1212
end
1313

14-
%w{draft post publish page}.each do |file|
14+
%w{draft post publish unpublish page}.each do |file|
1515
require File.expand_path("jekyll/commands/#{file}.rb", File.dirname(__FILE__))
1616
end

lib/jekyll/commands/unpublish.rb

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
module Jekyll
2+
module Commands
3+
class Unpublish < Command
4+
def self.init_with_program(prog)
5+
prog.command(:unpublish) do |c|
6+
c.syntax 'unpublish POST_PATH'
7+
c.description 'Moves a post back into the _drafts directory'
8+
9+
c.action do |args, options|
10+
process(args, options)
11+
end
12+
end
13+
end
14+
15+
def self.process(args = [], options = {})
16+
params = UnpublishArgParser.new args, options
17+
params.validate!
18+
19+
movement = PostMovementInfo.new params
20+
21+
mover = PostMover.new movement
22+
mover.move
23+
end
24+
25+
end
26+
27+
class UnpublishArgParser
28+
attr_reader :args, :options
29+
def initialize(args, options)
30+
@args = args
31+
@options = options
32+
end
33+
34+
def validate!
35+
raise ArgumentError.new('You must specify a post path.') if args.empty?
36+
end
37+
38+
def post_path
39+
args.join ' '
40+
end
41+
42+
def post_name
43+
File.basename(post_path).sub /\d{4}-\d{2}-\d{2}-/, ''
44+
end
45+
end
46+
47+
class PostMovementInfo
48+
attr_reader :params
49+
def initialize(params)
50+
@params = params
51+
end
52+
53+
def from
54+
params.post_path
55+
end
56+
57+
def to
58+
"_drafts/#{params.post_name}"
59+
end
60+
end
61+
62+
class PostMover
63+
attr_reader :movement
64+
def initialize(movement)
65+
@movement = movement
66+
end
67+
68+
def move
69+
validate_source
70+
ensure_directory_exists
71+
move_file
72+
end
73+
74+
def validate_source
75+
raise ArgumentError.new("There was no post found at '#{movement.from}'.") unless File.exist? movement.from
76+
end
77+
78+
def ensure_directory_exists
79+
Dir.mkdir("_drafts") unless Dir.exist?("_drafts")
80+
end
81+
82+
def move_file
83+
FileUtils.mv(movement.from, movement.to)
84+
puts "Post #{movement.from} was moved to #{movement.to}"
85+
end
86+
end
87+
end
88+
end

spec/unpublish_spec.rb

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
RSpec.describe(Jekyll::Commands::Unpublish) do
2+
let(:drafts_dir) { Pathname.new(source_dir('_drafts')) }
3+
let(:posts_dir) { Pathname.new(source_dir('_posts')) }
4+
let(:post_name) { "a-test-post.md" }
5+
let(:post_filename) { "2012-03-04-#{post_name}" }
6+
let(:post_path) { posts_dir.join post_filename }
7+
let(:draft_path) { drafts_dir.join post_name }
8+
9+
let(:args) { ["_posts/#{post_filename}"] }
10+
11+
before(:all) do
12+
FileUtils.mkdir_p source_dir unless File.directory? source_dir
13+
Dir.chdir source_dir
14+
end
15+
16+
before(:each) do
17+
FileUtils.mkdir_p drafts_dir unless File.directory? drafts_dir
18+
FileUtils.mkdir_p posts_dir unless File.directory? posts_dir
19+
FileUtils.touch post_path
20+
end
21+
22+
after(:each) do
23+
FileUtils.rm_r drafts_dir if File.directory? drafts_dir
24+
FileUtils.rm_r posts_dir if File.directory? posts_dir
25+
end
26+
27+
it 'moves a post back to _drafts' do
28+
expect(post_path).to exist
29+
expect(draft_path).not_to exist
30+
capture_stdout { described_class.process(args) }
31+
expect(post_path).not_to exist
32+
expect(draft_path).to exist
33+
end
34+
35+
it 'writes a helpful message on success' do
36+
expect(post_path).to exist
37+
output = capture_stdout { described_class.process(args) }
38+
expect(output).to eql("Post _posts/#{post_filename} was moved to _drafts/#{post_name}\n")
39+
end
40+
41+
it 'creates the drafts folder if necessary' do
42+
FileUtils.rm_r drafts_dir if File.directory? drafts_dir
43+
capture_stdout { described_class.process(args) }
44+
expect(drafts_dir).to exist
45+
end
46+
47+
it 'errors if there is no argument' do
48+
expect(-> {
49+
capture_stdout { described_class.process }
50+
}).to raise_error('You must specify a post path.')
51+
end
52+
53+
it 'errors if no file exists at given path' do
54+
weird_path = '_posts/i-forgot-the-date.md'
55+
expect(-> {
56+
capture_stdout { described_class.process [weird_path] }
57+
}).to raise_error("There was no post found at '#{weird_path}'.")
58+
end
59+
60+
end

0 commit comments

Comments
 (0)