Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion History.markdown
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
## HEAD

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

Expand Down
4 changes: 3 additions & 1 deletion lib/jekyll-compose.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
require "jekyll-compose/version"
require "jekyll-compose/arg_parser"
require "jekyll-compose/movement_arg_parser"
require "jekyll-compose/file_creator"
require "jekyll-compose/file_mover"
require "jekyll-compose/file_info"

module Jekyll
Expand All @@ -11,6 +13,6 @@ module Compose
end
end

%w{draft post publish page}.each do |file|
%w{draft post publish unpublish page}.each do |file|
require File.expand_path("jekyll/commands/#{file}.rb", File.dirname(__FILE__))
end
34 changes: 34 additions & 0 deletions lib/jekyll-compose/file_mover.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
module Jekyll
module Compose
class FileMover
attr_reader :movement
def initialize(movement)
@movement = movement
end

def resource_type
'file'
end

def move
validate_source
ensure_directory_exists
move_file
end

def validate_source
raise ArgumentError.new("There was no #{resource_type} found at '#{movement.from}'.") unless File.exist? movement.from
end

def ensure_directory_exists
dir = File.dirname movement.to
Dir.mkdir(dir) unless Dir.exist?(dir)
end

def move_file
FileUtils.mv(movement.from, movement.to)
puts "#{resource_type.capitalize} #{movement.from} was moved to #{movement.to}"
end
end
end
end
19 changes: 19 additions & 0 deletions lib/jekyll-compose/movement_arg_parser.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module Jekyll
module Compose
class MovementArgParser
attr_reader :args, :options
def initialize(args, options)
@args = args
@options = options
end

def validate!
raise ArgumentError.new("You must specify a #{resource_type} path.") if args.empty?
end

def path
args.join ' '
end
end
end
end
2 changes: 1 addition & 1 deletion lib/jekyll/commands/post.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def self.process(args = [], options = {})

class PostArgParser < Compose::ArgParser
def date
date = options["date"].nil? ? Time.now : DateTime.parse(options["date"])
options["date"].nil? ? Time.now : DateTime.parse(options["date"])
end
end

Expand Down
50 changes: 35 additions & 15 deletions lib/jekyll/commands/publish.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,31 +15,51 @@ def self.init_with_program(prog)
end

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

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

raise ArgumentError.new("There was no draft found at '#{draft_path}'.") unless File.exist? draft_path
mover = DraftMover.new movement
mover.move
end

end

Dir.mkdir("_posts") unless Dir.exist?("_posts")
post_path = post_name(date, draft_name(draft_path))
FileUtils.mv(draft_path, post_path)
class PublishArgParser < Compose::MovementArgParser
def resource_type
"draft"
end

puts "Draft #{draft_path} was published to #{post_path}"
def date
options["date"].nil? ? Date.today : Date.parse(options["date"])
end

# Internal: Gets the filename of the post to be created
#
# Returns the filename of the post, as a String
def self.post_name(date, name)
"_posts/#{date.strftime('%Y-%m-%d')}-#{name}"
def name
File.basename path
end
end

def self.draft_name(path)
File.basename(path)
class DraftMovementInfo
attr_reader :params
def initialize(params)
@params = params
end

def from
params.path
end

def to
date_stamp = params.date.strftime '%Y-%m-%d'
"_posts/#{date_stamp}-#{params.name}"
end
end

class DraftMover < Compose::FileMover
def resource_type
'draft'
end
end
end
end
58 changes: 58 additions & 0 deletions lib/jekyll/commands/unpublish.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
module Jekyll
module Commands
class Unpublish < Command
def self.init_with_program(prog)
prog.command(:unpublish) do |c|
c.syntax 'unpublish POST_PATH'
c.description 'Moves a post back into the _drafts directory'

c.action do |args, options|
process(args, options)
end
end
end

def self.process(args = [], options = {})
params = UnpublishArgParser.new args, options
params.validate!

movement = PostMovementInfo.new params

mover = PostMover.new movement
mover.move
end

end

class UnpublishArgParser < Compose::MovementArgParser
def resource_type
'post'
end

def name
File.basename(path).sub /\d{4}-\d{2}-\d{2}-/, ''
end
end

class PostMovementInfo
attr_reader :params
def initialize(params)
@params = params
end

def from
params.path
end

def to
"_drafts/#{params.name}"
end
end

class PostMover < Compose::FileMover
def resource_type
'post'
end
end
end
end
29 changes: 18 additions & 11 deletions spec/publish_spec.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
RSpec.describe(Jekyll::Commands::Publish) do
let(:drafts_dir) { source_dir('_drafts') }
let(:posts_dir) { source_dir('_posts') }
let(:drafts_dir) { Pathname.new source_dir('_drafts') }
let(:posts_dir) { Pathname.new source_dir('_posts') }
let(:draft_to_publish) { 'a-test-post.md' }
let(:datestamp) { Time.now.strftime('%Y-%m-%d') }
let(:post_filename) { "#{datestamp}-#{draft_to_publish}" }
let(:args) { ["_drafts/#{draft_to_publish}"] }

let(:draft_path) { Pathname.new(File.join(drafts_dir, draft_to_publish)) }
let(:post_path) { Pathname.new(File.join(posts_dir, post_filename))}
let(:draft_path) { drafts_dir.join draft_to_publish }
let(:post_path) { posts_dir.join post_filename }

before(:all) do
FileUtils.mkdir_p source_dir unless File.directory? source_dir
Expand All @@ -28,28 +28,35 @@
end

it 'publishes a draft post' do
expect(Pathname.new(post_path)).not_to exist
expect(Pathname.new(draft_path)).to exist
expect(post_path).not_to exist
expect(draft_path).to exist
capture_stdout { described_class.process(args) }
expect(Pathname.new(post_path)).to exist
expect(post_path).to exist
end

it 'publishes with a specified date' do
path = posts_dir.join "2012-03-04-#{draft_to_publish}"
expect(path).not_to exist
capture_stdout { described_class.process(args, {'date'=>'2012-3-4'}) }
expect(path).to exist
end

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

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

it 'creates the posts folder if necessary' do
FileUtils.rm_r posts_dir if File.directory? posts_dir
capture_stdout { described_class.process(args) }
expect(Pathname.new(posts_dir)).to exist
expect(posts_dir).to exist
end

it 'errors if there is no argument' do
Expand Down
60 changes: 60 additions & 0 deletions spec/unpublish_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
RSpec.describe(Jekyll::Commands::Unpublish) do
let(:drafts_dir) { Pathname.new(source_dir('_drafts')) }
let(:posts_dir) { Pathname.new(source_dir('_posts')) }
let(:post_name) { "a-test-post.md" }
let(:post_filename) { "2012-03-04-#{post_name}" }
let(:post_path) { posts_dir.join post_filename }
let(:draft_path) { drafts_dir.join post_name }

let(:args) { ["_posts/#{post_filename}"] }

before(:all) do
FileUtils.mkdir_p source_dir unless File.directory? source_dir
Dir.chdir source_dir
end

before(:each) do
FileUtils.mkdir_p drafts_dir unless File.directory? drafts_dir
FileUtils.mkdir_p posts_dir unless File.directory? posts_dir
FileUtils.touch post_path
end

after(:each) do
FileUtils.rm_r drafts_dir if File.directory? drafts_dir
FileUtils.rm_r posts_dir if File.directory? posts_dir
end

it 'moves a post back to _drafts' do
expect(post_path).to exist
expect(draft_path).not_to exist
capture_stdout { described_class.process(args) }
expect(post_path).not_to exist
expect(draft_path).to exist
end

it 'writes a helpful message on success' do
expect(post_path).to exist
output = capture_stdout { described_class.process(args) }
expect(output).to eql("Post _posts/#{post_filename} was moved to _drafts/#{post_name}\n")
end

it 'creates the drafts folder if necessary' do
FileUtils.rm_r drafts_dir if File.directory? drafts_dir
capture_stdout { described_class.process(args) }
expect(drafts_dir).to exist
end

it 'errors if there is no argument' do
expect(-> {
capture_stdout { described_class.process }
}).to raise_error('You must specify a post path.')
end

it 'errors if no file exists at given path' do
weird_path = '_posts/i-forgot-the-date.md'
expect(-> {
capture_stdout { described_class.process [weird_path] }
}).to raise_error("There was no post found at '#{weird_path}'.")
end

end