# coding: utf-8 require 'date' require 'fileutils' require 'set' require 'page_local' module Sitegen def self.init @local = {} @remote = {} @want = Set[] end def self.add(page) @deps = nil if page.is_a?(LocalPage) page.local_depends.keys.each do |filename| @local[filename] = page unless filename.empty? end else @remote[page.url] = page end end def self.pages @local.values.to_set.merge(@remote.values) 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(@local[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 @local[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('') file.print(@local[target].atom) end when target.end_with?(".html") puts "html #{target}" write_atomic(target) do |file| file.print(@local[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