Class: SiteFuel::SiteFuelRuntime
- Includes:
- Logging
- Defined in:
- lib/sitefuel/SiteFuelRuntime.rb
Instance Attribute Summary collapse
-
#abort_on_errors ⇒ Object
whether a deployment should be aborted due to errors.
-
#abort_on_warnings ⇒ Object
whether a deployment should be aborted due to warnings.
-
#action ⇒ Object
what action is the runtime supposed to preform.
-
#deploy_from ⇒ Object
what is the source from which we are deploying.
-
#deploy_to ⇒ Object
what is the source to which we are deploying.
-
#deploymentconfiguration ⇒ Object
configuration loaded from a deployment.yml file.
-
#only_list_recognized_files ⇒ Object
only lists file which have a known processor.
-
#processors ⇒ Object
readonly
gives the array of processors available to this runtime.
-
#scm_system ⇒ Object
what is the scm system.
-
#staging_directory ⇒ Object
readonly
what is the staging directory.
Class Method Summary collapse
-
.find_processors ⇒ Object
returns a list of processors found by looking for all children of SiteFuel::Processor::AbstractProcessor.
-
.load_processors ⇒ Object
finds all processors under processors/ and loads them.
-
.processor_loaded?(file) ⇒ Boolean
gives true if the given file (typically a processor) has already been loaded (by looking into $“).
Instance Method Summary collapse
-
#actions ⇒ Object
lists the actions which are possible with this runtime.
-
#add_processor(proc) ⇒ Object
adds a processor or an array of processors to the runtime.
- #check_messages ⇒ Object
-
#choose_processor(filename) ⇒ Object
gives the processor to use for a given file.
-
#choose_processor!(filename) ⇒ Object
like #choose_processor but prints a message if there are clashing processors and returns the first of the clashing processors.
-
#classify_repository_system(pull_source) ⇒ Object
decides what repository system to use (SVN or Git) based on the pull source given (eg. ssh://… is typically git; svn+ssh://… is SVN, etc.).
- #classify_repository_system!(pull_source) ⇒ Object
-
#deploy ⇒ Object
create a deployment.
-
#find_all_files(path) ⇒ Object
gives an array listing of all files on a given path.
- #finish ⇒ Object
-
#get_base_resource_name(filename) ⇒ Object
given a file name will remove the staging directory from it and give just the base name for the resource.
-
#get_full_deployed_name(filename) ⇒ Object
given a source file name will remove the staging directory and give the fully qualified fully qualified name to which this resource is being deployed.
-
#initialize ⇒ SiteFuelRuntime
constructor
A new instance of SiteFuelRuntime.
-
#pull ⇒ Object
pulls files out of a given repository or file system.
- #section_divider(name) ⇒ Object
-
#stage ⇒ Object
implements the stage command.
-
#staging_statistics ⇒ Object
outputs a little grid showing the number of files of each processor and the total savings.
-
#verbosity(level = 1) ⇒ Object
changes the verbosity of the runtime by adjusting the log level.
Methods included from Logging
#debug, #error, #fatal, #info, #logger=, #warn
Constructor Details
#initialize ⇒ SiteFuelRuntime
Returns a new instance of SiteFuelRuntime.
89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/sitefuel/SiteFuelRuntime.rb', line 89 def initialize @processors = SiteFuelRuntime.find_processors self.logger = SiteFuelLogger.instance SiteFuelLogger.instance.log_style = :clean @only_list_recognized_files = false @abort_on_errors = true @abort_on_warnings = false @scm_system = nil end |
Instance Attribute Details
#abort_on_errors ⇒ Object
whether a deployment should be aborted due to errors
83 84 85 |
# File 'lib/sitefuel/SiteFuelRuntime.rb', line 83 def abort_on_errors @abort_on_errors end |
#abort_on_warnings ⇒ Object
whether a deployment should be aborted due to warnings
86 87 88 |
# File 'lib/sitefuel/SiteFuelRuntime.rb', line 86 def abort_on_warnings @abort_on_warnings end |
#action ⇒ Object
what action is the runtime supposed to preform
62 63 64 |
# File 'lib/sitefuel/SiteFuelRuntime.rb', line 62 def action @action end |
#deploy_from ⇒ Object
what is the source from which we are deploying
65 66 67 |
# File 'lib/sitefuel/SiteFuelRuntime.rb', line 65 def deploy_from @deploy_from end |
#deploy_to ⇒ Object
what is the source to which we are deploying
74 75 76 |
# File 'lib/sitefuel/SiteFuelRuntime.rb', line 74 def deploy_to @deploy_to end |
#deploymentconfiguration ⇒ Object
configuration loaded from a deployment.yml file
77 78 79 |
# File 'lib/sitefuel/SiteFuelRuntime.rb', line 77 def deploymentconfiguration @deploymentconfiguration end |
#only_list_recognized_files ⇒ Object
only lists file which have a known processor
80 81 82 |
# File 'lib/sitefuel/SiteFuelRuntime.rb', line 80 def only_list_recognized_files @only_list_recognized_files end |
#processors ⇒ Object (readonly)
gives the array of processors available to this runtime
164 165 166 |
# File 'lib/sitefuel/SiteFuelRuntime.rb', line 164 def processors @processors end |
#scm_system ⇒ Object
what is the scm system
71 72 73 |
# File 'lib/sitefuel/SiteFuelRuntime.rb', line 71 def scm_system @scm_system end |
#staging_directory ⇒ Object (readonly)
what is the staging directory
68 69 70 |
# File 'lib/sitefuel/SiteFuelRuntime.rb', line 68 def staging_directory @staging_directory end |
Class Method Details
.find_processors ⇒ Object
returns a list of processors found by looking for all children of SiteFuel::Processor::AbstractProcessor
for a processor to be automatically included it has to:
-
be loaded (see #load_processors)
-
be a child class of AbstractProcessor
-
the class name must end with Processor
152 153 154 |
# File 'lib/sitefuel/SiteFuelRuntime.rb', line 152 def self.find_processors Processor::AbstractProcessor.find_processors end |
.load_processors ⇒ Object
finds all processors under processors/ and loads them. Any file matching *Processor.rb will be loaded
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/sitefuel/SiteFuelRuntime.rb', line 120 def self.load_processors dir = File.dirname(__FILE__).split(File::SEPARATOR) dir = File.join(*dir[0..-2]) + File::SEPARATOR # build up the search pattern by taking this file's directory and shoving # it onto the search pattern patt = File.join(dir, 'sitefuel/processors/*Processor.rb') # find all file matching that pattern files = Dir[patt] # rip off the path prefix eg. 'sitefuel/lib/b/foo.rb' becomes 'b/foo.rb' files = files.map do |filename| filename.gsub(Regexp.new("^"+Regexp.escape(dir)), '') end # get rid of anything we've already loaded files = files.delete_if { |file| processor_loaded?(file) } # load whatever files we're left with files.each { |f| require f } end |
.processor_loaded?(file) ⇒ Boolean
gives true if the given file (typically a processor) has already been loaded (by looking into $“). Unfortunately #require is easily tricked, so this function uses some heuristics to prevent processors from being loaded twice (by basically comparing the ”core“ part of the filename)
107 108 109 110 111 112 113 114 115 |
# File 'lib/sitefuel/SiteFuelRuntime.rb', line 107 def self.processor_loaded?(file) $".map do |f| if File.equivalent?(file, f) return true end end return false end |
Instance Method Details
#actions ⇒ Object
lists the actions which are possible with this runtime.
158 159 160 |
# File 'lib/sitefuel/SiteFuelRuntime.rb', line 158 def actions [ :deploy, :stage ] end |
#add_processor(proc) ⇒ Object
adds a processor or an array of processors to the runtime
168 169 170 171 172 173 174 175 176 177 |
# File 'lib/sitefuel/SiteFuelRuntime.rb', line 168 def add_processor(proc) case proc when Array proc.each { |p| @processors << p } else @processors << proc end end |
#check_messages ⇒ Object
394 395 396 397 398 399 400 401 402 403 404 405 406 |
# File 'lib/sitefuel/SiteFuelRuntime.rb', line 394 def error_count = SiteFuelLogger.instance.error_count if @abort_on_errors and error_count > 0 fatal "Aborting due to errors. Use --force to deploy anyway." exit(-1) end warn_count = SiteFuelLogger.instance.error_count if @abort_on_warnings and warn_count > 0 fatal "Aborting due to warnings. Use --ignore-warnings to deploy anyway." exit(-1) end end |
#choose_processor(filename) ⇒ Object
gives the processor to use for a given file
181 182 183 184 185 186 187 188 189 190 191 192 193 |
# File 'lib/sitefuel/SiteFuelRuntime.rb', line 181 def choose_processor(filename) matching = processors.clone.delete_if {|proc| not proc.processes_file?(filename) } case when matching.length > 1 chosen = matching.first raise Processor::MultipleApplicableProcessors.new(filename, matching, chosen) when matching.length == 1 return matching.first else return nil end end |
#choose_processor!(filename) ⇒ Object
like #choose_processor but prints a message if there are clashing processors and returns the first of the clashing processors. (effectively alerting the user, but continuing to work)
199 200 201 202 203 204 205 206 207 |
# File 'lib/sitefuel/SiteFuelRuntime.rb', line 199 def choose_processor!(filename) begin choose_processor(filename) rescue Processor::MultipleApplicableProcessors => exception # log the exception warn exception exception.chosen_processor end end |
#classify_repository_system(pull_source) ⇒ Object
decides what repository system to use (SVN or Git) based on the pull source given (eg. ssh://… is typically git; svn+ssh://… is SVN, etc.)
217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 |
# File 'lib/sitefuel/SiteFuelRuntime.rb', line 217 def classify_repository_system(pull_source) # note that http:// and https:// repositories, in general could be # anything. case pull_source when /^git:\/\/.*$/i, /^ssh:\/\/.*$/i, /^rsync:\/\/.*$/i, /^.*\.git$/i :git when /^svn:\/\/.*$/i, /^svn\+ssh:\/\/.*$/i, /^file:\/\/.*$/i :svn when /^([-.a-zA-Z0-9\/])*$/i :filesystem else raise UnknownVersioningSystem.new(pull_source) end end |
#classify_repository_system!(pull_source) ⇒ Object
241 242 243 244 245 246 |
# File 'lib/sitefuel/SiteFuelRuntime.rb', line 241 def classify_repository_system!(pull_source) classify_repository_system(pull_source) rescue UnknownVersioningSystem => exception fatal(exception.to_s) exit(-1) end |
#deploy ⇒ Object
create a deployment
410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 |
# File 'lib/sitefuel/SiteFuelRuntime.rb', line 410 def deploy # first we have to stage the files stage return if @deploy_to == nil section_divider('Deploying') file_tree = FileTree.new(@deploy_to) # write out content @resource_processors.each_key do |filename| results = @resource_processors[filename] if results == nil putc '.' # copy the file over file_destination = get_full_deployed_name(filename) info("Copying #{filename} to #{file_destination}") FileUtils.copy(filename, file_destination) else putc results.processor_symbol results.save(file_tree) end STDOUT.flush end finish end |
#find_all_files(path) ⇒ Object
gives an array listing of all files on a given path
This is a very lightweight wrapper around Dir.
453 454 455 456 457 458 459 460 461 |
# File 'lib/sitefuel/SiteFuelRuntime.rb', line 453 def find_all_files(path) if File.directory?(path) Dir[File.join(path, "**/*")] elsif File.file?(path) return path else return [] end end |
#finish ⇒ Object
443 444 445 446 447 |
# File 'lib/sitefuel/SiteFuelRuntime.rb', line 443 def finish puts '' puts '' section_divider('Finished') end |
#get_base_resource_name(filename) ⇒ Object
given a file name will remove the staging directory from it and give just the base name for the resource
288 289 290 |
# File 'lib/sitefuel/SiteFuelRuntime.rb', line 288 def get_base_resource_name(filename) filename.gsub(Regexp.new('^'+Regexp.escape(@staging_directory)), '') end |
#get_full_deployed_name(filename) ⇒ Object
given a source file name will remove the staging directory and give the fully qualified fully qualified name to which this resource is being deployed
296 297 298 |
# File 'lib/sitefuel/SiteFuelRuntime.rb', line 296 def get_full_deployed_name(filename) File.join(@deploy_to, get_base_resource_name(filename)) end |
#pull ⇒ Object
pulls files out of a given repository or file system
250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 |
# File 'lib/sitefuel/SiteFuelRuntime.rb', line 250 def pull section_divider 'Pulling' if @scm_system == nil @scm_system = classify_repository_system!(@deploy_from) info "Using #{@scm_system} version control to access #{@deploy_from}" end # TODO this should be modularized; but in general there should be a # 'discoverable' class that automates creation of plugins case @scm_system.to_sym when :svn @staging_directory = External::SVN.export(@deploy_from) when :git @staging_directory = External::GIT.shallow_clone(@deploy_from) when :filesystem # kind of dangerous because it can override the source files; it's # assumed every processor will not override the original. @staging_directory = @deploy_from else fatal "Unknown SCM system: #{@scm_system}" exit(-1) end info "Pulled files for staging into #{@staging_directory}" rescue External::ProgramExitedWithFailure => exception fatal "Couldn't pull files from SCM:\n#{exception}" end |
#section_divider(name) ⇒ Object
209 210 211 |
# File 'lib/sitefuel/SiteFuelRuntime.rb', line 209 def section_divider(name) puts "== #{name} ".ljust(TerminalInfo.width, '=') end |
#stage ⇒ Object
implements the stage command. Staging, by itself, will give statistics on the deployment; how many bytes were saved by minification; etc.
However, #stage when part of #deploy will go and create the requisite files in a temporary directory
306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 |
# File 'lib/sitefuel/SiteFuelRuntime.rb', line 306 def stage pull return nil if @staging_directory == nil section_divider('Staging') printer = ColumnPrinter.new([5, :span, 6]) # find all files under deploy_from files = find_all_files @staging_directory total_original_size = 0 total_processed_size = 0 @resource_processors = {} @processor_statistics = Hash.new([0, 0, 0]) files.each do |filename| processor = choose_processor!(filename) if processor == nil @resource_processors[filename] = nil else resource_name = get_base_resource_name(filename) @resource_processors[filename] = processor.process_file(filename, :resource_name => resource_name) end processor = @resource_processors[filename] if processor == nil if only_list_recognized_files == false printer.row('--', filename) end else total_original_size += processor.original_size total_processed_size += processor.processed_size stats = @processor_statistics[processor.class.processor_name].clone stats[0] += 1 stats[1] += processor.original_size stats[2] += processor.processed_size @processor_statistics[processor.class.processor_name] = stats printer.row( cyan(processor.class.processor_name), filename, '%4.3f'%(processor.processed_size.prec_f/processor.original_size.prec_f) ) end end printer.divider puts 'Size delta: %+5d bytes; %4.3f' % [ total_processed_size - total_original_size, total_processed_size.prec_f/total_original_size.prec_f ] staging_statistics end |
#staging_statistics ⇒ Object
outputs a little grid showing the number of files of each processor and the total savings
todo: this should be computed in the staging step
369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 |
# File 'lib/sitefuel/SiteFuelRuntime.rb', line 369 def staging_statistics puts '' printer = ColumnPrinter.new([12, 8, :span, 6], [TerminalInfo.width, 50].min) printer.alignment([:left, :right, :right, :right]) printer.mode(:divided) headers = %w{processor files delta ratio}.map{|v| bold(v)} printer.row(*headers) printer.divider @processor_statistics.keys.sort.each do |key| printer.row( key, @processor_statistics[key][0], '%+12d'%(@processor_statistics[key][2] - @processor_statistics[key][1]), '%4.3f'%(@processor_statistics[key][2].prec_f / @processor_statistics[key][1].prec_f) ) end printer.divider puts '' end |
#verbosity(level = 1) ⇒ Object
changes the verbosity of the runtime by adjusting the log level
465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 |
# File 'lib/sitefuel/SiteFuelRuntime.rb', line 465 def verbosity(level = 1) case level when 0 SiteFuelLogger.instance.level = Logger::FATAL when 1 SiteFuelLogger.instance.level = Logger::ERROR when 2 SiteFuelLogger.instance.level = Logger::WARN when 3 SiteFuelLogger.instance.level = Logger::INFO when 4 SiteFuelLogger.instance.level = Logger::DEBUG else warn "Unknown verbosity level: #{level}; ignoring." end end |