reivt 1.6.0 → 1.6.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,67 +1,67 @@
1
- # An extension of our main module
2
- #
3
- # @author [brwnrclse]
4
- #
5
- module Reivt
6
- # Blueprint for Document objects
7
- #
8
- # @author [brwnrclse]
9
- #
10
- # @!attribute [rw] blob
11
- # @return [String] The contents of the file
12
- #
13
- # @!attribute [rw] content_type
14
- # @return [String] The type of content within the file
15
- #
16
- # @!attribute [rw] doc_name
17
- # @return [Array<DocumentClass>] The name of the file
18
- #
19
- # @!attribute [rw] has_diff
20
- # @return [Boolean] Whether or not the file will have a diff
21
- #
22
- class Document
23
- attr_accessor(:blob, :content_type, :doc_name, :name, :has_diff)
24
-
25
- def initialize(blob, content_type, doc_name, has_diff = false)
26
- @blob = blob
27
- @content_type = content_type
28
- @has_diff = has_diff
29
- @doc_name = doc_name
30
- end
31
-
32
- # Allows Documents objects to be compared using .eql? using their contents
33
- # and file name.
34
- #
35
- # @param other [Rev::Document] The Document to compare to
36
- #
37
- # @return [Boolean] True if equal
38
- # False if not equa
39
- #
40
- def eql?(other)
41
- self == other
42
- end
43
-
44
- # Allows Documents objects to be compared using hashes created from a
45
- # logical and (&) between the files contents and name.
46
- #
47
- # @param other [Rev::Document] The Document to compare to
48
- #
49
- # @return [Fixnum] The & between file content and name
50
- #
51
- def hash
52
- @blob.hash & @doc_name.hash
53
- end
54
-
55
- # Allows Documents objects to be compared using == using their contents
56
- # and file name.
57
- #
58
- # @param other [Rev::Document] The Document to compare to
59
- #
60
- # @return [Boolean] True if equal
61
- # False if not equa
62
- #
63
- def ==(other)
64
- @blob == other.blob && @doc_name == other.doc_name
65
- end
66
- end
67
- end
1
+ # An extension of our main module
2
+ #
3
+ # @author [brwnrclse]
4
+ #
5
+ module Reivt
6
+ # Blueprint for Document objects
7
+ #
8
+ # @author [brwnrclse]
9
+ #
10
+ # @!attribute [rw] blob
11
+ # @return [String] The contents of the file
12
+ #
13
+ # @!attribute [rw] content_type
14
+ # @return [String] The type of content within the file
15
+ #
16
+ # @!attribute [rw] doc_name
17
+ # @return [Array<DocumentClass>] The name of the file
18
+ #
19
+ # @!attribute [rw] has_diff
20
+ # @return [Boolean] Whether or not the file will have a diff
21
+ #
22
+ class Document
23
+ attr_accessor(:blob, :content_type, :doc_name, :name, :has_diff)
24
+
25
+ def initialize(blob, content_type, doc_name, has_diff = false)
26
+ @blob = blob
27
+ @content_type = content_type
28
+ @has_diff = has_diff
29
+ @doc_name = doc_name
30
+ end
31
+
32
+ # Allows Documents objects to be compared using .eql? using their contents
33
+ # and file name.
34
+ #
35
+ # @param other [Rev::Document] The Document to compare to
36
+ #
37
+ # @return [Boolean] True if equal
38
+ # False if not equa
39
+ #
40
+ def eql?(other)
41
+ self == other
42
+ end
43
+
44
+ # Allows Documents objects to be compared using hashes created from a
45
+ # logical and (&) between the files contents and name.
46
+ #
47
+ # @param other [Rev::Document] The Document to compare to
48
+ #
49
+ # @return [Fixnum] The & between file content and name
50
+ #
51
+ def hash
52
+ @blob.hash & @doc_name.hash
53
+ end
54
+
55
+ # Allows Documents objects to be compared using == using their contents
56
+ # and file name.
57
+ #
58
+ # @param other [Rev::Document] The Document to compare to
59
+ #
60
+ # @return [Boolean] True if equal
61
+ # False if not equa
62
+ #
63
+ def ==(other)
64
+ @blob == other.blob && @doc_name == other.doc_name
65
+ end
66
+ end
67
+ end
@@ -1,48 +1,52 @@
1
- # An extension of our main module
2
- #
3
- # @author [brwnrclse]
4
- #
5
- module Reivt
6
- # Custom errors for dealing with repos in revit
7
- #
8
- # @author [bwrnrclse]
9
- #
10
- class BaemptyException < IOError
11
- def initialize(msg = 'Empty File/Repo!')
12
- msg << "\n visit this url for more information: https://bitbucket.org/vaemoi/revit/wiki/Exceptions%20-%20Bare%20Repo"
13
- super(msg)
14
- end
15
- end
16
-
17
- # Custom errors for dealing with graphql in revit
18
- #
19
- # @author [bwrnrclse]
20
- #
21
- class GraphQLDataException < IOError
22
- def initialize(msg = 'GraphQL Data Exception')
23
- msg << "\n visit this url for more information: https://bitbucket.org/vaemoi/revit/wiki/Exceptions%20-%20GraphQL%20Data%20Issue"
24
- super(msg)
25
- end
26
- end
27
-
28
- # Custom errors for dealing with graphql in revit
29
- #
30
- # @author [bwrnrclse]
31
- #
32
- class GraphQLValidationException < IOError
33
- def initialize(msg = 'GraphQL Validation Exception')
34
- msg << "\n visit this url for more information: https://bitbucket.org/vaemoi/revit/wiki/Exceptions%20-%20GraphQL%20Validation%20Error"
35
- super(msg)
36
- end
37
- end
38
-
39
- # Custom error for dealing with users who aren't logged in
40
- #
41
- # @author [firaga]
42
- #
43
- class LoginException < StandardError
44
- def initialize(msg = 'LoginException - run revit login to login.')
45
- super(msg)
46
- end
47
- end
48
- end
1
+ # An extension of our main module
2
+ #
3
+ # @author [brwnrclse]
4
+ #
5
+ module Reivt
6
+ # Custom errors for dealing with repos in revit
7
+ #
8
+ # @author [bwrnrclse]
9
+ #
10
+ class BaemptyException < IOError
11
+ def initialize(msg = 'Bare or Empty repo passed!')
12
+ msg = "BaemptyException:\n" + msg + "\nVisit here for more info => " \
13
+ 'link.vaemoi.co/revitbaempty'
14
+ super(msg)
15
+ end
16
+ end
17
+
18
+ # Custom errors for dealing with graphql in revit
19
+ #
20
+ # @author [bwrnrclse]
21
+ #
22
+ class GraphQLDataException < IOError
23
+ def initialize(msg = 'Error in GraphQL API request!')
24
+ msg = "GraphQLDataException:\n" + msg + "\nVisit her for more info => " \
25
+ 'link.vaemoi.co/revitgqde'
26
+ super(msg)
27
+ end
28
+ end
29
+
30
+ # Custom errors for dealing with graphql in revit
31
+ #
32
+ # @author [bwrnrclse]
33
+ #
34
+ class GraphQLValidationException < IOError
35
+ def initialize(msg = 'Error in GraphQL Validation!')
36
+ msg = "GraphQLValidationException:\n" + msg + "\nVisit here for more " \
37
+ 'info => link.vaemoi.co/revitgqve'
38
+ super(msg)
39
+ end
40
+ end
41
+
42
+ # Custom error for dealing with users who aren't logged in
43
+ #
44
+ # @author [firaga]
45
+ #
46
+ class LoginException < StandardError
47
+ def initialize
48
+ msg = 'LoginException: Run ' + Paint['revit login', :yellow] + ' first.'
49
+ super(msg)
50
+ end
51
+ end
52
+ end
data/lib/reivt/util.rb CHANGED
@@ -1,112 +1,113 @@
1
- # rubocop:disable Metrics/CyclomaticComplexity, Metrics/AbcSize
2
- require 'rugged'
3
- require 'tempfile'
4
-
5
- # An extension of our main module
6
- #
7
- # @author [brwnrclse]
8
- #
9
- module Reivt
10
- # A collection of utility functions for use with reivt
11
- #
12
- # @author [brwnrclse]
13
- #
14
- module Util
15
- # Wrapper for creating a Document object from a path
16
- #
17
- # @param path [String] Location on the filesystem to access for files
18
- #
19
- # @param has_diff [Boolean] A flag to tell if the document has a dif
20
- #
21
- # @param spinner [TTY:Spinner] A spinner for feedback
22
- #
23
- # @return [Revit::Document] A newly created Document object
24
- #
25
- def self.doc_from_path(path, has_diff = false)
26
- blob = File.read(path).gsub("\r\n", "\n") #gsub replace CRLF line endings and converts to LF
27
- doc_name = File.basename(path)
28
- content_type = Util.ext_to_lang(File.extname(path))
29
- Document.new(blob, content_type, doc_name, has_diff)
30
- end
31
-
32
- # Creates a list of documents from files in the passed directory
33
- #
34
- # @param path [String] Location on the filesystem to access for files
35
- #
36
- # @return [Array<Reivt::Document>] List of documents from directory
37
- #
38
- def self.docs_from_dir(path)
39
- docs = []
40
-
41
- # Recursively get all file paths in a directory
42
- entries = Dir.glob("#{path}/**/*").reject { |entry| Dir.exist?(entry) }
43
-
44
- entries.each do |entry|
45
- docs.push(Util.doc_from_path(entry)) if entry != '.' && entry != '..'
46
- end
47
-
48
- docs
49
- end
50
-
51
- # Creates a list of documents from repo changelist
52
- #
53
- # @param path [String] Location on the filesystem to access for files
54
- #
55
- # @return [Array<Reivt::Document>] List of documents from repo commit
56
- #
57
- def self.docs_from_repo(path)
58
- docs = []
59
- repo = Rugged::Repository.discover(path)
60
-
61
- if repo.bare? || repo.empty?
62
- raise Reivt::BaemptyException, "Bad repo: #{path}"
63
- end
64
-
65
- commit = repo.head.target
66
- diff = commit.parents.first.diff(commit)
67
-
68
- diff.find_similar!
69
- diff.each_delta do |d|
70
- file_path = d.new_file[:path]
71
- docs.push(Util.doc_from_path("#{path}/#{file_path}", true))
72
-
73
- ofile = repo.lookup(d.old_file[:oid])
74
- nfile = repo.lookup(d.new_file[:oid])
75
- diff_file = Tempfile.new([File.basename(file_path).to_s, '.diff'])
76
-
77
- diff_file.write(ofile.diff(nfile).to_s)
78
- docs.push(Util.doc_from_path(diff_file.path))
79
- diff_file.close
80
- diff_file.unlink
81
- end
82
-
83
- docs
84
- end
85
-
86
- # Translates a file extenstion to its corresponding programming language.
87
- #
88
- # @param extension [String] The file extension to be analyzed
89
- #
90
- # @return [String] The name of the language corresponding to the extension
91
- #
92
- def self.ext_to_lang(extension)
93
- case extension.downcase
94
- when '.rb', '.gemspec' then 'ruby'
95
- when '.py', '.pyw', '.pyd', '.py3' then 'python'
96
- when '.c', '.cpp', '.h', '.hpp' then 'c/c++'
97
- when '.js', '.jsx' then 'javascript'
98
- when '.java', '.class' then 'java'
99
- when '.json' then 'json'
100
- when '.yml', '.yaml' then 'yaml'
101
- when '.xml' then 'xml'
102
- when '.txt', ' ' then 'plain text'
103
- when '.sh', '.zsh', '.bash' then 'shell script'
104
- when '.md', '.markdown' then 'markdown'
105
- when '.fountain' then 'fountain'
106
- when '.diff' then 'diff'
107
- else
108
- 'unknown'
109
- end
110
- end
111
- end
112
- end
1
+ # rubocop:disable Metrics/CyclomaticComplexity, Metrics/AbcSize
2
+ require 'rugged'
3
+ require 'tempfile'
4
+
5
+ # An extension of our main module
6
+ #
7
+ # @author [brwnrclse]
8
+ #
9
+ module Reivt
10
+ # A collection of utility functions for use with reivt
11
+ #
12
+ # @author [brwnrclse]
13
+ #
14
+ module Util
15
+ # Wrapper for creating a Document object from a path, removes all carriage
16
+ # returns from file contents
17
+ #
18
+ # @param path [String] Location on the filesystem to access for files
19
+ #
20
+ # @param has_diff [Boolean] A flag to tell if the document has a dif
21
+ #
22
+ # @param spinner [TTY:Spinner] A spinner for feedback
23
+ #
24
+ # @return [Revit::Document] A newly created Document object
25
+ #
26
+ def self.doc_from_path(path, has_diff = false)
27
+ blob = File.read(path).gsub("\r\n", "\n")
28
+ doc_name = File.basename(path)
29
+ content_type = Util.ext_to_lang(File.extname(path))
30
+ Document.new(blob, content_type, doc_name, has_diff)
31
+ end
32
+
33
+ # Creates a list of documents from files in the passed directory
34
+ #
35
+ # @param path [String] Location on the filesystem to access for files
36
+ #
37
+ # @return [Array<Reivt::Document>] List of documents from directory
38
+ #
39
+ def self.docs_from_dir(path)
40
+ docs = []
41
+
42
+ # Recursively get all file paths in a directory
43
+ entries = Dir.glob("#{path}/**/*").reject { |entry| Dir.exist?(entry) }
44
+
45
+ entries.each do |entry|
46
+ docs.push(Util.doc_from_path(entry)) if entry != '.' && entry != '..'
47
+ end
48
+
49
+ docs
50
+ end
51
+
52
+ # Creates a list of documents from repo changelist
53
+ #
54
+ # @param path [String] Location on the filesystem to access for files
55
+ #
56
+ # @return [Array<Reivt::Document>] List of documents from repo commit
57
+ #
58
+ def self.docs_from_repo(path)
59
+ docs = []
60
+ repo = Rugged::Repository.discover(path)
61
+
62
+ if repo.bare? || repo.empty?
63
+ raise Reivt::BaemptyException, "Bad repo: #{path}"
64
+ end
65
+
66
+ commit = repo.head.target
67
+ diff = commit.parents.first.diff(commit)
68
+
69
+ diff.find_similar!
70
+ diff.each_delta do |d|
71
+ file_path = d.new_file[:path]
72
+ docs.push(Util.doc_from_path("#{path}/#{file_path}", true))
73
+
74
+ ofile = repo.lookup(d.old_file[:oid])
75
+ nfile = repo.lookup(d.new_file[:oid])
76
+ diff_file = Tempfile.new([File.basename(file_path).to_s, '.diff'])
77
+
78
+ diff_file.write(ofile.diff(nfile).to_s)
79
+ docs.push(Util.doc_from_path(diff_file.path))
80
+ diff_file.close
81
+ diff_file.unlink
82
+ end
83
+
84
+ docs
85
+ end
86
+
87
+ # Translates a file extenstion to its corresponding programming language.
88
+ #
89
+ # @param extension [String] The file extension to be analyzed
90
+ #
91
+ # @return [String] The name of the language corresponding to the extension
92
+ #
93
+ def self.ext_to_lang(extension)
94
+ case extension.downcase
95
+ when '.rb', '.gemspec' then 'ruby'
96
+ when '.py', '.pyw', '.pyd', '.py3' then 'python'
97
+ when '.c', '.cpp', '.h', '.hpp' then 'c/c++'
98
+ when '.js', '.jsx' then 'javascript'
99
+ when '.java', '.class' then 'java'
100
+ when '.json' then 'json'
101
+ when '.yml', '.yaml' then 'yaml'
102
+ when '.xml' then 'xml'
103
+ when '.txt', ' ' then 'plain text'
104
+ when '.sh', '.zsh', '.bash' then 'shell script'
105
+ when '.md', '.markdown' then 'markdown'
106
+ when '.fountain' then 'fountain'
107
+ when '.diff' then 'diff'
108
+ else
109
+ 'unknown'
110
+ end
111
+ end
112
+ end
113
+ end
data/lib/reivt/version.rb CHANGED
@@ -1,3 +1,3 @@
1
- module Reivt
2
- VERSION = '1.6.0'.freeze
3
- end
1
+ module Reivt
2
+ VERSION = '1.6.1'.freeze
3
+ end
data/lib/reivt.rb CHANGED
@@ -1,42 +1,42 @@
1
- require 'fileutils'
2
- require 'logger'
3
- require 'paint'
4
- require 'pstore'
5
-
6
- # The cli tool for rev. Revit process paths passed to it in order to create new
7
- # documents to review online. Each path passed is determined to be a file,
8
- # directory or git repo. In the case of the first two "Document" objects
9
- # are created as a simple wrapper around important info we need to pass to
10
- # the Rev API. In the case of the repo, we only use files from the latest
11
- # commit (or a passed commit hash) along with diffs for each. The iops are
12
- # grouped together and the api calls are made last (aside from creating
13
- # the rev). This allows us to have UI feedback (spinnys) that'll keep the
14
- # user informed about what's going on
15
- #
16
- # @author [brwnrclse]
17
- #
18
- module Reivt
19
- FileUtils.mkdir_p("#{Dir.home}/.reivt")
20
-
21
- REIVT_STORE = PStore.new("#{Dir.home}/.reivt/reivt.pstore")
22
- LOGGER = Logger.new(STDOUT)
23
- DEVLOGGER = Logger.new("#{Dir.home}/.reivt/reivt-dev.log")
24
-
25
- DEVLOGGER.datetime_format = '%Y-%m-%d %H:%M:%S '
26
- LOGGER.formatter = proc do |severity, _, _, msg|
27
- case severity
28
- when 'ERROR' then "\n#{Paint[severity, :red]}: #{msg}\n"
29
- when 'FATAL' then "\n#{Paint[severity, :red]}L #{msg}\n"
30
- else
31
- "\n#{msg}\n"
32
- end
33
- end
34
- end
35
-
36
- require 'reivt/api'
37
- require 'reivt/auth'
38
- require 'reivt/cli'
39
- require 'reivt/document'
40
- require 'reivt/exception'
41
- require 'reivt/util'
42
- require 'reivt/version'
1
+ require 'fileutils'
2
+ require 'logger'
3
+ require 'paint'
4
+ require 'pstore'
5
+
6
+ # The cli tool for rev. Revit process paths passed to it in order to create new
7
+ # documents to review online. Each path passed is determined to be a file,
8
+ # directory or git repo. In the case of the first two "Document" objects
9
+ # are created as a simple wrapper around important info we need to pass to
10
+ # the Rev API. In the case of the repo, we only use files from the latest
11
+ # commit (or a passed commit hash) along with diffs for each. The iops are
12
+ # grouped together and the api calls are made last (aside from creating
13
+ # the rev). This allows us to have UI feedback (spinnys) that'll keep the
14
+ # user informed about what's going on
15
+ #
16
+ # @author [brwnrclse]
17
+ #
18
+ module Reivt
19
+ FileUtils.mkdir_p("#{Dir.home}/.reivt")
20
+
21
+ REIVT_STORE = PStore.new("#{Dir.home}/.reivt/reivt.pstore")
22
+ LOGGER = Logger.new(STDOUT)
23
+ DEVLOGGER = Logger.new("#{Dir.home}/.reivt/reivt-dev.log")
24
+
25
+ DEVLOGGER.datetime_format = '%Y-%m-%d %H:%M:%S '
26
+ LOGGER.formatter = proc do |severity, _, _, msg|
27
+ case severity
28
+ when 'ERROR' then "\n#{Paint[severity, :red]}: #{msg}\n"
29
+ when 'FATAL' then "\n#{Paint[severity, :red]}L #{msg}\n"
30
+ else
31
+ "\n#{msg}\n"
32
+ end
33
+ end
34
+ end
35
+
36
+ require 'reivt/api'
37
+ require 'reivt/auth'
38
+ require 'reivt/cli'
39
+ require 'reivt/document'
40
+ require 'reivt/exception'
41
+ require 'reivt/util'
42
+ require 'reivt/version'
data/revit.gemspec CHANGED
@@ -1,44 +1,44 @@
1
- # rubocop disable Metrics/BlockLength
2
- # coding: utf-8
3
-
4
- lib = File.expand_path('../lib', __FILE__)
5
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
6
- require 'reivt/version'
7
-
8
- Gem::Specification.new do |spec|
9
- spec.name = 'reivt'
10
- spec.version = Reivt::VERSION
11
- spec.authors = ['vaemoi', 'Barry Harris, Tarik Massac']
12
- spec.email = ['dev@vaemoi.co', 'brwnrclse@vaemoi.co', 'tai@vaemoi.co']
13
- spec.summary = 'NOTICE!!! - we will be moving to revit in a few days ' \
14
- "https://rubygems.org/gems/revit !!! \n\n" \
15
- ' Creating and uploading code reviews to use with rev' \
16
- ' - https://rev.vaemoi.co'
17
- spec.homepage = 'https://rev.vaemoi.co'
18
- spec.license = 'MIT'
19
-
20
- spec.files = `git ls-files -z`.split("\x0").reject do |f|
21
- f.match(%r{^(test|spec|features)/})
22
- end
23
-
24
- spec.bindir = 'exe'
25
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
26
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
27
- spec.require_paths = ['lib']
28
- spec.required_ruby_version = '>= 2.3.0'
29
-
30
- spec.add_dependency 'graphql-client', '~> 0.8.0'
31
- spec.add_dependency 'thor', '~> 0.19.4'
32
- spec.add_dependency 'tty-spinner', '~> 0.4.1'
33
-
34
- spec.add_runtime_dependency 'bcrypt', '~> 3.1', '>= 3.1.11'
35
- spec.add_runtime_dependency 'paint', '~> 2.0', '>= 2.0.0'
36
- spec.add_runtime_dependency 'sysrandom', '~> 1.0', '>= 1.0.5'
37
-
38
- spec.add_development_dependency 'bundler', '~> 1.13'
39
- spec.add_development_dependency 'pry', '~> 0.10.4'
40
- spec.add_development_dependency 'rake', '~> 10.0'
41
- spec.add_development_dependency 'rspec', '~> 3.5', '>= 3.5.0'
42
- spec.add_development_dependency 'rubocop', '~> 0.48.1'
43
- spec.add_development_dependency 'webmock', '~> 2.3', '>= 2.3.2'
44
- end
1
+ # rubocop disable Metrics/BlockLength
2
+ # coding: utf-8
3
+
4
+ lib = File.expand_path('../lib', __FILE__)
5
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
6
+ require 'reivt/version'
7
+
8
+ Gem::Specification.new do |spec|
9
+ spec.name = 'reivt'
10
+ spec.version = Reivt::VERSION
11
+ spec.authors = ['vaemoi', 'Barry Harris, Tarik Massac']
12
+ spec.email = ['dev@vaemoi.co', 'brwnrclse@vaemoi.co', 'tai@vaemoi.co']
13
+ spec.summary = 'NOTICE!!! - we will be moving to revit in a few days ' \
14
+ "https://rubygems.org/gems/revit !!! \n\n" \
15
+ ' Creating and uploading code reviews to use with rev' \
16
+ ' - https://rev.vaemoi.co'
17
+ spec.homepage = 'https://rev.vaemoi.co'
18
+ spec.license = 'MIT'
19
+
20
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
21
+ f.match(%r{^(test|spec|features)/})
22
+ end
23
+
24
+ spec.bindir = 'exe'
25
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
26
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
27
+ spec.require_paths = ['lib']
28
+ spec.required_ruby_version = '>= 2.3.0'
29
+
30
+ spec.add_dependency 'graphql-client', '~> 0.8.0'
31
+ spec.add_dependency 'thor', '~> 0.19.4'
32
+ spec.add_dependency 'tty-spinner', '~> 0.4.1'
33
+
34
+ spec.add_runtime_dependency 'bcrypt', '~> 3.1', '>= 3.1.11'
35
+ spec.add_runtime_dependency 'paint', '~> 2.0', '>= 2.0.0'
36
+ spec.add_runtime_dependency 'sysrandom', '~> 1.0', '>= 1.0.5'
37
+
38
+ spec.add_development_dependency 'bundler', '~> 1.13'
39
+ spec.add_development_dependency 'pry', '~> 0.10.4'
40
+ spec.add_development_dependency 'rake', '~> 10.0'
41
+ spec.add_development_dependency 'rspec', '~> 3.5', '>= 3.5.0'
42
+ spec.add_development_dependency 'rubocop', '~> 0.48.1'
43
+ spec.add_development_dependency 'webmock', '~> 2.3', '>= 2.3.2'
44
+ end