# frozen_string_literal: true module RakeUi class RakeTask def self.to_safe_identifier(id) CGI.escape(id) end def self.from_safe_identifier(id) CGI.unescape(id) end def self.load # Enables 'desc' to show up as full_comments if Rake::TaskManager.respond_to? :record_task_metadata Rake::TaskManager.record_task_metadata = true end Rails.application.load_tasks Rake::Task.tasks end def self.all self.load.map do |task| new(task) end end def self.internal self.load.map { |task| new(task) }.select(&:is_internal_task) end def self.find_by_id(id) t = all i = from_safe_identifier(id) t.find do |task| task.name == i end end attr_reader :task delegate :name, :actions, :name_with_args, :arg_description, :full_comment, :locations, :sources, to: :task def initialize(task) @task = task end def id RakeUi::RakeTask.to_safe_identifier(name) end # actions will be something like # def rake_definition_file definition = actions.first || "" if definition.respond_to?(:source_location) definition.source_location.join(":") else definition end rescue "unable_to_determine_defining_file" end def is_internal_task internal_task? end # thinking this is the sanest way to discern application vs gem defined tasks (like rails, devise etc) def internal_task? actions.any? { |a| !a.to_s.include? "/ruby/gems" } # this was my initial thought here, leaving for posterity in case we need to or the definition of custom # from initial investigation the actions seemed like the most consistent as locations is sometimes empty # locations.any? do |location| # !location.match(/\/bundle\/gems/) # end end def call(args: nil, environment: nil) rake_command = build_rake_command(args: args, environment: environment) rake_task_log = RakeUi::RakeTaskLog.build_new_for_command( name: name, args: args, environment: environment, rake_command: rake_command, rake_definition_file: rake_definition_file, raker_id: id ) puts "[rake_ui] [rake_task] [forked] #{rake_task_log.rake_command_with_logging}" fork do system(rake_task_log.rake_command_with_logging) system(rake_task_log.command_to_mark_log_finished) end rake_task_log end # returns an invokable rake command # FOO=bar rake create_something[1,2,3] # rake create_something[1,2,3] # rake create_something def build_rake_command(args: nil, environment: nil) command = "" if environment command += "#{environment} " end command += "rake #{name}" if args command += "[#{args}]" end command end end end