smallcage 0.2.6 → 0.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,10 +1,13 @@
1
- YAML::ENGINE.yamler = 'syck' if RUBY_VERSION >= "1.9.2"
1
+ YAML::ENGINE.yamler = 'syck' if RUBY_VERSION >= '1.9.2'
2
2
 
3
3
  module SmallCage
4
+ #
5
+ # .smc file loader
6
+ #
4
7
  class Loader
5
- DEFAULT_TEMPLATE = "default"
6
- DIR_PROP_FILE = "_dir.smc"
7
- LOCAL_PROP_FILE = "_local.smc"
8
+ DEFAULT_TEMPLATE = 'default'
9
+ DIR_PROP_FILE = '_dir.smc'
10
+ LOCAL_PROP_FILE = '_local.smc'
8
11
  MAX_DEPTH = 100
9
12
 
10
13
  attr_reader :root, :target, :erb_base
@@ -15,28 +18,28 @@ module SmallCage
15
18
 
16
19
  @target = target # absolute
17
20
  @root = self.class.find_root(target) # absolute
18
- @templates_dir = @root + "_smc/templates"
19
- @helpers_dir = @root + "_smc/helpers"
20
- @filters_dir = @root + "_smc/filters"
21
+ @templates_dir = @root + '_smc/templates'
22
+ @helpers_dir = @root + '_smc/helpers'
23
+ @filters_dir = @root + '_smc/filters'
21
24
  @erb_base = load_erb_base
22
25
  @filters = load_filters
23
26
  end
24
27
 
25
28
  # return root dir Pathname object.
26
29
  def self.find_root(path, depth = MAX_DEPTH)
27
- raise "Not found: #{path}" unless path.exist?
30
+ fail "Not found: #{ path }" unless path.exist?
28
31
  d = path.realpath
29
32
  d = d.parent if d.file?
30
33
  loop do
31
- return d if d.join("_smc").directory?
34
+ return d if d.join('_smc').directory?
32
35
  break if d.root? || (depth -= 1) <= 0
33
36
  d = d.parent
34
37
  end
35
- raise "Root not found: #{path}"
38
+ fail "Root not found: #{ path }"
36
39
  end
37
40
 
38
41
  def load(path)
39
- raise "Not found: #{path}" unless path.exist?
42
+ fail "Not found: #{ path }" unless path.exist?
40
43
 
41
44
  docpath = DocumentPath.new(@root, path)
42
45
 
@@ -48,15 +51,15 @@ module SmallCage
48
51
  end
49
52
 
50
53
  def load_smc_file(docpath)
51
- raise "Path is not smc file: #{docpath}" unless docpath.smc?
54
+ fail "Path is not smc file: #{ docpath }" unless docpath.smc?
52
55
 
53
56
  result = create_base_smc_object(docpath.outfile.path, docpath.path,
54
57
  docpath.outuri, docpath.uri)
55
58
 
56
- result["template"] = DEFAULT_TEMPLATE
57
- result["dirs"] = load_dirs(docpath.path)
59
+ result['template'] = DEFAULT_TEMPLATE
60
+ result['dirs'] = load_dirs(docpath.path)
58
61
 
59
- return result.merge(load_yaml(docpath.path))
62
+ result.merge(load_yaml(docpath.path))
60
63
  end
61
64
  private :load_smc_file
62
65
 
@@ -64,7 +67,7 @@ module SmallCage
64
67
  path_smc = nil
65
68
  uri_smc = nil
66
69
  uri_out = docpath.uri
67
- uri_out += "/" unless uri_out[-1] == ?/
70
+ uri_out += '/' unless uri_out[-1, 1] == '/'
68
71
 
69
72
  dir_prop_file = docpath.path + DIR_PROP_FILE
70
73
  local_prop_file = docpath.path + LOCAL_PROP_FILE
@@ -79,18 +82,18 @@ module SmallCage
79
82
  result.merge!(load_yaml(dir_prop_file)) if dir_prop_file.file?
80
83
  result.merge!(load_yaml(local_prop_file)) if local_prop_file.file?
81
84
 
82
- return result
85
+ result
83
86
  end
84
87
  private :load_dir_prop
85
88
 
86
89
  def create_base_smc_object(path_out, path_smc, uri_out, uri_smc)
87
90
  result = {}
88
- result["arrays"] = []
89
- result["strings"] = []
90
- result["body"] = nil
91
- result["path"] = DocumentPath.add_smc_method(path_out, path_smc)
92
- result["uri"] = DocumentPath.add_smc_method(uri_out, uri_smc )
93
- return result
91
+ result['arrays'] = []
92
+ result['strings'] = []
93
+ result['body'] = nil
94
+ result['path'] = DocumentPath.add_smc_method(path_out, path_smc)
95
+ result['uri'] = DocumentPath.add_smc_method(uri_out, uri_smc)
96
+ result
94
97
  end
95
98
  private :create_base_smc_object
96
99
 
@@ -103,23 +106,23 @@ module SmallCage
103
106
  obj = YAML.load_stream(source)
104
107
  return result if obj.nil?
105
108
  rescue => e
106
- raise "Can't load file: #{path} / #{e}"
109
+ raise "Can't load file: #{ path } / #{ e }"
107
110
  end
108
111
  obj.documents.each do |o|
109
112
  case o
110
113
  when Hash
111
114
  result.merge!(o)
112
115
  when Array
113
- result["arrays"] ||= []
114
- result["arrays"] << o
116
+ result['arrays'] ||= []
117
+ result['arrays'] << o
115
118
  else
116
- result["strings"] ||= []
117
- result["strings"] << o.to_s
119
+ result['strings'] ||= []
120
+ result['strings'] << o.to_s
118
121
  end
119
122
  end
120
- result["body"] ||= result["strings"][0] if result["strings"]
123
+ result['body'] ||= result['strings'][0] if result['strings']
121
124
 
122
- return result
125
+ result
123
126
  end
124
127
  private :load_yaml
125
128
 
@@ -128,16 +131,16 @@ module SmallCage
128
131
  loop do
129
132
  path = path.parent
130
133
  result.unshift load(path)
131
- break if path.join("_smc").directory?
132
- raise "Root directory not found!" if path.root?
134
+ break if path.join('_smc').directory?
135
+ fail 'Root directory not found!' if path.root?
133
136
  end
134
- return result
137
+ result
135
138
  end
136
139
 
137
140
  def template_path(name)
138
- result = @templates_dir + "#{name}.rhtml"
141
+ result = @templates_dir + "#{ name }.rhtml"
139
142
  return nil unless result.file?
140
- return result
143
+ result
141
144
  end
142
145
 
143
146
  def each_smc_obj
@@ -154,7 +157,7 @@ module SmallCage
154
157
  if @target.directory?
155
158
  path = Pathname.new(@target)
156
159
  Dir.chdir(@target) do
157
- Dir.glob("**/*.smc").sort.each do |f|
160
+ Dir.glob('**/*.smc').sort.each do |f|
158
161
  yield path + f
159
162
  end
160
163
  end
@@ -167,29 +170,29 @@ module SmallCage
167
170
  if @target.directory?
168
171
  path = Pathname.new(@target)
169
172
  Dir.chdir(@target) do
170
- Dir.glob("**/*").sort.each do |f|
173
+ Dir.glob('**/*').sort.each do |f|
171
174
  f = path + f
172
175
  next if f.directory?
173
176
  next if f.to_s =~ %r{/_smc/}
174
- next if f.to_s =~ %r{\.smc$}
177
+ next if f.to_s =~ /\.smc$/
175
178
  yield DocumentPath.new(@root, path + f)
176
179
  end
177
180
  end
178
181
  else
179
182
  return if @target.to_s =~ %r{/_smc/}
180
- return if @target.to_s =~ %r{\.smc$}
183
+ return if @target.to_s =~ /\.smc$/
181
184
  yield DocumentPath.new(@root, @target)
182
185
  end
183
186
  end
184
187
 
185
188
  def real_target(target)
186
189
  return target.realpath if target.directory?
187
- return target.realpath if target.file? and target.to_s =~ /\.smc$/
190
+ return target.realpath if target.file? && target.to_s =~ /\.smc$/
188
191
 
189
- tmp = Pathname.new(target.to_s + ".smc")
192
+ tmp = Pathname.new(target.to_s + '.smc')
190
193
  return tmp.realpath if tmp.file?
191
194
 
192
- raise "Target not found: " + target.to_s
195
+ fail 'Target not found: ' + target.to_s
193
196
  end
194
197
  private :real_target
195
198
 
@@ -197,7 +200,7 @@ module SmallCage
197
200
  result = Class.new(ErbBase)
198
201
  class << result
199
202
  def include_helpers(anon_module, mod_names)
200
- smc_module = anon_module.const_get("SmallCage")
203
+ smc_module = anon_module.const_get('SmallCage')
201
204
  mod_names.each do |name|
202
205
  helper_module = smc_module.const_get(name)
203
206
  include helper_module
@@ -205,43 +208,40 @@ module SmallCage
205
208
  end
206
209
  end
207
210
 
208
- helpers = SmallCage::AnonymousLoader.load(@helpers_dir, %r{([^/]+_helper)\.rb\z})
211
+ helpers = SmallCage::AnonymousLoader.load(@helpers_dir, /([^\/]+_helper)\.rb\z/)
209
212
  result.include_helpers(helpers[:module], helpers[:names])
210
213
 
211
- return result
214
+ result
212
215
  end
213
216
  private :load_erb_base
214
217
 
215
218
  def filters(name)
216
- if @filters[name].nil?
217
- return []
218
- end
219
- return @filters[name]
219
+ @filters[name].nil? ? [] : @filters[name]
220
220
  end
221
221
 
222
222
  def load_filters
223
223
  result = {}
224
224
  return {} unless @filters_dir.directory?
225
225
 
226
- filter_modules = SmallCage::AnonymousLoader.load(@filters_dir, %r{([^/]+_filter)\.rb\z})
227
- smc_module = filter_modules[:module].const_get("SmallCage")
226
+ filter_modules = SmallCage::AnonymousLoader.load(@filters_dir, /([^\/]+_filter)\.rb\z/)
227
+ smc_module = filter_modules[:module].const_get('SmallCage')
228
228
 
229
- load_filters_config.each do |filter_type,filter_list|
229
+ load_filters_config.each do |filter_type, filter_list|
230
230
  result[filter_type] = []
231
231
  filter_list.to_a.each do |fc|
232
- fc = { "name" => fc } if fc.is_a? String
233
- filter_class = smc_module.const_get(fc["name"].camelize)
232
+ fc = { 'name' => fc } if fc.is_a? String
233
+ filter_class = smc_module.const_get(fc['name'].camelize)
234
234
  result[filter_type] << filter_class.new(fc)
235
235
  end
236
236
  end
237
- return result
237
+ result
238
238
  end
239
239
  private :load_filters
240
240
 
241
241
  def load_filters_config
242
- path = @filters_dir.join("filters.yml")
242
+ path = @filters_dir.join('filters.yml')
243
243
  return {} unless path.file?
244
- return YAML.load(path.read()) || {}
244
+ YAML.load(path.read) || {}
245
245
  end
246
246
  private :load_filters_config
247
247
  end
@@ -4,7 +4,7 @@ class String
4
4
  def camelize(first_letter_in_uppercase = true)
5
5
  s = self
6
6
  if first_letter_in_uppercase
7
- s.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
7
+ s.gsub(/\/(.?)/) { '::' + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
8
8
  else
9
9
  s[0..0] + s.camelize[1..-1]
10
10
  end
@@ -0,0 +1,251 @@
1
+ # Parse command-line arguments.
2
+ class SmallCage::OptionsParser
3
+ require 'optparse'
4
+
5
+ VERSION_NOTE = "SmallCage #{SmallCage::VERSION} - a simple website generator"
6
+
7
+ def initialize(argv)
8
+ @argv = argv
9
+ @options = {}
10
+ end
11
+
12
+ def parse
13
+ @parser = create_main_parser
14
+ parse_main_options
15
+
16
+ @command_parsers = create_command_parsers
17
+ parse_command
18
+ parse_command_options
19
+
20
+ @options
21
+ end
22
+
23
+ def create_main_parser
24
+ parser = OptionParser.new
25
+ parser.banner = <<BANNER
26
+ Usage: #{File.basename($PROGRAM_NAME)} [options] <subcommand> [subcommand-options]
27
+ #{VERSION_NOTE}
28
+ Subcommands are:
29
+ update [path] Build smc contents.
30
+ clean [path] Remove files generated from *.smc source.
31
+ server [path] [port] Start HTTP server.
32
+ auto [path] [port] Start auto update server.
33
+ import [name|uri] Import project.
34
+ export [path] [outputpath] Export project.
35
+ uri [path] Print URIs.
36
+ manifest [path] Generate Manifest.html file.
37
+
38
+ BANNER
39
+
40
+ parser.separator 'Options are:'
41
+ parser.on('-h', '--help', 'Show this help message.') do
42
+ puts parser
43
+ exit(true)
44
+ end
45
+ parser.on('-v', '--version', 'Show version info.') do
46
+ puts VERSION_NOTE
47
+ exit(true)
48
+ end
49
+
50
+ @options[:quiet] = false
51
+ parser.on('-q', '--quiet', 'Do not print message.') do |boolean|
52
+ @options[:quiet] = boolean
53
+ end
54
+
55
+ parser
56
+ end
57
+ private :create_main_parser
58
+
59
+ def parse_main_options
60
+ @parser.order!(@argv)
61
+ rescue OptionParser::InvalidOption => e
62
+ $stderr.puts e.message
63
+ exit(false)
64
+ end
65
+ private :parse_main_options
66
+
67
+ def create_command_parsers
68
+ banners = {
69
+ :update => <<EOT,
70
+ smc update [path] [options]
71
+ path : target directory. (default:'.')
72
+ EOT
73
+
74
+ :clean => <<EOT,
75
+ smc clean [path] [options]
76
+ path : target directory (default:'.')
77
+ EOT
78
+
79
+ :server => <<EOT,
80
+ smc server [path] [port] [options]
81
+ path : target directory (default:'.')
82
+ port : HTTP server port number (default:8080)
83
+ EOT
84
+
85
+ :auto => <<EOT,
86
+ smc auto [path] [port] [options]
87
+ path : target directory (default:'.')
88
+ port : HTTP server port number (default:don't launch the server)
89
+ EOT
90
+
91
+ :import => <<EOT,
92
+ smc import [name|uri] [options]
93
+ EOT
94
+
95
+ :export => <<EOT,
96
+ smc export [path] [outputpath] [options]
97
+ EOT
98
+
99
+ :help => <<EOT,
100
+ smc help [command]
101
+ EOT
102
+
103
+ :uri => <<EOT,
104
+ smc uri [path] [options]
105
+ EOT
106
+
107
+ :manifest => <<EOT,
108
+ smc manifest [path] [options]
109
+ EOT
110
+
111
+ }
112
+
113
+ parsers = {}
114
+ banners.each do |command, banner|
115
+ parsers[command] = create_default_command_parser(banner)
116
+ end
117
+
118
+ parsers[:update].on('--fast', 'Update only modified files.') do |boolean|
119
+ @options[:fast] = boolean
120
+ end
121
+
122
+ parsers[:auto].on('--fast', 'Update only modified files at first run.') do |boolean|
123
+ @options[:fast] = boolean
124
+ end
125
+
126
+ parsers[:auto].on('--bell', 'Ring bell after publishing files.') do |boolean|
127
+ @options[:bell] = boolean
128
+ end
129
+
130
+ parsers
131
+ end
132
+ private :create_command_parsers
133
+
134
+ def create_default_command_parser(banner)
135
+ parser = OptionParser.new
136
+ parser.banner = 'Usage: ' + banner
137
+ parser.separator 'Options are:'
138
+
139
+ # these options can place both before and after the subcommand.
140
+ parser.on('-h', '--help', 'Show this help message.') do
141
+ puts parser
142
+ exit(true)
143
+ end
144
+ parser.on('-v', '--version', 'Show version info.') do
145
+ puts VERSION_NOTE
146
+ exit(true)
147
+ end
148
+ parser.on('-q', '--quiet', 'Do not print message.') do |boolean|
149
+ @options[:quiet] = boolean
150
+ end
151
+
152
+ parser
153
+ end
154
+ private :create_default_command_parser
155
+
156
+ def parse_command
157
+ @options[:command] = command_sym
158
+
159
+ if @options[:command].nil?
160
+ puts @parser
161
+ exit(false)
162
+ end
163
+ parser = @command_parsers[@options[:command]]
164
+ if parser.nil?
165
+ $stderr.puts "no such subcommand: #{@options[:command]}"
166
+ exit(false)
167
+ end
168
+ parser.parse!(@argv)
169
+ rescue OptionParser::InvalidOption => e
170
+ $stderr.puts e.message
171
+ exit(false)
172
+ end
173
+ private :parse_command
174
+
175
+ # Resolve abbrev and return command name symbol.
176
+ def command_sym
177
+ commands = Hash.new { |h, k| k }
178
+ commands.merge!(
179
+ :up => :update,
180
+ :sv => :server,
181
+ :au => :auto
182
+ )
183
+
184
+ name = @argv.shift.to_s.strip
185
+ return nil if name.empty?
186
+ commands[name.to_sym]
187
+ end
188
+ private :command_sym
189
+
190
+ def parse_command_options
191
+ run_help_and_exit if @options[:command] == :help
192
+
193
+ if @options[:command] == :update
194
+ @options[:path] = @argv.shift
195
+ @options[:path] ||= '.'
196
+ @options[:fast] ||= false
197
+ elsif @options[:command] == :server
198
+ @options[:path] = @argv.shift
199
+ @options[:path] ||= '.'
200
+ @options[:port] = get_port_number(8080)
201
+ elsif @options[:command] == :auto
202
+ @options[:path] = @argv.shift
203
+ @options[:path] ||= '.'
204
+ @options[:port] = get_port_number(nil)
205
+ @options[:bell] ||= false
206
+ @options[:fast] ||= false
207
+ elsif @options[:command] == :import
208
+ @options[:from] = @argv.shift
209
+ @options[:from] ||= 'default'
210
+ @options[:to] = @argv.shift
211
+ @options[:to] ||= '.'
212
+ elsif @options[:command] == :export
213
+ @options[:path] = @argv.shift
214
+ @options[:path] ||= '.'
215
+ @options[:out] = @argv.shift
216
+ elsif @options[:command] == :uri
217
+ @options[:path] = @argv.shift
218
+ @options[:path] ||= '.'
219
+ elsif @options[:command] == :manifest
220
+ @options[:path] = @argv.shift
221
+ @options[:path] ||= '.'
222
+ elsif @options[:command] == :clean
223
+ @options[:path] = @argv.shift
224
+ @options[:path] ||= '.'
225
+ end
226
+ end
227
+ private :parse_command_options
228
+
229
+ def run_help_and_exit
230
+ subcmd = @argv.shift
231
+ if subcmd.nil?
232
+ puts @parser
233
+ else
234
+ puts @command_parsers[subcmd.to_sym]
235
+ end
236
+ exit true
237
+ end
238
+ private :run_help_and_exit
239
+
240
+ def get_port_number(default)
241
+ return default if @argv.empty?
242
+
243
+ port = @argv.shift
244
+ if port.to_i == 0
245
+ $stderr.puts "illegal port number: #{port}"
246
+ exit(false)
247
+ end
248
+ port.to_i
249
+ end
250
+ private :get_port_number
251
+ end
@@ -9,15 +9,14 @@ class SmallCage::Renderer
9
9
  path = @loader.template_path(name)
10
10
  return nil if path.nil?
11
11
  @current_template = path
12
- return render_string(path.read, obj)
12
+ render_string(path.read, obj)
13
13
  end
14
14
 
15
15
  def render_string(str, obj)
16
- erb_class = ERB.new(str, nil, '-', '@erbout').def_class(@loader.erb_base, "erb")
16
+ erb_class = ERB.new(str, nil, '-', '@erbout').def_class(@loader.erb_base, 'erb')
17
17
  return erb_class.new(@loader, self, obj).erb
18
18
  rescue => e
19
- STDERR.puts "Can't render: #{obj["uri"]}"
19
+ STDERR.puts "Can't render: #{ obj['uri'] }"
20
20
  raise e
21
21
  end
22
-
23
22
  end
@@ -6,46 +6,46 @@ module SmallCage
6
6
 
7
7
  def initialize(opts)
8
8
  @opts = opts
9
- require_command "base"
9
+ require_command 'base'
10
10
  end
11
11
 
12
12
  def update
13
- require_command "update"
13
+ require_command 'update'
14
14
  SmallCage::Commands::Update.execute(@opts)
15
15
  end
16
16
 
17
17
  def clean
18
- require_command "clean"
18
+ require_command 'clean'
19
19
  SmallCage::Commands::Clean.execute(@opts)
20
20
  end
21
21
 
22
22
  def server
23
- require_command "server"
23
+ require_command 'server'
24
24
  SmallCage::Commands::Server.execute(@opts)
25
25
  end
26
26
 
27
27
  def auto
28
- require_command "auto"
28
+ require_command 'auto'
29
29
  SmallCage::Commands::Auto.execute(@opts)
30
30
  end
31
31
 
32
32
  def import
33
- require_command "import"
33
+ require_command 'import'
34
34
  SmallCage::Commands::Import.execute(@opts)
35
35
  end
36
36
 
37
37
  def manifest
38
- require_command "manifest"
38
+ require_command 'manifest'
39
39
  SmallCage::Commands::Manifest.execute(@opts)
40
40
  end
41
41
 
42
42
  def export
43
- require_command "export"
43
+ require_command 'export'
44
44
  SmallCage::Commands::Export.execute(@opts)
45
45
  end
46
46
 
47
47
  def uri
48
- require_command "uri"
48
+ require_command 'uri'
49
49
  SmallCage::Commands::Uri.execute(@opts)
50
50
  end
51
51