jekyll_and_hyde 0.0.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -1,4 +1,7 @@
1
+ .DS_Store
1
2
  pkg/*
2
3
  *.gem
3
4
  .bundle
4
- Gemfile.lock
5
+ Gemfile.lock
6
+ *.iml
7
+ .idea
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --colour --format documentation
data/bin/jh ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- mode: ruby -*-
3
+
4
+ require 'jekyll_and_hyde'
5
+ JekyllAndHyde::Runner.start
@@ -0,0 +1,12 @@
1
+ Feature: presenter creates a skeletal installation
2
+
3
+ Scenario: creates a skeletal installation
4
+ Given the jekyll_and_hyde gem installed
5
+ When I run the "jh new test" command inside folder "/"
6
+ Then I should have a folder named "test" created
7
+ And I should have template files/folders "_config.yml, _includes, _layouts, index.html, stylesheets, .git, .gitmodules, slippy" inside folder "test"
8
+
9
+ Scenario: creates a skeletal installation with GitHub project page branch setup
10
+ Given the jekyll_and_hyde gem installed
11
+ When I run the "jh new test --github" command inside folder "/"
12
+ Then I should have a git branch named "gh-pages" created in folder "test"
@@ -0,0 +1,6 @@
1
+ Feature: presenter creates slides
2
+
3
+ Scenario: creates a slide
4
+ Given I run the "jh new test" command inside folder "/"
5
+ When I run the "jh generate test-slide" command inside folder "test"
6
+ Then I should have a file named "test-slide.markdown" prefixed with timestamp created in posts folder "test/_posts"
@@ -0,0 +1,42 @@
1
+ Before do
2
+ FileUtils.mkdir_p(DESTINATION_ROOT)
3
+ end
4
+
5
+ After do
6
+ FileUtils.rm_rf(DESTINATION_ROOT)
7
+ end
8
+
9
+ Given /^the jekyll_and_hyde gem installed$/ do
10
+ end
11
+
12
+ When /^I run the "jh ([^"]*)" command inside folder "([^"]*)"$/ do |parameters, folder|
13
+ parameters = parameters.split.map(&:strip)
14
+ task = parameters.shift
15
+ args, opts = Thor::Options.split(parameters)
16
+
17
+ @task = JekyllAndHyde::Util.find_task_class(task).new(args, opts)
18
+ @task.destination_root = File.join(DESTINATION_ROOT, folder)
19
+ @task.invoke(JekyllAndHyde.to_namespace(task))
20
+ end
21
+
22
+ Then /^I should have a folder named "([^"]*)" created$/ do |folder_name|
23
+ File.should be_directory(File.join(DESTINATION_ROOT, folder_name))
24
+ end
25
+
26
+ And /^I should have template files\/folders "([^"]*)" inside folder "([^"]*)"$/ do |template_files, folder_name|
27
+ template_files.split(',').map(&:strip).each do |template_file|
28
+ File.should be_exist(File.join(DESTINATION_ROOT, folder_name, template_file))
29
+ end
30
+ end
31
+
32
+ Then /^I should have a git branch named "([^"]*)" created in folder "([^"]*)"$/ do |branch_name, folder_name|
33
+ output = IO.popen("cd #{File.join(DESTINATION_ROOT, folder_name)} && git branch")
34
+ output.readlines.first.include?(branch_name)
35
+ end
36
+
37
+ Then /^I should have a file named "([^"]*)" prefixed with timestamp created in posts folder "([^"]*)"$/ do |file_name, folder_name|
38
+ posts_folder = Dir[File.join(DESTINATION_ROOT, folder_name, "**", "*.*")]
39
+ posts_folder.should have(1).file
40
+ post_file_name = posts_folder.first.scan(/\d\d\d\d-\d\d-\d\d-\d\d-\d\d-\d\d-(.*)/).flatten.first
41
+ post_file_name.should == file_name
42
+ end
@@ -0,0 +1,4 @@
1
+ $LOAD_PATH << File.expand_path('../../../lib', __FILE__)
2
+ require 'jekyll_and_hyde'
3
+
4
+ DESTINATION_ROOT = File.expand_path('../../test_target', File.dirname(__FILE__))
@@ -13,10 +13,13 @@ Gem::Specification.new do |s|
13
13
  s.description = %q{jekyll_and_hyde is a simple HTML presentation generator based on jekyll(https://github.com/mojombo/jekyll) and slippy(https://github.com/Seldaek/slippy).}
14
14
 
15
15
  s.rubyforge_project = "jekyll_and_hyde"
16
-
16
+
17
+ s.add_dependency('thor')
18
+
17
19
  s.add_development_dependency('rspec')
18
20
  s.add_development_dependency('cucumber')
19
-
21
+ s.add_development_dependency('fakefs')
22
+
20
23
  s.files = `git ls-files`.split("\n")
21
24
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
22
25
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
@@ -0,0 +1,20 @@
1
+ module JekyllAndHyde
2
+ module Actions
3
+ def inside_app_path(config = {}, &block)
4
+ inside app_path, config, &block
5
+ end
6
+
7
+ def run_command(command, config={})
8
+ result = run(command, config)
9
+ raise Error, "Errors occured when running command \"#{command}\"." unless result
10
+ end
11
+
12
+ def say_status(status, message, log_status=true)
13
+ self.shell.say_status(status, message, log_status)
14
+ end
15
+
16
+ def set_color(string, color, bold=false)
17
+ self.shell.set_color(string, color, bold)
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,5 @@
1
+ class String
2
+ def titlecase
3
+ gsub(/([a-zA-Z]*)/).map { |m| m.capitalize }.join
4
+ end
5
+ end
@@ -0,0 +1,3 @@
1
+ module JekyllAndHyde
2
+ class Error < Thor::Error; end
3
+ end
@@ -0,0 +1,7 @@
1
+ module JekyllAndHyde
2
+ class Group < Thor::Group
3
+ include JekyllAndHyde::ThorExt
4
+ include Thor::Actions
5
+ include JekyllAndHyde::Actions
6
+ end
7
+ end
@@ -0,0 +1,16 @@
1
+ module JekyllAndHyde
2
+ class << self
3
+ def namespace
4
+ Thor::Util.namespace_from_thor_class(self)
5
+ end
6
+
7
+ def to_namespace(str)
8
+ str = "#{namespace}:#{str}" unless str.include?(':')
9
+ str
10
+ end
11
+
12
+ def trim_namespace(str)
13
+ str.gsub("#{namespace}:", "")
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,81 @@
1
+ $thor_runner = true
2
+
3
+ class JekyllAndHyde::Runner < Thor
4
+ def help(meth = nil)
5
+ if meth && !self.respond_to?(meth)
6
+ klass, task = JekyllAndHyde::Util.find_class_and_task_by_namespace(meth)
7
+ start_task(klass, task, ["-h", task].compact)
8
+ else
9
+ super
10
+ end
11
+ end
12
+
13
+ desc "list [SEARCH]", "List the available jekyll_and_hyde tasks by an optional [SEARCH] string."
14
+
15
+ def list(search="")
16
+ search = /^.*#{JekyllAndHyde.to_namespace(search)}.*/i
17
+ klasses = Thor::Base.subclasses.select do |k|
18
+ k.namespace =~ search
19
+ end
20
+
21
+ display_klasses(klasses)
22
+ end
23
+
24
+ desc "version", "Show jekyll_and_hyde version"
25
+
26
+ def version
27
+ say "JekyllAndHyde #{JekyllAndHyde::VERSION}"
28
+ end
29
+
30
+ private
31
+
32
+ def method_missing(meth, *args)
33
+ klass, task = JekyllAndHyde::Util.find_class_and_task_by_namespace(meth.to_s)
34
+ args.unshift(task) if task
35
+ start_task(klass, task, args)
36
+ end
37
+
38
+ def start_task(klass, task, args)
39
+ if klass.nil?
40
+ say "Don't know how to build task '#{JekyllAndHyde.trim_namespace(task)}'."
41
+ else
42
+ klass.start(args, :shell => self.shell)
43
+ end
44
+ end
45
+
46
+ def self.banner(task, all = false, subcommand = false)
47
+ "#{basename} #{task.formatted_usage(self, all, subcommand)}"
48
+ end
49
+
50
+ # Display information about the given klasses. If with_module is given,
51
+ # it shows a table with information extracted from the yaml file.
52
+ def display_klasses(klasses=Thor::Base.subclasses)
53
+ klasses -= JekyllAndHyde::Group.ancestors
54
+ raise Error, "No JekyllAndHyde tasks available" if klasses.empty?
55
+
56
+ list = Hash.new { |h, k| h[k] = [] }
57
+ groups = klasses.select { |k| k.ancestors.include?(Thor::Group) }
58
+
59
+ # Get classes which inherit from Thor
60
+ (klasses - groups).each { |k| list[k.namespace.split(":").first] += k.printable_tasks(false) }
61
+
62
+ # Get classes which inherit from Thor::Base
63
+ groups.map! { |k| k.printable_tasks(false).first }
64
+
65
+ list["root"] = groups
66
+
67
+ # Order namespaces with default coming first
68
+ list = list.sort { |a, b| a[0].sub(/^default/, '') <=> b[0].sub(/^default/, '') }
69
+ list.each { |n, tasks| display_tasks(n, tasks) unless tasks.empty? }
70
+ end
71
+
72
+ def display_tasks(namespace, list) #:nodoc:
73
+ list.sort! { |a, b| a[0] <=> b[0] }
74
+
75
+ say shell.set_color(namespace, :blue, true)
76
+ say "-" * namespace.size
77
+
78
+ print_table(list, :truncate => true)
79
+ say
80
+ end
81
+ end
@@ -0,0 +1,26 @@
1
+ module JekyllAndHyde
2
+ class Generate < JekyllAndHyde::Group
3
+ argument :title, :type => :string, :required => true, :desc => "The title of the slide."
4
+ class_option :format, :type => :string, :default => 'markdown', :desc => 'The format of the slide. It supports markdown and textile.'
5
+ desc "Generate a slide using the defined template."
6
+
7
+ SUPPORT_FORMATS = %W{markdown md textile}
8
+
9
+ def validate_current_folder
10
+ self.class.source_root(destination_root)
11
+ find_in_source_paths("_config.yml")
12
+ end
13
+
14
+ def create_slide
15
+ format = options[:format]
16
+ raise Error, "Unsupport format #{format}, --format=#{SUPPORT_FORMATS.join(",")}." unless SUPPORT_FORMATS.include?(format)
17
+ create_file File.join("_posts", "#{timestamp}-#{title}.#{format}")
18
+ end
19
+
20
+ private
21
+
22
+ def timestamp
23
+ Time.now.strftime("%Y-%m-%d-%H-%M-%S")
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,68 @@
1
+ module JekyllAndHyde
2
+ class New < JekyllAndHyde::Group
3
+ JEKYLL_AND_HYDE_TEMPLATE_GIT_REPO = 'git://github.com/jingweno/jekyll_and_hyde_template.git'
4
+ SLIPPY_GIT_REPO = 'git://github.com/jingweno/slippy.git'
5
+
6
+ argument :app_path, :type => :string, :required => true, :desc => "The app path to generate the skeletal installation"
7
+ class_option :github, :type => :boolean, :desc => "Create branching information for GitHub Project Pages, details in http://pages.github.com/."
8
+ desc "Generate a skeletal jekyll_and_hyde installation in [APP_PATH]."
9
+
10
+ def make_app_path_dir
11
+ empty_directory app_path
12
+ end
13
+
14
+ # TODO: pass in the url as parameter
15
+ def git_clone_template
16
+ inside_app_path do
17
+ run_command "git clone #{JEKYLL_AND_HYDE_TEMPLATE_GIT_REPO} ."
18
+ remove_file('.git')
19
+ end
20
+ end
21
+
22
+ def git_init
23
+ inside_app_path do
24
+ run_command "git init"
25
+ end
26
+ end
27
+
28
+ def add_slippy_git_submodule
29
+ inside_app_path do
30
+ run_command "git submodule add #{SLIPPY_GIT_REPO}"
31
+ end
32
+ end
33
+
34
+ def git_add_all
35
+ inside_app_path do
36
+ run_command "git add ."
37
+ end
38
+ end
39
+
40
+ def create_git_hub_page
41
+ if options.github?
42
+ inside_app_path do
43
+ create_github_page_branch()
44
+ say
45
+ print_next_steps()
46
+ say
47
+ end
48
+ end
49
+ end
50
+
51
+ private
52
+
53
+ def create_github_page_branch
54
+ run_command 'git commit -am "Template files generated by jekyll_and_hyde."'
55
+ run_command 'git checkout -b gh-pages'
56
+ run_command 'git branch -d master'
57
+ say_status :create, 'branch "gh-pages" for GitHub project page, details in http://pages.github.com/.'
58
+ end
59
+
60
+ def print_next_steps
61
+ next_step_string = "Next steps:"
62
+ say set_color(next_step_string, :blue, true)
63
+ say "-" * next_step_string.size
64
+ say 'git remote add origin git@github.com:your_github_username/your_git_repo.git'
65
+ say 'git push origin gh-pages'
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,13 @@
1
+ module JekyllAndHyde
2
+ module ThorExt
3
+ def self.included(base)
4
+ base.extend JekyllAndHyde::ThorExt::ClassMethods
5
+ end
6
+
7
+ module ClassMethods
8
+ def self_task
9
+ Thor::DynamicTask.new(self.namespace.split(':').last, class_options)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ module JekyllAndHyde
2
+ module Util
3
+ class << self
4
+ def find_task_class(task_name)
5
+ find_class_and_task_by_namespace(task_name).first
6
+ end
7
+
8
+ def find_class_and_task_by_namespace(task_name)
9
+ Thor::Util.find_class_and_task_by_namespace(JekyllAndHyde.to_namespace(task_name))
10
+ end
11
+ end
12
+ end
13
+ end
@@ -1,3 +1,3 @@
1
1
  module JekyllAndHyde
2
- VERSION = "0.0.1"
2
+ VERSION = "1.0.0"
3
3
  end
@@ -1,3 +1,17 @@
1
- module JekyllAndHyde
2
- # Your code goes here...
3
- end
1
+ require 'rubygems'
2
+ require 'thor'
3
+ require 'thor/group'
4
+ require 'thor/runner'
5
+
6
+ require 'jekyll_and_hyde/core_ext/string'
7
+
8
+ require 'jekyll_and_hyde/version'
9
+ require 'jekyll_and_hyde/namespace'
10
+ require 'jekyll_and_hyde/thor_ext'
11
+ require 'jekyll_and_hyde/actions'
12
+ require 'jekyll_and_hyde/error'
13
+ require 'jekyll_and_hyde/util'
14
+ require 'jekyll_and_hyde/group'
15
+ require 'jekyll_and_hyde/tasks/new'
16
+ require 'jekyll_and_hyde/tasks/generate'
17
+ require 'jekyll_and_hyde/runner'
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ describe String do
4
+ describe "#titlecase" do
5
+ it "should return title case of any string" do
6
+ ["task_name", "Task-name", "task_Name"].each do |name|
7
+ name.titlecase.should == "TaskName"
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ describe JekyllAndHyde do
4
+ describe "#namespace" do
5
+ it "should return namespace separated by ':'" do
6
+ JekyllAndHyde.namespace.should == "jekyll_and_hyde"
7
+ end
8
+ end
9
+
10
+ describe "#to_namespace" do
11
+ it "should append to namespace when string doesn't contain a colon" do
12
+ JekyllAndHyde.to_namespace("str").should == "jekyll_and_hyde:str"
13
+ end
14
+
15
+ it "shouldn't append to namespace when string constains a colon" do
16
+ JekyllAndHyde.to_namespace("test:str").should == "test:str"
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+
3
+ module JekyllAndHyde
4
+ describe Generate do
5
+ before(:each) do
6
+ @generate_task = JekyllAndHyde::Generate.new(["test_slide"], {}, {})
7
+ end
8
+
9
+ describe "#timestamp" do
10
+ it "should return timestamp separated by '-'" do
11
+ @generate_task.send(:timestamp).to_s.scan(/\d\d\d\d-\d\d-\d\d-\d\d-\d\d-\d\d/).should_not be_empty
12
+ end
13
+ end
14
+
15
+ describe "#create_slide" do
16
+ it "should create a file" do
17
+ @generate_task.should_receive(:create_file)
18
+ @generate_task.create_slide
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ module JekyllAndHyde
4
+ describe New do
5
+ before(:each) do
6
+ @new_task = JekyllAndHyde::New.new(["app_path"], {}, {})
7
+ end
8
+
9
+ describe "#make_app_path_dir" do
10
+ it "should create the given directory" do
11
+ @new_task.should_receive(:empty_directory).with("app_path")
12
+ @new_task.make_app_path_dir
13
+ end
14
+ end
15
+
16
+ describe "#inside_app_path" do
17
+ it "should have all other operations execute inside app path" do
18
+ %W{git_clone_template git_init add_slippy_git_submodule git_add_all}.each do |method|
19
+ @new_task.should_receive(:inside_app_path)
20
+ @new_task.send(method)
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ module JekyllAndHyde
4
+ describe Util do
5
+ describe "#find_task_class" do
6
+ it "should return result for existing task" do
7
+ class JekyllAndHyde::TestTask < Thor; end
8
+
9
+ JekyllAndHyde::Util.find_task_class("test_task").should be
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,7 @@
1
+ require 'jekyll_and_hyde'
2
+
3
+ RSpec.configure do |config|
4
+ def destination_root
5
+ File.expand_path('../test_target', File.dirname(__FILE__))
6
+ end
7
+ end
metadata CHANGED
@@ -3,10 +3,10 @@ name: jekyll_and_hyde
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
+ - 1
6
7
  - 0
7
8
  - 0
8
- - 1
9
- version: 0.0.1
9
+ version: 1.0.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Jingwen Owen Ou
@@ -14,11 +14,11 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2011-01-10 00:00:00 -08:00
17
+ date: 2011-01-26 00:00:00 -08:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
- name: rspec
21
+ name: thor
22
22
  prerelease: false
23
23
  requirement: &id001 !ruby/object:Gem::Requirement
24
24
  none: false
@@ -28,10 +28,10 @@ dependencies:
28
28
  segments:
29
29
  - 0
30
30
  version: "0"
31
- type: :development
31
+ type: :runtime
32
32
  version_requirements: *id001
33
33
  - !ruby/object:Gem::Dependency
34
- name: cucumber
34
+ name: rspec
35
35
  prerelease: false
36
36
  requirement: &id002 !ruby/object:Gem::Requirement
37
37
  none: false
@@ -43,22 +43,70 @@ dependencies:
43
43
  version: "0"
44
44
  type: :development
45
45
  version_requirements: *id002
46
+ - !ruby/object:Gem::Dependency
47
+ name: cucumber
48
+ prerelease: false
49
+ requirement: &id003 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ segments:
55
+ - 0
56
+ version: "0"
57
+ type: :development
58
+ version_requirements: *id003
59
+ - !ruby/object:Gem::Dependency
60
+ name: fakefs
61
+ prerelease: false
62
+ requirement: &id004 !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ segments:
68
+ - 0
69
+ version: "0"
70
+ type: :development
71
+ version_requirements: *id004
46
72
  description: jekyll_and_hyde is a simple HTML presentation generator based on jekyll(https://github.com/mojombo/jekyll) and slippy(https://github.com/Seldaek/slippy).
47
73
  email:
48
74
  - owen@owenou.com
49
- executables: []
50
-
75
+ executables:
76
+ - jh
51
77
  extensions: []
52
78
 
53
79
  extra_rdoc_files: []
54
80
 
55
81
  files:
56
82
  - .gitignore
83
+ - .rspec
57
84
  - Gemfile
58
85
  - Rakefile
86
+ - bin/jh
87
+ - features/presenter_creates_a_skeletal_installation.feature
88
+ - features/presenter_creates_slides.feature
89
+ - features/step_definitions/jekyll_and_hyde_steps.rb
90
+ - features/support/env.rb
59
91
  - jekyll_and_hyde.gemspec
60
92
  - lib/jekyll_and_hyde.rb
93
+ - lib/jekyll_and_hyde/actions.rb
94
+ - lib/jekyll_and_hyde/core_ext/string.rb
95
+ - lib/jekyll_and_hyde/error.rb
96
+ - lib/jekyll_and_hyde/group.rb
97
+ - lib/jekyll_and_hyde/namespace.rb
98
+ - lib/jekyll_and_hyde/runner.rb
99
+ - lib/jekyll_and_hyde/tasks/generate.rb
100
+ - lib/jekyll_and_hyde/tasks/new.rb
101
+ - lib/jekyll_and_hyde/thor_ext.rb
102
+ - lib/jekyll_and_hyde/util.rb
61
103
  - lib/jekyll_and_hyde/version.rb
104
+ - spec/jekyll_and_hyde/core_ext/string_spec.rb
105
+ - spec/jekyll_and_hyde/namespace_spec.rb
106
+ - spec/jekyll_and_hyde/tasks/generate_spec.rb
107
+ - spec/jekyll_and_hyde/tasks/new_spec.rb
108
+ - spec/jekyll_and_hyde/util_spec.rb
109
+ - spec/spec_helper.rb
62
110
  has_rdoc: true
63
111
  homepage: http://github.com/jingweno/jekyll_and_hyde
64
112
  licenses: []
@@ -91,5 +139,14 @@ rubygems_version: 1.3.7
91
139
  signing_key:
92
140
  specification_version: 3
93
141
  summary: A simple HTML presentation generator based on jekyll and slippy.
94
- test_files: []
95
-
142
+ test_files:
143
+ - features/presenter_creates_a_skeletal_installation.feature
144
+ - features/presenter_creates_slides.feature
145
+ - features/step_definitions/jekyll_and_hyde_steps.rb
146
+ - features/support/env.rb
147
+ - spec/jekyll_and_hyde/core_ext/string_spec.rb
148
+ - spec/jekyll_and_hyde/namespace_spec.rb
149
+ - spec/jekyll_and_hyde/tasks/generate_spec.rb
150
+ - spec/jekyll_and_hyde/tasks/new_spec.rb
151
+ - spec/jekyll_and_hyde/util_spec.rb
152
+ - spec/spec_helper.rb