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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 60d562f95a7e106a56e44fc6a391390d09611fb54763f982f799e068eb35c635
4
- data.tar.gz: c5092384cc830ad87f0c1173001507e1deb84011f923b1e4133ed418b75df5b5
3
+ metadata.gz: 2f77ed60aa6667fcc2fc18e2205e6e2a2c9dffd5fba9499750fc9dbcdea61bf5
4
+ data.tar.gz: 4292d9a83b73e309e731e00d393d7029750d1a7b6ddbe3685f7379af1efc61c6
5
5
  SHA512:
6
- metadata.gz: ef290cb5584a36e590203d5e6b46ec8a6c2427170c028f5a0c7444319381d462de3aaf54d8226e02875c1951991c3b3b3e9d1fb7d82d800bbb5b1ac51b774d92
7
- data.tar.gz: bc35ab922d0d328f9ea00fd90318936bf19c61363891c042743e3767f3a1b2af894d17f0067258e7bfbda933b3fc91997025a3397bd40724502f638b96d66d82
6
+ metadata.gz: 6aa418455aa98b9068bfa46c71eaf12e9a9943c5f1591e015cd713e7bf0d034beff33d98c15506dadd348811834451958f8d11018407910e0da1c29580059430
7
+ data.tar.gz: 7e1a09482cca627de3794587a480be4f695e9422bec933abc514ddabd3546c2b05485c0da1c141ed4ae0356ab41943607875bed7e376787050ada52e25551b19
data/Rakefile CHANGED
@@ -24,4 +24,4 @@ APP_RAKEFILE = File.expand_path("spec/dummy/Rakefile", __dir__)
24
24
  load "rails/tasks/engine.rake"
25
25
 
26
26
  Bundler::GemHelper.install_tasks
27
- import "tasks/release.rake"
27
+ import "lib/tasks/release.rake"
@@ -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
- yield workplace_link.resource
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
- workplace_links.group("worker_plugins_workplace_links.resource_type").order("worker_plugins_workplace_links.id").each do |workplace_link|
27
- resource_type = workplace_link.resource_type
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 = constant.where(id: ids_slice)
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(resource_id: query.distinct.select(query.klass.primary_key))
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
- if resources_to_add.none?
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: result.fetch(: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
@@ -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
@@ -1,3 +1,3 @@
1
1
  module WorkerPlugins
2
- VERSION = "0.0.11".freeze
2
+ VERSION = "0.0.13".freeze
3
3
  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.11
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-03-23 00:00:00.000000000 Z
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