Only require parsers when they're needed
[git-blog.git] / lib / git-blog.rb
blob293c097ab339ee8fbdf00e5c77dc56c3e68173a5
1 require 'fileutils'
2 include FileUtils
4 require 'git-blog/core'
6 desc 'Setup the blog repository'
7 task :initialize do
8   path = File.expand_path '.'
9   
10   # Will create the repo if it doesn't exist
11   until (blog = Git.open path rescue false)
12     Git.init path
13   end
14   
15   cd path
16   mkdir 'posts'
17   mkdir 'design'
18   cp GitBlog::Scope / :prepped / '.gitignore', '.'
19   %w(welcome_to_your_git_blog.markdown .gitignore).each do |file|
20     cp GitBlog::Scope / :prepped / :posts / file, 'posts'
21   end
22   %w(main.css post.haml index.haml).each do |file|
23     cp GitBlog::Scope / :prepped / :design / file, 'design'
24   end
25   
26   Dir['**/**'].each do |file|
27     if File.directory? file
28       chmod 0775, file
29     else
30       chmod 0664, file
31     end
32   end
33   chmod 0755, '.git'
34   chmod 0664, '.gitignore'
35   chmod 0664, :posts / '.gitignore'
36   
37   blog.add
38   blog.commit_all("A bird... no, a plane... no, a git-blog!")
39 end
41 desc 'Attach the blog to a GitHub repository - can also clone an existing git-blog repository here'
42 task :github, :user_name, :repo_name do |_, params|
43   path = File.expand_path '.'
44   user_name = params[:user_name].nil? ? %x(whoami).chomp : params[:user_name]
45   repo_name = params[:repo_name].nil? ? File.basename(path) : params[:repo_name]
46   
47   github_url = "git@github.com:#{user_name.downcase}/#{repo_name.downcase}.git"
48   
49   if File.directory? File.join(path, 'posts') and
50     (blog = Git.open path rescue false)
51     
52     github = blog.add_remote 'github', github_url
53     blog.push github
54   else
55     system "git-init"
56     system "git-remote add -f github #{github_url}"
57     system "git checkout -b master github/master"
58   end
59 end
61 desc 'Prepare the blog to be served (configures hooks)'
62 task :servable do
63   should_be_initialized File.expand_path('.')
64   
65   mv '.git' / :hooks / 'post-receive', '.git' / :hooks / 'post-receive.old'
66   cp GitBlog::Scope / :prepped / 'post-receive.hook', '.git' / :hooks / 'post-receive'
67   chmod 0775, '.git' / :hooks / 'post-receive'
68   
69   puts '** git-blog is prepared for serving (git post-recieve hook prepared)'
70 end
72 desc 'Create and open for editing a new post'
73 task :post do
74   @resume = false
75   temporary_post = :post_in_progress.markdown
76   
77   should_be_initialized File.expand_path('.')
78   
79   if File.file? temporary_post
80     puts '** You have an unfinished post from before,'
81     puts 'do you want to r)esume it or overwrite it with a n)ew one? '
82     case STDIN.gets
83     when /r/i
84       @resume = true
85     when /n/i
86       # do nothing, go on to overwriting it
87     else
88       raise 'Invalid entry, exiting out'
89     end
90   end
91   
92   unless @resume
93     File.open temporary_post, File::RDWR|File::TRUNC|File::CREAT, 0664 do |post|
94       post.puts  'Replace this text with your title!'
95       post.puts  '=================================='
96       post.print "\n"; post.close
97     end
98   end
99   
100   system "#{ENV['VISUAL']} #{temporary_post}"
101   
102   first_line = File.open(temporary_post, File::RDONLY).gets.chomp
103   markup = case first_line
104     when /^\</        then 'xhtml'
105     when /^\%/        then 'haml'
106     when /^\#|h\d\./  then 'textile'
107     else                   'markdown'
108   end
110   title = (first_line.match GitBlog::TitleRegexen[markup])[1]
111   path = :posts / title.slugize.send(markup.to_sym)
112   mv temporary_post, path
113   
114   blog = Git.open File.expand_path('.')
115   blog.add path
116   blog.commit "New post: #{title}"
117   
118   puts "Post '#{title.slugize}' comitted."
121 desc 'Push changes'
122 task :push, :remote_name do |_, params|
123   should_be_initialized File.expand_path('.')
124   
125   remote_name = params[:remote_name].nil? ? 'github' : params[:remote_name]
126   blog = Git.open '.'
127   remote = blog.remote remote_name
128   blog.push remote
129   puts "Changes pushed to #{remote_name}."
132 desc 'Remove all generated xhtml'
133 task :clobber do
134   Dir['posts/*.xhtml'].each do |path|
135     rm_f path
136   end
139 # desc 'Invisible task, generates index.xhtml'
140 task :index do
141   path = File.expand_path('.')
142   repo = should_be_initialized path
143   
144   commits = repo.log.select {|c| c.message =~ /New post: /}
145   posts = []
146   commits.map do |commit|
147     title = commit.message.match(/New post: (.*)$/)[1]
148     posts << {:title => title, :slug => title.slugize}
149   end
150   
151   template = IO.read :design / :index.haml
152   
153   completed = Haml::Engine.new(template, :filename => :design / :index.haml).
154     to_html Object.new, :posts => posts
155   
156   destination = :index.xhtml
157   file = File.open destination, File::RDWR|File::TRUNC|File::CREAT, 0664
158   file.puts completed
159   file.close
160   puts "index.xhtml compiled"
163 desc 'Generate xhtml files from posts and design'
164 task :deploy => [:clobber, :index] do
165   should_be_initialized File.expand_path('.')
166   
167   Dir['posts/*.*'].each do |path|
168     markup = File.extname(path).downcase.gsub(/^\./,'')
169     content = IO.read path
170     first_line = content.match(/^(.*)\n/)[1]
171     
172     post_title = (first_line.match GitBlog::TitleRegexen[markup])[1]
173     parsed = begin
174       require "git-blog/parser/#{markup.downcase}"
175       parser = GitBlog::Parsers.const_get(markup.gsub(/\b\w/){$&.upcase})
176       parser.send :parse, content
177     end
178     
179     template = IO.read :design / :post.haml
180     
181     completed = Haml::Engine.new(template, :filename => :design / :post.haml).
182       to_html Object.new, {:content => parsed, :title => post_title}
183     
184     completed = GitBlog::Parsers::fix_pres(completed)
185     
186     destination = path.gsub /.#{markup}$/, '.xhtml'
187     file = File.open destination, File::RDWR|File::TRUNC|File::CREAT, 0664
188     file.puts completed
189     file.close
190     puts "#{path} -> #{destination} (as #{markup})"
191   end
195 # desc 'Invisible task, forces checkout (for the post-receive hook)'
196 task :force_checkout do
197   puts 'Forcing update of working copy...'
198   system 'git-checkout -f master'
201 # desc 'Invisible task, run as the post-receive hook'
202 task :post_receive => [:force_checkout, :deploy]
204 def should_be_initialized path
205   raise "** You haven't used `rake initialize` yet." unless
206     File.directory? File.join(path, 'posts') and
207     (blog = Git.open path rescue false)
208   blog