command_proposal 1.0.10 → 1.0.14

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: ab98adfd455b086e6e9837ebabb3461fadfe73e95060b7061e61e05c4eae374a
4
- data.tar.gz: 8449a6b67001d913bd5cf8a9e89bb8a3fe730dc384449fb51957a8eb018c53af
3
+ metadata.gz: 49fcf371fa04144d6c3a47f4cf8170bd30c1571c61f44d636df41591227f4d66
4
+ data.tar.gz: 990a726d0441c95757ec17679e495b1300f4de2e5ac284df842bf82180c6912f
5
5
  SHA512:
6
- metadata.gz: 277d11f925f481a5c5a8f53a4f17dce9725305964f04473cebd92693f0684335e5d77161966186444f29e5fcb113571feb029662bb4b3d82a7182bee38ea89ff
7
- data.tar.gz: 02c2e3f743f0dd76bbabe43c3fe0f22d332af4d03a5d9561ee1a459e62f185b515f8961ee8a2f96d3ce0424c1153f10769759daed07f38441c8d41abe4eb4f4b
6
+ metadata.gz: 3d9d03fbe537ce4da08d6229829148ef8dbdbe1433ae56db6b08f97313a6329d41b2f63c8f433a197f34559521e37a652bad931f9be3a2eb0f4b12265184f1bf
7
+ data.tar.gz: 24ba8d9ad1147fa9d6ee21298d547e774fd444ee0370bc79e629c1ad63fefb9d022aa95d9d78e56b1f58db7cf8d2e191731dd4970b88fd60484395c9ec376ccb
@@ -141,6 +141,16 @@ cmdDocReady(function() {
141
141
  line.textContent = console_input.textContent
142
142
 
143
143
  console_input.textContent = ""
144
+
145
+ var result = document.createElement("div")
146
+ result.classList.add("result")
147
+
148
+ var spinner = document.createElement("i")
149
+ spinner.className = "fa fa-circle-o-notch fa-spin cmd-icon-grey"
150
+ result.append(spinner)
151
+
152
+ line.appendChild(result)
153
+
144
154
  lines.appendChild(line)
145
155
  stored_entry = undefined
146
156
  history_cmd_idx = undefined
@@ -167,6 +177,8 @@ cmdDocReady(function() {
167
177
  done: function(res, status, req) {
168
178
  if (status == 200) {
169
179
  var json = JSON.parse(res)
180
+ line.querySelector(".result").remove()
181
+
170
182
  var result = document.createElement("div")
171
183
  result.classList.add("result")
172
184
 
@@ -174,7 +186,21 @@ cmdDocReady(function() {
174
186
  result.classList.add("cmd-error")
175
187
  result.textContent = json.error
176
188
  } else {
177
- result.textContent = json.result
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
+ }
178
204
  }
179
205
 
180
206
  line.appendChild(result)
@@ -29,6 +29,7 @@ cmdDocReady(function() {
29
29
  }
30
30
  document.querySelector("td[data-iteration-status]").innerText = json.status
31
31
  document.querySelector("td[data-iteration-duration]").innerText = json.duration
32
+ document.querySelector("td[data-iteration-started]").innerText = json.started_at
32
33
 
33
34
  if (continue_statuses.includes(json.status)) {
34
35
  setTimeout(function() { pingFeed(terminal) }, 1000)
@@ -4,13 +4,13 @@ cmdDocReady(function() {
4
4
  function setReadOnlyUI(cm) {
5
5
  cm.getWrapperElement().classList.add("CodeMirror-readonly")
6
6
 
7
- pencil = document.createElement("i")
7
+ var pencil = document.createElement("i")
8
8
  pencil.className = "fa fa-pencil fa-stack-1x"
9
9
 
10
- ban = document.createElement("i")
10
+ var ban = document.createElement("i")
11
11
  ban.className = "fa fa-ban fa-stack-2x fa-flip-horizontal"
12
12
 
13
- stack = document.createElement("span")
13
+ var stack = document.createElement("span")
14
14
  stack.className = "fa-stack fa-2x"
15
15
  stack.append(pencil)
16
16
  stack.append(ban)
@@ -6,6 +6,12 @@
6
6
  width: 100%;
7
7
  }
8
8
 
9
+ .cmd-truncated-download {
10
+ font-size: 12px;
11
+ color: grey;
12
+ text-decoration: underline;
13
+ }
14
+
9
15
  .cmd-flex-row {
10
16
  display: flex;
11
17
  }
@@ -29,3 +35,20 @@
29
35
  background: lightgrey;
30
36
  }
31
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
+ }
@@ -6,14 +6,12 @@
6
6
  background: #112435;
7
7
  padding: 10px 20px;
8
8
  padding-left: 40px;
9
- overflow-x: auto;
10
- overflow-y: visible;
11
9
  color: lime;
12
10
  font-family: monospace;
13
11
  text-align: left;
14
- white-space: nowrap;
15
- white-space: pre;
16
12
  counter-reset: line-count;
13
+ white-space: pre-wrap;
14
+ word-wrap: break-word;
17
15
 
18
16
  .line {
19
17
  min-height: 18px;
@@ -67,6 +65,3 @@
67
65
  color: black;
68
66
  }
69
67
  }
70
- .cmd-terminal {
71
- white-space: pre-wrap;
72
- }
@@ -28,14 +28,18 @@ class ::CommandProposal::IterationsController < ::CommandProposal::EngineControl
28
28
 
29
29
  return error!("Session has expired. Please start a new session.") if runner.nil?
30
30
 
31
-
32
31
  @task.user = command_user # Separate from update to ensure it's set first
33
32
  @task.update(code: params[:code]) # Creates a new iteration
34
33
  @iteration = @task.current_iteration
35
34
  @iteration.update(status: :approved) # Task was already approved, and this is line-by-line
36
35
 
37
- # in-sync
38
- runner.execute(@iteration)
36
+ # async, but wait for the job to finish
37
+ ::CommandProposal::CommandRunnerJob.perform_later(@iteration.id)
38
+ loop do
39
+ sleep 0.2
40
+
41
+ break if @iteration.reload.complete?
42
+ end
39
43
 
40
44
  render json: {
41
45
  result: @iteration.result
@@ -65,6 +65,7 @@ class ::CommandProposal::RunnerController < ::CommandProposal::EngineController
65
65
  result: @iteration.result,
66
66
  status: @iteration.status,
67
67
  duration: humanized_duration(@iteration.duration),
68
+ started_at: @iteration.started_at&.strftime("%b %-d '%y, %-l:%M%P")
68
69
  }.tap do |response|
69
70
  if @iteration.started?
70
71
  response[:endpoint] = runner_url(@task, @iteration)
@@ -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,6 +53,7 @@ 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
56
+ @task.skip_approval = true unless approval_required?
54
57
 
55
58
  # Cannot create the iteration until the task is created, so save then update
56
59
  if @task.save && @task.update(task_params)
@@ -69,6 +72,7 @@ class ::CommandProposal::TasksController < ::CommandProposal::EngineController
69
72
  def update
70
73
  @task = ::CommandProposal::Task.find_by!(friendly_id: params[:id])
71
74
  @task.user = command_user
75
+ @task.skip_approval = true unless approval_required?
72
76
 
73
77
  if @task.update(task_params)
74
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
@@ -2,14 +2,14 @@ module CommandProposal
2
2
  module PermissionsHelper
3
3
  def can_command?(user=command_user)
4
4
  return false unless permitted_to_use?
5
- return true unless cmd_config.approval_required?
5
+ return true unless approval_required?
6
6
 
7
7
  command_user.try("#{cmd_config.role_scope}?")
8
8
  end
9
9
 
10
10
  def can_approve?(iteration)
11
11
  return false unless permitted_to_use?
12
- return true unless cmd_config.approval_required?
12
+ return true unless approval_required?
13
13
  return if iteration.nil?
14
14
 
15
15
  command_user.try("#{cmd_config.role_scope}?") && !current_is_author?(iteration)
@@ -17,11 +17,15 @@ module CommandProposal
17
17
 
18
18
  def has_approval?(task)
19
19
  return false unless permitted_to_use?
20
- return true unless cmd_config.approval_required?
20
+ return true unless approval_required?
21
21
 
22
22
  task&.approved?
23
23
  end
24
24
 
25
+ def approval_required?
26
+ cmd_config.approval_required?
27
+ end
28
+
25
29
  def current_is_author?(iteration)
26
30
  return false unless permitted_to_use?
27
31
 
@@ -21,6 +21,10 @@ class ::CommandProposal::Iteration < ApplicationRecord
21
21
  serialize :args, ::CommandProposal::Service::JSONWrapper
22
22
  include ::CommandProposal::Service::ExternalBelong
23
23
 
24
+ TRUNCATE_COUNT = 2000
25
+ # Also hardcoded in JS: app/assets/javascripts/command_proposal/console.js
26
+ PAGINATION_PER = 2
27
+
24
28
  has_many :comments
25
29
  belongs_to :task
26
30
  external_belongs_to :requester
@@ -37,6 +41,12 @@ class ::CommandProposal::Iteration < ApplicationRecord
37
41
  terminated: 7, # Closed via server restart
38
42
  }
39
43
 
44
+ scope :cmd_page, ->(page=nil) {
45
+ page = page.presence&.to_i || 1
46
+ per = ::CommandProposal::PAGINATION_PER
47
+ limit(per).offset(per * (page - 1))
48
+ }
49
+
40
50
  delegate :name, to: :task
41
51
  delegate :description, to: :task
42
52
  delegate :session_type, to: :task
@@ -52,6 +62,10 @@ class ::CommandProposal::Iteration < ApplicationRecord
52
62
  ::CommandProposal::Task.module.where(friendly_id: bring_str.scan(/\s+\:(\w+),?/).flatten)
53
63
  end
54
64
 
65
+ def primary_iteration?
66
+ task.primary_iteration == self
67
+ end
68
+
55
69
  def complete?
56
70
  success? || failed? || cancelled? || terminated?
57
71
  end
@@ -70,6 +84,10 @@ class ::CommandProposal::Iteration < ApplicationRecord
70
84
  (completed_at || stopped_at || Time.current) - started_at
71
85
  end
72
86
 
87
+ def end_time
88
+ completed_at || stopped_at || Time.current
89
+ end
90
+
73
91
  def force_reset
74
92
  # Debugging method. Should never actually be called.
75
93
  update(status: :approved, result: nil, completed_at: nil, stopped_at: nil, started_at: nil)
@@ -7,7 +7,7 @@
7
7
 
8
8
  class ::CommandProposal::Task < ApplicationRecord
9
9
  self.table_name = :command_proposal_tasks
10
- attr_accessor :user
10
+ attr_accessor :user, :skip_approval
11
11
 
12
12
  has_many :iterations
13
13
  has_many :ordered_iterations, -> { order(created_at: :desc) }, class_name: "CommandProposal::Iteration"
@@ -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
@@ -79,7 +91,17 @@ class ::CommandProposal::Task < ApplicationRecord
79
91
  end
80
92
 
81
93
  def code=(new_code)
82
- iterations.create(code: new_code, requester: user)
94
+ if skip_approval
95
+ iterations.create(
96
+ code: new_code,
97
+ requester: user,
98
+ status: :approved,
99
+ approver: user,
100
+ approved_at: Time.current
101
+ )
102
+ else
103
+ iterations.create(code: new_code, requester: user)
104
+ end
83
105
  end
84
106
 
85
107
  private
@@ -1,8 +1,18 @@
1
1
  <% if lines.none? && !(skip_empty ||= false) -%><div class="line"></div><% end
2
2
  -%><% lines.each do |iteration| -%>
3
- <div class="line"><%= iteration.code -%><%
4
- if iteration.result.present?
5
- -%><div class="result"><%= iteration.result %></div><%
6
- end
7
- -%></div>
8
- <% end -%>
3
+ <div class="line"><%= iteration.code
4
+ -%><div class="result"><%=
5
+ truncate = ::CommandProposal::Iteration::TRUNCATE_COUNT
6
+ if iteration.result.present?
7
+ iteration.result.truncate(truncate)
8
+ elsif iteration.complete?
9
+ "Error: No response"
10
+ else
11
+ content_tag :i, nil, class: "fa fa-circle-o-notch fa-spin cmd-icon-grey"
12
+ end
13
+ %></div
14
+ ></div><%=
15
+ if iteration.result.length > truncate
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
+ end
18
+ %><% end -%>
@@ -1,4 +1,8 @@
1
1
  <% if lines.blank? && !(skip_empty ||= false) -%><div class="line"></div><% end
2
2
  -%><% lines&.split("\n").each do |line|
3
- -%><div class="line"><%= line -%></div><%
3
+ truncate = ::CommandProposal::Iteration::TRUNCATE_COUNT
4
+ -%><div class="line"><%= line.truncate(truncate) -%></div><%=
5
+ if line.length > truncate
6
+ link_to("Output truncated. Click here to download full result.", "data:application/txt,#{ERB::Util.url_encode(line)}", class: "cmd-truncated-download", download: "result.txt")
7
+ end -%><%
4
8
  end -%>
@@ -7,15 +7,12 @@
7
7
  <!-- <th>Diff</th> -->
8
8
  </thead>
9
9
  <tbody>
10
- <% primary_iteration = @task.primary_iteration %>
11
- <% @task.iterations.where.not(id: @iteration&.id).order(created_at: :desc).each do |iteration| %>
10
+ <% paginated_iterations = @task.iterations.cmd_page(params[:page]) %>
11
+ <% paginated_iterations.order(created_at: :desc).each do |iteration| %>
12
12
  <tr>
13
13
  <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 %>
14
+ <%= ">" if iteration == @iteration %>
15
+ <%= link_to iteration.created_at.strftime("%b %-d, %Y at %H:%M"), cmd_path(@task, iteration: iteration.id) %>
19
16
  </td>
20
17
  <td><%= iteration.status.capitalize %></td>
21
18
  <!-- <td><%#= iteration.comments.count %></td> -->
@@ -24,4 +21,6 @@
24
21
  <% end %>
25
22
  </tbody>
26
23
  </table>
24
+
25
+ <%= command_paginate paginated_iterations %>
27
26
  <% end %>
@@ -10,7 +10,7 @@
10
10
  <tr>
11
11
  <td><%= @iteration&.requester_name.presence || "ID: #{@iteration&.requester_id}" if @iteration&.requester_id.present? %></td>
12
12
  <td><%= @iteration&.approver_name.presence || "ID: #{@iteration&.approver_id}" if @iteration&.approver_id.present? %></td>
13
- <td><%= @iteration&.started_at&.strftime("%b %-d '%y, %-l:%M%P") %></td>
13
+ <td data-iteration-started><%= @iteration&.started_at&.strftime("%b %-d '%y, %-l:%M%P") %></td>
14
14
  <td data-iteration-status><%= @iteration&.status&.capitalize %></td>
15
15
  <td data-iteration-duration><%= humanized_duration(@iteration&.duration) %></td>
16
16
  </tr>
@@ -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>
@@ -66,7 +66,7 @@ module CommandProposal
66
66
  # Rollback the create/update if anything fails
67
67
  ActiveRecord::Base.transaction do
68
68
  command_request if @task.function? && @iteration.approved_at? && @iteration.complete?
69
- @iteration.update(@params)
69
+ @iteration.update(@params.merge(requester: @user))
70
70
 
71
71
  error!("Cannot run without approval.") unless has_approval?(@task)
72
72
  end
@@ -91,7 +91,8 @@ module CommandProposal
91
91
  if ::CommandProposal.sessions.key?("task:#{@task.id}")
92
92
  @task.first_iteration.update(status: :success, completed_at: Time.current)
93
93
  else
94
- @task.first_iteration.update(status: :terminated, completed_at: Time.current)
94
+ ended_at = @task.iterations.last&.end_time || Time.current
95
+ @task.first_iteration.update(status: :terminated, completed_at: ended_at)
95
96
  end
96
97
  ::CommandProposal.sessions.delete("task:#{@task.id}")
97
98
  end
@@ -11,12 +11,28 @@ module CommandProposal
11
11
  end
12
12
 
13
13
  def self.command(friendly_id, user, params={})
14
- ::CommandProposal::Services::CommandInterpreter.command(
14
+ # Hack magic because requires are not playing well with spring
15
+ require "command_proposal/services/command_interpreter"
16
+
17
+ params = params.to_unsafe_h if params.is_a?(ActionController::Parameters)
18
+
19
+ iteration = ::CommandProposal::Services::CommandInterpreter.command(
15
20
  ::CommandProposal::Task.find_by!(friendly_id: friendly_id).primary_iteration,
16
21
  :run,
17
22
  user,
18
- params.except(:action, :controller)
23
+ { args: params }
19
24
  )
25
+
26
+ start = Time.current
27
+ wait_time = 5 # seconds
28
+ loop do
29
+ sleep 0.4
30
+
31
+ break if iteration.reload.complete?
32
+ break if Time.current - start > wait_time
33
+ end
34
+
35
+ iteration
20
36
  end
21
37
 
22
38
  def initialize
@@ -60,7 +76,11 @@ module CommandProposal
60
76
 
61
77
  def run
62
78
  begin
63
- @session.eval("#{bring_function};params = #{@iteration.args || {}}.with_indifferent_access")
79
+ params_str = ""
80
+ unless @iteration.task.console? # Don't bring params into the console
81
+ params_str = "params = #{@iteration.args || {}}.with_indifferent_access"
82
+ end
83
+ @session.eval("#{bring_function};#{params_str}")
64
84
  rescue Exception => e # rubocop:disable Lint/RescueException - Yes, rescue full Exception so that we can catch typos in evals as well
65
85
  return @iteration.result = results_from_exception(e)
66
86
  end
@@ -72,9 +92,10 @@ module CommandProposal
72
92
 
73
93
  running_thread = Thread.new do
74
94
  begin
75
- # Run bring functions in here so we can capture any string outputs
95
+ # Run `bring` functions in here so we can capture any string outputs
76
96
  # OR! Run the full runner and instead of saving to an iteration, return the string for prepending here
77
97
  result = @session.eval("_ = (#{@iteration.code})").inspect # rubocop:disable Security/Eval - Eval is scary, but in this case it's exactly what we need.
98
+ result = nil unless @iteration.task.console? # Only store final result for consoles
78
99
  status = :success
79
100
  rescue Exception => e # rubocop:disable Lint/RescueException - Yes, rescue full Exception so that we can catch typos in evals as well
80
101
  status = :failed
@@ -104,7 +125,7 @@ module CommandProposal
104
125
 
105
126
  $stdout = stored_stdout
106
127
  @iteration.status = status
107
- @iteration.result = [output, "#{result || 'nil'}"].compact.join("\n")
128
+ @iteration.result = [output, result].compact.join("\n")
108
129
  end
109
130
 
110
131
  def bring_function
@@ -1,3 +1,3 @@
1
1
  module CommandProposal
2
- VERSION = "1.0.10"
2
+ VERSION = "1.0.14"
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.10
4
+ version: 1.0.14
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-09-25 00:00:00.000000000 Z
11
+ date: 2022-01-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails