command_proposal 1.0.12 → 1.0.13
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 +4 -4
- data/app/assets/stylesheets/command_proposal/components.scss +17 -0
- data/app/controllers/command_proposal/iterations_controller.rb +7 -2
- data/app/controllers/command_proposal/tasks_controller.rb +4 -2
- data/app/helpers/command_proposal/params_helper.rb +43 -0
- data/app/models/command_proposal/iteration.rb +11 -0
- data/app/models/command_proposal/task.rb +14 -2
- data/app/views/command_proposal/tasks/_past_iterations_list.html.erb +6 -7
- data/app/views/command_proposal/tasks/index.html.erb +7 -3
- data/lib/command_proposal/services/runner.rb +6 -2
- data/lib/command_proposal/version.rb +1 -1
- data/lib/command_proposal.rb +2 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d57823efe2c4175b2786f8346a67ea68e96804bc980f06fc4afb0feb30a8dc9a
|
4
|
+
data.tar.gz: 212e7e868bf94fe559701ee696fc5487a9a17bcc3b549f35880843d8564f927d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 96795b4fff0569ca5ed7c965cc1d27dcaa2fd753301a62cee0da1a0e7f684daa9489b5ca5f51f195bd58a8a86c3f9f77aea2b9e21017fc6c14c5ee61b73169e3
|
7
|
+
data.tar.gz: 6e15d7c2aeadeb488bfc35784cdeb2626a29cfa18f6a98264af30d35e45ecc7b8df8d8356d70ef4e7b07ca2228c78149dfd3a0bd7bc77e6ad00a3d17df2d63b1
|
@@ -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
|
+
}
|
@@ -33,8 +33,13 @@ class ::CommandProposal::IterationsController < ::CommandProposal::EngineControl
|
|
33
33
|
@iteration = @task.current_iteration
|
34
34
|
@iteration.update(status: :approved) # Task was already approved, and this is line-by-line
|
35
35
|
|
36
|
-
#
|
37
|
-
|
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
|
38
43
|
|
39
44
|
render json: {
|
40
45
|
result: @iteration.result
|
@@ -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.
|
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
|
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
|
@@ -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
|
@@ -23,6 +23,7 @@ class ::CommandProposal::Iteration < ApplicationRecord
|
|
23
23
|
|
24
24
|
TRUNCATE_COUNT = 2000
|
25
25
|
# Also hardcoded in JS: app/assets/javascripts/command_proposal/console.js
|
26
|
+
PAGINATION_PER = 2
|
26
27
|
|
27
28
|
has_many :comments
|
28
29
|
belongs_to :task
|
@@ -40,6 +41,12 @@ class ::CommandProposal::Iteration < ApplicationRecord
|
|
40
41
|
terminated: 7, # Closed via server restart
|
41
42
|
}
|
42
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
|
+
|
43
50
|
delegate :name, to: :task
|
44
51
|
delegate :description, to: :task
|
45
52
|
delegate :session_type, to: :task
|
@@ -55,6 +62,10 @@ class ::CommandProposal::Iteration < ApplicationRecord
|
|
55
62
|
::CommandProposal::Task.module.where(friendly_id: bring_str.scan(/\s+\:(\w+),?/).flatten)
|
56
63
|
end
|
57
64
|
|
65
|
+
def primary_iteration?
|
66
|
+
task.primary_iteration == self
|
67
|
+
end
|
68
|
+
|
58
69
|
def complete?
|
59
70
|
success? || failed? || cancelled? || terminated?
|
60
71
|
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
|
@@ -7,15 +7,12 @@
|
|
7
7
|
<!-- <th>Diff</th> -->
|
8
8
|
</thead>
|
9
9
|
<tbody>
|
10
|
-
<%
|
11
|
-
<%
|
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
|
-
|
15
|
-
|
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 %>
|
@@ -1,9 +1,11 @@
|
|
1
1
|
<div class="cmd-wrapper">
|
2
|
-
|
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",
|
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>
|
@@ -76,7 +76,11 @@ module CommandProposal
|
|
76
76
|
|
77
77
|
def run
|
78
78
|
begin
|
79
|
-
|
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}")
|
80
84
|
rescue Exception => e # rubocop:disable Lint/RescueException - Yes, rescue full Exception so that we can catch typos in evals as well
|
81
85
|
return @iteration.result = results_from_exception(e)
|
82
86
|
end
|
@@ -88,7 +92,7 @@ module CommandProposal
|
|
88
92
|
|
89
93
|
running_thread = Thread.new do
|
90
94
|
begin
|
91
|
-
# 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
|
92
96
|
# OR! Run the full runner and instead of saving to an iteration, return the string for prepending here
|
93
97
|
result = @session.eval("_ = (#{@iteration.code})").inspect # rubocop:disable Security/Eval - Eval is scary, but in this case it's exactly what we need.
|
94
98
|
result = nil unless @iteration.task.console? # Only store final result for consoles
|
data/lib/command_proposal.rb
CHANGED
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.
|
4
|
+
version: 1.0.13
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rocco Nicholls
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-01-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|