command_proposal 1.0.12 → 1.0.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ab0271a9e0e80bf0df78d8284cc8e13d292ef2254ab57180b1434f50b351dcb7
4
- data.tar.gz: 21b077ee6cfa9ede8ea83315523297ff9268bf5236de797c9f3acae9f1ef3910
3
+ metadata.gz: 321b3627d2af7cf183da1cd1071775e7f13907b0fda6101acce253f9649f8a42
4
+ data.tar.gz: c9a30e58a53bb372807e05e765a7b92368433ced38325e8d7800e9f6b983eeb8
5
5
  SHA512:
6
- metadata.gz: 52a46842e394c99d8dbb4527c222ab93e93dc437992996b3b9af3850a9bc6571bac4e472268c7f821d6b541c17074d21954d0b18e5e15d2109141a4f04179491
7
- data.tar.gz: eb670b929efd2d6c612997e569276fac67aa494325db38d357a5589496bdba19b0d5335d68696d715022b45e9ed13eae4e2245d4ddc12f53371ad3d611e4987b
6
+ metadata.gz: ddcd08648f107fb5e50c57ae46a7ff93ddb1f7e79ea900e7a052afd6fb31574fd85fae1bf4a2214313a6fae8b46d79e4406d2be6756714319d928c259b612557
7
+ data.tar.gz: 629c1bc1f60e363396a7672122dc0a945c042baed8c43339fbc5ae7d80cb71aa645de0d3c199709d923cc1c1376e3d305b273ef3f71275ae53215899e59e3ef1
@@ -142,14 +142,16 @@ cmdDocReady(function() {
142
142
 
143
143
  console_input.textContent = ""
144
144
 
145
- var result = document.createElement("div")
146
- result.classList.add("result")
145
+ if (!(/^[\s\n]*$/.test(line.textContent))) {
146
+ var result = document.createElement("div")
147
+ result.classList.add("result")
147
148
 
148
- var spinner = document.createElement("i")
149
- spinner.className = "fa fa-circle-o-notch fa-spin cmd-icon-grey"
150
- result.append(spinner)
149
+ var spinner = document.createElement("i")
150
+ spinner.className = "fa fa-circle-o-notch fa-spin cmd-icon-grey"
151
+ result.append(spinner)
151
152
 
152
- line.appendChild(result)
153
+ line.appendChild(result)
154
+ }
153
155
 
154
156
  lines.appendChild(line)
155
157
  stored_entry = undefined
@@ -176,41 +178,77 @@ cmdDocReady(function() {
176
178
  body: JSON.stringify(params),
177
179
  done: function(res, status, req) {
178
180
  if (status == 200) {
179
- var json = JSON.parse(res)
180
- line.querySelector(".result").remove()
181
-
182
- var result = document.createElement("div")
183
- result.classList.add("result")
184
-
185
- if (json.error) {
186
- result.classList.add("cmd-error")
187
- result.textContent = json.error
188
- } else {
189
- var truncate = 2000
190
- if (json.result.length > truncate-3) {
191
- result.textContent = json.result.slice(0, truncate-3) + "..."
192
- var encoded = encodeURIComponent(json.result)
193
-
194
- var download = document.createElement("a")
195
- download.classList.add("cmd-truncated-download")
196
- download.setAttribute("href", "data:application/txt," + encoded)
197
- download.setAttribute("download", "result.txt")
198
- download.textContent = "Output truncated. Click here to download full result."
199
-
200
- line.insertAdjacentElement("afterend", download)
201
- } else {
202
- result.textContent = json.result
203
- }
204
- }
205
-
206
- line.appendChild(result)
181
+ handleSuccessfulCommand(evt, line, JSON.parse(res))
207
182
  } else {
208
183
  console.log("Error: ", res, req);
209
184
  }
210
- evt.finish()
211
185
  }
212
186
  })
213
187
  })
214
188
  }
189
+
190
+ function handleSuccessfulCommand(evt, line, json) {
191
+ if (json.error) {
192
+ addLineResult(line, json.error, "cmd-error")
193
+ } else if (json.status != "started") {
194
+ addLineResult(line, json.result, json.status == "failed" ? "cmd-error" : "")
195
+ } else {
196
+ return setTimeout(function() { pollIteration(evt, line, json.results_endpoint) }, 2000)
197
+ }
198
+
199
+ evt.finish()
200
+ }
201
+
202
+ function addLineResult(line, text, result_class) {
203
+ line.querySelector(".result").remove()
204
+
205
+ if (!text || /^[\s\n]*$/.test(text)) { return }
206
+
207
+ var result = document.createElement("div")
208
+ result.classList.add("result")
209
+ if (result_class) { result.classList.add(result_class) }
210
+
211
+ var truncate = 2000
212
+ if (text.length > truncate-3) {
213
+ result.textContent = text.slice(0, truncate-3) + "..."
214
+ var encoded = encodeURIComponent(text)
215
+
216
+ var download = document.createElement("a")
217
+ download.classList.add("cmd-truncated-download")
218
+ download.setAttribute("href", "data:application/txt," + encoded)
219
+ download.setAttribute("download", "result.txt")
220
+ download.textContent = "Output truncated. Click here to download full result."
221
+
222
+ line.insertAdjacentElement("afterend", download)
223
+ } else {
224
+ result.textContent = text
225
+ }
226
+
227
+ line.appendChild(result)
228
+ }
229
+
230
+ function pollIteration(evt, line, endpoint) {
231
+ var client = new HttpClient()
232
+ client.get(endpoint, {
233
+ headers: {
234
+ "Content-Type": "application/json",
235
+ "X-CSRF-Token": $.rails.csrfToken()
236
+ },
237
+ done: function(res, status, req) {
238
+ if (status == 200) {
239
+ var json = JSON.parse(res)
240
+ if (json.status == "started") {
241
+ setTimeout(function() { pollIteration(evt, line, endpoint) }, 2000)
242
+ } else {
243
+ addLineResult(line, json.result, json.status == "failed" ? "cmd-error" : "")
244
+ evt.finish()
245
+ }
246
+ } else {
247
+ console.log("Error: ", res, req);
248
+ evt.finish()
249
+ }
250
+ }
251
+ })
252
+ }
215
253
  }
216
254
  })
@@ -35,3 +35,20 @@
35
35
  background: lightgrey;
36
36
  }
37
37
  }
38
+
39
+ .cmd-pagination {
40
+ text-align: center;
41
+ margin-top: 10px;
42
+
43
+ .cmd-pagination-link {
44
+ text-decoration: none;
45
+
46
+ &:hover {
47
+ text-decoration: underline;
48
+ }
49
+
50
+ &.current-page {
51
+ font-weight: bold;
52
+ }
53
+ }
54
+ }
@@ -75,4 +75,7 @@
75
75
  font-size: 12px;
76
76
  color: grey;
77
77
  }
78
+ &.cmd-past-iterations tbody tr:nth-child(even) {
79
+ background: whitesmoke;
80
+ }
78
81
  }
@@ -9,6 +9,16 @@ class ::CommandProposal::IterationsController < ::CommandProposal::EngineControl
9
9
 
10
10
  layout "application"
11
11
 
12
+ def show
13
+ @iteration = ::CommandProposal::Iteration.find(params[:id])
14
+
15
+ render json: {
16
+ results_endpoint: cmd_path(@iteration),
17
+ result: @iteration.result,
18
+ status: @iteration.status
19
+ }
20
+ end
21
+
12
22
  def create
13
23
  return error!("You do not have permission to run commands.") unless can_command?
14
24
 
@@ -17,27 +27,32 @@ class ::CommandProposal::IterationsController < ::CommandProposal::EngineControl
17
27
  return error!("Can only run commands on type: :console") unless @task.console?
18
28
  return error!("Session has not been approved.") unless has_approval?(@task)
19
29
 
20
- if @task.iterations.many?
21
- runner = ::CommandProposal.sessions["task:#{@task.id}"]
22
- elsif @task.iterations.one?
30
+ if @task.iterations.one?
23
31
  # Track console details in first iteration
24
32
  @task.first_iteration.update(started_at: Time.current, status: :started)
25
- runner = ::CommandProposal::Services::Runner.new
26
- ::CommandProposal.sessions["task:#{@task.id}"] = runner
27
33
  end
28
34
 
29
- return error!("Session has expired. Please start a new session.") if runner.nil?
30
-
31
35
  @task.user = command_user # Separate from update to ensure it's set first
32
36
  @task.update(code: params[:code]) # Creates a new iteration
33
37
  @iteration = @task.current_iteration
34
38
  @iteration.update(status: :approved) # Task was already approved, and this is line-by-line
35
39
 
36
- # in-sync
37
- runner.execute(@iteration)
40
+ # async, but wait for the job to finish
41
+ ::CommandProposal::CommandRunnerJob.perform_later(@iteration.id, "task:#{@task.id}")
42
+
43
+ max_wait_seconds = 3
44
+ loop do
45
+ break unless max_wait_seconds.positive?
46
+
47
+ max_wait_seconds -= sleep 0.2
48
+
49
+ break if @iteration.reload.complete?
50
+ end
38
51
 
39
52
  render json: {
40
- result: @iteration.result
53
+ results_endpoint: cmd_path(@iteration),
54
+ result: @iteration.result,
55
+ status: @iteration.status
41
56
  }
42
57
  end
43
58
 
@@ -17,7 +17,8 @@ class ::CommandProposal::TasksController < ::CommandProposal::EngineController
17
17
  @tasks = ::CommandProposal::Task.includes(:iterations)
18
18
  @tasks = @tasks.order(Arel.sql("COALESCE(command_proposal_tasks.last_executed_at, command_proposal_tasks.created_at) DESC"))
19
19
  @tasks = @tasks.search(params[:search]) if params[:search].present?
20
- @tasks = @tasks.where(session_type: params[:filter]) if params[:filter].present?
20
+ @tasks = @tasks.by_session(params[:filter])
21
+ @tasks = @tasks.cmd_page(params[:page])
21
22
  end
22
23
 
23
24
  def show
@@ -37,7 +38,8 @@ class ::CommandProposal::TasksController < ::CommandProposal::EngineController
37
38
  end
38
39
 
39
40
  def new
40
- @task = ::CommandProposal::Task.new(session_type: params[:session_type])
41
+ @task = ::CommandProposal::Task.new
42
+ @task.session_type = params[:session_type] if params[:session_type].in?(::CommandProposal::Task.session_types)
41
43
 
42
44
  render "form"
43
45
  end
@@ -51,12 +53,12 @@ class ::CommandProposal::TasksController < ::CommandProposal::EngineController
51
53
  def create
52
54
  @task = ::CommandProposal::Task.new(task_params.except(:code))
53
55
  @task.user = command_user
54
- @task.skip_approval = true unless approval_required?
56
+ @task.skip_approval = true unless approval_required?(@task.session_type)
55
57
 
56
58
  # Cannot create the iteration until the task is created, so save then update
57
59
  if @task.save && @task.update(task_params)
58
60
  if @task.console?
59
- @task.iterations.create(requester: command_user) # Blank iteration to track approval
61
+ @task.code = nil # Creates a blank iteration to track approval
60
62
  redirect_to cmd_path(@task)
61
63
  else
62
64
  redirect_to cmd_path(:edit, @task)
@@ -70,7 +72,7 @@ class ::CommandProposal::TasksController < ::CommandProposal::EngineController
70
72
  def update
71
73
  @task = ::CommandProposal::Task.find_by!(friendly_id: params[:id])
72
74
  @task.user = command_user
73
- @task.skip_approval = true unless approval_required?
75
+ @task.skip_approval = true unless approval_required?(@task.session_type)
74
76
 
75
77
  if @task.update(task_params)
76
78
  redirect_to cmd_path(@task)
@@ -22,6 +22,15 @@ module ::CommandProposal::ParamsHelper
22
22
  end
23
23
  end
24
24
 
25
+ def current_path(new_params={})
26
+ if @task.present?
27
+ new_params.merge!(iteration: @iteration.id) if @iteration.present? && !@iteration.primary_iteration?
28
+ cmd_path(@task, new_params)
29
+ else
30
+ cmd_path(:tasks, current_params(new_params))
31
+ end
32
+ end
33
+
25
34
  def truthy?(val)
26
35
  val.to_s.downcase.in?(["true", "t", "1"])
27
36
  end
@@ -60,4 +69,38 @@ module ::CommandProposal::ParamsHelper
60
69
  return "< 1s" if str_parts.none?
61
70
  str_parts.join(" ")
62
71
  end
72
+
73
+ def div(opts={}, &block)
74
+ "<div #{opts.map { |k, v| "#{k}=\"#{v}\"" }.join(" ")}>#{yield}</div>".html_safe
75
+ end
76
+
77
+ def command_paginate(paged_collection)
78
+ collection = paged_collection.unscope(:limit, :offset)
79
+
80
+ per = ::CommandProposal::PAGINATION_PER
81
+ total_pages = (collection.count / per.to_f).ceil
82
+ current_page = params[:page].presence&.to_i || 1
83
+
84
+ return if total_pages <= 1
85
+
86
+ div(class: "cmd-pagination") do
87
+ links = []
88
+ links << ["<<", { page: 1 }] if current_page > 1
89
+ links << ["<", { page: current_page - 1 }] if current_page > 1
90
+
91
+ (current_page-2..current_page+2).each do |page_window|
92
+ next if page_window < 1
93
+ next if page_window > total_pages
94
+
95
+ links << [page_window, { page: page_window }]
96
+ end
97
+
98
+ links << [">", page: current_page + 1] if current_page < total_pages
99
+ links << [">>", page: total_pages] if current_page < total_pages
100
+
101
+ links.map do |link_text, link_params|
102
+ "<a class=\"cmd-pagination-link #{'current-page' if link_params[:page] == current_page}\" href=\"#{current_path(link_params)}\">#{link_text}</a>"
103
+ end.join("\n")
104
+ end
105
+ end
63
106
  end
@@ -9,7 +9,7 @@ module CommandProposal
9
9
 
10
10
  def can_approve?(iteration)
11
11
  return false unless permitted_to_use?
12
- return true unless approval_required?
12
+ return true unless approval_required?(iteration.task.session_type)
13
13
  return if iteration.nil?
14
14
 
15
15
  command_user.try("#{cmd_config.role_scope}?") && !current_is_author?(iteration)
@@ -17,13 +17,18 @@ module CommandProposal
17
17
 
18
18
  def has_approval?(task)
19
19
  return false unless permitted_to_use?
20
- return true unless approval_required?
20
+ return true unless approval_required?(task.session_type)
21
21
 
22
22
  task&.approved?
23
23
  end
24
24
 
25
- def approval_required?
26
- cmd_config.approval_required?
25
+ def approval_required?(task_type=nil)
26
+ return false unless cmd_config.approval_required?
27
+ return true if task_type.blank?
28
+
29
+ skips = cmd_config.skip_approval_for_types.presence || []
30
+
31
+ Array.wrap(skips).map(&:to_sym).exclude?(task_type.to_sym)
27
32
  end
28
33
 
29
34
  def current_is_author?(iteration)
@@ -2,10 +2,26 @@ module CommandProposal
2
2
  class CommandRunnerJob < ApplicationJob
3
3
  queue_as :default
4
4
 
5
- def perform(iteration_id)
5
+ def perform(iteration_id, runner_key=nil)
6
6
  iteration = ::CommandProposal::Iteration.find(iteration_id)
7
+ runner = ::CommandProposal.sessions[runner_key] if runner_key.present?
7
8
 
8
- ::CommandProposal::Services::Runner.new.execute(iteration)
9
+ if runner_key.present? && runner.blank?
10
+ if iteration.task.console? && iteration.task.iterations.count > 2 # 1 for init, and the 1 for current running code
11
+ return ::CommandProposal::Services::Runner.new.quick_fail(
12
+ iteration,
13
+ "Session has expired. Please start a new session."
14
+ )
15
+ else
16
+ runner = ::CommandProposal::Services::Runner.new
17
+ end
18
+
19
+ ::CommandProposal.sessions[runner_key] = runner if runner_key.present?
20
+ else
21
+ runner ||= ::CommandProposal::Services::Runner.new
22
+ end
23
+
24
+ runner.execute(iteration)
9
25
  end
10
26
  end
11
27
  end
@@ -40,6 +40,12 @@ class ::CommandProposal::Iteration < ApplicationRecord
40
40
  terminated: 7, # Closed via server restart
41
41
  }
42
42
 
43
+ scope :cmd_page, ->(page=nil) {
44
+ page = page.presence&.to_i || 1
45
+ per = ::CommandProposal::PAGINATION_PER
46
+ limit(per).offset(per * (page - 1))
47
+ }
48
+
43
49
  delegate :name, to: :task
44
50
  delegate :description, to: :task
45
51
  delegate :session_type, to: :task
@@ -55,6 +61,10 @@ class ::CommandProposal::Iteration < ApplicationRecord
55
61
  ::CommandProposal::Task.module.where(friendly_id: bring_str.scan(/\s+\:(\w+),?/).flatten)
56
62
  end
57
63
 
64
+ def primary_iteration?
65
+ task.primary_iteration == self
66
+ end
67
+
58
68
  def complete?
59
69
  success? || failed? || cancelled? || terminated?
60
70
  end
@@ -15,12 +15,24 @@ class ::CommandProposal::Task < ApplicationRecord
15
15
  scope :search, ->(text) {
16
16
  where("name ILIKE :q OR description ILIKE :q", q: "%#{text}%")
17
17
  }
18
+ scope :by_session, ->(filter) {
19
+ if filter.present?
20
+ where(session_type: filter) if filter.to_s.in?(session_types.keys)
21
+ else
22
+ where(session_type: :function)
23
+ end
24
+ }
25
+ scope :cmd_page, ->(page=nil) {
26
+ page = page.presence&.to_i || 1
27
+ per = ::CommandProposal::PAGINATION_PER
28
+ limit(per).offset(per * (page - 1))
29
+ }
18
30
 
19
31
  enum session_type: {
20
- # Task will have multiple iterations that are all essentially the same just with code changes
21
- task: 0,
22
32
  # Function iterations are much like tasks
23
33
  function: 1,
34
+ # Task will have multiple iterations that are all essentially the same just with code changes
35
+ task: 0,
24
36
  # Console iterations are actually line by line, so order matters
25
37
  console: 2,
26
38
  # Modules are included in tasks and not run independently
@@ -1,18 +1,18 @@
1
1
  <% if lines.none? && !(skip_empty ||= false) -%><div class="line"></div><% end
2
2
  -%><% lines.each do |iteration| -%>
3
3
  <div class="line"><%= iteration.code
4
- -%><div class="result"><%=
4
+ -%><div class="result <%= 'cmd-error' if iteration.failed? %>"><%=
5
5
  truncate = ::CommandProposal::Iteration::TRUNCATE_COUNT
6
6
  if iteration.result.present?
7
7
  iteration.result.truncate(truncate)
8
- elsif iteration.completed?
8
+ elsif iteration.complete?
9
9
  "Error: No response"
10
10
  else
11
11
  content_tag :i, nil, class: "fa fa-circle-o-notch fa-spin cmd-icon-grey"
12
12
  end
13
13
  %></div
14
14
  ></div><%=
15
- if iteration.result.length > truncate
15
+ if iteration.result&.length.to_i > truncate
16
16
  link_to("Output truncated. Click here to download full result.", "data:application/txt,#{ERB::Util.url_encode(iteration.result)}", class: "cmd-truncated-download", download: "result.txt")
17
17
  end
18
18
  %><% end -%>
@@ -1,27 +1,38 @@
1
- <% if @task.iterations.many? %>
2
- <table class="cmd-table">
1
+ <% if @task.iterations.any? %>
2
+ <table class="cmd-table cmd-past-iterations">
3
3
  <thead>
4
4
  <th>Timestamp / Link</th>
5
5
  <th>Status</th>
6
+ <% if @iteration&.params.present? %>
7
+ <th>Params</th>
8
+ <% end %>
9
+ <th>Result</th>
6
10
  <!-- <th># Comments</th> -->
7
11
  <!-- <th>Diff</th> -->
8
12
  </thead>
9
13
  <tbody>
10
- <% primary_iteration = @task.primary_iteration %>
11
- <% @task.iterations.where.not(id: @iteration&.id).order(created_at: :desc).each do |iteration| %>
14
+ <% paginated_iterations = @task.iterations.cmd_page(params[:page]) %>
15
+ <% paginated_iterations.order(created_at: :desc).each do |iteration| %>
12
16
  <tr>
13
17
  <td>
14
- <% if iteration.id == primary_iteration&.id %>
15
- <%= link_to iteration.created_at.strftime("%b %-d, %Y at %H:%M"), cmd_path(@task) %>
16
- <% else %>
17
- <%= link_to iteration.created_at.strftime("%b %-d, %Y at %H:%M"), cmd_path(@task, iteration: iteration.id) %>
18
- <% end %>
18
+ <%= ">" if iteration == @iteration %>
19
+ <%= link_to iteration.created_at.strftime("%b %-d, %Y at %H:%M"), cmd_path(@task, iteration: iteration.id) %>
19
20
  </td>
20
21
  <td><%= iteration.status.capitalize %></td>
22
+ <% if @iteration&.params.present? %>
23
+ <td>
24
+ <% iteration&.args.each do |arg_k, arg_v| %>
25
+ <span class=cmd-arg""><%= arg_k %>=<%= arg_v.to_s.truncate(50) %></span>
26
+ <% end %>
27
+ </td>
28
+ <% end %>
29
+ <td><%= iteration.result.to_s.truncate(200) %></td>
21
30
  <!-- <td><%#= iteration.comments.count %></td> -->
22
31
  <!-- <td><%#= link_to "Diff", cmd_path(@task, iteration: @iteration.id, diff: iteration.id) %></td> -->
23
32
  </tr>
24
33
  <% end %>
25
34
  </tbody>
26
35
  </table>
36
+
37
+ <%= command_paginate paginated_iterations %>
27
38
  <% end %>
@@ -1,9 +1,11 @@
1
1
  <div class="cmd-wrapper">
2
- <%= link_to "New #{params[:filter].presence&.capitalize || 'Command'}", cmd_path(:new, :task, session_type: params[:filter] || :task) %> <br>
2
+ <% filter_name = params[:filter].presence&.capitalize %>
3
+ <% filter_name = filter_name.blank? || filter_name == "All" ? "Command" : filter_name %>
4
+ <%= link_to "New #{filter_name}", cmd_path(:new, :task, session_type: params[:filter] || :task) %> <br>
3
5
  <br>
4
- <%= link_to "All", cmd_path(:tasks, current_params.except(:filter)), class: "cmd-tab #{:active unless params.key?(:filter)}"
6
+ <%= link_to "All", toggled_param(filter: :all), class: "cmd-tab #{:active if params[:filter] == "all"}"
5
7
  %><% ::CommandProposal::Task.session_types.each_with_index do |(session_type, _session_enum), idx| %><%=
6
- selected = params[:filter] == session_type.to_s
8
+ selected = params[:filter] == session_type.to_s || (!params.key?(:filter) && session_type == "function")
7
9
  # Offset closing RB tags to fix spacing issues
8
10
  link_to session_type.capitalize, toggled_param(filter: session_type), class: "cmd-tab #{:active if selected}"
9
11
  %><% end %>
@@ -42,4 +44,6 @@
42
44
  <% end %>
43
45
  <% end %>
44
46
  </div>
47
+
48
+ <%= command_paginate @tasks %>
45
49
  </div>
@@ -13,6 +13,7 @@ module CommandProposal
13
13
  :approval_callback,
14
14
  :success_callback,
15
15
  :failed_callback,
16
+ :skip_approval_for_types,
16
17
  )
17
18
 
18
19
  def initialize
@@ -30,6 +31,7 @@ module CommandProposal
30
31
  @approval_callback = nil
31
32
  @success_callback = nil
32
33
  @failed_callback = nil
34
+ @skip_approval_for_types = nil
33
35
  end
34
36
 
35
37
  def user_class
@@ -51,6 +51,19 @@ module CommandProposal
51
51
  proposal
52
52
  end
53
53
 
54
+ def quick_fail(iteration, msg)
55
+ @iteration = iteration
56
+ prepare
57
+
58
+ @iteration.status = :failed
59
+ @iteration.result = msg
60
+
61
+ complete
62
+ proposal = ::CommandProposal::Service::ProposalPresenter.new(@iteration)
63
+ @iteration = nil
64
+ proposal
65
+ end
66
+
54
67
  def quick_run(friendly_id)
55
68
  task = ::CommandProposal::Task.module.find_by!(friendly_id: friendly_id)
56
69
  iteration = task&.primary_iteration
@@ -76,7 +89,11 @@ module CommandProposal
76
89
 
77
90
  def run
78
91
  begin
79
- @session.eval("#{bring_function};params = #{@iteration.args || {}}.with_indifferent_access")
92
+ params_str = ""
93
+ unless @iteration.task.console? # Don't bring params into the console
94
+ params_str = "params = #{@iteration.args || {}}.with_indifferent_access"
95
+ end
96
+ @session.eval("#{bring_function};#{params_str}")
80
97
  rescue Exception => e # rubocop:disable Lint/RescueException - Yes, rescue full Exception so that we can catch typos in evals as well
81
98
  return @iteration.result = results_from_exception(e)
82
99
  end
@@ -88,7 +105,7 @@ module CommandProposal
88
105
 
89
106
  running_thread = Thread.new do
90
107
  begin
91
- # Run bring functions in here so we can capture any string outputs
108
+ # Run `bring` functions in here so we can capture any string outputs
92
109
  # OR! Run the full runner and instead of saving to an iteration, return the string for prepending here
93
110
  result = @session.eval("_ = (#{@iteration.code})").inspect # rubocop:disable Security/Eval - Eval is scary, but in this case it's exactly what we need.
94
111
  result = nil unless @iteration.task.console? # Only store final result for consoles
@@ -1,3 +1,3 @@
1
1
  module CommandProposal
2
- VERSION = "1.0.12"
2
+ VERSION = "1.0.15"
3
3
  end
@@ -6,6 +6,8 @@ require "command_proposal/services/shut_down"
6
6
 
7
7
  module CommandProposal
8
8
  class Error < StandardError; end
9
+ PAGINATION_PER = 10
10
+
9
11
  def self.sessions
10
12
  @sessions ||= {}
11
13
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: command_proposal
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.12
4
+ version: 1.0.15
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rocco Nicholls
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-10-26 00:00:00.000000000 Z
11
+ date: 2022-03-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails