Object
TODO: Probably rename this class –“Application” is too generic. TODO: Continue to imporve CLI layer.
New Syckle Application.
# File lib/syckle/application.rb, line 54 def initialize(cli_options) @cli = cli_options #Syckle::CLI.new @io = Syckle::IO.new(@cli) @script = Syckle::Script.new(:io=>io, :cli=>cli) @config = Syckle::Config.new(project) #@services, @actions = *load_service_configuration load_plugins end
Returns an array of actived services.
# File lib/syckle/application.rb, line 123 def active_services @active_services ||= ( activelist = [] #autolist = [] #if config.automatic? # Syckle.services.each do |service_name, service_class| # if service_class.available?(project) && # service_class.autorun?(project) && # !config.standard.include?(service_name) # autolist << service_class # end # end #end service_configs.each do |key, opts| next unless opts && opts['active'] != false service_name = opts.delete('service') || key service_class = Syckle.services[service_name.downcase] abort "Unkown service #{service_name}." unless service_class if service_class.available?(project) #autolist.delete(service_class) # remove class from autolist #opts = inject_environment(opts) # TODO: DEPRECATE opts = defaults[service_name.downcase].to_h.merge(opts) activelist << service_class.new(script, key, opts) #project, #else # warn "Service #{service_class} is not available." end end ## If any autorunning services are not accounted for then add to active list. #autolist.each do |service_class| # service_name = service_class.basename.downcase # service_opts = defaults[service_name.downcase].to_h # activelist << service_class.new(script, service_name, service_opts) #end # sorting here trickles down to processing activelist = activelist.sort_by{ |s| s.priority || 0 } #activelist = activelist.sort_by{ |sc, cn, key, opts| opts['priority'] || 0 } activelist ) end
Generates a master configuration template. This is only used for reference purposes.
# File lib/syckle/application.rb, line 109 def config_template cfg = {} Syckle.services.each do |srv_name, srv_class| attrs = srv_class.instance_methods.select{ |m| m.to_s =~ /\w+=$/ && !%{taguri=}.include?(m.to_s) } atcfg = attrs.inject({}){ |h, m| h[m.to_s.chomp('=')] = nil; h } atcfg['service'] = srv_class.basename.downcase atcfg['active'] = false cfg[srv_name] = atcfg end cfg end
User-defined service defaults.
# File lib/syckle/application.rb, line 102 def defaults config.defaults end
Returns a list of all the phases that terminate a pipleline execution. FIXME: phase_map is not defined.
# File lib/syckle/application.rb, line 423 def end_phases (phase_map.keys - phase_map.values).compact end
# File lib/syckle/application.rb, line 66 def load_plugins ::Plugin.find("syckle/*.rb").each do |file| #Syckle.plugins.each do |file| require(file) #Syckle.module_eval(File.read(file)) end end
Load custom plugins. FIXME: how to load?
# File lib/syckle/application.rb, line 410 def load_project_plugins #scripts = project.config_syckle.glob('*.rb') scripts = project.plugin.glob('*.rb') scripts.each do |script| load(script.to_s) # self.class.class_eval(File.read(script)) #instance_eval(File.read(script)) end end
Multitask mode?
# File lib/syckle/application.rb, line 76 def multitask? cli.multitask? && defined?(Parallel) #parallel? end
Give an overview of phases this pipeline supports. FIXME: end_phases blows up.
# File lib/syckle/application.rb, line 430 def overview end_phases.each do |phase_name| action_plan(phase_name).each do |act| io.display_action(act) end puts end end
Provides access to the Project instance.
# File lib/syckle/application.rb, line 96 def project script.project end
Run the cycle upto the specified cycle-phase.
# File lib/syckle/application.rb, line 288 def run(job) # tab completion -- improve this in the future. #if cli == '?' # m, l = [], [] # Syckle.pipelines.each do |key, pipe| # pipe.phasemap.keys.each do |phase| # if key == :main # m << "#{phase}" # l << "#{key}:#{phase}" # else # l << "#{key}:#{phase}" # end # end # end # puts m.sort.join(" ") + l.sort.join(" ") # exit #end if job name, phase = job.split(':') name, phase = 'main', name unless phase else name = 'main' phase = nil end name = name.to_sym phase = phase.to_sym if phase lifecycle = Syckle.lifecycles[name] raise "Unknown life-cycle -- #{name}" unless lifecycle if phase system = lifecycle.cycle_with_phase(phase) raise "Unknown phase -- #{phase}" unless system else #overview $stderr.puts "Unknown name:phase given." exit 0 end # prime the services (so as to fail early) active_services.each do |srv| srv.preconfigure if srv.respond_to?("preconfigure") end if multitask? h = ["#{project.metadata.title} v#{project.metadata.version} [M]", "#{project.root}"] else h = ["#{project.metadata.title} v#{project.metadata.version}", "#{project.root}"] end io.status_header(*h) start_time = Time.now system.each do |run_phase| next if skip.include?("#{run_phase}") # TODO: Should we really allow skipping phases? service_hooks(name, ('pre_' + run_phase.to_s).to_sym) service_calls(name, ('pre_' + run_phase.to_s).to_sym) service_calls(name, run_phase) service_calls(name, ('aft_' + run_phase.to_s).to_sym) service_hooks(name, ('aft_' + run_phase.to_s).to_sym) break if phase == run_phase end stop_time = Time.now puts "\nFinished in #{stop_time - start_time} seconds." unless script.quiet? end
Run a service given the service, pipe name and phase name.
# File lib/syckle/application.rb, line 395 def run_a_service(srv, pipe, phase) # run if the service supports the pipe and phase. if srv.respond_to?("#{pipe}_#{phase}") if script.verbose? io.status_line("#{srv.key.to_s} (#{srv.class}##{pipe}_#{phase})", phase.to_s.gsub('_', '-').capitalize) else io.status_line("#{srv.key.to_s}", phase.to_s.gsub('_', '-').capitalize) end srv.__send__("#{pipe}_#{phase}") end end
Run individual syckle scripts/tasks.
# File lib/syckle/application.rb, line 257 def runscript(script, job) @service_configs = load_service_configs(script) run(job) end
Make service calls.
# File lib/syckle/application.rb, line 375 def service_calls(pipe, phase) prioritized_services = active_services.group_by{ |srv| srv.priority }.sort_by{ |k,v| k } prioritized_services.each do |(priority, services)| # remove any services specified by the -s option on the comamndline. services = services.reject{ |srv| skip.include?(srv.key.to_s) } tasklist = services.map{ |srv| [srv, pipe, phase] } if multitask? results = Parallel.in_processes(tasklist.size) do |i| run_a_service(*tasklist[i]) end else tasklist.each do |args| run_a_service(*args) end end end end
Service configuration. These are stored in the project's task/ or script/ folder as YAML files.
# File lib/syckle/application.rb, line 187 def service_configs config.services #@service_configs ||= ( # load_service_configs(files) #) end
Execute service hook for given pipe and phase.
# File lib/syckle/application.rb, line 362 def service_hooks(pipe, phase) dir = project.config + "syckle/hooks" #hook = dir + ("#{pipe}/#{phase}.rb".gsub('_', '-')) name = phase.to_s.gsub('_', '-') hook = dir + "#{name}.rb" if hook.exist? io.status_line("hook", name.capitalize) script.instance_eval(hook.read) end end
Returns a list of services to skip as specificed on the commandline.
# File lib/syckle/application.rb, line 251 def skip @skip ||= cli.skip.to_list.map{ |s| s.downcase } end
Start the cycle.
# File lib/syckle/application.rb, line 264 def start(argv=ARGV) Dir.chdir(project.root) # change into project directory load_project_plugins # load any local plugins cli.parse # parse the cli job = argv.shift #cli.command # what cycle-phase has been requested #help(job) if !job # if none then show help and exit #help(cli,job) if cli.help? # display help message if requested #help(job) if cli.options[:help] run(job) end
Generated with the Darkfish Rdoc Generator 2.