Class: Webby::Apps::Generator

Inherits:
Object
  • Object
show all
Defined in:
lib/webby/apps/generator.rb

Overview

webby gen template site => creates the tmplate webby gen -h / –help webby gen => same as –help

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeGenerator

Initialize a new generator object.



25
26
27
28
29
# File 'lib/webby/apps/generator.rb', line 25

def initialize
  @options = {}
  @site = @template = nil
  @stdout, @stdin = $stdout, $stdin
end

Instance Attribute Details

#optionsObject (readonly)

Returns the value of attribute options.



21
22
23
# File 'lib/webby/apps/generator.rb', line 21

def options
  @options
end

#siteObject

Returns the value of attribute site.



20
21
22
# File 'lib/webby/apps/generator.rb', line 20

def site
  @site
end

#templateObject

Returns the value of attribute template.



20
21
22
# File 'lib/webby/apps/generator.rb', line 20

def template
  @template
end

Class Method Details

.run(args) ⇒ Object

Create a new Generator instance and run the webby application given the command line args.



16
17
18
# File 'lib/webby/apps/generator.rb', line 16

def self.run( args )
  self.new.run args
end

Instance Method Details

#abort(msg) ⇒ Object

Prints an abort message to the screen and then exits the Ruby interpreter. A non-zero return code is used to indicate an error.



223
224
225
226
227
228
# File 'lib/webby/apps/generator.rb', line 223

def abort( msg )
  @stdout.puts "\nAborting!"
  @stdout.puts "    #{msg}"
  @stdout.puts
  exit 1
end

#cp(file) ⇒ Object

Copy a file from the template location to the user specified site location. A message will be displayed to the screen indicating tha the file is being created.



163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/webby/apps/generator.rb', line 163

def cp( file )
  src = template / file
  dst = site / file

  if test(?e, dst) 
    if identical?(src, dst)
      identical(dst)
      return
    end

    choice = case options[:collision]
      when :force then :force
      when :skip  then :skip
      else force_file_collision?( dst ) end

    case choice
      when :force then force(dst)
      when :skip  then skip(dst); return
      else raise "Invalid collision choice: #{choice.inspect}" end
  else
    create(dst)
  end
  return if pretend?

  if WINDOWS then win_line_endings(src, dst)
  else FileUtils.cp(src, dst) end
end

#create_siteObject

Create the site from the template specified by the user.



119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/webby/apps/generator.rb', line 119

def create_site
  files = site_files

  # in update mode we only want to update the tasks directory
  if options[:update]
    FileUtils.mkdir_p site unless pretend?
    mkdir 'tasks'
    files['tasks'].sort.each {|file| cp file}
  else
    dirs = files.keys.concat %w[content layouts lib tasks templates]
    dirs.sort!
    dirs.uniq!

    # create the directories first
    dirs.each do |dir|
      next if dir =~ %r/^output\/.*$/
      mkdir dir
    end

    # and the create the files under each directory
    dirs.each do |dir|
      next if dir =~ %r/^output(\/.*)?$/
      files[dir].sort.each {|file| cp file}
    end
  end
end

#force_file_collision?(dst) ⇒ Boolean

Ask the user what to do about the file collision.

Returns:

  • (Boolean)


266
267
268
269
270
271
272
273
274
275
276
277
278
# File 'lib/webby/apps/generator.rb', line 266

def force_file_collision?( dst )
  dst = dst.sub(%r/#{site}\/?/, '')
  @stdout.print "overwrite #{dst}? [(Y)es (n)o (q)uit] "
  @stdout.flush
  case @stdin.gets
    when %r/q/i  then abort 'user asked to quit'
    when %r/n/i  then :skip
    when %r/y/i  then :force
    when %r/\s*/ then :force
    else force_file_collision?(dst) end
rescue
  retry
end

#identical?(src, dst) ⇒ Boolean

Returns true if the source file is identical to the destination file. Returns false if this is not the case.

Returns:

  • (Boolean)


256
257
258
259
260
261
262
# File 'lib/webby/apps/generator.rb', line 256

def identical?( src, dst )
  # FIXME: this most likely won't work on windows machines
  #        because the line endings are modified when the site is gnerated
  source      = IO.read(src)
  destination = IO.read(dst)
  source == destination
end

#message(type, msg) ⇒ Object

Print the given message and message type to stdout.



214
215
216
217
218
# File 'lib/webby/apps/generator.rb', line 214

def message( type, msg )
  msg = msg.sub(%r/#{site}\/?/, '')
  return if msg.empty?
  @stdout.puts "%13s  %s" % [type, msg]
end

#mkdir(dir) ⇒ Object

Make a directory in the user specified site location. A message will be displayed to the screen indicating tha the directory is being created.



149
150
151
152
153
154
155
156
157
# File 'lib/webby/apps/generator.rb', line 149

def mkdir( dir )
  dir = dir.empty? ? site : site / dir
  if test ?d, dir
    exists dir
  else
    create dir
    FileUtils.mkdir_p dir unless pretend?
  end
end

#parse(args) ⇒ Object

Parse out the command line options found in the args array.



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
# File 'lib/webby/apps/generator.rb', line 41

def parse( args )
  opts = OptionParser.new
  opts.banner = 'Usage: webby-gen [options] template site'

  opts.separator ''
  opts.separator 'The webby-gen command is used to generate a site from a standard template.'
  opts.separator 'A new site can be created, or an existing site can be added to or updated.'

  opts.separator ''
  opts.on('-f', '--force',
          'overwrite files that already exist') {options[:collision] = :force}
  opts.on('-s', '--skip',
          'skip files that already exist') {options[:collision] = :skip}
  opts.on('-u', '--update',
          'update rake tasks for the site') {options[:update] = true}
  opts.on('-p', '--pretend',
          'run but do not make any changes') {options[:pretend] = true}

  opts.separator ''
  opts.on('-t', '--templates', 'list available templates') {
    ary = templates.map {|t| ::File.basename(t)}
    ary.delete 'webby'
    @stdout.puts "\nAvailable Templates"
    @stdout.puts "    #{ary.join(', ')}"
    @stdout.puts
    exit
  }

  opts.separator ''
  opts.separator 'common options:'

  opts.on( '-h', '--help', 'show this message' ) {@stdout.puts opts; exit}
  opts.on( '--version', 'show version' ) do
    @stdout.puts "Webby #{::Webby::VERSION}"
    exit
  end

  # parse the command line arguments
  opts.parse! args
  tmpl, @site = args

  # if no site was given, see if there is a Sitefile in the current
  # directory
  if site.nil?
    self.site = '.' if test(?f, 'Sitefile')
  end

  # exit if comand line args are missing
  if site.nil? or tmpl.nil?
    @stdout.puts opts
    exit 1
  end

  templates.each {|t| self.template = t if t =~ %r/\/#{tmpl}$/}
  if template.nil?
    @stdout.puts opts
    abort "Could not find template '#{tmpl}'"
  end

  nil
end

#pretend?Boolean

Returns true if we are only going to pretend to do something. All the output messages will be written, but no changes will be made on the disc.

Returns:

  • (Boolean)


107
108
109
# File 'lib/webby/apps/generator.rb', line 107

def pretend?
  options[:pretend] == true
end

#run(args) ⇒ Object

Run the generator executing the commands specified by the user on the command line.



34
35
36
37
# File 'lib/webby/apps/generator.rb', line 34

def run( args )
  parse args
  create_site
end

#site_filesObject

Iterates over all the files in the template directory and stores them in a hash.



233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
# File 'lib/webby/apps/generator.rb', line 233

def site_files
  exclude = %r/tmp$|bak$|~$|CVS|\.svn/o

  rgxp = %r/\A#{template}\/?/o
  paths = Hash.new {|h,k| h[k] = []}

  Find.find(template) do |p|
    next if exclude =~ p

    if test(?d, p)
      paths[p.sub(rgxp, '')]
      next
    end
    dir = ::File.dirname(p).sub(rgxp, '')
    paths[dir] << p.sub(rgxp, '')
  end

  paths
end

#templatesObject

Returns an array of available site templates.



113
114
115
# File 'lib/webby/apps/generator.rb', line 113

def templates
  Dir.glob(::Webby.path('examples') / '*').sort
end

#win_line_endings(src, dst) ⇒ Object

Copy the file from the src location to the dst location and transform the line endings to the windows “rn” format.



194
195
196
197
198
199
200
201
202
203
204
205
206
# File 'lib/webby/apps/generator.rb', line 194

def win_line_endings( src, dst )
  case ::File.extname(src)
  when *%w[.png .gif .jpg .jpeg]
    FileUtils.cp src, dst
  else
    ::File.open(dst,'w') do |fd|
      ::File.foreach(src, "\n") do |line|
        line.tr!("\r\n",'')
        fd.puts line
      end
    end
  end
end