diff options
Diffstat (limited to 'lib/sitegen.rb')
-rw-r--r-- | lib/sitegen.rb | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/lib/sitegen.rb b/lib/sitegen.rb new file mode 100644 index 0000000..ca0c4bf --- /dev/null +++ b/lib/sitegen.rb @@ -0,0 +1,98 @@ +# coding: utf-8 +require 'date' +require 'fileutils' +require 'set' + +module Sitegen + def self.init + @mk = {} + @want = Set[] + end + def self.add(page) + @deps = nil + page.local_depends.keys.each do |filename| + @mk[filename] = page unless filename.empty? + end + end + def self.pages + @mk.values.to_set + end + def self.want(filename) + @deps = nil + @want.add(filename) + end + def self.dependencies + if @deps.nil? + libfiles = Dir::entries('lib').select{|s|s!='..'}.map{|s|"lib/#{s}"}.to_set + ret = {} + ret[:all] = @want + @want.each do |filename| + ret[filename] = libfiles.clone.merge(@mk[filename].local_depends[filename]) + end + @deps = ret + end + @deps + end + def self.Makefile() + str = '' + dependencies.each do |target, deps| + str += "#{target.to_s}: #{deps.sort.join(' ')}\n" + end + return str + end + + def self.make(target) + newest = Time::new(0) + (dependencies[target] || []).each do |dep| + ts = make(dep) + newest = ts if ts > newest + end + unless target.is_a?(String) + return Time::now + end + if File::exist?(target) + ctime = File::ctime(target) + if ctime > newest + return ctime + end + end + generate(target) + return File::ctime(target) + end + + def self.generate(target) + case + when @mk[target].nil? + raise "No rule to make target '#{target}'. Stop." + when target.end_with?(".atom") + puts "atom #{target}" + write_atomic(target) do |file| + file.puts('<?xml version="1.0" encoding="utf-8"?>') + file.print(@mk[target].atom) + end + when target.end_with?(".html") + puts "html #{target}" + write_atomic(target) do |file| + file.print(@mk[target].html) + end + else + raise "No rule to make target '#{target}'. Stop." + end + end + + def self.write_atomic(outfilename) + tmpfilename = "#{File::dirname(outfilename)}/.tmp#{File::basename(outfilename)}" + + FileUtils::mkdir_p(File::dirname(tmpfilename)) + tmpfile = File::new(tmpfilename, 'wb') + begin + yield tmpfile + rescue Exception => e + tmpfile.close + File::unlink(tmpfilename) + raise e + end + tmpfile.close + File::rename(tmpfilename, outfilename) + end +end |