Skip to content

Commit 099bd1a

Browse files
committed
Merge pull request #26 from FellowMD/unpublish
Add unpublish command
2 parents eca6e26 + 0cffc5e commit 099bd1a

File tree

9 files changed

+230
-29
lines changed

9 files changed

+230
-29
lines changed

History.markdown

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
## HEAD
22

3-
* Commands will create directories if necessary (#17, #23)
43
* Add the `page` command (#15)
4+
* Add the `unpublish` command (#21)
5+
* Commands will create directories if necessary (#17, #23)
56
* Display relative directories without ./ (#22)
67
* Change `-t`, `--type` options to `-x`, `--extension` (#25)
78

lib/jekyll-compose.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
require "jekyll-compose/version"
22
require "jekyll-compose/arg_parser"
3+
require "jekyll-compose/movement_arg_parser"
34
require "jekyll-compose/file_creator"
5+
require "jekyll-compose/file_mover"
46
require "jekyll-compose/file_info"
57

68
module Jekyll
@@ -11,6 +13,6 @@ module Compose
1113
end
1214
end
1315

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

lib/jekyll-compose/file_mover.rb

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
module Jekyll
2+
module Compose
3+
class FileMover
4+
attr_reader :movement
5+
def initialize(movement)
6+
@movement = movement
7+
end
8+
9+
def resource_type
10+
'file'
11+
end
12+
13+
def move
14+
validate_source
15+
ensure_directory_exists
16+
move_file
17+
end
18+
19+
def validate_source
20+
raise ArgumentError.new("There was no #{resource_type} found at '#{movement.from}'.") unless File.exist? movement.from
21+
end
22+
23+
def ensure_directory_exists
24+
dir = File.dirname movement.to
25+
Dir.mkdir(dir) unless Dir.exist?(dir)
26+
end
27+
28+
def move_file
29+
FileUtils.mv(movement.from, movement.to)
30+
puts "#{resource_type.capitalize} #{movement.from} was moved to #{movement.to}"
31+
end
32+
end
33+
end
34+
end
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
module Jekyll
2+
module Compose
3+
class MovementArgParser
4+
attr_reader :args, :options
5+
def initialize(args, options)
6+
@args = args
7+
@options = options
8+
end
9+
10+
def validate!
11+
raise ArgumentError.new("You must specify a #{resource_type} path.") if args.empty?
12+
end
13+
14+
def path
15+
args.join ' '
16+
end
17+
end
18+
end
19+
end

lib/jekyll/commands/post.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ def self.process(args = [], options = {})
3333

3434
class PostArgParser < Compose::ArgParser
3535
def date
36-
date = options["date"].nil? ? Time.now : DateTime.parse(options["date"])
36+
options["date"].nil? ? Time.now : DateTime.parse(options["date"])
3737
end
3838
end
3939

lib/jekyll/commands/publish.rb

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,31 +15,51 @@ def self.init_with_program(prog)
1515
end
1616

1717
def self.process(args = [], options = {})
18-
raise ArgumentError.new('You must specify a draft path.') if args.empty?
18+
params = PublishArgParser.new args, options
19+
params.validate!
1920

20-
date = options["date"].nil? ? Date.today : Date.parse(options["date"])
21-
draft_path = args.shift
21+
movement = DraftMovementInfo.new params
2222

23-
raise ArgumentError.new("There was no draft found at '#{draft_path}'.") unless File.exist? draft_path
23+
mover = DraftMover.new movement
24+
mover.move
25+
end
26+
27+
end
2428

25-
Dir.mkdir("_posts") unless Dir.exist?("_posts")
26-
post_path = post_name(date, draft_name(draft_path))
27-
FileUtils.mv(draft_path, post_path)
29+
class PublishArgParser < Compose::MovementArgParser
30+
def resource_type
31+
"draft"
32+
end
2833

29-
puts "Draft #{draft_path} was published to #{post_path}"
34+
def date
35+
options["date"].nil? ? Date.today : Date.parse(options["date"])
3036
end
3137

32-
# Internal: Gets the filename of the post to be created
33-
#
34-
# Returns the filename of the post, as a String
35-
def self.post_name(date, name)
36-
"_posts/#{date.strftime('%Y-%m-%d')}-#{name}"
38+
def name
39+
File.basename path
3740
end
41+
end
3842

39-
def self.draft_name(path)
40-
File.basename(path)
43+
class DraftMovementInfo
44+
attr_reader :params
45+
def initialize(params)
46+
@params = params
4147
end
4248

49+
def from
50+
params.path
51+
end
52+
53+
def to
54+
date_stamp = params.date.strftime '%Y-%m-%d'
55+
"_posts/#{date_stamp}-#{params.name}"
56+
end
57+
end
58+
59+
class DraftMover < Compose::FileMover
60+
def resource_type
61+
'draft'
62+
end
4363
end
4464
end
4565
end

lib/jekyll/commands/unpublish.rb

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
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 < Compose::MovementArgParser
28+
def resource_type
29+
'post'
30+
end
31+
32+
def name
33+
File.basename(path).sub /\d{4}-\d{2}-\d{2}-/, ''
34+
end
35+
end
36+
37+
class PostMovementInfo
38+
attr_reader :params
39+
def initialize(params)
40+
@params = params
41+
end
42+
43+
def from
44+
params.path
45+
end
46+
47+
def to
48+
"_drafts/#{params.name}"
49+
end
50+
end
51+
52+
class PostMover < Compose::FileMover
53+
def resource_type
54+
'post'
55+
end
56+
end
57+
end
58+
end

spec/publish_spec.rb

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
RSpec.describe(Jekyll::Commands::Publish) do
2-
let(:drafts_dir) { source_dir('_drafts') }
3-
let(:posts_dir) { source_dir('_posts') }
2+
let(:drafts_dir) { Pathname.new source_dir('_drafts') }
3+
let(:posts_dir) { Pathname.new source_dir('_posts') }
44
let(:draft_to_publish) { 'a-test-post.md' }
55
let(:datestamp) { Time.now.strftime('%Y-%m-%d') }
66
let(:post_filename) { "#{datestamp}-#{draft_to_publish}" }
77
let(:args) { ["_drafts/#{draft_to_publish}"] }
88

9-
let(:draft_path) { Pathname.new(File.join(drafts_dir, draft_to_publish)) }
10-
let(:post_path) { Pathname.new(File.join(posts_dir, post_filename))}
9+
let(:draft_path) { drafts_dir.join draft_to_publish }
10+
let(:post_path) { posts_dir.join post_filename }
1111

1212
before(:all) do
1313
FileUtils.mkdir_p source_dir unless File.directory? source_dir
@@ -28,28 +28,35 @@
2828
end
2929

3030
it 'publishes a draft post' do
31-
expect(Pathname.new(post_path)).not_to exist
32-
expect(Pathname.new(draft_path)).to exist
31+
expect(post_path).not_to exist
32+
expect(draft_path).to exist
3333
capture_stdout { described_class.process(args) }
34-
expect(Pathname.new(post_path)).to exist
34+
expect(post_path).to exist
35+
end
36+
37+
it 'publishes with a specified date' do
38+
path = posts_dir.join "2012-03-04-#{draft_to_publish}"
39+
expect(path).not_to exist
40+
capture_stdout { described_class.process(args, {'date'=>'2012-3-4'}) }
41+
expect(path).to exist
3542
end
3643

3744
it 'writes a helpful message on success' do
38-
expect(Pathname.new(draft_path)).to exist
45+
expect(draft_path).to exist
3946
output = capture_stdout { described_class.process(args) }
40-
expect(output).to eql("Draft _drafts/#{draft_to_publish} was published to _posts/#{post_filename}\n")
47+
expect(output).to eql("Draft _drafts/#{draft_to_publish} was moved to _posts/#{post_filename}\n")
4148
end
4249

4350
it 'publishes a draft on the specified date' do
44-
path = Pathname.new(posts_dir).join "2012-03-04-a-test-post.md"
51+
path = posts_dir.join "2012-03-04-a-test-post.md"
4552
capture_stdout { described_class.process(args, {"date" => '2012-3-4'}) }
4653
expect(path).to exist
4754
end
4855

4956
it 'creates the posts folder if necessary' do
5057
FileUtils.rm_r posts_dir if File.directory? posts_dir
5158
capture_stdout { described_class.process(args) }
52-
expect(Pathname.new(posts_dir)).to exist
59+
expect(posts_dir).to exist
5360
end
5461

5562
it 'errors if there is no argument' do

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)