worker_plugins 0.0.11 → 0.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/Rakefile +1 -1
- data/app/models/worker_plugins/workplace.rb +30 -7
- data/app/services/worker_plugins/query_links_status.rb +9 -1
- data/app/services/worker_plugins/select_column_with_type_cast.rb +9 -1
- data/app/services/worker_plugins/switch_query.rb +5 -33
- data/db/migrate/20260325100902_ensure_session_id_exists_on_worker_plugins_workplaces.rb +6 -0
- data/db/migrate/20260415143000_change_workplace_id_to_bigint_on_worker_plugins_workplace_links.rb +9 -0
- data/lib/tasks/release.rake +182 -0
- data/lib/worker_plugins/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2f77ed60aa6667fcc2fc18e2205e6e2a2c9dffd5fba9499750fc9dbcdea61bf5
|
|
4
|
+
data.tar.gz: 4292d9a83b73e309e731e00d393d7029750d1a7b6ddbe3685f7379af1efc61c6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6aa418455aa98b9068bfa46c71eaf12e9a9943c5f1591e015cd713e7bf0d034beff33d98c15506dadd348811834451958f8d11018407910e0da1c29580059430
|
|
7
|
+
data.tar.gz: 7e1a09482cca627de3794587a480be4f695e9422bec933abc514ddabd3546c2b05485c0da1c141ed4ae0356ab41943607875bed7e376787050ada52e25551b19
|
data/Rakefile
CHANGED
|
@@ -14,8 +14,14 @@ class WorkerPlugins::Workplace < WorkerPlugins::ApplicationRecord
|
|
|
14
14
|
links_query = workplace_links.order(:id)
|
|
15
15
|
links_query = links_query.where(resource_type: types) if types
|
|
16
16
|
links_query.find_in_batches do |workplace_links|
|
|
17
|
+
resources_by_type_and_id = load_resources_by_type_and_id(workplace_links)
|
|
18
|
+
|
|
17
19
|
workplace_links.each do |workplace_link|
|
|
18
|
-
|
|
20
|
+
resource = resources_by_type_and_id
|
|
21
|
+
.fetch(workplace_link.resource_type)[workplace_link.resource_id.to_s]
|
|
22
|
+
next unless resource
|
|
23
|
+
|
|
24
|
+
yield resource
|
|
19
25
|
count += 1
|
|
20
26
|
return if limit && count >= limit # rubocop:disable Lint/NonLocalExitFromIterator
|
|
21
27
|
end
|
|
@@ -23,15 +29,19 @@ class WorkerPlugins::Workplace < WorkerPlugins::ApplicationRecord
|
|
|
23
29
|
end
|
|
24
30
|
|
|
25
31
|
def each_query_for_resources
|
|
26
|
-
|
|
27
|
-
|
|
32
|
+
resource_ids_by_type = workplace_links
|
|
33
|
+
.order(:id)
|
|
34
|
+
.pluck(:resource_type, :resource_id)
|
|
35
|
+
.each_with_object({}) do |(resource_type, resource_id), grouped_ids|
|
|
36
|
+
grouped_ids[resource_type] ||= []
|
|
37
|
+
grouped_ids[resource_type] << resource_id
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
resource_ids_by_type.each do |resource_type, ids|
|
|
28
41
|
constant = Object.const_get(resource_type)
|
|
29
|
-
ids = workplace_links.where(resource_type: workplace_link.resource_type).pluck(:resource_id)
|
|
30
42
|
|
|
31
43
|
ids.each_slice(500) do |ids_slice|
|
|
32
|
-
query
|
|
33
|
-
|
|
34
|
-
yield(query:, resource_type:)
|
|
44
|
+
yield(query: constant.where(id: ids_slice), resource_type:)
|
|
35
45
|
end
|
|
36
46
|
end
|
|
37
47
|
end
|
|
@@ -61,6 +71,19 @@ private
|
|
|
61
71
|
inserted_ids
|
|
62
72
|
end
|
|
63
73
|
|
|
74
|
+
def load_resources_by_type_and_id(workplace_links)
|
|
75
|
+
workplace_links
|
|
76
|
+
.group_by(&:resource_type)
|
|
77
|
+
.transform_values do |links_for_type|
|
|
78
|
+
resource_class = Object.const_get(links_for_type.first.resource_type)
|
|
79
|
+
resource_ids = links_for_type.map(&:resource_id)
|
|
80
|
+
|
|
81
|
+
resource_class
|
|
82
|
+
.where(id: resource_ids)
|
|
83
|
+
.index_by { |resource| resource.id.to_s }
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
64
87
|
def validate_owner
|
|
65
88
|
if user.present? && session_id.present?
|
|
66
89
|
errors.add(:base, "Workplace can't belong to both a user and a session")
|
|
@@ -4,7 +4,7 @@ class WorkerPlugins::QueryLinksStatus < WorkerPlugins::ApplicationService
|
|
|
4
4
|
def perform
|
|
5
5
|
checked_count = workplace
|
|
6
6
|
.workplace_links
|
|
7
|
-
.where(
|
|
7
|
+
.where(resource_type: query.klass.name, resource_id: query_with_selected_ids)
|
|
8
8
|
.count
|
|
9
9
|
|
|
10
10
|
query_count = query.count
|
|
@@ -16,4 +16,12 @@ class WorkerPlugins::QueryLinksStatus < WorkerPlugins::ApplicationService
|
|
|
16
16
|
some_checked: checked_count.positive? && checked_count < query_count
|
|
17
17
|
)
|
|
18
18
|
end
|
|
19
|
+
|
|
20
|
+
def query_with_selected_ids
|
|
21
|
+
WorkerPlugins::SelectColumnWithTypeCast.execute!(
|
|
22
|
+
column_name_to_select: query.klass.primary_key,
|
|
23
|
+
column_to_compare_with: WorkerPlugins::WorkplaceLink.column_for_attribute(:resource_id),
|
|
24
|
+
query: query.distinct
|
|
25
|
+
)
|
|
26
|
+
end
|
|
19
27
|
end
|
|
@@ -46,6 +46,14 @@ class WorkerPlugins::SelectColumnWithTypeCast < WorkerPlugins::ApplicationServic
|
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
def same_type?
|
|
49
|
-
column_to_select.type == column_to_compare_with.type
|
|
49
|
+
column_to_select.type == column_to_compare_with.type || mysql_string_uuid_compatible_types?
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def mysql_string_uuid_compatible_types?
|
|
53
|
+
return false unless mysql?
|
|
54
|
+
|
|
55
|
+
types = [column_to_select.type, column_to_compare_with.type]
|
|
56
|
+
|
|
57
|
+
types.include?(:string) && types.include?(:uuid)
|
|
50
58
|
end
|
|
51
59
|
end
|
|
@@ -2,48 +2,20 @@ class WorkerPlugins::SwitchQuery < WorkerPlugins::ApplicationService
|
|
|
2
2
|
arguments :query, :workplace
|
|
3
3
|
|
|
4
4
|
def perform
|
|
5
|
-
|
|
5
|
+
add_query_service = WorkerPlugins::AddQuery.new(query:, workplace:)
|
|
6
|
+
created = add_query_service.created
|
|
7
|
+
|
|
8
|
+
if created.empty?
|
|
6
9
|
result = WorkerPlugins::RemoveQuery.execute!(query:, workplace:)
|
|
7
10
|
succeed!(
|
|
8
11
|
destroyed: result.fetch(:destroyed),
|
|
9
12
|
mode: :destroyed
|
|
10
13
|
)
|
|
11
14
|
else
|
|
12
|
-
result = WorkerPlugins::AddQuery.execute!(query:, workplace:)
|
|
13
15
|
succeed!(
|
|
14
|
-
created:
|
|
16
|
+
created: add_query_service.tap(&:add_query_to_workplace).created,
|
|
15
17
|
mode: :created
|
|
16
18
|
)
|
|
17
19
|
end
|
|
18
20
|
end
|
|
19
|
-
|
|
20
|
-
def ids_added_already_query
|
|
21
|
-
workplace
|
|
22
|
-
.workplace_links
|
|
23
|
-
.where(resource_type: model_class.name, resource_id: query_with_selected_ids)
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
def ids_added_already
|
|
27
|
-
WorkerPlugins::SelectColumnWithTypeCast.execute!(
|
|
28
|
-
column_name_to_select: :resource_id,
|
|
29
|
-
column_to_compare_with: model_class.column_for_attribute(:id),
|
|
30
|
-
query: ids_added_already_query
|
|
31
|
-
)
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
def model_class
|
|
35
|
-
@model_class ||= query.klass
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
def query_with_selected_ids
|
|
39
|
-
WorkerPlugins::SelectColumnWithTypeCast.execute!(
|
|
40
|
-
column_name_to_select: :id,
|
|
41
|
-
column_to_compare_with: WorkerPlugins::WorkplaceLink.column_for_attribute(:resource_id),
|
|
42
|
-
query:
|
|
43
|
-
)
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
def resources_to_add
|
|
47
|
-
@resources_to_add ||= query.where.not(id: ids_added_already)
|
|
48
|
-
end
|
|
49
21
|
end
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
class EnsureSessionIdExistsOnWorkerPluginsWorkplaces < ActiveRecord::Migration[6.0]
|
|
2
|
+
def change
|
|
3
|
+
add_column :worker_plugins_workplaces, :session_id, :string unless column_exists?(:worker_plugins_workplaces, :session_id)
|
|
4
|
+
add_index :worker_plugins_workplaces, :session_id, unique: true unless index_exists?(:worker_plugins_workplaces, :session_id)
|
|
5
|
+
end
|
|
6
|
+
end
|
data/db/migrate/20260415143000_change_workplace_id_to_bigint_on_worker_plugins_workplace_links.rb
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
class ChangeWorkplaceIdToBigintOnWorkerPluginsWorkplaceLinks < ActiveRecord::Migration[6.0]
|
|
2
|
+
def up
|
|
3
|
+
change_column :worker_plugins_workplace_links, :workplace_id, :bigint, null: false
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
def down
|
|
7
|
+
change_column :worker_plugins_workplace_links, :workplace_id, :integer, null: false
|
|
8
|
+
end
|
|
9
|
+
end
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
require "English"
|
|
2
|
+
require "fileutils"
|
|
3
|
+
require "pathname"
|
|
4
|
+
require "rubygems/version"
|
|
5
|
+
require "shellwords"
|
|
6
|
+
|
|
7
|
+
class WorkerPluginsRubygemsRelease
|
|
8
|
+
VERSION_FILE = Pathname.new(File.expand_path("../worker_plugins/version.rb", __dir__)) unless const_defined?(:VERSION_FILE)
|
|
9
|
+
|
|
10
|
+
def call
|
|
11
|
+
ensure_clean_worktree!
|
|
12
|
+
checkout_master!
|
|
13
|
+
fetch!
|
|
14
|
+
merge!
|
|
15
|
+
|
|
16
|
+
next_version = determine_next_version
|
|
17
|
+
|
|
18
|
+
bump_version!(next_version)
|
|
19
|
+
commit!(next_version)
|
|
20
|
+
push!
|
|
21
|
+
gem_file = build_gem!(next_version)
|
|
22
|
+
push_gem!(gem_file)
|
|
23
|
+
delete_gem_file!(gem_file)
|
|
24
|
+
rescue StandardError
|
|
25
|
+
warn "Release failed."
|
|
26
|
+
raise
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
def ensure_clean_worktree!
|
|
32
|
+
dirty_entries = git_status_lines.grep_v(%r{\A\?\? worker_plugins-[^/]+\.gem\z})
|
|
33
|
+
return if dirty_entries.empty?
|
|
34
|
+
|
|
35
|
+
raise "Working tree must be clean before releasing:\n#{dirty_entries.join("\n")}"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def checkout_master!
|
|
39
|
+
run!("git", "checkout", "master")
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def fetch!
|
|
43
|
+
run!("git", "fetch", remote_name)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def merge!
|
|
47
|
+
run!("git", "merge", "--ff-only", "#{remote_name}/master")
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def determine_next_version
|
|
51
|
+
requested_version || bumped_version
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def requested_version
|
|
55
|
+
version = ENV["VERSION"]&.strip
|
|
56
|
+
return if version.to_s.empty?
|
|
57
|
+
|
|
58
|
+
Gem::Version.new(version)
|
|
59
|
+
version
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def bumped_version
|
|
63
|
+
major, minor, patch = version_segments
|
|
64
|
+
|
|
65
|
+
case bump_type
|
|
66
|
+
when "major"
|
|
67
|
+
format_version(major + 1, 0, 0)
|
|
68
|
+
when "minor"
|
|
69
|
+
format_version(major, minor + 1, 0)
|
|
70
|
+
when "patch"
|
|
71
|
+
format_version(major, minor, patch + 1)
|
|
72
|
+
else
|
|
73
|
+
raise "Unsupported BUMP=#{bump_type.inspect}. Use patch, minor, major, or VERSION=x.y.z."
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def version_segments
|
|
78
|
+
@version_segments ||= begin
|
|
79
|
+
segments = Gem::Version.new(current_version).segments
|
|
80
|
+
segments << 0 while segments.length < 3
|
|
81
|
+
segments
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def current_version
|
|
86
|
+
@current_version ||= VERSION_FILE.read[/VERSION = "([^"]+)"\.freeze/, 1] || raise("Could not find current version")
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def format_version(major, minor, patch)
|
|
90
|
+
[major, minor, patch].join(".")
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def bump_version!(next_version)
|
|
94
|
+
raise "Next version must differ from current version" if next_version == current_version
|
|
95
|
+
|
|
96
|
+
VERSION_FILE.write(
|
|
97
|
+
VERSION_FILE.read.sub(
|
|
98
|
+
/VERSION = "[^"]+"\.freeze/,
|
|
99
|
+
%(VERSION = "#{next_version}".freeze)
|
|
100
|
+
)
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
sync_lockfile!
|
|
104
|
+
run!("git", "add", VERSION_FILE.to_s, "Gemfile.lock")
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def sync_lockfile!
|
|
108
|
+
run!("bundle", "lock")
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def commit!(next_version)
|
|
112
|
+
run!("git", "commit", "-m", "Release #{next_version}")
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def push!
|
|
116
|
+
run!("git", "push", remote_name, "master")
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def build_gem!(next_version)
|
|
120
|
+
gem_file = "worker_plugins-#{next_version}.gem"
|
|
121
|
+
run!("gem", "build", "worker_plugins.gemspec")
|
|
122
|
+
gem_file
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def push_gem!(gem_file)
|
|
126
|
+
run!("gem", "push", gem_file)
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def delete_gem_file!(gem_file)
|
|
130
|
+
FileUtils.rm_f(gem_file)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def git_status_lines
|
|
134
|
+
capture!("git", "status", "--porcelain").split("\n").reject(&:empty?)
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def bump_type
|
|
138
|
+
ENV.fetch("BUMP", "patch")
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def remote_name
|
|
142
|
+
ENV.fetch("REMOTE", "origin")
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def capture!(*command)
|
|
146
|
+
output = `#{command.map { |part| Shellwords.escape(part) }.join(" ")}`
|
|
147
|
+
raise "Command failed: #{command.join(' ')}" unless $CHILD_STATUS&.success?
|
|
148
|
+
|
|
149
|
+
output
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def run!(*command)
|
|
153
|
+
return if system(*command)
|
|
154
|
+
|
|
155
|
+
raise "Command failed: #{command.join(' ')}"
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
namespace :release do
|
|
160
|
+
desc "Release a patch version from master by fetching, fast-forward merging, bumping version, refreshing Gemfile.lock, pushing, and publishing"
|
|
161
|
+
task patch: :environment do
|
|
162
|
+
ENV["BUMP"] = "patch"
|
|
163
|
+
WorkerPluginsRubygemsRelease.new.call
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
desc "Release a minor version from master by fetching, fast-forward merging, bumping version, refreshing Gemfile.lock, pushing, and publishing"
|
|
167
|
+
task minor: :environment do
|
|
168
|
+
ENV["BUMP"] = "minor"
|
|
169
|
+
WorkerPluginsRubygemsRelease.new.call
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
desc "Release a major version from master by fetching, fast-forward merging, bumping version, refreshing Gemfile.lock, pushing, and publishing"
|
|
173
|
+
task major: :environment do
|
|
174
|
+
ENV["BUMP"] = "major"
|
|
175
|
+
WorkerPluginsRubygemsRelease.new.call
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
desc "Release the gem from master by fetching, fast-forward merging, bumping version, refreshing Gemfile.lock, pushing, and publishing"
|
|
179
|
+
task rubygems: :environment do
|
|
180
|
+
WorkerPluginsRubygemsRelease.new.call
|
|
181
|
+
end
|
|
182
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: worker_plugins
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.13
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Kasper Stöckel
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-04-15 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: Rails framework for easily choosing and creating lists of objects and
|
|
14
14
|
execute plugins against them.
|
|
@@ -41,6 +41,9 @@ files:
|
|
|
41
41
|
- db/migrate/20200702072306_change_workplace_links_resource_id_to_string_to_support_uuids.rb
|
|
42
42
|
- db/migrate/20210106190349_change_resource_id_to_string_to_support_uuid.rb
|
|
43
43
|
- db/migrate/20260322194625_add_session_id_to_worker_plugins_workplaces.rb
|
|
44
|
+
- db/migrate/20260325100902_ensure_session_id_exists_on_worker_plugins_workplaces.rb
|
|
45
|
+
- db/migrate/20260415143000_change_workplace_id_to_bigint_on_worker_plugins_workplace_links.rb
|
|
46
|
+
- lib/tasks/release.rake
|
|
44
47
|
- lib/tasks/worker_plugins_tasks.rake
|
|
45
48
|
- lib/worker_plugins.rb
|
|
46
49
|
- lib/worker_plugins/engine.rb
|