percy-common 2.1.0 → 3.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: e83edb8522d97d14d009c557cc1cf30e9dfb8e14
4
- data.tar.gz: ed41e132239c852c14c9db2387f075cf200ec694
2
+ SHA256:
3
+ metadata.gz: fe94763bb303e12d788d293e1b2a1947fccfb61a1334a04c71179f99590ab639
4
+ data.tar.gz: 113a9533d5286c9753d21df7d631b2f6c64601680cd698db5600503d9e638c23
5
5
  SHA512:
6
- metadata.gz: 20290f9419c06622b11192f2a40de6265593e868d2ee70cf9d9cd5a4443fb9c38db76246f75ca95438e4a405f399c3bf4c0267ddd3daca2676990d87ece77905
7
- data.tar.gz: ba60224166e45dbd34f6919d27b2bff99c4d660d78dab56002240a358678d43fe02f30b22ed9fa8107eb1ca04f2fb796f0ce9c48b9d718d9c6193cba9fa1ff74
6
+ metadata.gz: 6ea47390164289c6a3402ce8f108f19ba698a69d1b2fb50dcaa58d12961ab10c18a74e1d54ed47e268a827b9851986136766ab436397b5bf475d690631a65f09
7
+ data.tar.gz: 1ae7c46e24ff481bb6d986d0cdfdca18450c27b350cb89d0938cd54101f4fc8f8edcd518220b64339edbb14b9846beb7390bffab59f2c94100350614ca736f24
@@ -0,0 +1,18 @@
1
+ version: 2.1
2
+
3
+ jobs:
4
+ ruby_25:
5
+ docker:
6
+ - image: circleci/ruby:2.5-node-browsers
7
+ steps:
8
+ - checkout
9
+ - run: gem update --system
10
+ - run: gem install bundler
11
+ - run: bundle install
12
+ - run: bundle exec rubocop -D
13
+
14
+ workflows:
15
+ version: 2
16
+ test:
17
+ jobs:
18
+ - ruby_25
@@ -2,6 +2,14 @@ inherit_gem:
2
2
  percy-style:
3
3
  - default.yml
4
4
 
5
+ inherit_mode:
6
+ merge:
7
+ - Include
8
+
5
9
  RSpec/DescribeClass:
6
10
  Exclude:
7
11
  - spec/percy/logger_spec.rb
12
+
13
+ AllCops:
14
+ Exclude:
15
+ - spec/support/redis_mock.rb
@@ -1,5 +1,5 @@
1
1
  module Percy
2
2
  module Common
3
- VERSION = '2.1.0'.freeze
3
+ VERSION = '3.1.0'.freeze
4
4
  end
5
5
  end
@@ -2,7 +2,8 @@ require 'logger'
2
2
 
3
3
  module Percy
4
4
  def self.logger
5
- @logger if defined?(@logger)
5
+ return @logger if defined?(@logger)
6
+
6
7
  @logger ||= Logger.new(STDOUT)
7
8
  @logger.level = Logger::INFO if ENV['PERCY_ENV'] == 'production'
8
9
  @logger.formatter = proc do |severity, _datetime, _progname, msg|
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'redis'
4
+
5
+ module Percy
6
+ class RedisClient
7
+ attr_reader :options
8
+ attr_reader :client
9
+
10
+ def initialize(options = {})
11
+ @options = options
12
+ @client = ::Redis.new(
13
+ options.merge(
14
+ ssl: ssl_enabled?,
15
+ ssl_params: ssl_params,
16
+ ),
17
+ )
18
+ end
19
+
20
+ private def ssl_enabled?
21
+ provided_url.to_s.start_with?('rediss://')
22
+ end
23
+
24
+ private def provided_url
25
+ options.dig(:url)
26
+ end
27
+
28
+ private def ssl_params
29
+ return {} unless ssl_enabled?
30
+
31
+ {
32
+ ca_file: certificate_authority_file,
33
+ cert: OpenSSL::X509::Certificate.new(client_certificate),
34
+ key: OpenSSL::PKey::RSA.new(private_key),
35
+ }
36
+ end
37
+
38
+ private def client_certificate
39
+ ENV.fetch(
40
+ 'REDIS_SSL_CLIENT_CERTIFICATE',
41
+ File.read(client_certificate_path),
42
+ )
43
+ end
44
+
45
+ private def client_certificate_path
46
+ ENV.fetch(
47
+ 'REDIS_SSL_CLIENT_CERTIFICATE_PATH',
48
+ File.join(cert_path, 'user.crt'),
49
+ )
50
+ end
51
+
52
+ private def private_key
53
+ ENV.fetch(
54
+ 'REDIS_SSL_PRIVATE_KEY',
55
+ File.read(private_key_path),
56
+ )
57
+ end
58
+
59
+ private def private_key_path
60
+ ENV.fetch(
61
+ 'REDIS_SSL_PRIVATE_KEY_PATH',
62
+ File.join(cert_path, 'user_private.key'),
63
+ )
64
+ end
65
+
66
+ private def certificate_authority_file
67
+ ENV.fetch(
68
+ 'REDIS_SSL_CERTIFICATE_AUTHORITY_PATH',
69
+ File.join(cert_path, 'server_ca.pem'),
70
+ )
71
+ end
72
+
73
+ private def cert_path
74
+ ENV.fetch(
75
+ 'REDIS_SSL_CERTIFICATE_PATH',
76
+ File.expand_path('../../redis', __dir__),
77
+ )
78
+ end
79
+ end
80
+ end
@@ -3,41 +3,74 @@ require 'time'
3
3
 
4
4
  module Percy
5
5
  class Stats < ::Datadog::Statsd
6
- def initialize(host = nil, port = nil, opts = {}, max_buffer_size = 50)
7
- host ||= ENV.fetch('DATADOG_AGENT_HOST', ::Datadog::Statsd::DEFAULT_HOST)
8
- port ||= Integer(ENV.fetch('DATADOG_AGENT_PORT', ::Datadog::Statsd::DEFAULT_PORT))
9
- opts[:tags] ||= []
10
- opts[:tags] << "env:#{ENV['PERCY_ENV'] || 'development'}"
11
- retry_delay = opts[:retry_delay] || 1
12
- retry_count = opts[:retry_count] || 3
13
- retries = 0
14
-
15
- begin
16
- super(host, port, opts, max_buffer_size)
17
- rescue SocketError
18
- host = 'localhost' if retries >= retry_count
19
- sleep retry_delay
20
- retries += 1
21
- retry
22
- end
6
+ DEFAULT_HOST = ENV.fetch(
7
+ 'DATADOG_AGENT_HOST',
8
+ ::Datadog::Statsd::Connection::DEFAULT_HOST,
9
+ )
10
+
11
+ DEFAULT_PORT = Integer(
12
+ ENV.fetch(
13
+ 'DATADOG_AGENT_PORT',
14
+ ::Datadog::Statsd::Connection::DEFAULT_PORT,
15
+ ),
16
+ )
17
+
18
+ DEFAULT_TAGS = %W[
19
+ env:#{ENV.fetch('PERCY_ENV', 'development')}
20
+ ].freeze
21
+
22
+ def initialize(
23
+ host = DEFAULT_HOST,
24
+ port = DEFAULT_PORT,
25
+ tags: DEFAULT_TAGS,
26
+ **kwargs
27
+ )
28
+ super(host, port, tags: tags, **kwargs)
23
29
  end
24
30
 
25
- # Equivalent to stats.time, but without wrapping in blocks and dealing with var scoping issues.
31
+ # Equivalent to stats.time, but without wrapping in blocks and dealing with
32
+ # var scoping issues.
26
33
  #
27
34
  # @example Report the time taken to activate an account.
28
35
  # stats.start_timing
29
36
  # account.activate!
30
37
  # stats.stop_timing('account.activate')
31
38
  def start_timing
32
- @_timing_start = Time.now
39
+ @_timing_start = now
33
40
  true
34
41
  end
35
42
 
36
43
  def stop_timing(stat, options = {})
37
- raise 'no timing started' unless @_timing_start # Programmer mistake, so raise an error.
38
- time_since(stat, @_timing_start, options)
44
+ # Programmer mistake, so raise an error.
45
+ raise 'no timing started' unless @_timing_start
46
+
47
+ time_since_monotonic(stat, @_timing_start, options)
39
48
  @_timing_start = nil
40
49
  true
41
50
  end
51
+
52
+ # dogstatsd uses a monotonic (linearly increasing) clock to calculate time
53
+ # intervals, so this should be used where necessary. However, it's not
54
+ # possible to compare monotonic time values with fixed times, so both are
55
+ # available.
56
+ def time_since_monotonic(stat, start, opts = {})
57
+ unless start.instance_of? Float
58
+ raise ArgumentError, 'start value must be Float'
59
+ end
60
+
61
+ timing(stat, ((now.to_f - start.to_f) * 1000).round, opts)
62
+ end
63
+
64
+ def time_since(stat, start, opts = {})
65
+ unless start.instance_of? Time
66
+ raise ArgumentError, 'start value must be Time'
67
+ end
68
+
69
+ timing(stat, ((Time.now.to_f - start.to_f) * 1000).round, opts)
70
+ end
71
+
72
+ private def now
73
+ Process.clock_gettime(Process::CLOCK_MONOTONIC)
74
+ end
42
75
  end
43
76
  end
@@ -1,5 +1,4 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
1
+ lib = File.expand_path('lib', __dir__)
3
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
3
  require 'percy/common/version'
5
4
 
@@ -9,19 +8,22 @@ Gem::Specification.new do |spec|
9
8
  spec.authors = ['Perceptual Inc.']
10
9
  spec.email = ['team@percy.io']
11
10
 
12
- spec.summary = %q{Server-side common library for Percy.}
13
- spec.description = %q{}
11
+ spec.summary = 'Server-side common library for Percy.'
12
+ spec.description = ''
14
13
  spec.homepage = ''
15
14
 
16
- spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
15
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
16
+ f.match(/^(test|spec|features)\//)
17
+ end
17
18
  spec.require_paths = ['lib']
18
19
 
19
- spec.add_dependency 'dogstatsd-ruby', '~> 3.1'
20
+ spec.add_dependency 'dogstatsd-ruby', '~> 4.4.0'
20
21
  spec.add_dependency 'excon', '~> 0.57'
22
+ spec.add_dependency 'redis', '~> 4.1.3'
21
23
 
22
- spec.add_development_dependency 'bundler', '~> 1.15'
23
- spec.add_development_dependency 'rake', '~> 10.0'
24
- spec.add_development_dependency 'rspec', '~> 3.2'
24
+ spec.add_development_dependency 'bundler', '~> 2.1.4'
25
25
  spec.add_development_dependency 'guard-rspec', '~> 4.7'
26
- spec.add_development_dependency 'percy-style'
26
+ spec.add_development_dependency 'percy-style', '~> 0.6.0'
27
+ spec.add_development_dependency 'rake', '~> 12.3'
28
+ spec.add_development_dependency 'rspec', '~> 3.2'
27
29
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: percy-common
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 3.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Perceptual Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-01-17 00:00:00.000000000 Z
11
+ date: 2020-04-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dogstatsd-ruby
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '3.1'
19
+ version: 4.4.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '3.1'
26
+ version: 4.4.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: excon
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -38,76 +38,90 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0.57'
41
+ - !ruby/object:Gem::Dependency
42
+ name: redis
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 4.1.3
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 4.1.3
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: bundler
43
57
  requirement: !ruby/object:Gem::Requirement
44
58
  requirements:
45
59
  - - "~>"
46
60
  - !ruby/object:Gem::Version
47
- version: '1.15'
61
+ version: 2.1.4
48
62
  type: :development
49
63
  prerelease: false
50
64
  version_requirements: !ruby/object:Gem::Requirement
51
65
  requirements:
52
66
  - - "~>"
53
67
  - !ruby/object:Gem::Version
54
- version: '1.15'
68
+ version: 2.1.4
55
69
  - !ruby/object:Gem::Dependency
56
- name: rake
70
+ name: guard-rspec
57
71
  requirement: !ruby/object:Gem::Requirement
58
72
  requirements:
59
73
  - - "~>"
60
74
  - !ruby/object:Gem::Version
61
- version: '10.0'
75
+ version: '4.7'
62
76
  type: :development
63
77
  prerelease: false
64
78
  version_requirements: !ruby/object:Gem::Requirement
65
79
  requirements:
66
80
  - - "~>"
67
81
  - !ruby/object:Gem::Version
68
- version: '10.0'
82
+ version: '4.7'
69
83
  - !ruby/object:Gem::Dependency
70
- name: rspec
84
+ name: percy-style
71
85
  requirement: !ruby/object:Gem::Requirement
72
86
  requirements:
73
87
  - - "~>"
74
88
  - !ruby/object:Gem::Version
75
- version: '3.2'
89
+ version: 0.6.0
76
90
  type: :development
77
91
  prerelease: false
78
92
  version_requirements: !ruby/object:Gem::Requirement
79
93
  requirements:
80
94
  - - "~>"
81
95
  - !ruby/object:Gem::Version
82
- version: '3.2'
96
+ version: 0.6.0
83
97
  - !ruby/object:Gem::Dependency
84
- name: guard-rspec
98
+ name: rake
85
99
  requirement: !ruby/object:Gem::Requirement
86
100
  requirements:
87
101
  - - "~>"
88
102
  - !ruby/object:Gem::Version
89
- version: '4.7'
103
+ version: '12.3'
90
104
  type: :development
91
105
  prerelease: false
92
106
  version_requirements: !ruby/object:Gem::Requirement
93
107
  requirements:
94
108
  - - "~>"
95
109
  - !ruby/object:Gem::Version
96
- version: '4.7'
110
+ version: '12.3'
97
111
  - !ruby/object:Gem::Dependency
98
- name: percy-style
112
+ name: rspec
99
113
  requirement: !ruby/object:Gem::Requirement
100
114
  requirements:
101
- - - ">="
115
+ - - "~>"
102
116
  - !ruby/object:Gem::Version
103
- version: '0'
117
+ version: '3.2'
104
118
  type: :development
105
119
  prerelease: false
106
120
  version_requirements: !ruby/object:Gem::Requirement
107
121
  requirements:
108
- - - ">="
122
+ - - "~>"
109
123
  - !ruby/object:Gem::Version
110
- version: '0'
124
+ version: '3.2'
111
125
  description: ''
112
126
  email:
113
127
  - team@percy.io
@@ -115,10 +129,10 @@ executables: []
115
129
  extensions: []
116
130
  extra_rdoc_files: []
117
131
  files:
132
+ - ".circleci/config.yml"
118
133
  - ".gitignore"
119
134
  - ".rspec"
120
135
  - ".rubocop.yml"
121
- - ".travis.yml"
122
136
  - Gemfile
123
137
  - Guardfile
124
138
  - LICENSE
@@ -132,6 +146,7 @@ files:
132
146
  - lib/percy/logger.rb
133
147
  - lib/percy/network_helpers.rb
134
148
  - lib/percy/process_helpers.rb
149
+ - lib/percy/redis_client.rb
135
150
  - lib/percy/stats.rb
136
151
  - percy-common.gemspec
137
152
  homepage: ''
@@ -152,8 +167,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
152
167
  - !ruby/object:Gem::Version
153
168
  version: '0'
154
169
  requirements: []
155
- rubyforge_project:
156
- rubygems_version: 2.6.13
170
+ rubygems_version: 3.1.2
157
171
  signing_key:
158
172
  specification_version: 4
159
173
  summary: Server-side common library for Percy.
@@ -1,12 +0,0 @@
1
- language: ruby
2
- sudo: false
3
- cache: bundler
4
- rvm:
5
- - 2.4
6
- - ruby-head
7
- before_install:
8
- - gem update --system
9
- - gem update bundler
10
- script:
11
- - bundle exec rubocop -D
12
- - bundle exec rspec