copy_tuner_client 2.1.2 → 2.2.0
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/.gitignore +5 -0
- data/.rubocop.yml +46 -1
- data/CLAUDE.md +1 -0
- data/Gemfile +1 -0
- data/copy_tuner_client.gemspec +3 -3
- data/gemfiles/8.0.gemfile +3 -3
- data/gemfiles/8.1.gemfile +3 -3
- data/gemfiles/main.gemfile +3 -3
- data/lib/copy_tuner_client/cache.rb +34 -27
- data/lib/copy_tuner_client/client.rb +35 -23
- data/lib/copy_tuner_client/configuration.rb +62 -40
- data/lib/copy_tuner_client/copyray/rewriter.rb +1 -1
- data/lib/copy_tuner_client/copyray.rb +1 -0
- data/lib/copy_tuner_client/copyray_middleware.rb +31 -24
- data/lib/copy_tuner_client/dotted_hash.rb +7 -7
- data/lib/copy_tuner_client/engine.rb +4 -6
- data/lib/copy_tuner_client/helper_extension.rb +58 -54
- data/lib/copy_tuner_client/i18n_backend.rb +12 -14
- data/lib/copy_tuner_client/i18n_compat.rb +2 -1
- data/lib/copy_tuner_client/poller.rb +3 -4
- data/lib/copy_tuner_client/prefixed_logger.rb +13 -12
- data/lib/copy_tuner_client/process_guard.rb +29 -26
- data/lib/copy_tuner_client/queue_with_timeout.rb +29 -19
- data/lib/copy_tuner_client/rails.rb +9 -8
- data/lib/copy_tuner_client/request_sync.rb +26 -24
- data/lib/copy_tuner_client/simple_form_extention.rb +10 -6
- data/lib/copy_tuner_client/translation_log.rb +10 -5
- data/lib/copy_tuner_client/version.rb +1 -1
- data/lib/copy_tuner_client.rb +4 -8
- data/lib/tasks/copy_tuner_client_tasks.rake +14 -16
- data/skills/copy-tuner-to-locales-migrate-prefix/scripts/migrate_prefix.rb +14 -7
- data/skills/copy-tuner-to-t-migrate/scripts/migrate_tt.rb +19 -17
- data/spec/copy_tuner_client/cache_spec.rb +63 -57
- data/spec/copy_tuner_client/client_spec.rb +82 -81
- data/spec/copy_tuner_client/configuration_spec.rb +223 -222
- data/spec/copy_tuner_client/copyray/marker_spec.rb +2 -1
- data/spec/copy_tuner_client/copyray/rewriter_spec.rb +15 -10
- data/spec/copy_tuner_client/copyray_middleware_spec.rb +9 -6
- data/spec/copy_tuner_client/copyray_spec.rb +8 -8
- data/spec/copy_tuner_client/dotted_hash_spec.rb +33 -33
- data/spec/copy_tuner_client/helper_extension_spec.rb +47 -44
- data/spec/copy_tuner_client/i18n_backend_spec.rb +144 -143
- data/spec/copy_tuner_client/poller_spec.rb +25 -24
- data/spec/copy_tuner_client/prefixed_logger_spec.rb +15 -12
- data/spec/copy_tuner_client/process_guard_spec.rb +27 -27
- data/spec/copy_tuner_client/request_sync_spec.rb +51 -58
- data/spec/copy_tuner_client/translation_log_spec.rb +38 -24
- data/spec/copy_tuner_client_spec.rb +5 -6
- data/spec/support/client_spec_helpers.rb +1 -1
- data/spec/support/defines_constants.rb +3 -34
- data/spec/support/fake_client.rb +1 -3
- data/spec/support/fake_copy_tuner_app.rb +54 -62
- data/spec/support/fake_html_safe_string.rb +2 -3
- data/spec/support/fake_logger.rb +22 -21
- data/spec/support/fake_passenger.rb +4 -6
- data/spec/support/fake_unicorn.rb +2 -4
- data/spec/support/middleware_stack.rb +3 -3
- data/spec/support/writing_cache.rb +4 -4
- metadata +1 -1
|
@@ -13,12 +13,12 @@ class FakeCopyTunerApp < Sinatra::Base
|
|
|
13
13
|
Thin::Logging.silent = true
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
-
Rack::Handler::Thin.run self, :
|
|
16
|
+
Rack::Handler::Thin.run self, Port: port
|
|
17
17
|
end
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
def self.port
|
|
21
|
-
(
|
|
21
|
+
ENV.fetch('COPY_TUNER_PORT', 3002).to_i
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
def self.add_project(api_key)
|
|
@@ -35,11 +35,11 @@ class FakeCopyTunerApp < Sinatra::Base
|
|
|
35
35
|
|
|
36
36
|
def with_project(api_key)
|
|
37
37
|
if api_key == 'raise_error'
|
|
38
|
-
halt 500, { :
|
|
39
|
-
elsif project = Project.find(api_key)
|
|
38
|
+
halt 500, { error: 'Blah ha' }.to_json
|
|
39
|
+
elsif (project = Project.find(api_key))
|
|
40
40
|
yield project
|
|
41
41
|
else
|
|
42
|
-
halt 404, { :
|
|
42
|
+
halt 404, { error: 'No such project' }.to_json
|
|
43
43
|
end
|
|
44
44
|
end
|
|
45
45
|
|
|
@@ -84,47 +84,7 @@ class FakeCopyTunerApp < Sinatra::Base
|
|
|
84
84
|
class Project
|
|
85
85
|
attr_reader :draft, :published, :api_key
|
|
86
86
|
|
|
87
|
-
|
|
88
|
-
@api_key = attrs['api_key']
|
|
89
|
-
@draft = attrs['draft'] || {}
|
|
90
|
-
@etag = attrs['etag'] || 1
|
|
91
|
-
@published = attrs['published'] || {}
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
def to_hash
|
|
95
|
-
{
|
|
96
|
-
'api_key' => @api_key,
|
|
97
|
-
'etag' => @etag,
|
|
98
|
-
'draft' => @draft,
|
|
99
|
-
'published' => @published
|
|
100
|
-
}
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
def update(attrs)
|
|
104
|
-
if attrs['draft']
|
|
105
|
-
@draft.update attrs['draft']
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
if attrs['published']
|
|
109
|
-
@published.update attrs['published']
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
@etag += 1
|
|
113
|
-
self.class.save self
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
def reload
|
|
117
|
-
self.class.find api_key
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
def deploy
|
|
121
|
-
@published.update @draft
|
|
122
|
-
self.class.save self
|
|
123
|
-
end
|
|
124
|
-
|
|
125
|
-
def etag
|
|
126
|
-
@etag.to_s
|
|
127
|
-
end
|
|
87
|
+
MUTEX = Mutex.new
|
|
128
88
|
|
|
129
89
|
def self.create(api_key)
|
|
130
90
|
project = Project.new('api_key' => api_key)
|
|
@@ -134,18 +94,14 @@ class FakeCopyTunerApp < Sinatra::Base
|
|
|
134
94
|
|
|
135
95
|
def self.find(api_key)
|
|
136
96
|
open_project_data do |data|
|
|
137
|
-
if project_hash = data[api_key]
|
|
97
|
+
if (project_hash = data[api_key])
|
|
138
98
|
Project.new project_hash.dup
|
|
139
|
-
else
|
|
140
|
-
nil
|
|
141
99
|
end
|
|
142
100
|
end
|
|
143
101
|
end
|
|
144
102
|
|
|
145
103
|
def self.delete_all
|
|
146
|
-
open_project_data
|
|
147
|
-
data.clear
|
|
148
|
-
end
|
|
104
|
+
open_project_data(&:clear)
|
|
149
105
|
end
|
|
150
106
|
|
|
151
107
|
def self.save(project)
|
|
@@ -154,26 +110,62 @@ class FakeCopyTunerApp < Sinatra::Base
|
|
|
154
110
|
end
|
|
155
111
|
end
|
|
156
112
|
|
|
157
|
-
MUTEX = Mutex.new
|
|
158
113
|
def self.open_project_data
|
|
159
114
|
MUTEX.synchronize do
|
|
160
|
-
project_file = File.expand_path('
|
|
115
|
+
project_file = File.expand_path('../../tmp/projects.json', __dir__)
|
|
161
116
|
FileUtils.mkdir_p File.dirname(project_file)
|
|
162
117
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
118
|
+
data =
|
|
119
|
+
if File.exist? project_file
|
|
120
|
+
JSON.parse(File.read(project_file))
|
|
121
|
+
else
|
|
122
|
+
{}
|
|
123
|
+
end
|
|
168
124
|
|
|
169
125
|
result = yield(data)
|
|
170
126
|
|
|
171
|
-
File.
|
|
172
|
-
file.write data.to_json
|
|
173
|
-
end
|
|
127
|
+
File.write(project_file, data.to_json)
|
|
174
128
|
|
|
175
129
|
result
|
|
176
130
|
end
|
|
177
131
|
end
|
|
132
|
+
|
|
133
|
+
def initialize(attrs)
|
|
134
|
+
@api_key = attrs['api_key']
|
|
135
|
+
@draft = attrs.fetch('draft', {})
|
|
136
|
+
@etag = attrs.fetch('etag', 1)
|
|
137
|
+
@published = attrs.fetch('published', {})
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def to_hash
|
|
141
|
+
{
|
|
142
|
+
'api_key' => @api_key,
|
|
143
|
+
'etag' => @etag,
|
|
144
|
+
'draft' => @draft,
|
|
145
|
+
'published' => @published,
|
|
146
|
+
}
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def update(attrs)
|
|
150
|
+
@draft.update attrs['draft'] if attrs['draft']
|
|
151
|
+
|
|
152
|
+
@published.update attrs['published'] if attrs['published']
|
|
153
|
+
|
|
154
|
+
@etag += 1
|
|
155
|
+
self.class.save self
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def reload
|
|
159
|
+
self.class.find api_key
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def deploy
|
|
163
|
+
@published.update @draft
|
|
164
|
+
self.class.save self
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def etag
|
|
168
|
+
@etag.to_s
|
|
169
|
+
end
|
|
178
170
|
end
|
|
179
171
|
end
|
data/spec/support/fake_logger.rb
CHANGED
|
@@ -1,32 +1,32 @@
|
|
|
1
1
|
class FakeLogger
|
|
2
2
|
def initialize
|
|
3
3
|
@entries = {
|
|
4
|
-
:
|
|
5
|
-
:
|
|
6
|
-
:
|
|
7
|
-
:
|
|
8
|
-
:
|
|
4
|
+
info: [],
|
|
5
|
+
debug: [],
|
|
6
|
+
warn: [],
|
|
7
|
+
error: [],
|
|
8
|
+
fatal: [],
|
|
9
9
|
}
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
-
def info(message = nil, &
|
|
13
|
-
log(:info, message, &
|
|
12
|
+
def info(message = nil, &)
|
|
13
|
+
log(:info, message, &)
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
-
def debug(message = nil, &
|
|
17
|
-
log(:debug, message, &
|
|
16
|
+
def debug(message = nil, &)
|
|
17
|
+
log(:debug, message, &)
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
-
def warn(message = nil, &
|
|
21
|
-
log(:warn, message, &
|
|
20
|
+
def warn(message = nil, &)
|
|
21
|
+
log(:warn, message, &)
|
|
22
22
|
end
|
|
23
23
|
|
|
24
|
-
def error(message = nil, &
|
|
25
|
-
log(:error, message, &
|
|
24
|
+
def error(message = nil, &)
|
|
25
|
+
log(:error, message, &)
|
|
26
26
|
end
|
|
27
27
|
|
|
28
|
-
def fatal(message = nil, &
|
|
29
|
-
log(:fatal, message, &
|
|
28
|
+
def fatal(message = nil, &)
|
|
29
|
+
log(:fatal, message, &)
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
def log(severity, message = nil, &block)
|
|
@@ -56,13 +56,14 @@ RSpec::Matchers.define :have_entry do |severity, entry|
|
|
|
56
56
|
end
|
|
57
57
|
|
|
58
58
|
def entries
|
|
59
|
-
lines =
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
59
|
+
lines =
|
|
60
|
+
@logger.entries.inject([]) do |result, (severity, entries)|
|
|
61
|
+
if entries.empty?
|
|
62
|
+
result
|
|
63
|
+
else
|
|
64
|
+
result << "#{severity}:\n#{entries.join("\n")}"
|
|
65
|
+
end
|
|
64
66
|
end
|
|
65
|
-
end
|
|
66
67
|
lines.join("\n\n")
|
|
67
68
|
end
|
|
68
69
|
end
|
|
@@ -9,19 +9,17 @@ class FakePassenger
|
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
def call_event(name, *args)
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
handler.call(*args)
|
|
15
|
-
end
|
|
12
|
+
@handlers[name]&.each do |handler|
|
|
13
|
+
handler.call(*args)
|
|
16
14
|
end
|
|
17
15
|
end
|
|
18
16
|
|
|
19
17
|
def become_master
|
|
20
|
-
$0 =
|
|
18
|
+
$0 = 'PassengerApplicationSpawner'
|
|
21
19
|
end
|
|
22
20
|
|
|
23
21
|
def spawn
|
|
24
|
-
$0 =
|
|
22
|
+
$0 = 'PassengerFork'
|
|
25
23
|
call_event(:starting_worker_process, true)
|
|
26
24
|
end
|
|
27
25
|
end
|
|
@@ -3,11 +3,11 @@ class MiddlewareStack
|
|
|
3
3
|
@middlewares = []
|
|
4
4
|
end
|
|
5
5
|
|
|
6
|
-
def use(klass, *
|
|
7
|
-
@middlewares << klass.new('fake_app', *
|
|
6
|
+
def use(klass, *)
|
|
7
|
+
@middlewares << klass.new('fake_app', *)
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
def include?(klass)
|
|
11
|
-
@middlewares.any?
|
|
11
|
+
@middlewares.any?(klass)
|
|
12
12
|
end
|
|
13
13
|
end
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
class WritingCache
|
|
2
|
+
FLUSHED = 'flushed'.freeze
|
|
3
|
+
|
|
2
4
|
def flush
|
|
3
|
-
File.
|
|
4
|
-
file.write(object_id.to_s)
|
|
5
|
-
end
|
|
5
|
+
File.write(path, FLUSHED)
|
|
6
6
|
end
|
|
7
7
|
|
|
8
8
|
def written?
|
|
9
|
-
|
|
9
|
+
File.exist?(path) && File.read(path) == FLUSHED
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
private
|