Class: RakeUi::RakeTask
- Inherits:
-
Object
- Object
- RakeUi::RakeTask
- Defined in:
- app/models/rake_ui/rake_task.rb
Instance Attribute Summary collapse
-
#task ⇒ Object
readonly
Returns the value of attribute task.
Class Method Summary collapse
- .all ⇒ Object
- .find_by_id(id) ⇒ Object
- .from_safe_identifier(id) ⇒ Object
- .internal ⇒ Object
- .load ⇒ Object
- .to_safe_identifier(id) ⇒ Object
Instance Method Summary collapse
- #build_rake_command(args: nil, environment: nil) ⇒ Object
- #call(args: nil, environment: nil) ⇒ Object
- #id ⇒ Object
-
#initialize(task) ⇒ RakeTask
constructor
A new instance of RakeTask.
-
#internal_task? ⇒ Boolean
thinking this is the sanest way to discern application vs gem defined tasks (like rails, devise etc).
- #is_internal_task ⇒ Object
-
#rake_definition_file ⇒ Object
actions will be something like #Proc:0x000055a2737fe778@/some/rails/app/lib/tasks/auto_annotate_models.rake:4.
Constructor Details
#initialize(task) ⇒ RakeTask
Returns a new instance of RakeTask.
49 50 51 |
# File 'app/models/rake_ui/rake_task.rb', line 49 def initialize(task) @task = task end |
Instance Attribute Details
#task ⇒ Object (readonly)
Returns the value of attribute task.
46 47 48 |
# File 'app/models/rake_ui/rake_task.rb', line 46 def task @task end |
Class Method Details
.all ⇒ Object
25 26 27 28 29 |
# File 'app/models/rake_ui/rake_task.rb', line 25 def self.all self.load.map do |task| new(task) end end |
.find_by_id(id) ⇒ Object
37 38 39 40 41 42 43 44 |
# File 'app/models/rake_ui/rake_task.rb', line 37 def self.find_by_id(id) t = all i = from_safe_identifier(id) t.find do |task| task.name == i end end |
.from_safe_identifier(id) ⇒ Object
11 12 13 |
# File 'app/models/rake_ui/rake_task.rb', line 11 def self.from_safe_identifier(id) CGI.unescape(id) end |
.internal ⇒ Object
31 32 33 34 35 |
# File 'app/models/rake_ui/rake_task.rb', line 31 def self.internal self.load.map { |task| new(task) }.select(&:is_internal_task) end |
.load ⇒ Object
15 16 17 18 19 20 21 22 23 |
# File 'app/models/rake_ui/rake_task.rb', line 15 def self.load # Enables 'desc' to show up as full_comments if Rake::TaskManager.respond_to? :record_task_metadata Rake::TaskManager. = true end Rails.application.load_tasks Rake::Task.tasks end |
.to_safe_identifier(id) ⇒ Object
7 8 9 |
# File 'app/models/rake_ui/rake_task.rb', line 7 def self.to_safe_identifier(id) CGI.escape(id) end |
Instance Method Details
#build_rake_command(args: nil, environment: nil) ⇒ Object
112 113 114 115 116 117 118 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 145 146 147 |
# File 'app/models/rake_ui/rake_task.rb', line 112 def build_rake_command(args: nil, environment: nil) command = "" if environment # Safely escape environment variables to prevent shell injection # Only accept KEY=VALUE pairs; reject malicious tokens # # Shellwords.split raises ArgumentError on malformed input (e.g. an # unbalanced quote like FOO="bar). Treat that as no usable env tokens # rather than letting the exception bubble up as a 500. tokens = begin Shellwords.split(environment) rescue ArgumentError [] end escaped_env = tokens.map do |token| next unless token.match?(/\A[A-Z_][A-Z0-9_]*=.*\z/i) # Valid KEY=VALUE pattern - escape only the value key, value = token.split("=", 2) "#{key}=#{Shellwords.escape(value)}" end.compact.join(" ") command += "#{escaped_env} " if escaped_env.present? end command += "rake #{name}" if args # Escape args to prevent shell injection command += "[#{Shellwords.escape(args)}]" end command end |
#call(args: nil, environment: nil) ⇒ Object
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'app/models/rake_ui/rake_task.rb', line 85 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 |
#id ⇒ Object
53 54 55 |
# File 'app/models/rake_ui/rake_task.rb', line 53 def id RakeUi::RakeTask.to_safe_identifier(name) end |
#internal_task? ⇒ Boolean
thinking this is the sanest way to discern application vs gem defined tasks (like rails, devise etc)
75 76 77 78 79 80 81 82 83 |
# File 'app/models/rake_ui/rake_task.rb', line 75 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 |
#is_internal_task ⇒ Object
70 71 72 |
# File 'app/models/rake_ui/rake_task.rb', line 70 def is_internal_task internal_task? end |
#rake_definition_file ⇒ Object
actions will be something like #Proc:0x000055a2737fe778@/some/rails/app/lib/tasks/auto_annotate_models.rake:4
58 59 60 61 62 63 64 65 66 67 68 |
# File 'app/models/rake_ui/rake_task.rb', line 58 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 |