percy-client 1.9.2 → 1.10.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/.rubocop.yml +67 -0
- data/.rubocop_todo.yml +101 -0
- data/.travis.yml +7 -4
- data/Gemfile +6 -1
- data/Rakefile +0 -1
- data/lib/percy.rb +13 -9
- data/lib/percy/client.rb +10 -10
- data/lib/percy/client/builds.rb +6 -8
- data/lib/percy/client/connection.rb +5 -3
- data/lib/percy/client/environment.rb +26 -18
- data/lib/percy/client/resources.rb +1 -2
- data/lib/percy/client/snapshots.rb +4 -4
- data/lib/percy/client/version.rb +1 -1
- data/spec/lib/percy/client/builds_spec.rb +7 -5
- data/spec/lib/percy/client/connection_spec.rb +4 -4
- data/spec/lib/percy/client/environment_spec.rb +32 -6
- data/spec/lib/percy/client/resources_spec.rb +4 -4
- data/spec/lib/percy/client/snapshots_spec.rb +7 -5
- data/spec/lib/percy/client_spec.rb +1 -1
- data/spec/lib/percy/config_spec.rb +10 -8
- data/spec/lib/percy_spec.rb +1 -1
- data/spec/support/vcr_setup.rb +1 -1
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: faeea13f560dc02b0e342b7ff1b150f1cb328992
|
4
|
+
data.tar.gz: 66c65cadf25bf1f38c43d8408235aa383dd0649a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c8cdecfd7259f45698e015f57b09c2f7c6800daacaea64c88ba36cf5b905220bedc98a3b5c9141743d15e651ea838f23df1742d5d76dc6884dfbe8c98b4c1c88
|
7
|
+
data.tar.gz: f6c3d6f4f5fa2870c6cde224e954c297ff49b88700cbdd0417a43eadcbada8cd053d2a3aa265a6aa575e5afe019d4b7daeb826fd0eb3c6dc0bc5f5f3012e4198
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
require: rubocop-rspec
|
2
|
+
inherit_from: .rubocop_todo.yml
|
3
|
+
AllCops:
|
4
|
+
Include:
|
5
|
+
- Rakefile
|
6
|
+
- lib/**/*.rake
|
7
|
+
|
8
|
+
Lint/EndAlignment:
|
9
|
+
EnforcedStyleAlignWith: variable
|
10
|
+
|
11
|
+
Metrics/LineLength:
|
12
|
+
Max: 101
|
13
|
+
|
14
|
+
Style/AlignParameters:
|
15
|
+
EnforcedStyle: with_fixed_indentation
|
16
|
+
|
17
|
+
Style/CaseIndentation:
|
18
|
+
EnforcedStyle: end
|
19
|
+
|
20
|
+
Style/Documentation:
|
21
|
+
Enabled: false
|
22
|
+
|
23
|
+
Style/DoubleNegation:
|
24
|
+
Enabled: false
|
25
|
+
|
26
|
+
Style/IndentArray:
|
27
|
+
EnforcedStyle: consistent
|
28
|
+
|
29
|
+
Style/MultilineMethodCallIndentation:
|
30
|
+
EnforcedStyle: indented
|
31
|
+
|
32
|
+
Style/MultilineOperationIndentation:
|
33
|
+
EnforcedStyle: indented
|
34
|
+
|
35
|
+
# Disable Style/NumericLiterals so numbers don't need underscores
|
36
|
+
Style/NumericLiterals:
|
37
|
+
Enabled: false
|
38
|
+
|
39
|
+
Style/NumericPredicate:
|
40
|
+
EnforcedStyle: comparison
|
41
|
+
|
42
|
+
Style/RedundantBegin:
|
43
|
+
Enabled: false
|
44
|
+
|
45
|
+
Style/RegexpLiteral:
|
46
|
+
EnforcedStyle: slashes
|
47
|
+
AllowInnerSlashes: true
|
48
|
+
|
49
|
+
Style/SpaceInsideHashLiteralBraces:
|
50
|
+
EnforcedStyle: no_space
|
51
|
+
|
52
|
+
Style/TrailingCommaInArguments:
|
53
|
+
EnforcedStyleForMultiline: consistent_comma
|
54
|
+
|
55
|
+
Style/TrailingCommaInLiteral:
|
56
|
+
EnforcedStyleForMultiline: consistent_comma
|
57
|
+
|
58
|
+
RSpec/MessageSpies:
|
59
|
+
EnforcedStyle: receive
|
60
|
+
|
61
|
+
|
62
|
+
|
63
|
+
|
64
|
+
|
65
|
+
# Will be able to do this in >= v1.11
|
66
|
+
# RSpec/DescribedClass:
|
67
|
+
# EnforcedStyle: explicit
|
data/.rubocop_todo.yml
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
# This configuration was generated by
|
2
|
+
# `rubocop --auto-gen-config`
|
3
|
+
# on 2017-02-11 20:36:15 -0800 using RuboCop version 0.47.1.
|
4
|
+
# The point is for the user to remove these configuration records
|
5
|
+
# one by one as the offenses are removed from the code base.
|
6
|
+
# Note that changes in the inspected code, or installation of new
|
7
|
+
# versions of RuboCop, may require this file to be generated again.
|
8
|
+
|
9
|
+
# Offense count: 1
|
10
|
+
Lint/EmptyWhen:
|
11
|
+
Exclude:
|
12
|
+
- 'lib/percy/client/environment.rb'
|
13
|
+
|
14
|
+
# Offense count: 13
|
15
|
+
Metrics/AbcSize:
|
16
|
+
Max: 65
|
17
|
+
|
18
|
+
# Offense count: 24
|
19
|
+
# Configuration parameters: CountComments, ExcludedMethods.
|
20
|
+
Metrics/BlockLength:
|
21
|
+
Max: 450
|
22
|
+
|
23
|
+
# Offense count: 10
|
24
|
+
Metrics/CyclomaticComplexity:
|
25
|
+
Max: 14
|
26
|
+
|
27
|
+
# Offense count: 1
|
28
|
+
# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
|
29
|
+
# URISchemes: http, https
|
30
|
+
Metrics/LineLength:
|
31
|
+
Max: 101
|
32
|
+
|
33
|
+
# Offense count: 14
|
34
|
+
# Configuration parameters: CountComments.
|
35
|
+
Metrics/MethodLength:
|
36
|
+
Max: 57
|
37
|
+
|
38
|
+
# Offense count: 1
|
39
|
+
# Configuration parameters: CountComments.
|
40
|
+
Metrics/ModuleLength:
|
41
|
+
Max: 220
|
42
|
+
|
43
|
+
# Offense count: 6
|
44
|
+
Metrics/PerceivedComplexity:
|
45
|
+
Max: 13
|
46
|
+
|
47
|
+
# Offense count: 4
|
48
|
+
RSpec/AnyInstance:
|
49
|
+
Exclude:
|
50
|
+
- 'spec/lib/percy/client/builds_spec.rb'
|
51
|
+
- 'spec/lib/percy/client/snapshots_spec.rb'
|
52
|
+
|
53
|
+
# Offense count: 113
|
54
|
+
# Configuration parameters: SkipBlocks.
|
55
|
+
RSpec/DescribedClass:
|
56
|
+
Exclude:
|
57
|
+
- 'spec/lib/percy/client/environment_spec.rb'
|
58
|
+
- 'spec/lib/percy/client_spec.rb'
|
59
|
+
- 'spec/lib/percy_spec.rb'
|
60
|
+
|
61
|
+
# Offense count: 22
|
62
|
+
# Configuration parameters: Max.
|
63
|
+
RSpec/ExampleLength:
|
64
|
+
Exclude:
|
65
|
+
- 'spec/lib/percy/client/builds_spec.rb'
|
66
|
+
- 'spec/lib/percy/client/connection_spec.rb'
|
67
|
+
- 'spec/lib/percy/client/environment_spec.rb'
|
68
|
+
- 'spec/lib/percy/client/resources_spec.rb'
|
69
|
+
- 'spec/lib/percy/client/snapshots_spec.rb'
|
70
|
+
- 'spec/lib/percy/config_spec.rb'
|
71
|
+
- 'spec/lib/percy_spec.rb'
|
72
|
+
|
73
|
+
# Offense count: 20
|
74
|
+
# Configuration parameters: SupportedStyles.
|
75
|
+
# SupportedStyles: implicit, each, example
|
76
|
+
RSpec/HookArgument:
|
77
|
+
EnforcedStyle: each
|
78
|
+
|
79
|
+
# Offense count: 8
|
80
|
+
# Configuration parameters: AssignmentOnly.
|
81
|
+
RSpec/InstanceVariable:
|
82
|
+
Exclude:
|
83
|
+
- 'spec/lib/percy/client/environment_spec.rb'
|
84
|
+
|
85
|
+
# Offense count: 27
|
86
|
+
RSpec/MultipleExpectations:
|
87
|
+
Max: 10
|
88
|
+
|
89
|
+
# Offense count: 12
|
90
|
+
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
91
|
+
# SupportedStyles: not_to, to_not
|
92
|
+
RSpec/NotToNot:
|
93
|
+
Exclude:
|
94
|
+
- 'spec/lib/percy/client/builds_spec.rb'
|
95
|
+
- 'spec/lib/percy/client/environment_spec.rb'
|
96
|
+
- 'spec/lib/percy_spec.rb'
|
97
|
+
|
98
|
+
# Offense count: 1
|
99
|
+
Style/MethodMissing:
|
100
|
+
Exclude:
|
101
|
+
- 'lib/percy.rb'
|
data/.travis.yml
CHANGED
@@ -8,10 +8,13 @@ addons:
|
|
8
8
|
- libgmp-dev
|
9
9
|
cache: bundler
|
10
10
|
rvm:
|
11
|
-
-
|
12
|
-
- 2.
|
13
|
-
- 2.
|
11
|
+
- ruby-2.2.6
|
12
|
+
- ruby-2.3.3
|
13
|
+
- ruby-2.4.0
|
14
14
|
- ruby-head
|
15
15
|
before_install:
|
16
|
+
- gem update --system
|
16
17
|
- gem update bundler
|
17
|
-
script:
|
18
|
+
script:
|
19
|
+
- bundle exec rspec
|
20
|
+
- bundle exec rubocop -D
|
data/Gemfile
CHANGED
data/Rakefile
CHANGED
data/lib/percy.rb
CHANGED
@@ -25,25 +25,29 @@ module Percy
|
|
25
25
|
@logger if defined?(@logger)
|
26
26
|
@logger ||= Logger.new(STDOUT)
|
27
27
|
@logger.level = config.debug ? Logger::DEBUG : Logger::INFO
|
28
|
-
@logger.formatter = proc do |severity,
|
29
|
-
|
28
|
+
@logger.formatter = proc do |severity, _datetime, _progname, msg|
|
29
|
+
"[percy][#{severity}] #{msg}\n"
|
30
30
|
end
|
31
31
|
@logger
|
32
32
|
end
|
33
33
|
|
34
34
|
# @private
|
35
|
-
|
36
|
-
|
37
|
-
|
35
|
+
if RUBY_VERSION >= '1.9'
|
36
|
+
def self.respond_to_missing?(method_name, include_private = false)
|
37
|
+
client.respond_to?(method_name, include_private)
|
38
|
+
end
|
39
|
+
end
|
38
40
|
|
39
41
|
# @private
|
40
|
-
|
41
|
-
|
42
|
-
|
42
|
+
if RUBY_VERSION < '1.9'
|
43
|
+
def self.respond_to?(method_name, include_private = false)
|
44
|
+
client.respond_to?(method_name, include_private) || super
|
45
|
+
end
|
46
|
+
end
|
43
47
|
|
44
48
|
# @private
|
45
49
|
def self.method_missing(method_name, *args, &block)
|
46
|
-
return super
|
50
|
+
return super unless client.respond_to?(method_name)
|
47
51
|
client.send(method_name, *args, &block)
|
48
52
|
end
|
49
53
|
private :method_missing
|
data/lib/percy/client.rb
CHANGED
@@ -14,7 +14,7 @@ module Percy
|
|
14
14
|
include Percy::Client::Snapshots
|
15
15
|
include Percy::Client::Resources
|
16
16
|
|
17
|
-
class Error <
|
17
|
+
class Error < RuntimeError; end
|
18
18
|
class TimeoutError < Error; end
|
19
19
|
class ConnectionFailed < Error; end
|
20
20
|
class HttpError < Error
|
@@ -32,18 +32,18 @@ module Percy
|
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
|
-
class ClientError < HttpError; end
|
36
|
-
class BadRequestError < ClientError; end
|
37
|
-
class UnauthorizedError < ClientError; end
|
38
|
-
class PaymentRequiredError < ClientError; end
|
39
|
-
class ForbiddenError < ClientError; end
|
35
|
+
class ClientError < HttpError; end # 4xx;
|
36
|
+
class BadRequestError < ClientError; end # 400.
|
37
|
+
class UnauthorizedError < ClientError; end # 401.
|
38
|
+
class PaymentRequiredError < ClientError; end # 402.
|
39
|
+
class ForbiddenError < ClientError; end # 403.
|
40
40
|
class NotFoundError < ClientError; end # 404.
|
41
41
|
class ConflictError < ClientError; end # 409.
|
42
42
|
|
43
|
-
class ServerError < HttpError; end
|
44
|
-
class InternalServerError < ServerError; end
|
45
|
-
class BadGatewayError < ServerError; end
|
46
|
-
class ServiceUnavailableError < ServerError; end
|
43
|
+
class ServerError < HttpError; end # 5xx.
|
44
|
+
class InternalServerError < ServerError; end # 500.
|
45
|
+
class BadGatewayError < ServerError; end # 502.
|
46
|
+
class ServiceUnavailableError < ServerError; end # 503.
|
47
47
|
|
48
48
|
attr_reader :config
|
49
49
|
|
data/lib/percy/client/builds.rb
CHANGED
@@ -14,7 +14,7 @@ module Percy
|
|
14
14
|
# Only pass parallelism data if it all exists and there is more than 1 shard.
|
15
15
|
in_parallel_environment = parallel_nonce && \
|
16
16
|
parallel_total_shards && parallel_total_shards > 1
|
17
|
-
|
17
|
+
unless in_parallel_environment
|
18
18
|
parallel_nonce = nil
|
19
19
|
parallel_total_shards = nil
|
20
20
|
end
|
@@ -36,18 +36,18 @@ module Percy
|
|
36
36
|
'parallel-nonce' => parallel_nonce,
|
37
37
|
'parallel-total-shards' => parallel_total_shards,
|
38
38
|
},
|
39
|
-
}
|
39
|
+
},
|
40
40
|
}
|
41
41
|
|
42
42
|
if resources
|
43
|
-
|
44
|
-
raise ArgumentError
|
45
|
-
'resources argument must be an iterable of Percy::Client::Resource objects'
|
43
|
+
unless resources.respond_to?(:each)
|
44
|
+
raise ArgumentError,
|
45
|
+
'resources argument must be an iterable of Percy::Client::Resource objects'
|
46
46
|
end
|
47
47
|
relationships_data = {
|
48
48
|
'relationships' => {
|
49
49
|
'resources' => {
|
50
|
-
'data' => resources.map
|
50
|
+
'data' => resources.map(&:serialize),
|
51
51
|
},
|
52
52
|
},
|
53
53
|
}
|
@@ -71,5 +71,3 @@ module Percy
|
|
71
71
|
end
|
72
72
|
end
|
73
73
|
end
|
74
|
-
|
75
|
-
|
@@ -39,12 +39,14 @@ module Percy
|
|
39
39
|
error_class = Percy::Client::BadGatewayError
|
40
40
|
when 503
|
41
41
|
error_class = Percy::Client::ServiceUnavailableError
|
42
|
-
when CLIENT_ERROR_STATUS_RANGE
|
42
|
+
when CLIENT_ERROR_STATUS_RANGE # Catchall.
|
43
43
|
error_class = Percy::Client::HttpError
|
44
44
|
end
|
45
|
+
return unless error_class
|
45
46
|
raise error_class.new(
|
46
|
-
|
47
|
-
|
47
|
+
env.status, env.method.upcase, env.url, env.body,
|
48
|
+
"Got #{env.status} (#{env.method.upcase} #{env.url}):\n#{env.body}",
|
49
|
+
)
|
48
50
|
end
|
49
51
|
end
|
50
52
|
|
@@ -9,34 +9,35 @@ module Percy
|
|
9
9
|
'COMMITTER_EMAIL:%ae',
|
10
10
|
'COMMITTED_DATE:%ai',
|
11
11
|
# Note: order is important, this must come last because the regex is a multiline match.
|
12
|
-
'COMMIT_MESSAGE:%B'
|
12
|
+
'COMMIT_MESSAGE:%B',
|
13
13
|
].freeze
|
14
14
|
|
15
|
-
class Error <
|
16
|
-
class RepoNotFoundError <
|
15
|
+
class Error < RuntimeError; end
|
16
|
+
class RepoNotFoundError < RuntimeError; end
|
17
17
|
|
18
18
|
def self.current_ci
|
19
19
|
return :travis if ENV['TRAVIS_BUILD_ID']
|
20
|
-
return :jenkins if ENV['JENKINS_URL'] && ENV['ghprbPullId']
|
20
|
+
return :jenkins if ENV['JENKINS_URL'] && ENV['ghprbPullId'] # Pull Request Builder plugin.
|
21
21
|
return :circle if ENV['CIRCLECI']
|
22
22
|
return :codeship if ENV['CI_NAME'] && ENV['CI_NAME'] == 'codeship'
|
23
23
|
return :drone if ENV['DRONE'] == 'true'
|
24
24
|
return :semaphore if ENV['SEMAPHORE'] == 'true'
|
25
25
|
return :buildkite if ENV['BUILDKITE'] == 'true'
|
26
|
+
return :gitlab if ENV['GITLAB_CI']
|
26
27
|
end
|
27
28
|
|
28
29
|
# @return [Hash] All commit data from the current commit. Might be empty if commit data could
|
29
30
|
# not be found.
|
30
31
|
def self.commit
|
31
32
|
output = _raw_commit_output(_commit_sha) if _commit_sha
|
32
|
-
output = _raw_commit_output('HEAD')
|
33
|
+
output = _raw_commit_output('HEAD') unless output
|
33
34
|
|
34
35
|
# Use the specified SHA or, if not given, the parsed SHA at HEAD.
|
35
36
|
commit_sha = _commit_sha || output && output.match(/COMMIT_SHA:(.*)/)[1]
|
36
37
|
|
37
38
|
# If not running in a git repo, allow nils for certain commit attributes.
|
38
|
-
extract_or_nil =
|
39
|
-
|
39
|
+
extract_or_nil = ->(regex) { (output && output.match(regex) || [])[1] }
|
40
|
+
{
|
40
41
|
# The only required attribute:
|
41
42
|
branch: branch,
|
42
43
|
# An optional but important attribute:
|
@@ -48,7 +49,7 @@ module Percy
|
|
48
49
|
# These GIT_ environment vars are from the Jenkins Git Plugin, but could be
|
49
50
|
# used generically. This behavior may change in the future.
|
50
51
|
author_name: extract_or_nil.call(/AUTHOR_NAME:(.*)/) || ENV['GIT_AUTHOR_NAME'],
|
51
|
-
author_email: extract_or_nil.call(/AUTHOR_EMAIL:(.*)/)
|
52
|
+
author_email: extract_or_nil.call(/AUTHOR_EMAIL:(.*)/) || ENV['GIT_AUTHOR_EMAIL'],
|
52
53
|
committer_name: extract_or_nil.call(/COMMITTER_NAME:(.*)/) || ENV['GIT_COMMITTER_NAME'],
|
53
54
|
committer_email: extract_or_nil.call(/COMMITTER_EMAIL:(.*)/) || ENV['GIT_COMMITTER_EMAIL'],
|
54
55
|
}
|
@@ -80,14 +81,16 @@ module Percy
|
|
80
81
|
# Buildkite mixes SHAs and non-SHAs in BUILDKITE_COMMIT, so we return null if non-SHA.
|
81
82
|
return if ENV['BUILDKITE_COMMIT'] == 'HEAD'
|
82
83
|
ENV['BUILDKITE_COMMIT']
|
84
|
+
when :gitlab
|
85
|
+
ENV['CI_BUILD_REF']
|
83
86
|
end
|
84
87
|
end
|
85
88
|
|
86
89
|
# @private
|
87
90
|
def self._raw_commit_output(commit_sha)
|
88
|
-
format = GIT_FORMAT_LINES.join('%n')
|
91
|
+
format = GIT_FORMAT_LINES.join('%n') # "git show" format uses %n for newlines.
|
89
92
|
output = `git show --quiet #{commit_sha} --format="#{format}" 2> /dev/null`.strip
|
90
|
-
return if
|
93
|
+
return if $CHILD_STATUS.to_i != 0
|
91
94
|
output
|
92
95
|
end
|
93
96
|
|
@@ -114,9 +117,12 @@ module Percy
|
|
114
117
|
ENV['BRANCH_NAME']
|
115
118
|
when :buildkite
|
116
119
|
ENV['BUILDKITE_BRANCH']
|
120
|
+
when :gitlab
|
121
|
+
ENV['CI_BUILD_REF_NAME']
|
117
122
|
else
|
118
123
|
_raw_branch_output
|
119
124
|
end
|
125
|
+
|
120
126
|
if result == ''
|
121
127
|
STDERR.puts '[percy] Warning: not in a git repo, setting PERCY_BRANCH to "master".'
|
122
128
|
result = 'master'
|
@@ -138,7 +144,7 @@ module Percy
|
|
138
144
|
|
139
145
|
def self.repo
|
140
146
|
return ENV['PERCY_PROJECT'] if ENV['PERCY_PROJECT']
|
141
|
-
return ENV['PERCY_REPO_SLUG'] if ENV['PERCY_REPO_SLUG']
|
147
|
+
return ENV['PERCY_REPO_SLUG'] if ENV['PERCY_REPO_SLUG'] # Deprecated.
|
142
148
|
|
143
149
|
case current_ci
|
144
150
|
when :travis
|
@@ -150,15 +156,15 @@ module Percy
|
|
150
156
|
else
|
151
157
|
origin_url = _get_origin_url.strip
|
152
158
|
if origin_url == ''
|
153
|
-
raise Percy::Client::Environment::RepoNotFoundError
|
154
|
-
'No local git repository found. '
|
155
|
-
'You can manually set PERCY_PROJECT to fix this. See https://percy.io/docs'
|
159
|
+
raise Percy::Client::Environment::RepoNotFoundError,
|
160
|
+
'No local git repository found. ' \
|
161
|
+
'You can manually set PERCY_PROJECT to fix this. See https://percy.io/docs'
|
156
162
|
end
|
157
163
|
match = origin_url.match(Regexp.new('[:/]([^/]+\/[^/]+?)(\.git)?\Z'))
|
158
|
-
|
159
|
-
raise Percy::Client::Environment::RepoNotFoundError
|
160
|
-
"Could not determine repository name from URL: #{origin_url.inspect}\n"
|
161
|
-
|
164
|
+
unless match
|
165
|
+
raise Percy::Client::Environment::RepoNotFoundError,
|
166
|
+
"Could not determine repository name from URL: #{origin_url.inspect}\n" \
|
167
|
+
'You can manually set PERCY_PROJECT to fix this. See https://percy.io/docs'
|
162
168
|
end
|
163
169
|
match[1]
|
164
170
|
end
|
@@ -204,6 +210,8 @@ module Percy
|
|
204
210
|
ENV['SEMAPHORE_BUILD_NUMBER']
|
205
211
|
when :buildkite
|
206
212
|
ENV['BUILDKITE_BUILD_ID']
|
213
|
+
when :gitlab
|
214
|
+
ENV['CI_BUILD_ID']
|
207
215
|
end
|
208
216
|
end
|
209
217
|
|
@@ -4,7 +4,6 @@ require 'addressable/uri'
|
|
4
4
|
|
5
5
|
module Percy
|
6
6
|
class Client
|
7
|
-
|
8
7
|
# A simple data container object used to pass data to create_snapshot.
|
9
8
|
class Resource
|
10
9
|
attr_accessor :sha
|
@@ -48,7 +47,7 @@ module Percy
|
|
48
47
|
content_msg = content.nil? ? '' : "content.length: #{content.length}"
|
49
48
|
"<Resource #{sha} #{resource_url} is_root:#{!!is_root} #{mimetype} #{content_msg}>"
|
50
49
|
end
|
51
|
-
|
50
|
+
alias to_s inspect
|
52
51
|
end
|
53
52
|
|
54
53
|
module Resources
|
@@ -2,9 +2,9 @@ module Percy
|
|
2
2
|
class Client
|
3
3
|
module Snapshots
|
4
4
|
def create_snapshot(build_id, resources, options = {})
|
5
|
-
|
6
|
-
raise ArgumentError
|
7
|
-
'resources argument must be an iterable of Percy::Client::Resource objects'
|
5
|
+
unless resources.respond_to?(:each)
|
6
|
+
raise ArgumentError,
|
7
|
+
'resources argument must be an iterable of Percy::Client::Resource objects'
|
8
8
|
end
|
9
9
|
|
10
10
|
widths = options[:widths] || config.default_widths
|
@@ -18,7 +18,7 @@ module Percy
|
|
18
18
|
},
|
19
19
|
'relationships' => {
|
20
20
|
'resources' => {
|
21
|
-
'data' => resources.map
|
21
|
+
'data' => resources.map(&:serialize),
|
22
22
|
},
|
23
23
|
},
|
24
24
|
},
|
data/lib/percy/client/version.rb
CHANGED
@@ -7,7 +7,8 @@ RSpec.describe Percy::Client::Builds, :vcr do
|
|
7
7
|
# Whitebox test to check POST data.
|
8
8
|
expect_any_instance_of(Percy::Client).to \
|
9
9
|
receive(:post)
|
10
|
-
.with(
|
10
|
+
.with(
|
11
|
+
/\/api\/v1\/repos\/fotinakis\/percy-examples\/builds\//,
|
11
12
|
'data' => {
|
12
13
|
'type' => 'builds',
|
13
14
|
'attributes' => {
|
@@ -25,7 +26,7 @@ RSpec.describe Percy::Client::Builds, :vcr do
|
|
25
26
|
'parallel-total-shards' => nil,
|
26
27
|
},
|
27
28
|
},
|
28
|
-
|
29
|
+
).and_call_original
|
29
30
|
|
30
31
|
build = Percy.create_build('fotinakis/percy-examples')
|
31
32
|
expect(build).to be
|
@@ -73,7 +74,8 @@ RSpec.describe Percy::Client::Builds, :vcr do
|
|
73
74
|
# Whitebox test to check POST data.
|
74
75
|
expect_any_instance_of(Percy::Client).to \
|
75
76
|
receive(:post)
|
76
|
-
.with(
|
77
|
+
.with(
|
78
|
+
/\/api\/v1\/repos\/fotinakis\/percy-examples\/builds\//,
|
77
79
|
'data' => {
|
78
80
|
'type' => 'builds',
|
79
81
|
'attributes' => {
|
@@ -91,7 +93,7 @@ RSpec.describe Percy::Client::Builds, :vcr do
|
|
91
93
|
'parallel-total-shards' => 4,
|
92
94
|
},
|
93
95
|
},
|
94
|
-
|
96
|
+
)
|
95
97
|
|
96
98
|
Percy.create_build('fotinakis/percy-examples')
|
97
99
|
end
|
@@ -112,7 +114,7 @@ RSpec.describe Percy::Client::Builds, :vcr do
|
|
112
114
|
it 'finalizes a build' do
|
113
115
|
build = Percy.create_build('fotinakis/percy-examples')
|
114
116
|
result = Percy.finalize_build(build['data']['id'])
|
115
|
-
expect(result).to eq(
|
117
|
+
expect(result).to eq('success' => true)
|
116
118
|
end
|
117
119
|
end
|
118
120
|
end
|
@@ -8,7 +8,7 @@ RSpec.describe Percy::Client::Connection do
|
|
8
8
|
it 'performs a GET request to the api_url and parses response' do
|
9
9
|
stub_request(:get, "#{Percy.config.api_url}/test").to_return(body: {foo: true}.to_json)
|
10
10
|
data = Percy.client.get("#{Percy.config.api_url}/test")
|
11
|
-
expect(data).to eq(
|
11
|
+
expect(data).to eq('foo' => true)
|
12
12
|
end
|
13
13
|
it 'raises customized timeout errors' do
|
14
14
|
stub_request(:get, "#{Percy.config.api_url}/test").to_raise(Faraday::TimeoutError)
|
@@ -28,7 +28,7 @@ RSpec.describe Percy::Client::Connection do
|
|
28
28
|
.then.to_return(body: {foo: true}.to_json, status: 200)
|
29
29
|
|
30
30
|
data = Percy.client.get("#{Percy.config.api_url}/test")
|
31
|
-
expect(data).to eq(
|
31
|
+
expect(data).to eq('foo' => true)
|
32
32
|
end
|
33
33
|
it 'raises error after 3 retries' do
|
34
34
|
stub_request(:get, "#{Percy.config.api_url}/test")
|
@@ -42,7 +42,7 @@ RSpec.describe Percy::Client::Connection do
|
|
42
42
|
it 'performs a POST request to the api_url and parses response' do
|
43
43
|
stub_request(:post, "#{Percy.config.api_url}/test").to_return(body: {foo: true}.to_json)
|
44
44
|
data = Percy.client.post("#{Percy.config.api_url}/test", {})
|
45
|
-
expect(data).to eq(
|
45
|
+
expect(data).to eq('foo' => true)
|
46
46
|
end
|
47
47
|
it 'raises customized timeout errors' do
|
48
48
|
stub_request(:post, "#{Percy.config.api_url}/test").to_raise(Faraday::TimeoutError)
|
@@ -101,7 +101,7 @@ RSpec.describe Percy::Client::Connection do
|
|
101
101
|
.then.to_return(body: {foo: true}.to_json, status: 200)
|
102
102
|
|
103
103
|
data = Percy.client.post("#{Percy.config.api_url}/test", {})
|
104
|
-
expect(data).to eq(
|
104
|
+
expect(data).to eq('foo' => true)
|
105
105
|
end
|
106
106
|
it 'raises error after 3 retries' do
|
107
107
|
stub_request(:post, "#{Percy.config.api_url}/test")
|
@@ -6,7 +6,7 @@ RSpec.describe Percy::Client::Environment do
|
|
6
6
|
ENV['PERCY_TARGET_BRANCH'] = nil
|
7
7
|
ENV['PERCY_PULL_REQUEST'] = nil
|
8
8
|
ENV['PERCY_PROJECT'] = nil
|
9
|
-
ENV['PERCY_REPO_SLUG'] = nil
|
9
|
+
ENV['PERCY_REPO_SLUG'] = nil # Deprecated.
|
10
10
|
ENV['PERCY_PARALLEL_NONCE'] = nil
|
11
11
|
ENV['PERCY_PARALLEL_TOTAL'] = nil
|
12
12
|
|
@@ -51,7 +51,7 @@ RSpec.describe Percy::Client::Environment do
|
|
51
51
|
ENV['DRONE_BRANCH'] = nil
|
52
52
|
ENV['CI_PULL_REQUEST'] = nil
|
53
53
|
|
54
|
-
# Unset Semaphore CI vars
|
54
|
+
# Unset Semaphore CI vars.
|
55
55
|
ENV['CI'] = nil
|
56
56
|
ENV['SEMAPHORE'] = nil
|
57
57
|
ENV['REVISION'] = nil
|
@@ -61,12 +61,18 @@ RSpec.describe Percy::Client::Environment do
|
|
61
61
|
ENV['SEMAPHORE_CURRENT_THREAD'] = nil
|
62
62
|
ENV['PULL_REQUEST_NUMBER'] = nil
|
63
63
|
|
64
|
-
# Unset Buildkite CI vars
|
64
|
+
# Unset Buildkite CI vars.
|
65
65
|
ENV['BUILDKITE'] = nil
|
66
66
|
ENV['BUILDKITE_COMMIT'] = nil
|
67
67
|
ENV['BUILDKITE_BRANCH'] = nil
|
68
68
|
ENV['BUILDKITE_PULL_REQUEST'] = nil
|
69
69
|
ENV['BUILDKITE_BUILD_ID'] = nil
|
70
|
+
|
71
|
+
# Unset Gitlab CI vars.
|
72
|
+
ENV['GITLAB_CI'] = nil
|
73
|
+
ENV['CI_BUILD_REF'] = nil
|
74
|
+
ENV['CI_BUILD_REF_NAME'] = nil
|
75
|
+
ENV['CI_BUILD_ID'] = nil
|
70
76
|
end
|
71
77
|
|
72
78
|
before(:each) do
|
@@ -183,7 +189,8 @@ RSpec.describe Percy::Client::Environment do
|
|
183
189
|
it 'errors if unable to parse local repo name' do
|
184
190
|
expect(Percy::Client::Environment).to receive(:_get_origin_url).once.and_return('foo')
|
185
191
|
expect { Percy::Client::Environment.repo }.to raise_error(
|
186
|
-
Percy::Client::Environment::RepoNotFoundError
|
192
|
+
Percy::Client::Environment::RepoNotFoundError,
|
193
|
+
)
|
187
194
|
end
|
188
195
|
end
|
189
196
|
describe '#parallel_nonce' do
|
@@ -301,7 +308,7 @@ RSpec.describe Percy::Client::Environment do
|
|
301
308
|
ENV['CI_NAME'] = 'codeship'
|
302
309
|
ENV['CI_BRANCH'] = 'codeship-branch'
|
303
310
|
ENV['CI_BUILD_NUMBER'] = 'codeship-build-number'
|
304
|
-
ENV['CI_PULL_REQUEST'] = 'false'
|
311
|
+
ENV['CI_PULL_REQUEST'] = 'false' # This is always false on Codeship, unfortunately.
|
305
312
|
ENV['CI_COMMIT_ID'] = 'codeship-commit-sha'
|
306
313
|
ENV['CI_NODE_TOTAL'] = ''
|
307
314
|
end
|
@@ -385,7 +392,7 @@ RSpec.describe Percy::Client::Environment do
|
|
385
392
|
expect(Percy::Client::Environment.branch).to eq('buildkite-branch')
|
386
393
|
expect(Percy::Client::Environment._commit_sha).to eq('buildkite-commit-sha')
|
387
394
|
expect(Percy::Client::Environment.pull_request_number).to be_nil
|
388
|
-
expect(Percy::Client::Environment.repo).to eq('percy/percy-client')
|
395
|
+
expect(Percy::Client::Environment.repo).to eq('percy/percy-client') # From git, not env.
|
389
396
|
expect(Percy::Client::Environment.parallel_nonce).to eq('buildkite-build-id')
|
390
397
|
expect(Percy::Client::Environment.parallel_total_shards).to be_nil
|
391
398
|
end
|
@@ -406,6 +413,25 @@ RSpec.describe Percy::Client::Environment do
|
|
406
413
|
end
|
407
414
|
end
|
408
415
|
end
|
416
|
+
context 'in Gitlab CI' do
|
417
|
+
before(:each) do
|
418
|
+
ENV['GITLAB_CI'] = 'yes'
|
419
|
+
ENV['CI_BUILD_REF'] = 'gitlab-commit-sha'
|
420
|
+
ENV['CI_BUILD_REF_NAME'] = 'gitlab-branch'
|
421
|
+
ENV['CI_BUILD_ID'] = 'gitlab-build-id'
|
422
|
+
end
|
423
|
+
|
424
|
+
it 'has the correct properties' do
|
425
|
+
expect(Percy::Client::Environment.current_ci).to eq(:gitlab)
|
426
|
+
expect(Percy::Client::Environment.branch).to eq('gitlab-branch')
|
427
|
+
expect(Percy::Client::Environment._commit_sha).to eq('gitlab-commit-sha')
|
428
|
+
expect(Percy::Client::Environment.pull_request_number).to be_nil
|
429
|
+
expect(Percy::Client::Environment.parallel_nonce).to eq('gitlab-build-id')
|
430
|
+
expect(Percy::Client::Environment.parallel_total_shards).to be_nil
|
431
|
+
# TODO: repo is deprecated, remove this:
|
432
|
+
expect(Percy::Client::Environment.repo).to eq('percy/percy-client') # From git, not env.
|
433
|
+
end
|
434
|
+
end
|
409
435
|
describe 'local git repo methods' do
|
410
436
|
describe '#commit' do
|
411
437
|
it 'returns current local commit data' do
|
@@ -7,7 +7,7 @@ RSpec.describe Percy::Client::Resources, :vcr do
|
|
7
7
|
describe 'Percy::Client::Resource' do
|
8
8
|
it 'can be initialized with minimal data' do
|
9
9
|
resource = Percy::Client::Resource.new('/foo.html', sha: sha)
|
10
|
-
expect(resource.serialize).to eq(
|
10
|
+
expect(resource.serialize).to eq(
|
11
11
|
'type' => 'resources',
|
12
12
|
'id' => sha,
|
13
13
|
'attributes' => {
|
@@ -15,7 +15,7 @@ RSpec.describe Percy::Client::Resources, :vcr do
|
|
15
15
|
'mimetype' => nil,
|
16
16
|
'is-root' => nil,
|
17
17
|
},
|
18
|
-
|
18
|
+
)
|
19
19
|
end
|
20
20
|
it 'can be initialized with all data' do
|
21
21
|
resource = Percy::Client::Resource.new(
|
@@ -25,7 +25,7 @@ RSpec.describe Percy::Client::Resources, :vcr do
|
|
25
25
|
mimetype: 'text/html',
|
26
26
|
content: content,
|
27
27
|
)
|
28
|
-
expect(resource.serialize).to eq(
|
28
|
+
expect(resource.serialize).to eq(
|
29
29
|
'type' => 'resources',
|
30
30
|
'id' => sha,
|
31
31
|
'attributes' => {
|
@@ -33,7 +33,7 @@ RSpec.describe Percy::Client::Resources, :vcr do
|
|
33
33
|
'mimetype' => 'text/html',
|
34
34
|
'is-root' => true,
|
35
35
|
},
|
36
|
-
|
36
|
+
)
|
37
37
|
end
|
38
38
|
it 'errors if not given sha or content' do
|
39
39
|
expect { Percy::Client::Resource.new('/foo.html') }.to raise_error(ArgumentError)
|
@@ -12,7 +12,8 @@ RSpec.describe Percy::Client::Snapshots, :vcr do
|
|
12
12
|
# Whitebox test to catch POST data that is sent but is not returned in the API response.
|
13
13
|
expect_any_instance_of(Percy::Client).to \
|
14
14
|
receive(:post)
|
15
|
-
.with(
|
15
|
+
.with(
|
16
|
+
/snapshots\/$/,
|
16
17
|
'data' => {
|
17
18
|
'type' => 'snapshots',
|
18
19
|
'attributes' => {
|
@@ -45,7 +46,7 @@ RSpec.describe Percy::Client::Snapshots, :vcr do
|
|
45
46
|
},
|
46
47
|
},
|
47
48
|
},
|
48
|
-
|
49
|
+
)
|
49
50
|
.and_call_original
|
50
51
|
|
51
52
|
snapshot = Percy.create_snapshot(
|
@@ -70,7 +71,8 @@ RSpec.describe Percy::Client::Snapshots, :vcr do
|
|
70
71
|
# Whitebox test to catch POST data that is sent but is not returned in the API response.
|
71
72
|
expect_any_instance_of(Percy::Client).to \
|
72
73
|
receive(:post)
|
73
|
-
.with(
|
74
|
+
.with(
|
75
|
+
/snapshots\/$/,
|
74
76
|
'data' => {
|
75
77
|
'type' => 'snapshots',
|
76
78
|
'attributes' => {
|
@@ -103,7 +105,7 @@ RSpec.describe Percy::Client::Snapshots, :vcr do
|
|
103
105
|
},
|
104
106
|
},
|
105
107
|
},
|
106
|
-
|
108
|
+
)
|
107
109
|
.and_call_original
|
108
110
|
|
109
111
|
snapshot = Percy.create_snapshot(
|
@@ -135,7 +137,7 @@ RSpec.describe Percy::Client::Snapshots, :vcr do
|
|
135
137
|
snapshot = Percy.create_snapshot(build['data']['id'], resources, name: 'homepage')
|
136
138
|
|
137
139
|
result = Percy.finalize_snapshot(snapshot['data']['id'])
|
138
|
-
expect(result).to eq(
|
140
|
+
expect(result).to eq('success' => true)
|
139
141
|
end
|
140
142
|
end
|
141
143
|
end
|
@@ -2,17 +2,19 @@ RSpec.describe Percy::Config do
|
|
2
2
|
let(:config) { described_class.new }
|
3
3
|
|
4
4
|
it 'returns the correct defaults' do
|
5
|
-
expect(config.keys).to eq(
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
5
|
+
expect(config.keys).to eq(
|
6
|
+
[
|
7
|
+
:access_token,
|
8
|
+
:api_url,
|
9
|
+
:debug,
|
10
|
+
:repo,
|
11
|
+
:default_widths,
|
12
|
+
],
|
13
|
+
)
|
12
14
|
expect(config.access_token).to be_nil
|
13
15
|
expect(config.api_url).to eq(ENV['PERCY_API'])
|
14
16
|
expect(config.debug).to eq(false)
|
15
17
|
expect(config.repo).to eq('percy/percy-client')
|
16
18
|
expect(config.default_widths).to eq([])
|
17
19
|
end
|
18
|
-
end
|
20
|
+
end
|
data/spec/lib/percy_spec.rb
CHANGED
data/spec/support/vcr_setup.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: percy-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.10.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: 2017-
|
11
|
+
date: 2017-02-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|
@@ -131,9 +131,10 @@ extra_rdoc_files: []
|
|
131
131
|
files:
|
132
132
|
- ".gitignore"
|
133
133
|
- ".rspec"
|
134
|
+
- ".rubocop.yml"
|
135
|
+
- ".rubocop_todo.yml"
|
134
136
|
- ".travis.yml"
|
135
137
|
- Gemfile
|
136
|
-
- Gemfile.lock
|
137
138
|
- Guardfile
|
138
139
|
- LICENSE
|
139
140
|
- README.md
|
@@ -187,7 +188,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
187
188
|
version: '0'
|
188
189
|
requirements: []
|
189
190
|
rubyforge_project:
|
190
|
-
rubygems_version: 2.
|
191
|
+
rubygems_version: 2.4.8
|
191
192
|
signing_key:
|
192
193
|
specification_version: 4
|
193
194
|
summary: Percy::Client
|