cover_rage 1.0.0 → 1.1.0

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: 5475081d89068cc543f39035786796e346ca90364f30c525680f4458118c211c
4
- data.tar.gz: 954ed2e2a6d4173e99b533c8914fd4c517730b53262bdbce0193c937644ad524
3
+ metadata.gz: 2d22a15a12e4376aa1a441dd5f4d21e7a6043390e1cef64e8739da1e6fcb81eb
4
+ data.tar.gz: ec07f2d32071bce21d03771e3d3ba3c6dd24e0e1cae745962fe0a36b89bc00ef
5
5
  SHA512:
6
- metadata.gz: e73234c452933ed861dec4cde8735e455ed5ea36ccbc9fc682bd7f695f43573ebfc5f5fb723b57c490af2fdd56743480e5812efd67a521f3f8672169d2d7af7d
7
- data.tar.gz: 36635a50188153c1f5d1df5b24eb024f12bcfc3b28496ec0deb2eaa918cd13cb571822945109b674f552b2f7fcad23519ef3347fc99d6e8f1ef91f85fdfdd179
6
+ metadata.gz: 16754fdef9cc29c0f6304e56a6f0c70dd91bc18c294bc944a7d3f927b642b07127acb079ecb9617156c3d0f703ec440536433f97b0f53d9742f6541d7df087cf
7
+ data.tar.gz: 94bddf50ab05b0f8227e42743910343b5f7c595c74774994bc60f5ecfc807dc1ec3f4bfcd5227ccb24a5207a2cfad77864077e934a986f91d4c8e254921cf359
@@ -27,16 +27,7 @@ module CoverRage
27
27
  end
28
28
 
29
29
  def self.interval
30
- @interval ||= begin
31
- args =
32
- ENV.fetch('COVER_RAGE_INTERVAL', '60:90').split(':').map!(&:to_i).first(2)
33
- args.push(args.first.succ) if args.length < 2
34
- Range.new(*args, true)
35
- end
36
- end
37
-
38
- def self.disable?
39
- @disable ||= ENV.key?('COVER_RAGE_DISABLE')
30
+ @interval ||= ENV.fetch('COVER_RAGE_INTERVAL', '60').to_i
40
31
  end
41
32
  end
42
33
  end
@@ -7,5 +7,12 @@ module CoverRage
7
7
  CoverRage::Launcher.start if pid.zero?
8
8
  pid
9
9
  end
10
+
11
+ def daemon(...)
12
+ CoverRage::Launcher.recorder.save(Coverage.result(stop: false))
13
+ returned = super
14
+ CoverRage::Launcher.start
15
+ returned
16
+ end
10
17
  end
11
18
  end
@@ -7,6 +7,8 @@ require 'coverage'
7
7
 
8
8
  module CoverRage
9
9
  class Launcher
10
+ singleton_class.attr_reader :recorder
11
+
10
12
  def self.start(**kwargs)
11
13
  if @recorder.nil?
12
14
  @recorder = CoverRage::Recorder.new(
@@ -16,9 +18,6 @@ module CoverRage
16
18
  )
17
19
  end
18
20
  @recorder.start
19
- return unless Process.respond_to?(:_fork)
20
- return if Process.singleton_class < CoverRage::ForkHook
21
-
22
21
  Process.singleton_class.prepend(CoverRage::ForkHook)
23
22
  end
24
23
  end
@@ -6,7 +6,6 @@ require 'digest'
6
6
 
7
7
  module CoverRage
8
8
  class Recorder
9
- INTERVAL = Config.interval
10
9
  attr_reader :store
11
10
 
12
11
  def initialize(path_prefix:, store:)
@@ -24,15 +23,15 @@ module CoverRage
24
23
  at_exit { save(Coverage.result) }
25
24
  end
26
25
  @thread = Thread.new do
26
+ interval = Config.interval
27
+ jitter = 0.15
27
28
  loop do
28
- sleep(rand(INTERVAL))
29
+ sleep(interval + rand * interval * jitter)
29
30
  save(Coverage.result(stop: false, clear: true))
30
31
  end
31
32
  end
32
33
  end
33
34
 
34
- private
35
-
36
35
  def save(coverage_result)
37
36
  records = []
38
37
  coverage_result.map do |filepath, execution_count|
@@ -53,6 +52,8 @@ module CoverRage
53
52
  @store.import(records) if records.any?
54
53
  end
55
54
 
55
+ private
56
+
56
57
  def read_file_with_revision(path)
57
58
  return @file_cache[path] if @file_cache.key?(path)
58
59
 
@@ -22,13 +22,11 @@ module CoverRage
22
22
  loop do
23
23
  break if @redis.watch(KEY) do
24
24
  records_to_save = Record.merge(list, records)
25
- if records_to_save.any?
26
- arguments = []
27
- records_to_save.each do |record|
28
- arguments.push(record.path, JSON.dump(record.to_h))
29
- end
30
- @redis.multi { _1.hset(KEY, *arguments) }
25
+ arguments = []
26
+ records_to_save.each do |record|
27
+ arguments.push(record.path, JSON.dump(record.to_h))
31
28
  end
29
+ @redis.multi { _1.hset(KEY, *arguments) }
32
30
  end
33
31
  end
34
32
  end
@@ -17,27 +17,37 @@ module CoverRage
17
17
  execution_count text not null
18
18
  )
19
19
  SQL
20
+ process_ext = Module.new
21
+ process_ext.module_exec(self) do |store|
22
+ define_method :_fork do
23
+ store.instance_variable_get(:@db).close
24
+ pid = super()
25
+ store.instance_variable_set(:@db, SQLite3::Database.new(path))
26
+ pid
27
+ end
28
+ end
29
+ Process.singleton_class.prepend(process_ext)
20
30
  end
21
31
 
22
32
  def import(records)
23
- @db.transaction do
33
+ @db.transaction(:exclusive) do
24
34
  records_to_save = Record.merge(list, records)
25
- if records_to_save.any?
26
- @db.execute(
27
- "insert or replace into records (path, revision, source, execution_count) values #{
28
- (['(?,?,?,?)'] * records_to_save.length).join(',')
29
- }",
30
- records_to_save.each_with_object([]) do |record, memo|
31
- memo.push(
32
- record.path,
33
- record.revision,
34
- record.source,
35
- JSON.dump(record.execution_count)
36
- )
37
- end
38
- )
39
- end
35
+ @db.execute(
36
+ "insert or replace into records (path, revision, source, execution_count) values #{
37
+ (['(?,?,?,?)'] * records_to_save.length).join(',')
38
+ }",
39
+ records_to_save.each_with_object([]) do |record, memo|
40
+ memo.push(
41
+ record.path,
42
+ record.revision,
43
+ record.source,
44
+ JSON.dump(record.execution_count)
45
+ )
46
+ end
47
+ )
40
48
  end
49
+ rescue SQLite3::BusyException
50
+ retry
41
51
  end
42
52
 
43
53
  def find(path)
@@ -59,7 +69,7 @@ module CoverRage
59
69
  def list
60
70
  @db
61
71
  .execute('select path, revision, source, execution_count from records')
62
- .map! do |(path, revision, source, execution_count)|
72
+ .map do |(path, revision, source, execution_count)|
63
73
  Record.new(
64
74
  path: path,
65
75
  revision: revision,
metadata CHANGED
@@ -1,15 +1,28 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cover_rage
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Weihang Jian
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2024-12-25 00:00:00.000000000 Z
10
+ date: 2024-12-28 00:00:00.000000000 Z
12
11
  dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: minitest
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '5.18'
19
+ type: :development
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: '5.18'
13
26
  - !ruby/object:Gem::Dependency
14
27
  name: rake
15
28
  requirement: !ruby/object:Gem::Requirement
@@ -25,26 +38,41 @@ dependencies:
25
38
  - !ruby/object:Gem::Version
26
39
  version: '13.0'
27
40
  - !ruby/object:Gem::Dependency
28
- name: minitest
41
+ name: redis
29
42
  requirement: !ruby/object:Gem::Requirement
30
43
  requirements:
31
44
  - - "~>"
32
45
  - !ruby/object:Gem::Version
33
- version: '5.18'
46
+ version: '5.3'
34
47
  type: :development
35
48
  prerelease: false
36
49
  version_requirements: !ruby/object:Gem::Requirement
37
50
  requirements:
38
51
  - - "~>"
39
52
  - !ruby/object:Gem::Version
40
- version: '5.18'
53
+ version: '5.3'
54
+ - !ruby/object:Gem::Dependency
55
+ name: sqlite3
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '2.5'
61
+ type: :development
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '2.5'
41
68
  description: |
42
- A Ruby production code coverage tool designed to assist you in identifying unused code, offering the following features:
69
+ cover_rage is a Ruby code coverage tool designed to be simple and easy to use. It can be used not only for test coverage but also in production services to identify unused code.
70
+
71
+ Key features:
43
72
 
44
- 1. zero dependencies
45
- 2. super easy setup
46
- 3. support process forking without additional configuration
47
- 4. minimal performance overhead
73
+ 1. Runs in continuous processes (e.g., Rails servers)
74
+ 2. Zero dependencies
75
+ 3. Supports forking and daemonization without additional setup
48
76
  email: tonytonyjan@gmail.com
49
77
  executables:
50
78
  - cover_rage
@@ -68,7 +96,6 @@ homepage: https://github.com/tonytonyjan/cover_rage
68
96
  licenses:
69
97
  - MIT
70
98
  metadata: {}
71
- post_install_message:
72
99
  rdoc_options: []
73
100
  require_paths:
74
101
  - lib
@@ -76,15 +103,16 @@ required_ruby_version: !ruby/object:Gem::Requirement
76
103
  requirements:
77
104
  - - ">="
78
105
  - !ruby/object:Gem::Version
79
- version: 2.3.0
106
+ version: '3.2'
80
107
  required_rubygems_version: !ruby/object:Gem::Requirement
81
108
  requirements:
82
109
  - - ">="
83
110
  - !ruby/object:Gem::Version
84
111
  version: '0'
85
112
  requirements: []
86
- rubygems_version: 3.5.23
87
- signing_key:
113
+ rubygems_version: 3.6.2
88
114
  specification_version: 4
89
- summary: A Ruby production code coverage tool
115
+ summary: cover_rage is a Ruby code coverage tool designed to be simple and easy to
116
+ use. It can be used not only for test coverage but also in production services to
117
+ identify unused code.
90
118
  test_files: []