rails_execution 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +109 -23
- data/app/assets/javascripts/executions/comments.js +2 -0
- data/app/assets/stylesheets/executions/comments.css +2 -1
- data/app/controllers/rails_execution/comments_controller.rb +1 -0
- data/app/controllers/rails_execution/tasks_controller.rb +30 -1
- data/app/models/rails_execution/task_review.rb +2 -0
- data/app/views/rails_execution/shared/_header.html.haml +1 -1
- data/app/views/rails_execution/tasks/_comments.html.haml +1 -1
- data/app/views/rails_execution/tasks/_form.html.haml +1 -1
- data/app/views/rails_execution/tasks/_form_scripts.html.haml +1 -0
- data/app/views/rails_execution/tasks/show.html.haml +4 -0
- data/config/routes.rb +1 -0
- data/lib/generators/rails_execution/templates/config.rb.tt +3 -0
- data/lib/rails_execution/config.rb +5 -0
- data/lib/rails_execution/files/uploader.rb +1 -1
- data/lib/rails_execution/services/notifier.rb +27 -0
- data/lib/rails_execution/version.rb +1 -1
- data/lib/rails_execution.rb +1 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7d04b62e7461cf38c3519551e7c96a9792418b5769d1e1782f317957c34bf617
|
4
|
+
data.tar.gz: cf09e00dfb2b487fae01323230b337f02b2867729ff05a6887d7dce0494cddbb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8ad2c6d2a14b9c6c3cb3be1e2728afbd9c691d5db1bd9d91f66a48d43219af9f334e4b9d23bf81d348e37422e7651d1d84469369845267d64b9ebf0aac4922de
|
7
|
+
data.tar.gz: b2e17748bdc9cb169ed742cb19fbe4ff80fc759c5465b25448f1d2ab47043d0bc40005b6b1c643cdd4f81c61944751f98108109e7f1ea1fcb086b7c220a8eabe
|
data/README.md
CHANGED
@@ -1,35 +1,121 @@
|
|
1
|
-
#
|
1
|
+
# Rails Execution
|
2
|
+
Rails Execution is an Engine to manage the Rails scripts for migration, cleanup, and fixing the bad data without deployment.
|
3
|
+
- Supported the Syntax checker
|
4
|
+
- Supported the Execution logs
|
5
|
+
- Supported the Reviewing process
|
6
|
+
- Supported the Attachment files
|
7
|
+
- Supported the Comments communication
|
8
|
+
- Supported the Activities tracking
|
2
9
|
|
3
|
-
Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/rails_execution`. To experiment with that code, run `bin/console` for an interactive prompt.
|
4
10
|
|
5
|
-
|
11
|
+
![image](https://user-images.githubusercontent.com/6081795/193129359-fc1e8858-c3e7-4376-be1e-ca453890a98d.png)
|
12
|
+
![image](https://user-images.githubusercontent.com/6081795/193129792-39176d6e-97fa-4a47-8541-30e7169841cd.png)
|
6
13
|
|
7
14
|
## Installation
|
8
15
|
|
9
|
-
|
16
|
+
Add the following line to your **Gemfile**:
|
10
17
|
|
11
|
-
|
18
|
+
```ruby
|
19
|
+
gem 'rails_execution'
|
20
|
+
```
|
21
|
+
Then run `bundle install`
|
12
22
|
|
13
|
-
If bundler is not being used to manage dependencies, install the gem by executing:
|
14
23
|
|
15
|
-
|
16
|
-
|
17
|
-
## Usage
|
24
|
+
## Getting started
|
18
25
|
|
19
26
|
### How to setup
|
27
|
+
You need to run the generator:
|
28
|
+
```bash
|
20
29
|
$ rails g rails_execution:install
|
30
|
+
```
|
31
|
+
And you can change the config in `config/initializers/rails_execution.rb`
|
32
|
+
|
33
|
+
Default is `Solo Mode`, without the Reviewing process.
|
34
|
+
|
35
|
+
#### Enable the Reviewing process
|
36
|
+
The first step is to disable the `Solo Mode`
|
37
|
+
```ruby
|
38
|
+
config.solo_mode = false
|
39
|
+
```
|
40
|
+
And then uncomment the configures of the `owner` and `reviewers`
|
41
|
+
```ruby
|
42
|
+
config.owner_model = 'User'
|
43
|
+
config.owner_method = :current_user
|
44
|
+
config.owner_name_method = :name
|
45
|
+
config.owner_avatar = ->(owner) { owner.avatar.url }
|
46
|
+
|
47
|
+
config.reviewers = -> do
|
48
|
+
User.where(is_admin: true).map do |user|
|
49
|
+
{
|
50
|
+
name: user.name,
|
51
|
+
id: user.id,
|
52
|
+
type: 'User',
|
53
|
+
avatar_url: user.avatar.url,
|
54
|
+
}
|
55
|
+
end
|
56
|
+
end
|
57
|
+
```
|
58
|
+
|
59
|
+
#### Enable the Attachment files
|
60
|
+
Run the generator to add the **FileUploader** and **FileReader**
|
61
|
+
```bash
|
21
62
|
$ rails g rails_execution:file_upload
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
63
|
+
```
|
64
|
+
And then uncomment the file upload
|
65
|
+
```ruby
|
66
|
+
config.file_upload = true
|
67
|
+
config.file_uploader = ::RailsExecution::FileUploader
|
68
|
+
config.file_reader = ::RailsExecution::FileReader
|
69
|
+
```
|
70
|
+
To limit the File types. Default: `.png`, `.gif`, `.jpg`, `.jpeg`, `.pdf`, `.csv`
|
71
|
+
You can modify the limitation like this
|
72
|
+
```ruby
|
73
|
+
config.acceptable_file_types = {
|
74
|
+
'.jpeg': 'image/jpeg',
|
75
|
+
'.pdf': 'application/pdf',
|
76
|
+
'.csv': ['text/csv', 'text/plain'],
|
77
|
+
}
|
78
|
+
```
|
79
|
+
|
80
|
+
#### Control the Permissions
|
81
|
+
For example with *[Pundit](https://github.com/varvet/pundit)* authorization.
|
82
|
+
```ruby
|
83
|
+
config.task_creatable = lambda do |user|
|
84
|
+
YourPolicy.new(user).creatable?
|
85
|
+
end
|
86
|
+
config.task_editable = lambda do |task, user|
|
87
|
+
YourPolicy.new(user, task).editable?
|
88
|
+
end
|
89
|
+
config.task_closable = lambda do |task, user|
|
90
|
+
YourPolicy.new(user, task).closable?
|
91
|
+
end
|
92
|
+
config.task_approvable = lambda do |task, user|
|
93
|
+
YourPolicy.new(user, task).approvable?
|
94
|
+
end
|
95
|
+
config.task_executable = lambda do |task, user|
|
96
|
+
YourPolicy.new(user, task).executable?
|
97
|
+
end
|
98
|
+
```
|
99
|
+
|
100
|
+
#### Setup the Logger
|
101
|
+
To storage the logfile
|
102
|
+
```ruby
|
103
|
+
config.logging = lambda do |file, task|
|
104
|
+
LoggerModel.create!(task: task, file: file)
|
105
|
+
end
|
106
|
+
```
|
107
|
+
And list the logfiles on Task page
|
108
|
+
```ruby
|
109
|
+
config.logging_files = lambda do |task|
|
110
|
+
LoggerModel.where(task: task).map do |log|
|
111
|
+
log.file.expiring_url(30.minutes.to_i)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
```
|
115
|
+
|
116
|
+
#### Others
|
117
|
+
To change the Per page of the tasks list.
|
118
|
+
Default value: `20`
|
119
|
+
```ruby
|
120
|
+
config.per_page = 10
|
121
|
+
```
|
@@ -12,6 +12,7 @@ window.comments.clickEditComment = function(el) {
|
|
12
12
|
status: false,
|
13
13
|
maxHeight: '150px',
|
14
14
|
showIcons: ['code'],
|
15
|
+
spellChecker: false,
|
15
16
|
placeholder: 'Type your comment here...',
|
16
17
|
renderingConfig: {
|
17
18
|
codeSyntaxHighlighting: true,
|
@@ -24,6 +25,7 @@ window.comments.initAddNewComment = function(id) {
|
|
24
25
|
status: false,
|
25
26
|
maxHeight: '100px',
|
26
27
|
showIcons: ['code'],
|
28
|
+
spellChecker: false,
|
27
29
|
placeholder: 'Type your comment here...',
|
28
30
|
renderingConfig: {
|
29
31
|
codeSyntaxHighlighting: true,
|
@@ -1,7 +1,8 @@
|
|
1
1
|
.g-height-50 { height: 50px; }
|
2
2
|
.g-width-50 { width: 50px !important; }
|
3
3
|
.g-bg-secondary { background-color: white !important; }
|
4
|
-
.media-comment { margin-top:20px }
|
4
|
+
.media-comment { margin-top:20px; }
|
5
|
+
.media-comment .media-body { overflow-x: auto; }
|
5
6
|
|
6
7
|
@media (min-width: 0) {
|
7
8
|
.g-mr-15 { margin-right: 1.07143rem !important; }
|
@@ -6,6 +6,7 @@ module RailsExecution
|
|
6
6
|
def create
|
7
7
|
@new_comment = current_task.comments.new(owner: current_owner, content: params.dig(:comment, :content))
|
8
8
|
if @new_comment.save
|
9
|
+
::RailsExecution.configuration.notifier.new(current_task).add_comment(current_owner, @new_comment.content)
|
9
10
|
current_task.activities.create(owner: current_owner, message: "Added a comment: #{@new_comment.content.truncate(30)}")
|
10
11
|
else
|
11
12
|
@alert = "Your comment can't adding!"
|
@@ -31,6 +31,7 @@ module RailsExecution
|
|
31
31
|
|
32
32
|
if @task.save
|
33
33
|
@task.add_files(params[:attachments]&.permit!.to_h, current_owner) if ::RailsExecution.configuration.file_upload
|
34
|
+
::RailsExecution.configuration.notifier.new(@task).after_create
|
34
35
|
flash[:notice] = 'Create the request is successful!'
|
35
36
|
redirect_to action: :index
|
36
37
|
else
|
@@ -38,6 +39,22 @@ module RailsExecution
|
|
38
39
|
end
|
39
40
|
end
|
40
41
|
|
42
|
+
def fork
|
43
|
+
raise(::RailsExecution::AccessDeniedError, 'Fork task') unless can_create_task?
|
44
|
+
|
45
|
+
@task = ::RailsExecution::Task.new({
|
46
|
+
status: :created,
|
47
|
+
owner_id: current_owner&.id,
|
48
|
+
owner_type: ::RailsExecution.configuration.owner_model.to_s,
|
49
|
+
title: current_task.title,
|
50
|
+
description: current_task.description,
|
51
|
+
script: current_task.script,
|
52
|
+
})
|
53
|
+
@task.syntax_status = ::RailsExecution::Services::SyntaxChecker.new(@task.script).call ? 'good' : 'bad'
|
54
|
+
|
55
|
+
render action: :new
|
56
|
+
end
|
57
|
+
|
41
58
|
def show
|
42
59
|
end
|
43
60
|
|
@@ -49,6 +66,7 @@ module RailsExecution
|
|
49
66
|
|
50
67
|
if current_task.update(status: :closed)
|
51
68
|
current_task.activities.create(owner: current_owner, message: 'Closed the task')
|
69
|
+
::RailsExecution.configuration.notifier.new(current_task).after_close
|
52
70
|
redirect_to(action: :show) and return
|
53
71
|
else
|
54
72
|
flash[:alert] = "Has problem when close this Task: #{current_task.errors.full_messages.join(', ')}"
|
@@ -66,6 +84,10 @@ module RailsExecution
|
|
66
84
|
raise(::RailsExecution::AccessDeniedError, 'Edit task') unless can_edit_task?(current_task)
|
67
85
|
|
68
86
|
@task = current_task
|
87
|
+
old_script = @task.script
|
88
|
+
old_reviewer_ids = @task.task_reviews.pluck(:owner_id)
|
89
|
+
checked_owner_ids = @task.task_reviews.checked.pluck(:owner_id)
|
90
|
+
|
69
91
|
update_data = {
|
70
92
|
title: params.dig(:task, :title),
|
71
93
|
description: params.dig(:task, :description),
|
@@ -78,6 +100,8 @@ module RailsExecution
|
|
78
100
|
if @task.update(update_data)
|
79
101
|
@task.add_files(params[:attachments]&.permit!.to_h, current_owner) if ::RailsExecution.configuration.file_upload
|
80
102
|
@task.activities.create(owner: current_owner, message: 'Updated the Task')
|
103
|
+
::RailsExecution.configuration.notifier.new(@task).after_update_script(current_owner, checked_owner_ids) if old_script != @task.script
|
104
|
+
::RailsExecution.configuration.notifier.new(@task).after_assign_reviewers(current_owner, @task.task_reviews.reload.pluck(:owner_id) - old_reviewer_ids)
|
81
105
|
redirect_to action: :show
|
82
106
|
else
|
83
107
|
render action: :edit
|
@@ -99,6 +123,7 @@ module RailsExecution
|
|
99
123
|
def reopen
|
100
124
|
if current_task.update(status: :created)
|
101
125
|
current_task.activities.create(owner: current_owner, message: 'Re-opened the Task')
|
126
|
+
::RailsExecution.configuration.notifier.new(current_task).after_reopen
|
102
127
|
flash[:notice] = 'Your task is re-opened'
|
103
128
|
else
|
104
129
|
flash[:alert] = "Re-open is failed: #{current_task.errors.full_messages.join(', ')}"
|
@@ -108,6 +133,7 @@ module RailsExecution
|
|
108
133
|
|
109
134
|
def reject
|
110
135
|
if ::RailsExecution::Services::Approvement.new(current_task, reviewer: current_owner).reject
|
136
|
+
::RailsExecution.configuration.notifier.new(current_task).after_reject(current_owner)
|
111
137
|
flash[:notice] = 'Your decision is updated!'
|
112
138
|
else
|
113
139
|
flash[:alert] = "Your decision is can't update!"
|
@@ -117,6 +143,7 @@ module RailsExecution
|
|
117
143
|
|
118
144
|
def approve
|
119
145
|
if ::RailsExecution::Services::Approvement.new(current_task, reviewer: current_owner).approve
|
146
|
+
::RailsExecution.configuration.notifier.new(current_task).after_approve(current_owner)
|
120
147
|
flash[:notice] = 'Your decision is updated!'
|
121
148
|
else
|
122
149
|
flash[:alert] = "Your decision is can't update!"
|
@@ -134,8 +161,10 @@ module RailsExecution
|
|
134
161
|
if execute_service.call
|
135
162
|
current_task.update(status: :completed)
|
136
163
|
current_task.activities.create(owner: current_owner, message: 'Execute: The task is completed')
|
164
|
+
::RailsExecution.configuration.notifier.new(current_task).after_execute_success(current_owner)
|
137
165
|
flash[:notice] = 'This task is executed'
|
138
166
|
else
|
167
|
+
::RailsExecution.configuration.notifier.new(current_task).after_execute_fail(current_owner)
|
139
168
|
flash[:alert] = "Sorry!!! This task can't execute right now"
|
140
169
|
end
|
141
170
|
|
@@ -167,7 +196,7 @@ module RailsExecution
|
|
167
196
|
helper_method :task_attachment_files
|
168
197
|
|
169
198
|
def reviewing_accounts
|
170
|
-
@reviewing_accounts ||= current_task.task_reviews
|
199
|
+
@reviewing_accounts ||= current_task.task_reviews.preload(:owner)
|
171
200
|
end
|
172
201
|
helper_method :reviewing_accounts
|
173
202
|
|
@@ -8,6 +8,6 @@
|
|
8
8
|
%li= link_to 'Processing', tasks_path, class: "nav-link px-2 link-#{ current_page?(tasks_path) ? 'secondary' : 'dark' }"
|
9
9
|
%li= link_to 'Completed', completed_tasks_path, class: "nav-link px-2 link-#{ current_page?(completed_tasks_path) ? 'secondary' : 'dark' }"
|
10
10
|
%li= link_to 'Closed', closed_tasks_path, class: "nav-link px-2 link-#{ current_page?(closed_tasks_path) ? 'secondary' : 'dark' }"
|
11
|
-
.col-md-
|
11
|
+
.col-md-6.text-end
|
12
12
|
= yield :page_actions
|
13
13
|
= link_to 'New Task', new_task_path, class: 'btn btn-outline-primary ms-2', disabled: !can_create_task?
|
@@ -1,4 +1,4 @@
|
|
1
|
-
= form_for task, html: { enctype: 'multipart/form-data' } do |f|
|
1
|
+
= form_for task, method: task.new_record? ? :post : :patch, html: { enctype: 'multipart/form-data' } do |f|
|
2
2
|
.row
|
3
3
|
- if task.errors.any?
|
4
4
|
.col-12.text-danger.small.mt-3= task.errors.full_messages.join("\n")
|
@@ -4,6 +4,10 @@
|
|
4
4
|
- elsif current_task.is_closed? && can_create_task?
|
5
5
|
= link_to 'Re-Open', reopen_task_path(current_task), class: 'btn btn-outline-info', method: :patch, data: { confirm: 'Are you sure?' }
|
6
6
|
|
7
|
+
- if can_create_task?
|
8
|
+
= link_to fork_task_path(current_task), class: 'btn btn-outline-info ms-1 me-2' do
|
9
|
+
%i.bi.bi-diagram-2
|
10
|
+
Fork
|
7
11
|
- if can_edit_task?(current_task)
|
8
12
|
= link_to 'Edit', edit_task_path(current_task), class: 'btn btn-outline-warning me-2'
|
9
13
|
|
data/config/routes.rb
CHANGED
@@ -44,6 +44,9 @@ module RailsExecution
|
|
44
44
|
# Paging
|
45
45
|
attr_accessor :per_page
|
46
46
|
|
47
|
+
# Notify
|
48
|
+
attr_accessor :notifier
|
49
|
+
|
47
50
|
def initialize
|
48
51
|
self.solo_mode = true
|
49
52
|
|
@@ -67,6 +70,8 @@ module RailsExecution
|
|
67
70
|
|
68
71
|
self.logging = -> (_log_file, _task) { }
|
69
72
|
self.logging_files = -> (_task) { [] }
|
73
|
+
|
74
|
+
self.notifier = ::RailsExecution::Services::Notifier
|
70
75
|
end
|
71
76
|
|
72
77
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module RailsExecution
|
2
|
+
module Services
|
3
|
+
class Notifier
|
4
|
+
|
5
|
+
def initialize(task)
|
6
|
+
@task = task
|
7
|
+
end
|
8
|
+
|
9
|
+
def after_create; end
|
10
|
+
def after_close; end
|
11
|
+
def after_reopen; end
|
12
|
+
def after_update_script(_editor, _reviewer_ids); end
|
13
|
+
def after_assign_reviewers(_editor, _new_reviewer_ids); end
|
14
|
+
def after_reject(_reviewer); end
|
15
|
+
def after_approve(_reviewer); end
|
16
|
+
def after_execute_success(_executor); end
|
17
|
+
def after_execute_fail(_executor); end
|
18
|
+
|
19
|
+
def add_comment(_commenter, _content); end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
attr_reader :task
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/rails_execution.rb
CHANGED
@@ -9,6 +9,7 @@ require 'rails_execution/files/reader'
|
|
9
9
|
require 'rails_execution/files/uploader'
|
10
10
|
require 'rails_execution/services/paging'
|
11
11
|
require 'rails_execution/services/executor'
|
12
|
+
require 'rails_execution/services/notifier'
|
12
13
|
require 'rails_execution/services/execution'
|
13
14
|
require 'rails_execution/services/approvement'
|
14
15
|
require 'rails_execution/services/syntax_checker'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rails_execution
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Khoa Nguyen
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-12-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: haml
|
@@ -124,6 +124,7 @@ files:
|
|
124
124
|
- lib/rails_execution/services/approvement.rb
|
125
125
|
- lib/rails_execution/services/execution.rb
|
126
126
|
- lib/rails_execution/services/executor.rb
|
127
|
+
- lib/rails_execution/services/notifier.rb
|
127
128
|
- lib/rails_execution/services/paging.rb
|
128
129
|
- lib/rails_execution/services/syntax_checker.rb
|
129
130
|
- lib/rails_execution/version.rb
|