percy-cli 0.0.1 → 0.0.2

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
  SHA1:
3
- metadata.gz: 9b424e941cc250a7a550f938ae216a99c51400ec
4
- data.tar.gz: 5bf813f4abe4ced40d3b7f213801b33caa39d0ea
3
+ metadata.gz: a79b07a50003692a4126836dca74ca72787c479c
4
+ data.tar.gz: 44b4607a5fe3267aae10e772c7b7057f33ded2eb
5
5
  SHA512:
6
- metadata.gz: a2e75cec943b3e4919590d256e562f129350a1a0775c34ea3de40e206e9300b105d2091b70f56b3a8a2baec0712222d47d3e2b2b20f5526058c41ee5251e6751
7
- data.tar.gz: db17492803a3c36a5a34c30f033590f54f4305137adf3155ec212051b2931a8097564984642ee387db2c22cc7fc01593833e7623b803e0ee8e631a27bdf8a24a
6
+ metadata.gz: 29b2632be605f99a12265a798b7afb40552934bc7445f514a48723ed9842d84672d1524a2f7f1f32fdc1f2615043ed96d14bdb526c3165961a03a0e5590a4549
7
+ data.tar.gz: 14b7f5941ca563a9bf5c3df841638a162d5c16dd3e3ede57fc644e9fe1190d39ba63dc6e10893f6e6a1e3a644c387e6f652a0bad0f57b0a1035b0b829cd57639
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --require spec_helper
3
+ --format d
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.1.1
5
+ - 2.2.2
6
+ - ruby-head
7
+ script: bundle exec rspec
data/bin/percy CHANGED
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
+ require 'commander'
3
4
  require 'percy/cli'
4
5
 
5
- puts 'test'
6
+ Percy::Cli.new.run if $0 == __FILE__
@@ -0,0 +1,212 @@
1
+ require 'find'
2
+ require 'digest'
3
+ require 'uri'
4
+
5
+ module Percy
6
+ class Cli
7
+ module Snapshot
8
+ # Static resource types that an HTML file might load and that we want to upload for rendering.
9
+ STATIC_RESOURCE_EXTENSIONS = [
10
+ '.css', '.jpg', '.jpeg', '.gif', '.ico', '.png', '.bmp', '.pict', '.tif', '.tiff', '.ttf',
11
+ '.eot', '.woff', '.otf', '.svg', '.svgz', '.webp', '.ps',
12
+ ].freeze
13
+
14
+ DEFAULT_SNAPSHOTS_REGEX = /\.(html|htm)$/
15
+
16
+ # Modified version of Diego Perini's URL regex. https://gist.github.com/dperini/729294
17
+ REMOTE_URL_REGEX_STRING = (
18
+ # protocol identifier
19
+ "(?:(?:https?:)?//)" +
20
+ "(?:" +
21
+ # IP address exclusion
22
+ # private & local networks
23
+ "(?!(?:10|127)(?:\\.\\d{1,3}){3})" +
24
+ "(?!(?:169\\.254|192\\.168)(?:\\.\\d{1,3}){2})" +
25
+ "(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})" +
26
+ # IP address dotted notation octets
27
+ # excludes loopback network 0.0.0.0
28
+ # excludes reserved space >= 224.0.0.0
29
+ # excludes network & broacast addresses
30
+ # (first & last IP address of each class)
31
+ "(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])" +
32
+ "(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}" +
33
+ "(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))" +
34
+ "|" +
35
+ # host name
36
+ "(?:(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)" +
37
+ # domain name
38
+ "(?:\\.(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)*" +
39
+ # TLD identifier
40
+ "(?:\\.(?:[a-z\\u00a1-\\uffff]{2,}))" +
41
+ ")" +
42
+ # port number
43
+ "(?::\\d{2,5})?" +
44
+ # resource path
45
+ "(?:/[^\\s\"']*)?"
46
+ )
47
+ HTML_REMOTE_URL_REGEX = Regexp.new("<link.*?href=['\"](" + REMOTE_URL_REGEX_STRING + ")")
48
+
49
+ # Match all url("https://...") calls, with whitespace and quote variatinos.
50
+ CSS_REMOTE_URL_REGEX = Regexp.new(
51
+ "url\\s*\\([\"'\s]*(" + REMOTE_URL_REGEX_STRING + ")[\"'\s]*\\)"
52
+ )
53
+
54
+ def run_snapshot(root_dir, options = {})
55
+ repo = options[:repo] || Percy.config.repo
56
+ strip_prefix = File.absolute_path(options[:strip_prefix] || root_dir)
57
+ autoload_remote_resources = options[:autoload_remote_resources] || false
58
+
59
+ # Create a Percy build for the snapshots.
60
+ build = Percy.create_build(repo)
61
+
62
+ # Find all the static files in the given root directory.
63
+ root_paths = find_root_paths(root_dir, snapshots_regex: options[:snapshots_regex])
64
+ resource_paths = find_resource_paths(root_dir)
65
+ root_resources = build_resources(root_paths, strip_prefix, is_root: true)
66
+ related_resources = build_resources(resource_paths, strip_prefix)
67
+
68
+ if autoload_remote_resources
69
+ remote_urls = find_remote_urls(root_paths + resource_paths)
70
+ related_resources += build_remote_resources(remote_urls)
71
+ end
72
+
73
+ # Upload a snapshot for every root resource, and associate the related_resources.
74
+ root_resources.each_with_index do |root_resource, i|
75
+ say "Uploading snapshot (#{i+1}/#{root_resources.length}): #{root_resource.resource_url}"
76
+ upload_snapshot(build, root_resource, related_resources)
77
+ end
78
+
79
+ # Finalize the build.
80
+ Percy.finalize_build(build['data']['id'])
81
+ end
82
+
83
+ private
84
+
85
+ def find_root_paths(dir_path, options = {})
86
+ snapshots_regex = options[:snapshots_regex] || DEFAULT_SNAPSHOTS_REGEX
87
+
88
+ file_paths = []
89
+ Find.find(dir_path).each do |relative_path|
90
+ path = File.absolute_path(relative_path)
91
+ # Skip directories.
92
+ next if !FileTest.file?(path)
93
+ # Skip files that don't match the snapshots_regex.
94
+ next if !path.match(snapshots_regex)
95
+ file_paths << path
96
+ end
97
+ file_paths
98
+ end
99
+
100
+ def find_resource_paths(dir_path)
101
+ file_paths = []
102
+ Find.find(dir_path).each do |relative_path|
103
+ path = File.absolute_path(relative_path)
104
+
105
+ # Skip directories.
106
+ next if !FileTest.file?(path)
107
+ # Skip dot files.
108
+ next if path.match(/\/\./)
109
+ # Only include files with the above static extensions.
110
+ next if !Percy::Cli::STATIC_RESOURCE_EXTENSIONS.include?(File.extname(path))
111
+
112
+ file_paths << path
113
+ end
114
+ file_paths
115
+ end
116
+
117
+ def find_remote_urls(file_paths)
118
+ urls = []
119
+ file_paths.each do |path|
120
+ extension = File.extname(path)
121
+ case extension
122
+ when '.html'
123
+ content = File.read(path)
124
+ urls += content.scan(HTML_REMOTE_URL_REGEX).map { |match| maybe_add_protocol(match[0]) }
125
+ when '.css'
126
+ content = File.read(path)
127
+ urls += content.scan(CSS_REMOTE_URL_REGEX).map { |match| maybe_add_protocol(match[0]) }
128
+ end
129
+ end
130
+ urls.uniq
131
+ end
132
+
133
+ def maybe_add_protocol(url)
134
+ url[0..1] == '//' ? "http:#{url}" : url
135
+ end
136
+
137
+ def build_resources(paths, strip_prefix, options = {})
138
+ resources = []
139
+
140
+ # Strip trailing slash from strip_prefix.
141
+ strip_prefix = strip_prefix[0..-2] if strip_prefix[-1] == '/'
142
+
143
+ paths.each do |path|
144
+ sha = Digest::SHA256.hexdigest(File.read(path))
145
+ resource_url = URI.escape(path.sub(strip_prefix, ''))
146
+ resources << Percy::Client::Resource.new(
147
+ resource_url, sha: sha, is_root: options[:is_root], path: path)
148
+ end
149
+ resources
150
+ end
151
+
152
+ def build_remote_resources(remote_urls)
153
+ resources = []
154
+
155
+ bar = Commander::UI::ProgressBar.new(
156
+ remote_urls.length,
157
+ title: 'Fetching remote resources...',
158
+ format: ':title |:progress_bar| :percent_complete% complete - :url',
159
+ width: 40,
160
+ complete_message: nil,
161
+ )
162
+
163
+ remote_urls.each do |url|
164
+ bar.increment url: url
165
+ begin
166
+ response = Faraday.get(url)
167
+ rescue Faraday::Error::ConnectionFailed => e
168
+ say_error e
169
+ next
170
+ end
171
+ if response.status != 200
172
+ say_error "Remote resource failed, skipping: #{url}"
173
+ next
174
+ end
175
+
176
+ sha = Digest::SHA256.hexdigest(response.body)
177
+ resources << Percy::Client::Resource.new(url, sha: sha, content: response.body)
178
+ end
179
+ resources
180
+ end
181
+
182
+ def upload_snapshot(build, root_resource, related_resources)
183
+ all_resources = [root_resource] + related_resources
184
+
185
+ # Create the snapshot for this page. For simplicity, include all non-HTML resources in the
186
+ # snapshot as related resources. May seem inefficient, but they will only be uploaded once.
187
+ snapshot = Percy.create_snapshot(build['data']['id'], all_resources)
188
+
189
+ # Upload the content for any missing resources.
190
+ missing_resources = snapshot['data']['relationships']['missing-resources']['data']
191
+ bar = Commander::UI::ProgressBar.new(
192
+ missing_resources.length,
193
+ title: 'Uploading resources...',
194
+ format: ':title |:progress_bar| :percent_complete% complete - :resource_url',
195
+ width: 40,
196
+ complete_message: nil,
197
+ )
198
+ missing_resources.each do |missing_resource|
199
+ missing_resource_sha = missing_resource['id']
200
+ resource = all_resources.find { |r| r.sha == missing_resource_sha }
201
+ path = resource.resource_url
202
+ bar.increment resource_url: resource.resource_url
203
+
204
+ # Remote resources are stored in 'content', local resources are read from the filesystem.
205
+ content = resource.content || File.read("#{resource.path}")
206
+
207
+ Percy.upload_resource(build['data']['id'], content)
208
+ end
209
+ end
210
+ end
211
+ end
212
+ end
@@ -1,5 +1,5 @@
1
1
  module Percy
2
- module Cli
3
- VERSION = "0.0.1"
2
+ class Cli
3
+ VERSION = '0.0.2'
4
4
  end
5
5
  end
data/lib/percy/cli.rb CHANGED
@@ -1,6 +1,63 @@
1
- require "percy/cli/version"
1
+ require 'commander'
2
+ require 'percy'
3
+ require 'percy/cli/version'
4
+ require 'percy/cli/snapshot'
2
5
 
3
6
  module Percy
4
- module Cli
7
+ class Cli
8
+ include Commander::Methods
9
+ include Percy::Cli::Snapshot
10
+
11
+ def say(*args)
12
+ $terminal.say(*args)
13
+ end
14
+
15
+ def say_error(*args)
16
+ STDERR.puts *args
17
+ end
18
+
19
+ def run
20
+ program :name, 'Percy CLI'
21
+ program :version, Percy::Cli::VERSION
22
+ program :description, 'Command-line interface for Percy (https://percy.io).'
23
+ program :help_formatter, :compact
24
+ default_command :help
25
+
26
+ command :snapshot do |c|
27
+ c.syntax = 'snapshot <root_dir>'
28
+ c.description = 'Snapshot a folder of static files.'
29
+ c.option \
30
+ '--strip_prefix PATH',
31
+ String,
32
+ 'Directory path to strip from generated URLs. Defaults to the given root directory.'
33
+ c.option \
34
+ '--repo STRING',
35
+ String,
36
+ 'Full GitHub repo slug (owner/repo-name). Defaults to the local git repo origin URL.'
37
+ c.option \
38
+ '--snapshots_regex REGEX',
39
+ String,
40
+ 'Regular expression for matching the files to snapshot. Defaults to: "\.(html|htm)$"'
41
+ c.option \
42
+ '--autoload_remote_resources',
43
+ 'Attempts to parse HTML and CSS for remote resources, fetch them, and include in ' +
44
+ 'snapshots. This can be very useful if your static website relies on remote resources.'
45
+
46
+ c.action do |args, options|
47
+ options.default autoload_remote_resources: false
48
+ raise OptionParser::MissingArgument, 'root folder path is required' if args.empty?
49
+ if args.length > 1
50
+ raise OptionParser::MissingArgument, 'only a single root folder path can be given'
51
+ end
52
+ root_dir = args.first
53
+
54
+ run_snapshot(root_dir, options.__hash__)
55
+ end
56
+ end
57
+
58
+ run!
59
+ end
5
60
  end
6
61
  end
62
+
63
+
data/percy-cli.gemspec CHANGED
@@ -18,8 +18,12 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ['lib']
20
20
 
21
+ spec.add_dependency 'commander', '~> 4'
21
22
  spec.add_dependency 'percy-client', '~> 0.2'
23
+ spec.add_dependency 'faraday', '>= 0.8'
22
24
 
23
25
  spec.add_development_dependency 'bundler', '~> 1.7'
24
26
  spec.add_development_dependency 'rake', '~> 10.0'
27
+ spec.add_development_dependency 'rspec', '~> 3'
28
+ spec.add_development_dependency 'webmock', '~> 1'
25
29
  end
@@ -0,0 +1,107 @@
1
+ require 'digest'
2
+
3
+ RSpec.describe Percy::Cli::Snapshot do
4
+ let(:root_dir) { File.expand_path('../testdata/', __FILE__) }
5
+
6
+ describe '#run_snapshot' do
7
+ xit 'snapshots a root directory of static files' do
8
+ # TODO(fotinakis): tests for this.
9
+ end
10
+ end
11
+ describe '#find_root_paths' do
12
+ it 'returns only the HTML files in the directory' do
13
+ paths = Percy::Cli.new.send(:find_root_paths, root_dir)
14
+ expect(paths).to match_array([
15
+ File.join(root_dir, 'index.html'),
16
+ File.join(root_dir, 'subdir/test.html'),
17
+ ])
18
+ end
19
+ end
20
+ describe '#find_resource_paths' do
21
+ it 'returns only the related static files in the directory' do
22
+ paths = Percy::Cli.new.send(:find_resource_paths, root_dir)
23
+ expect(paths).to match_array([
24
+ File.join(root_dir, 'css/base.css'),
25
+ File.join(root_dir, 'css/test with spaces.css'),
26
+ File.join(root_dir, 'images/jellybeans.png'),
27
+ ])
28
+ end
29
+ end
30
+ describe '#find_remote_urls' do
31
+ it 'returns remote resources referenced throughout the static website' do
32
+ root_paths = Percy::Cli.new.send(:find_root_paths, root_dir)
33
+ resource_paths = Percy::Cli.new.send(:find_resource_paths, root_dir)
34
+
35
+ remote_urls = Percy::Cli.new.send(:find_remote_urls, root_paths + resource_paths)
36
+ expect(remote_urls).to match_array([
37
+ # In index.html:
38
+ 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css',
39
+ 'http://example.com:12345/test-no-protocol.css',
40
+ 'http://example.com:12345/test-duplicate.css',
41
+ 'http://example.com:12345/test-query-param.css?v=1',
42
+ 'http://example.com:12345/test-single-quotes.css',
43
+ 'http://example.com:12345/test-diff-tag-order.css',
44
+
45
+ # In base.css:
46
+ 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css',
47
+ ])
48
+ end
49
+ end
50
+ describe '#build_resources' do
51
+ it 'returns resource objects' do
52
+ paths = [File.join(root_dir, 'css/base.css')]
53
+ resources = Percy::Cli.new.send(:build_resources, paths, root_dir)
54
+
55
+ expect(resources.length).to eq(1)
56
+ expect(resources.first.sha).to eq(Digest::SHA256.hexdigest(File.read(paths.first)))
57
+ expect(resources.first.is_root).to be_nil
58
+ expect(resources.first.content).to be_nil
59
+ expect(resources.first.path).to eq(paths.first)
60
+ end
61
+ it 'returns resource objects with is_root set if given' do
62
+ paths = [File.join(root_dir, 'index.html')]
63
+ resources = Percy::Cli.new.send(:build_resources, paths, root_dir, is_root: true)
64
+
65
+ expect(resources.length).to eq(1)
66
+ expect(resources.first.resource_url).to eq('/index.html')
67
+ expect(resources.first.sha).to eq(Digest::SHA256.hexdigest(File.read(paths.first)))
68
+ expect(resources.first.is_root).to be_truthy
69
+ expect(resources.first.content).to be_nil
70
+ expect(resources.first.path).to eq(paths.first)
71
+ end
72
+ it 'encodes the resource_url' do
73
+ paths = [File.join(root_dir, 'css/test with spaces.css')]
74
+ resources = Percy::Cli.new.send(:build_resources, paths, root_dir)
75
+
76
+ expect(resources.length).to eq(1)
77
+ expect(resources.first.resource_url).to eq('/css/test%20with%20spaces.css')
78
+ expect(resources.first.sha).to eq(Digest::SHA256.hexdigest(File.read(paths.first)))
79
+ expect(resources.first.is_root).to be_nil
80
+ expect(resources.first.content).to be_nil
81
+ expect(resources.first.path).to eq(paths.first)
82
+ end
83
+ end
84
+ describe '#build_remote_resources' do
85
+ it 'fetches the remote URLs and creates resource objects' do
86
+ urls = [
87
+ 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css',
88
+ 'http://example.com:12345/test-failure.css',
89
+ ]
90
+ stub_request(:get, 'http://example.com:12345/test-failure.css').to_return(status: 400)
91
+
92
+ resources = Percy::Cli.new.send(:build_remote_resources, urls)
93
+
94
+ expect(resources.length).to eq(1)
95
+ expect(resources[0].resource_url).to eq(urls[0])
96
+ expect(resources[0].sha).to be
97
+ expect(resources[0].is_root).to be_nil
98
+ expect(resources[0].content).to be
99
+ expect(resources[0].path).to be_nil
100
+ end
101
+ end
102
+ describe '#upload_snapshot' do
103
+ xit 'uploads the given resources to the build' do
104
+ # TODO(fotinakis): tests for this.
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,4 @@
1
+ @import url( //ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css);
2
+ @import url('/local/not-included.css');
3
+
4
+ h1 { color: red; }
@@ -0,0 +1 @@
1
+ h1 { color: blue; }
@@ -0,0 +1,19 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <title>Test Percy CLI</title>
4
+ <link href="css/base.css" rel="stylesheet" type="text/css">
5
+ <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet" type="text/css">
6
+ <link href="//example.com:12345/test-no-protocol.css" rel="stylesheet" type="text/css">
7
+ <link href='http://example.com:12345/test-single-quotes.css' rel="stylesheet" type="text/css">
8
+ <link href="http://example.com:12345/test-query-param.css?v=1" rel="stylesheet" type="text/css">
9
+
10
+ <link href="http://example.com:12345/test-duplicate.css" rel="stylesheet" type="text/css">
11
+ <link href="http://example.com:12345/test-duplicate.css" rel="stylesheet" type="text/css">
12
+
13
+ <link rel="stylesheet" type="text/css" href="http://example.com:12345/test-diff-tag-order.css">
14
+
15
+ <h1>Hello World!</h1>
16
+
17
+ Just some text, should not be included:
18
+ http://example.com/should-not-be-included.css
19
+ </html>
@@ -0,0 +1 @@
1
+ <!DOCTYPE html><html>Hello World!</html>
@@ -0,0 +1,34 @@
1
+ require 'percy/cli'
2
+ require 'webmock/rspec'
3
+
4
+ RSpec.configure do |config|
5
+ config.expect_with :rspec do |expectations|
6
+ # This option will default to `true` in RSpec 4.
7
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
8
+ end
9
+
10
+ config.mock_with :rspec do |mocks|
11
+ mocks.verify_partial_doubles = true
12
+ end
13
+
14
+ config.disable_monkey_patching!
15
+
16
+ # Run specs in random order to surface order dependencies. If you find an
17
+ # order dependency and want to debug it, you can fix the order by providing
18
+ # the seed, which is printed after each run.
19
+ # --seed 1234
20
+ config.order = :random
21
+
22
+ # Seed global randomization in this process using the `--seed` CLI option.
23
+ # Setting this allows you to use `--seed` to deterministically reproduce
24
+ # test failures related to randomization by passing the same `--seed` value
25
+ # as the one that triggered the failure.
26
+ Kernel.srand config.seed
27
+
28
+ config.before(:each) do
29
+ WebMock.disable_net_connect!(allow: [
30
+ 'maxcdn.bootstrapcdn.com',
31
+ 'ajax.googleapis.com',
32
+ ])
33
+ end
34
+ end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: percy-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Perceptual Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-06-04 00:00:00.000000000 Z
11
+ date: 2015-06-05 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: commander
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '4'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '4'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: percy-client
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -24,6 +38,20 @@ dependencies:
24
38
  - - "~>"
25
39
  - !ruby/object:Gem::Version
26
40
  version: '0.2'
41
+ - !ruby/object:Gem::Dependency
42
+ name: faraday
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0.8'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0.8'
27
55
  - !ruby/object:Gem::Dependency
28
56
  name: bundler
29
57
  requirement: !ruby/object:Gem::Requirement
@@ -52,6 +80,34 @@ dependencies:
52
80
  - - "~>"
53
81
  - !ruby/object:Gem::Version
54
82
  version: '10.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '3'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '3'
97
+ - !ruby/object:Gem::Dependency
98
+ name: webmock
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '1'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '1'
55
111
  description: ''
56
112
  email:
57
113
  - team@percy.io
@@ -61,14 +117,25 @@ extensions: []
61
117
  extra_rdoc_files: []
62
118
  files:
63
119
  - ".gitignore"
120
+ - ".rspec"
121
+ - ".travis.yml"
64
122
  - Gemfile
65
123
  - LICENSE
66
124
  - README.md
67
125
  - Rakefile
68
126
  - bin/percy
69
127
  - lib/percy/cli.rb
128
+ - lib/percy/cli/snapshot.rb
70
129
  - lib/percy/cli/version.rb
71
130
  - percy-cli.gemspec
131
+ - spec/percy/cli/snapshot_spec.rb
132
+ - spec/percy/cli/testdata/css/base.css
133
+ - spec/percy/cli/testdata/css/test with spaces.css
134
+ - spec/percy/cli/testdata/css/unrelated-no-extension
135
+ - spec/percy/cli/testdata/images/jellybeans.png
136
+ - spec/percy/cli/testdata/index.html
137
+ - spec/percy/cli/testdata/subdir/test.html
138
+ - spec/spec_helper.rb
72
139
  homepage: ''
73
140
  licenses:
74
141
  - MIT
@@ -93,5 +160,13 @@ rubygems_version: 2.2.2
93
160
  signing_key:
94
161
  specification_version: 4
95
162
  summary: Percy command-line interface
96
- test_files: []
163
+ test_files:
164
+ - spec/percy/cli/snapshot_spec.rb
165
+ - spec/percy/cli/testdata/css/base.css
166
+ - spec/percy/cli/testdata/css/test with spaces.css
167
+ - spec/percy/cli/testdata/css/unrelated-no-extension
168
+ - spec/percy/cli/testdata/images/jellybeans.png
169
+ - spec/percy/cli/testdata/index.html
170
+ - spec/percy/cli/testdata/subdir/test.html
171
+ - spec/spec_helper.rb
97
172
  has_rdoc: