maintenance_tasks 2.0.0 → 2.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 60d043a961d97e4db5e822b86bf17a29fd409cf14e3951c581ecfb92abc7e2af
4
- data.tar.gz: 5170cb9e4bb82c82fe31f07f0dba93ca28caeacffe2b68ec592a092623d6aafd
3
+ metadata.gz: c395c28308277378c5ac627845abc512bba455e11e085558aa4ef106f73b1130
4
+ data.tar.gz: 7e44c8b5c484aa44008e2ebd3dd35458f84dec2be2741c20cc1ae20871c10f48
5
5
  SHA512:
6
- metadata.gz: be30600ed5e353ef1fba3bc484d5349be4567249b0cbb808503e73e0f42af76ae0befe6403fc4bdead3fb3ce0a5cd36e920f427eb013ac5215900571ddbb976a
7
- data.tar.gz: 1242c76047b52eae2463ea562c0ac48d09d773f9d4b069a781a140e49c39c9175e25b1eb7d21db5dce6ee96d43844323337761575909db396ccf4bc044a8355b
6
+ metadata.gz: 825418a040b4b15f0a98c5e28b06c553e240ec7b0ba10b2adec7b28180203d3e7094cb4e4b2933076d7564050b42f33504ede5b830e1819274393cf9d574f058
7
+ data.tar.gz: d2d7aa0c97a37851d8540edea5a4e890b1eeb9fbfc740c157070558fbc51e60ef9d3ff882b5ab21cd9b80481f7b2692d9a3f8fbaa03bbdcd4256f1b51aa669ce
data/README.md CHANGED
@@ -33,12 +33,13 @@ take a look at the [Active Job documentation][active-job-docs].
33
33
  [async-adapter]: https://api.rubyonrails.org/classes/ActiveJob/QueueAdapters/AsyncAdapter.html
34
34
  [active-job-docs]: https://guides.rubyonrails.org/active_job_basics.html#setting-the-backend
35
35
 
36
-
37
36
  ### Autoloading
38
37
 
39
38
  The Maintenance Tasks framework does not support autoloading in `:classic` mode.
40
- Please ensure your application is using [Zeitwerk](https://github.com/fxn/zeitwerk) to load your code.
41
- For more information, please consult the [Rails guides on autoloading and reloading constants](https://guides.rubyonrails.org/autoloading_and_reloading_constants.html).
39
+ Please ensure your application is using
40
+ [Zeitwerk](https://github.com/fxn/zeitwerk) to load your code. For more
41
+ information, please consult the [Rails guides on autoloading and reloading
42
+ constants](https://guides.rubyonrails.org/autoloading_and_reloading_constants.html).
42
43
 
43
44
  ## Usage
44
45
 
@@ -51,7 +52,7 @@ The typical Maintenance Tasks workflow is as follows:
51
52
  - or by [using Ruby](#running-a-task-from-ruby).
52
53
  3. [Monitor the Task](#monitoring-your-tasks-status)
53
54
  - either by using the included web UI,
54
- - or by manually checking your task's run's status in your database.
55
+ - or by manually checking your tasks runs status in your database.
55
56
  4. Optionally, delete the Task code if you no longer need it.
56
57
 
57
58
  ### Creating a Task
@@ -70,11 +71,12 @@ The generated task is a subclass of `MaintenanceTasks::Task` that implements:
70
71
  over.
71
72
  * `process`: do the work of your maintenance task on a single record
72
73
 
73
- Optionally, tasks can also implement a custom `#count` method, defining the number
74
- of elements that will be iterated over. Your task's `tick_total` will be calculated
75
- automatically based on the collection size, but this value may be overriden if desired
76
- using the `#count` method (this might be done, for example, to avoid the query that would
77
- be produced to determine the size of your collection).
74
+ Optionally, tasks can also implement a custom `#count` method, defining the
75
+ number of elements that will be iterated over. Your tasks `tick_total` will be
76
+ calculated automatically based on the collection size, but this value may be
77
+ overridden if desired using the `#count` method (this might be done, for
78
+ example, to avoid the query that would be produced to determine the size of your
79
+ collection).
78
80
 
79
81
  Example:
80
82
 
@@ -98,10 +100,12 @@ end
98
100
 
99
101
  You can also write a Task that iterates on a CSV file. Note that writing CSV
100
102
  Tasks **requires Active Storage to be configured**. Ensure that the dependency
101
- is specified in your application's Gemfile, and that you've followed the [setup
102
- instuctions][setup].
103
+ is specified in your applications Gemfile, and that youve followed the [setup
104
+ instructions][storage-setup]. See also [Customizing which Active Storage service
105
+ to use][storage-customizing].
103
106
 
104
- [setup]: https://edgeguides.rubyonrails.org/active_storage_overview.html#setup
107
+ [storage-setup]: https://edgeguides.rubyonrails.org/active_storage_overview.html#setup
108
+ [storage-customizing]: #customizing-which-active-storage-service-to-use
105
109
 
106
110
  Generate a CSV Task by running:
107
111
 
@@ -134,12 +138,12 @@ My Title,Hello World!
134
138
  ```
135
139
 
136
140
  The files uploaded to your Active Storage service provider will be renamed
137
- to include an ISO8601 timestamp and the Task name in snake case format.
141
+ to include an ISO 8601 timestamp and the Task name in snake case format.
138
142
  The CSV is expected to have a trailing newline at the end of the file.
139
143
 
140
144
  #### Batch CSV Tasks
141
145
 
142
- Tasks can process CSVs in batches. Add the `in_batches` option to your task's
146
+ Tasks can process CSVs in batches. Add the `in_batches` option to your tasks
143
147
  `csv_collection` macro:
144
148
 
145
149
  ```ruby
@@ -156,12 +160,12 @@ module Maintenance
156
160
  end
157
161
  ```
158
162
 
159
- As with a regular CSV task, ensure you've implemented the following method:
163
+ As with a regular CSV task, ensure youve implemented the following method:
160
164
 
161
165
  * `process`: do the work of your Task on a batch (array of `CSV::Row` objects).
162
166
 
163
167
  Note that `#count` is calculated automatically based on the number of batches in
164
- your collection, and your Task's progress will be displayed in terms of batches
168
+ your collection, and your Tasks progress will be displayed in terms of batches
165
169
  (not the total number of rows in your CSV).
166
170
 
167
171
  ### Processing Batch Collections
@@ -188,13 +192,13 @@ module Maintenance
188
192
  end
189
193
  ```
190
194
 
191
- Ensure that you've implemented the following methods:
195
+ Ensure that youve implemented the following methods:
192
196
 
193
197
  * `collection`: return an `ActiveRecord::Batches::BatchEnumerator`.
194
198
  * `process`: do the work of your Task on a batch (`ActiveRecord::Relation`).
195
199
 
196
200
  Note that `#count` is calculated automatically based on the number of batches in
197
- your collection, and your Task's progress will be displayed in terms of batches
201
+ your collection, and your Tasks progress will be displayed in terms of batches
198
202
  (not the number of records in the relation).
199
203
 
200
204
  **Important!** Batches should only be used if `#process` is performing a batch
@@ -206,7 +210,7 @@ primary keys of the records of the batch first, and then perform an additional
206
210
  query to load the records when calling `each` (or any `Enumerable` method)
207
211
  inside `#process`.
208
212
 
209
- ### Tasks that don't need a Collection
213
+ ### Tasks that dont need a Collection
210
214
 
211
215
  Sometimes, you might want to run a Task that performs a single operation, such
212
216
  as enqueuing another background job or hitting an external API. The gem supports
@@ -264,7 +268,7 @@ module Maintenance
264
268
  end
265
269
  ```
266
270
 
267
- Note that it's up to you to define a throttling condition that makes sense for
271
+ Note that its up to you to define a throttling condition that makes sense for
268
272
  your app. Shopify implements `DatabaseStatus.healthy?` to check various MySQL
269
273
  metrics such as replication lag, DB threads, whether DB writes are available,
270
274
  etc.
@@ -273,7 +277,7 @@ Tasks can define multiple throttle conditions. Throttle conditions are inherited
273
277
  by descendants, and new conditions will be appended without impacting existing
274
278
  conditions.
275
279
 
276
- The backoff can also be specified as a proc:
280
+ The backoff can also be specified as a Proc:
277
281
 
278
282
  ```ruby
279
283
  # app/tasks/maintenance/update_posts_throttled_task.rb
@@ -287,11 +291,12 @@ module Maintenance
287
291
  end
288
292
  end
289
293
  ```
294
+
290
295
  ### Custom Task Parameters
291
296
 
292
297
  Tasks may need additional information, supplied via parameters, to run.
293
298
  Parameters can be defined as Active Model Attributes in a Task, and then become
294
- accessible to any of Task's methods: `#collection`, `#count`, or `#process`.
299
+ accessible to any of Tasks methods: `#collection`, `#count`, or `#process`.
295
300
 
296
301
  ```ruby
297
302
  # app/tasks/maintenance/update_posts_via_params_task.rb
@@ -315,7 +320,7 @@ end
315
320
  Tasks can leverage Active Model Validations when defining parameters. Arguments
316
321
  supplied to a Task accepting parameters will be validated before the Task starts
317
322
  to run. Since arguments are specified in the user interface via text area
318
- inputs, it's important to check that they conform to the format your Task
323
+ inputs, its important to check that they conform to the format your Task
319
324
  expects, and to sanitize any inputs if necessary.
320
325
 
321
326
  ### Using Task Callbacks
@@ -348,7 +353,7 @@ end
348
353
  Note: The `after_error` callback is guaranteed to complete,
349
354
  so any exceptions raised in your callback code are ignored.
350
355
  If your `after_error` callback code can raise an exception,
351
- you'll need to rescue it and handle it appropriately
356
+ youll need to rescue it and handle it appropriately
352
357
  within the callback.
353
358
 
354
359
  ```ruby
@@ -397,7 +402,7 @@ depend on the queue adapter but in general, you should follow these rules:
397
402
  safely interrupted and resumed.
398
403
  * Idempotency of `Task#process`: it should be safe to run `process` multiple
399
404
  times for the same element of the collection. Read more in [this Sidekiq best
400
- practice][sidekiq-idempotent]. It's important if the Task errors and you run
405
+ practice][sidekiq-idempotent]. Its important if the Task errors and you run
401
406
  it again, because the same element that errored the Task may well be processed
402
407
  again. It especially matters in the situation described above, when the
403
408
  iteration duration exceeds the timeout: if the job is re-enqueued, multiple
@@ -422,7 +427,7 @@ callbacks](#using-task-callbacks) to persist or log a report for example.
422
427
  ### Writing tests for a Task
423
428
 
424
429
  The task generator will also create a test file for your task in the folder
425
- `test/tasks/maintenance/`. At a minimum, it's recommended that the `#process`
430
+ `test/tasks/maintenance/`. At a minimum, its recommended that the `#process`
426
431
  method in your task be tested. You may also want to test the `#collection` and
427
432
  `#count` methods for your task if they are sufficiently complex.
428
433
 
@@ -477,7 +482,7 @@ end
477
482
 
478
483
  ### Writing tests for a Task with parameters
479
484
 
480
- Tests for tasks with parameters need to instatiate the task class in order to
485
+ Tests for tasks with parameters need to instantiate the task class in order to
481
486
  assign attributes. Once the task instance is setup, you may test `#process`
482
487
  normally.
483
488
 
@@ -525,7 +530,8 @@ bundle exec maintenance_tasks perform Maintenance::ImportPostsTask --csv "path/t
525
530
  The `--csv` option also works with CSV content coming from the standard input:
526
531
 
527
532
  ```sh-session
528
- curl "some/remote/csv" | bundle exec maintenance_tasks perform Maintenance::ImportPostsTask --csv
533
+ curl "some/remote/csv" |
534
+ bundle exec maintenance_tasks perform Maintenance::ImportPostsTask --csv
529
535
  ```
530
536
 
531
537
  To run a Task that takes arguments from the command line, use the `--arguments`
@@ -564,7 +570,7 @@ MaintenanceTasks::Runner.run(
564
570
  )
565
571
  ```
566
572
 
567
- ### Monitoring your Task's status
573
+ ### Monitoring your Tasks status
568
574
 
569
575
  The web UI will provide updates on the status of your Task. Here are the states
570
576
  a Task can be in:
@@ -620,11 +626,11 @@ When Sidekiq is stopping, it will give workers 25 seconds to finish before
620
626
  forcefully terminating them (this is the default but can be configured with the
621
627
  `--timeout` option). Before the worker threads are terminated, Sidekiq will try
622
628
  to re-enqueue the job so your Task will be resumed. However, the position in
623
- the collection won't be persisted so at least one iteration may run again.
629
+ the collection wont be persisted so at least one iteration may run again.
624
630
 
625
631
  #### Help! My Task is stuck
626
632
 
627
- Finally, if the queue adapter configured for your application doesn't have this
633
+ Finally, if the queue adapter configured for your application doesnt have this
628
634
  property, or if Sidekiq crashes, is forcefully terminated, or is unable to
629
635
  re-enqueue the jobs that were in progress, the Task may be in a seemingly stuck
630
636
  situation where it appears to be running but is not. In that situation, pausing
@@ -690,6 +696,26 @@ MaintenanceTasks.tasks_module = "TaskModule"
690
696
 
691
697
  If no value is specified, it will default to `Maintenance`.
692
698
 
699
+ #### Organizing tasks using namespaces
700
+
701
+ Tasks may be nested arbitrarily deeply under `app/tasks/maintenance`, for example given a
702
+ task file `app/tasks/maintenance/team_name/service_name/update_posts_task.rb` we
703
+ can define the task as:
704
+
705
+ ```ruby
706
+ module Maintenance
707
+ module TeamName
708
+ module ServiceName
709
+ class UpdatePostsTask < MaintenanceTasks::Task
710
+ def process(rows)
711
+ # ...
712
+ end
713
+ end
714
+ end
715
+ end
716
+ end
717
+ ```
718
+
693
719
  #### Customizing the underlying job class
694
720
 
695
721
  `MaintenanceTasks.job` can be configured to define a Job class for your tasks to
@@ -699,7 +725,7 @@ maintenance tasks in your application.
699
725
  ```ruby
700
726
  # config/initializers/maintenance_tasks.rb
701
727
 
702
- MaintenanceTasks.job = 'CustomTaskJob'
728
+ MaintenanceTasks.job = "CustomTaskJob"
703
729
 
704
730
  # app/jobs/custom_task_job.rb
705
731
 
@@ -730,9 +756,9 @@ If no value is specified, it will default to 1 second.
730
756
  #### Customizing which Active Storage service to use
731
757
 
732
758
  The Active Storage framework in Rails 6.1 and up supports multiple storage
733
- services per environment. To specify which service to use,
734
- `MaintenanceTasks.active_storage_service` can be configured with the service's
735
- key, as specified in your application's `config/storage.yml`:
759
+ services. To specify which service to use,
760
+ `MaintenanceTasks.active_storage_service` can be configured with the services
761
+ key, as specified in your applications `config/storage.yml`:
736
762
 
737
763
  ```yaml
738
764
  # config/storage.yml
@@ -757,7 +783,8 @@ MaintenanceTasks.active_storage_service = :internal
757
783
  ```
758
784
 
759
785
  There is no need to configure this option if your application uses only one
760
- storage service per environment.
786
+ storage service. `Rails.configuration.active_storage.service` is used by
787
+ default.
761
788
 
762
789
  #### Customizing the backtrace cleaner
763
790
 
@@ -788,11 +815,11 @@ bin/rails generate maintenance_tasks:install
788
815
 
789
816
  This ensures that new migrations are installed and run as well.
790
817
 
791
- **What if I've deleted my previous Maintenance Task migrations?**
818
+ **What if Ive deleted my previous Maintenance Task migrations?**
792
819
 
793
820
  The install command will attempt to reinstall these old migrations and migrating
794
821
  the database will cause problems. Use `bin/rails
795
- maintenance_tasks:install:migrations` to copy the gem's migrations to your
822
+ maintenance_tasks:install:migrations` to copy the gems migrations to your
796
823
  `db/migrate` folder. Check the release notes to see if any new migrations were
797
824
  added since your last gem upgrade. Ensure that these are kept, but remove any
798
825
  migrations that already ran.
@@ -820,8 +847,8 @@ Once a release is ready, follow these steps:
820
847
  * Deploy via [Shipit][shipit] and see the new version on
821
848
  <https://rubygems.org/gems/maintenance_tasks>.
822
849
  * Ensure the release has documented all changes and publish it.
823
- * Create a new [draft release on GitHub][release] with the title 'Upcoming
824
- Release'. The tag version can be left blank. This will be the starting point
850
+ * Create a new [draft release on GitHub][release] with the title Upcoming
851
+ Release”. The tag version can be left blank. This will be the starting point
825
852
  for documenting changes related to the next release.
826
853
 
827
854
  [release]: https://help.github.com/articles/creating-releases/
@@ -15,7 +15,7 @@ module MaintenanceTasks
15
15
  )
16
16
  policy.script_src(
17
17
  # page refresh script
18
- "'sha256-2RPaBS4XCMLp0JJ/sW407W9l4qjC+WQAHmTOFJTGfqo='",
18
+ "'sha256-NiHKryHWudRC2IteTqmY9v1VkaDUA/5jhgXkMTkgo2w='",
19
19
  )
20
20
  policy.frame_ancestors(:self)
21
21
  end
@@ -18,10 +18,14 @@ module MaintenanceTasks
18
18
  # Renders the page responsible for providing Task actions to users.
19
19
  # Shows running and completed instances of the Task.
20
20
  def show
21
- @task = TaskDataShow.find(params.fetch(:id))
22
- @active_runs = @task.active_runs
23
- set_refresh if @active_runs.any?
21
+ task_name = params.fetch(:id)
22
+ @task = TaskDataShow.new(task_name)
23
+ @task.active_runs.load
24
+ set_refresh if @task.active_runs.any?
24
25
  @runs_page = RunsPage.new(@task.completed_runs, params[:cursor])
26
+ if @task.active_runs.none? && @runs_page.records.none?
27
+ Task.named(task_name)
28
+ end
25
29
  end
26
30
 
27
31
  private
@@ -104,9 +104,10 @@ module MaintenanceTasks
104
104
  # Return the appropriate field tag for the parameter
105
105
  def parameter_field(form_builder, parameter_name)
106
106
  case form_builder.object.class.attribute_types[parameter_name]
107
- when ActiveModel::Type::Integer, ActiveModel::Type::Decimal,
108
- ActiveModel::Type::Float
107
+ when ActiveModel::Type::Integer
109
108
  form_builder.number_field(parameter_name)
109
+ when ActiveModel::Type::Decimal, ActiveModel::Type::Float
110
+ form_builder.number_field(parameter_name, { step: "any" })
110
111
  when ActiveModel::Type::DateTime
111
112
  form_builder.datetime_field(parameter_name)
112
113
  when ActiveModel::Type::Date
@@ -37,17 +37,22 @@ module MaintenanceTasks
37
37
 
38
38
  enum status: STATUSES.to_h { |status| [status, status.to_s] }
39
39
 
40
- validates :task_name, on: :create, inclusion: { in: ->(_) {
41
- Task.available_tasks.map(&:to_s)
42
- } }
40
+ validates :task_name, on: :create, inclusion: {
41
+ in: ->(_) { Task.available_tasks.map(&:to_s) },
42
+ }
43
43
  validate :csv_attachment_presence, on: :create
44
44
  validate :csv_content_type, on: :create
45
45
  validate :validate_task_arguments, on: :create
46
46
 
47
47
  attr_readonly :task_name
48
48
 
49
- serialize :backtrace
50
- serialize :arguments, JSON
49
+ if Rails.gem_version >= Gem::Version.new("7.1.alpha")
50
+ serialize :backtrace, coder: YAML
51
+ serialize :arguments, coder: JSON
52
+ else
53
+ serialize :backtrace
54
+ serialize :arguments, JSON
55
+ end
51
56
 
52
57
  scope :active, -> { where(status: ACTIVE_STATUSES) }
53
58
  scope :completed, -> { where(status: COMPLETED_STATUSES) }
@@ -175,7 +175,13 @@ module MaintenanceTasks
175
175
  namespace = MaintenanceTasks.tasks_module.safe_constantize
176
176
  return unless namespace
177
177
 
178
- namespace.constants.map { |constant| namespace.const_get(constant) }
178
+ load_const = lambda do |root|
179
+ root.constants.each do |name|
180
+ object = root.const_get(name)
181
+ load_const.call(object) if object.instance_of?(Module)
182
+ end
183
+ end
184
+ load_const.call(namespace)
179
185
  end
180
186
  end
181
187
 
@@ -11,26 +11,6 @@ module MaintenanceTasks
11
11
  #
12
12
  # @api private
13
13
  class TaskDataShow
14
- class << self
15
- # Initializes a Task Data by name, raising if the Task does not exist.
16
- #
17
- # For the purpose of this method, a Task does not exist if it's deleted
18
- # and doesn't have a Run. While technically, it could have existed and
19
- # been deleted since, if it never had a Run we may as well consider it
20
- # non-existent since we don't have interesting data to show.
21
- #
22
- # @param name [String] the name of the Task subclass.
23
- # @return [TaskDataShow] a Task Data instance.
24
- # @raise [Task::NotFoundError] if the Task does not exist and doesn't have
25
- # a Run.
26
- def find(name)
27
- task_data = new(name)
28
- task_data.active_runs.load
29
- task_data.has_any_run? || Task.named(name)
30
- task_data
31
- end
32
- end
33
-
34
14
  # Initializes a Task Data with a name and optionally a related run.
35
15
  #
36
16
  # @param name [String] the name of the Task subclass.
@@ -107,12 +87,6 @@ module MaintenanceTasks
107
87
  MaintenanceTasks::Task.named(name).new
108
88
  end
109
89
 
110
- # @return [Boolean] whether the Task has any Run.
111
- # @api private
112
- def has_any_run?
113
- active_runs.any? || completed_runs.any?
114
- end
115
-
116
90
  private
117
91
 
118
92
  def runs
@@ -15,9 +15,9 @@
15
15
  <%= csrf_meta_tags %>
16
16
 
17
17
  <%=
18
- stylesheet_link_tag(URI.join(controller.class::BULMA_CDN, 'npm/bulma@0.9.3/css/bulma.css'),
18
+ stylesheet_link_tag(URI.join(controller.class::BULMA_CDN, 'npm/bulma@0.9.4/css/bulma.css'),
19
19
  media: :all,
20
- integrity: 'sha384-Zkr9rpl37lclZu6AwYQZZm0CxiMqLZFiibodW+UXLnAWPBr6qgIzPpcmHkpwnyWD',
20
+ integrity: 'sha384-qQlNh1kc0FyhUqUDXKkl5wpiiSm8PXQw2ZWhAVfU46tmdMDfq2vXG2CXWYT+Dls3',
21
21
  crossorigin: 'anonymous') unless request.xhr?
22
22
  %>
23
23
 
@@ -33,17 +33,19 @@
33
33
 
34
34
  <script>
35
35
  function refresh() {
36
- if (!("refresh" in document.body.dataset)) return
36
+ const target = document.querySelector("[data-refresh]")
37
+ if (!target || !target.dataset.refresh) return
37
38
  window.setTimeout(() => {
38
39
  document.body.style.cursor = "wait"
39
40
  fetch(document.location, { headers: { "X-Requested-With": "XMLHttpRequest" } }).then(
40
41
  async response => {
41
42
  const text = await response.text()
42
43
  const newDocument = new DOMParser().parseFromString(text, "text/html")
43
- document.body.replaceWith(newDocument.body)
44
- <%# force a redraw for Safari %>
45
- window.scrollTo({ top: document.documentElement.scrollTop + 1 })
46
- window.scrollTo({ top: document.documentElement.scrollTop - 1 })
44
+ const newTarget = newDocument.querySelector("[data-refresh]")
45
+ if (newTarget) {
46
+ target.replaceWith(newTarget)
47
+ }
48
+ document.body.style.cursor = ""
47
49
  refresh()
48
50
  },
49
51
  error => location.reload()
@@ -54,7 +56,7 @@
54
56
  </script>
55
57
  </head>
56
58
 
57
- <%= tag.body(data: { refresh: defined?(@refresh) && @refresh }) do %>
59
+ <body>
58
60
  <%= render 'layouts/maintenance_tasks/navbar' %>
59
61
 
60
62
  <section class="section">
@@ -68,5 +70,5 @@
68
70
  <%= yield %>
69
71
  </div>
70
72
  </div>
71
- <% end %>
73
+ </body>
72
74
  </html>
@@ -1,22 +1,24 @@
1
- <% if @available_tasks.empty? %>
2
- <div class="content is-large">
3
- <h3 class="title is-3"> The MaintenanceTasks gem has been successfully installed! </h3>
4
- <p>
5
- Any new Tasks will show up here. To start writing your first Task,
6
- run <code>bin/rails generate maintenance_tasks:task my_task</code>.
7
- </p>
8
- </div>
9
- <% else %>
10
- <% if active_tasks = @available_tasks[:active] %>
11
- <h3 class="title is-3">Active Tasks</h3>
12
- <%= render partial: 'task', collection: active_tasks %>
13
- <% end %>
14
- <% if new_tasks = @available_tasks[:new] %>
15
- <h3 class="title is-3">New Tasks</h3>
16
- <%= render partial: 'task', collection: new_tasks %>
17
- <% end %>
18
- <% if completed_tasks = @available_tasks[:completed] %>
19
- <h3 class="title is-3">Completed Tasks</h3>
20
- <%= render partial: 'task', collection: completed_tasks %>
1
+ <%= tag.div(data: { refresh: (defined?(@refresh) && @refresh) || "" }) do %>
2
+ <% if @available_tasks.empty? %>
3
+ <div class="content is-large">
4
+ <h3 class="title is-3"> The MaintenanceTasks gem has been successfully installed! </h3>
5
+ <p>
6
+ Any new Tasks will show up here. To start writing your first Task,
7
+ run <code>bin/rails generate maintenance_tasks:task my_task</code>.
8
+ </p>
9
+ </div>
10
+ <% else %>
11
+ <% if active_tasks = @available_tasks[:active] %>
12
+ <h3 class="title is-3">Active Tasks</h3>
13
+ <%= render partial: 'task', collection: active_tasks %>
14
+ <% end %>
15
+ <% if new_tasks = @available_tasks[:new] %>
16
+ <h3 class="title is-3">New Tasks</h3>
17
+ <%= render partial: 'task', collection: new_tasks %>
18
+ <% end %>
19
+ <% if completed_tasks = @available_tasks[:completed] %>
20
+ <h3 class="title is-3">Completed Tasks</h3>
21
+ <%= render partial: 'task', collection: completed_tasks %>
22
+ <% end %>
21
23
  <% end %>
22
24
  <% end %>
@@ -38,20 +38,22 @@
38
38
  <pre><code><%= highlight_code(code) %></code></pre>
39
39
  <% end %>
40
40
 
41
- <% if @active_runs.any? %>
42
- <hr/>
41
+ <%= tag.div(data: { refresh: (defined?(@refresh) && @refresh) || "" }) do %>
42
+ <% if @task.active_runs.any? %>
43
+ <hr/>
43
44
 
44
- <h4 class="title is-4">Active Runs</h4>
45
+ <h4 class="title is-4">Active Runs</h4>
45
46
 
46
- <%= render @active_runs %>
47
- <% end %>
47
+ <%= render @task.active_runs %>
48
+ <% end %>
48
49
 
49
- <% if @runs_page.records.present? %>
50
- <hr/>
50
+ <% if @runs_page.records.present? %>
51
+ <hr/>
51
52
 
52
- <h4 class="title is-4">Previous Runs</h4>
53
+ <h4 class="title is-4">Previous Runs</h4>
53
54
 
54
- <%= render @runs_page.records %>
55
+ <%= render @runs_page.records %>
55
56
 
56
- <%= link_to "Next page", task_path(@task, cursor: @runs_page.next_cursor) unless @runs_page.last? %>
57
+ <%= link_to "Next page", task_path(@task, cursor: @runs_page.next_cursor) unless @runs_page.last? %>
58
+ <% end %>
57
59
  <% end %>
@@ -2,7 +2,12 @@
2
2
 
3
3
  class AddLockVersionToMaintenanceTasksRuns < ActiveRecord::Migration[6.0]
4
4
  def change
5
- add_column(:maintenance_tasks_runs, :lock_version, :integer,
6
- default: 0, null: false)
5
+ add_column(
6
+ :maintenance_tasks_runs,
7
+ :lock_version,
8
+ :integer,
9
+ default: 0,
10
+ null: false,
11
+ )
7
12
  end
8
13
  end
@@ -2,12 +2,18 @@
2
2
 
3
3
  class AddIndexOnTaskNameAndStatusToRuns < ActiveRecord::Migration[6.0]
4
4
  def change
5
- remove_index(:maintenance_tasks_runs,
6
- column: [:task_name, :created_at], order: { created_at: :desc },
7
- name: :index_maintenance_tasks_runs_on_task_name_and_created_at)
5
+ remove_index(
6
+ :maintenance_tasks_runs,
7
+ column: [:task_name, :created_at],
8
+ order: { created_at: :desc },
9
+ name: :index_maintenance_tasks_runs_on_task_name_and_created_at,
10
+ )
8
11
 
9
- add_index(:maintenance_tasks_runs, [:task_name, :status, :created_at],
12
+ add_index(
13
+ :maintenance_tasks_runs,
14
+ [:task_name, :status, :created_at],
10
15
  name: :index_maintenance_tasks_runs,
11
- order: { created_at: :desc })
16
+ order: { created_at: :desc },
17
+ )
12
18
  end
13
19
  end
@@ -9,10 +9,14 @@ module MaintenanceTasks
9
9
  desc "This generator creates a task file at app/tasks and a corresponding "\
10
10
  "test."
11
11
 
12
- class_option :csv, type: :boolean, default: false,
12
+ class_option :csv,
13
+ type: :boolean,
14
+ default: false,
13
15
  desc: "Generate a CSV Task."
14
16
 
15
- class_option :no_collection, type: :boolean, default: false,
17
+ class_option :no_collection,
18
+ type: :boolean,
19
+ default: false,
16
20
  desc: "Generate a collection-less Task."
17
21
 
18
22
  check_class_collision suffix: "Task"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: maintenance_tasks
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shopify Engineering
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-09-26 00:00:00.000000000 Z
11
+ date: 2023-04-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionpack
@@ -154,7 +154,7 @@ homepage: https://github.com/Shopify/maintenance_tasks
154
154
  licenses:
155
155
  - MIT
156
156
  metadata:
157
- source_code_uri: https://github.com/Shopify/maintenance_tasks/tree/v2.0.0
157
+ source_code_uri: https://github.com/Shopify/maintenance_tasks/tree/v2.1.1
158
158
  allowed_push_host: https://rubygems.org
159
159
  post_install_message:
160
160
  rdoc_options: []
@@ -171,7 +171,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
171
171
  - !ruby/object:Gem::Version
172
172
  version: '0'
173
173
  requirements: []
174
- rubygems_version: 3.3.3
174
+ rubygems_version: 3.4.10
175
175
  signing_key:
176
176
  specification_version: 4
177
177
  summary: A Rails engine for queuing and managing maintenance tasks