This repository has been archived by the owner on Feb 2, 2020. It is now read-only.
/
statig.rb
125 lines (102 loc) · 3.08 KB
/
statig.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
require 'yaml'
class SerializableProc
def initialize(block)
@block = block
to_proc
end
def to_proc
eval "Proc.new{ #{@block} }"
end
def method_missing(*args)
to_proc.send(*args)
end
end
class Statig < Thor
desc 'build', 'Build website in DIRECTORY'
method_options :force => :boolean, :config => :optional
def build(directory=Dir.pwd)
directory = File.expand_path(directory)
Dir.chdir(directory) do
abort('needs to be run inside of a git working directory') unless git?
files_list.each do |source|
destination = source.sub(File.extname(source), '.html')
next if !needs_update?(source, destination) && !options[:force]
puts "#{source} -> #{destination}"
File.open(destination, 'w') do |file|
file << content_for(source, destination)
git_ignore_if_needed(file.path)
end
end
end
end
private
def needs_update?(source, destination)
!File.exists?(destination) || File.mtime(source) > File.mtime(destination)
end
def content_for(source, destination)
parsed = parse_meta_data(File.read(source))
if template?
template(parsed)
else
formatter_for(source).call(parsed[:content])
end
end
def formatter_for(file_name)
config[File.extname(file_name)[1..-1].to_sym]
end
def files_list
Dir[glob].reject { |file| file =~ excludes }
end
def glob
"#{'**/' * config[:deepth]}*.{#{config[:extensions].map(&:to_s).join(',')}}"
end
def excludes
Regexp.union(*(config[:excludes] || []))
end
def template(variables)
formatter_for(config[:template]).call(load_template_file, variables)
end
def template?
load_template_file
end
def load_template_file
@template_content ||= begin
File.read(config[:template])
rescue Errno::ENOENT
nil
end
end
def config
@config = begin
YAML.load_file(options[:config] || 'statig.yml')
rescue Errno::ENOENT
abort "Couldn't load configuration file"
end
end
def parse_meta_data(string)
parsed = {:meta_data => [], :content => string}
return parsed unless string =~ /((\w[\w\s]+: .*\n)+)\n/
parsed.update(:content => $')
meta_data = $1.split("\n").inject({}) do |meta_data, line|
parts = line.split(':', 2)
key = parts.first.strip.downcase.to_sym
value = parts.last.strip
meta_data.update(key => value)
end
parsed.update(:meta_data => meta_data)
end
def git?
`git status &> /dev/null`
$?.exitstatus.to_i == 1
end
def git_ignore_if_needed(file)
unless git_ignored?(file)
puts "Ignoring #{file}"
File.open('.gitignore', 'a') { |f| f << "#{file}\n" }
end
end
def git_ignored?(file)
return false unless File.exists?('.gitignore')
File.readlines('.gitignore').map(&:chomp).include?(file)
end
end