gemometer 0.1.1 → 1.0.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
2
  SHA1:
3
- metadata.gz: a88b54c1fd3c4e74850a4ff3f69b4cf824883469
4
- data.tar.gz: 64edee0e7aba369d5c373809ef093d33e1d697bd
3
+ metadata.gz: 3e0e83b31e07397d043d8bc055544180d39dc6e1
4
+ data.tar.gz: 547d4937ca6744f1c1dab83b34e9ab92eb3a859d
5
5
  SHA512:
6
- metadata.gz: 5937815b3152d1f6004aa4e0412966ea93382077017701b014e993b706dac9dbb7d2e8c3bd7d76689ecade4ad6b569a1d970e7a6d1ac92793c927087f62b5656
7
- data.tar.gz: 2b140d9188a4b8684ec705e323441fbc90f7c61e2e4022dbaed647305efd98723f18e4c080941008b69194c1205d99b0a8f2e12c306cd8c0b32163a9a3efc7d6
6
+ metadata.gz: 5f6dd2a31965ba486962830447618bf8243b5e3602e072c9a966778906ae0fe9b9d3a8839d6419f455b7b87a527ff7ce0f8e582372bc68f084805aa4fde53351
7
+ data.tar.gz: 920b4da60d5eb01854bbc03d41e3c01eeaaaecd33650553629098cf8b04b6a3c072a2ee6c5251f750bc4a2592436ec2e9744a3041c913358dea85c576d1284b7
data/.gitignore CHANGED
@@ -7,4 +7,4 @@
7
7
  /pkg/
8
8
  /spec/reports/
9
9
  /tmp/
10
- .ruby-version
10
+ .ruby-version
@@ -0,0 +1,43 @@
1
+ # Official language image. Look for the different tagged releases at:
2
+ # https://hub.docker.com/r/library/ruby/tags/
3
+ image: "ruby:2.3"
4
+
5
+ # Cache gems in between builds
6
+ cache:
7
+ paths:
8
+ - vendor/ruby
9
+
10
+ before_script:
11
+ - ruby -v
12
+ - gem install bundler --no-ri --no-rdoc # Bundler is not installed with the image
13
+ - bundle install --jobs $(nproc) --path vendor # Install dependencies into ./vendor/ruby
14
+
15
+ rspec:
16
+ script:
17
+ - bundle exec rake
18
+ artifacts:
19
+ paths:
20
+ - coverage/
21
+
22
+ pages:
23
+ stage: deploy
24
+ dependencies:
25
+ - rspec
26
+ script:
27
+ - mv coverage/ public/
28
+ artifacts:
29
+ paths:
30
+ - public
31
+ expire_in: 30 days
32
+ only:
33
+ - master
34
+
35
+ gemometer:
36
+ stage: deploy
37
+ allow_failure: true
38
+ script:
39
+ - bundle exec gemometer mailgun -k "$MAILGUN_KEY" -d hugomaiavieira.com -t hugomaiavieira@gmail.com
40
+ - bundle exec gemometer slack -u "$SLACK_URL"
41
+ - bundle exec gemometer hipchat -u "$HIPCHAT_URL"
42
+ only:
43
+ - master
@@ -0,0 +1,6 @@
1
+ # Changelog
2
+
3
+ # 1.0.0
4
+
5
+ - Change command line interface. The --notifier option was removed and now it is a mandatory first argument.
6
+ - Add mailgun notifier.
data/README.md CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  Gemometer is intended to be used on your continuous integration server to notify when there are new versions of the gems used on your project. It is a primitive and free [Gemnasium](https://gemnasium.com).
4
4
 
5
+ [![build status](https://gitlab.com/hugomaiavieira/_gemometer/badges/master/build.svg)](https://gitlab.com/hugomaiavieira/_gemometer/commits/master)
6
+ [![code climate](https://codeclimate.com/github/hugomaiavieira/gemometer/badges/gpa.svg)](https://codeclimate.com/github/hugomaiavieira/gemometer)
7
+ [![coverage report](https://gitlab.com/hugomaiavieira/_gemometer/badges/master/coverage.svg)](http://hugomaiavieira.gitlab.io/_gemometer)
8
+
5
9
  ## Installation
6
10
 
7
11
  Add this line to your application's Gemfile:
@@ -20,17 +24,61 @@ Or install it yourself as:
20
24
 
21
25
  ## Usage
22
26
 
23
- ### Hipchat
27
+ To get the help you can do a `gemometer --help`.
28
+
29
+ ### [Hipchat](https://www.hipchat.com)
24
30
 
25
31
  Log into hipchat.com, go to **Rooms**, select the room and go to **Integrations**, then click on "Build Your Own integration".
26
32
 
27
- $ gemometer --notifier hipchat --url https://url-from-hipchat
33
+ $ gemometer hipchat --url https://url-from-hipchat
34
+
35
+ ### [Slack](https://slack.com)
36
+
37
+ Log into slack.com, on the "Channel settings" go to **Add an app or integration** and add a "Incoming WebHooks".
38
+
39
+ $ gemometer slack --url https://url-from-slack
40
+
41
+ ### [Mailgun](https://mailgun.com)
42
+
43
+ On mailgun, your first 10,000 emails are free every month. More than enough to notify you about your outdated gems ;)
44
+
45
+ Follow the instructions to add a domain. When its state became "Active", go to the domains page ("Domains" and click on the domain name) to get the **API Key** and use like this:
46
+
47
+ $ gemometer mailgun --domain your-domain.com --key <API Key> --to some@mail.com,other@mail.com
48
+
49
+ ## Examples
50
+
51
+ ### Using on GitLab CI
52
+
53
+ Add needed [secret variables](http://docs.gitlab.com/ee/ci/variables/README.html#secret-variables) (Hipchat URL for example). Then, add this to your *.gitlab-ci.yml*:
54
+
55
+ ``` yml
56
+ gemometer:
57
+ stage: deploy
58
+ allow_failure: true
59
+ script:
60
+ - gemometer hipchat -u "$HIPCHAT_URL"
61
+ only:
62
+ - master
63
+ ```
64
+
65
+ ### Using on Codeship
66
+
67
+ On Codeship, you can add this line on your test settings:
68
+
69
+ ``` bash
70
+ if [[ "$CI_BRANCH" = 'master' ]]; then gemometer hipchat -u https://url-from-hipchat; else true; fi
71
+ ```
72
+
73
+ This will run the gemometer only on `master` branch builds.
74
+
75
+ **Note**: The most important output of your CI should be the last one, so it's a good idea to do this before the tests commands.
28
76
 
29
- ### Slack
77
+ ### Outputs
30
78
 
31
- Log into slack.com, go to **Integrations** (or Configure Integrations) and add a "Incoming WebHooks"
79
+ On Hipchat, the output will be like this:
32
80
 
33
- $ gemometer --notifier slack --url https://url-from-slack
81
+ ![Hiptchat output](/uploads/cc0861088255f9ee50c96e2c5a580271/gemometer-hipcaht.png)
34
82
 
35
83
  ## Development
36
84
 
@@ -4,4 +4,4 @@ lib = File.expand_path('../../lib', __FILE__)
4
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
5
  require 'gemometer/cli'
6
6
 
7
- Gemometer::CLI.start(ARGV)
7
+ Gemometer::CLI.start(ARGV)
@@ -11,7 +11,7 @@ Gem::Specification.new do |spec|
11
11
 
12
12
  spec.summary = %q{Verify and notify about outdated dependencies based on project's Gemfile}
13
13
  spec.description = %q{Gemometer is intended to be used on your continuous integration server to notify when there are new versions of the gems used on your project.}
14
- spec.homepage = "https://github.com/hugomaiavieira/gemometer"
14
+ spec.homepage = "https://gitlab.com/hugomaiavieira/_gemometer"
15
15
  spec.license = "MIT"
16
16
 
17
17
  spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
@@ -19,9 +19,11 @@ Gem::Specification.new do |spec|
19
19
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
20
  spec.require_paths = ["lib"]
21
21
 
22
- spec.add_development_dependency "bundler", "~> 1.10"
23
- spec.add_development_dependency "rake", "~> 10.0"
24
- spec.add_development_dependency "vcr", "~> 2.9"
22
+ spec.add_runtime_dependency "bundler", ">= 1.10"
23
+ spec.add_development_dependency "rake", "~> 11.0"
24
+ spec.add_development_dependency "vcr", "~> 3.0"
25
25
  spec.add_development_dependency "webmock", "~> 1.22"
26
26
  spec.add_development_dependency "rspec"
27
+ spec.add_development_dependency "simplecov"
28
+ spec.add_development_dependency "codeclimate-test-reporter", "~> 1.0.0"
27
29
  end
@@ -8,9 +8,10 @@ require "gemometer/parser"
8
8
  require "gemometer/notifiers/base"
9
9
  require "gemometer/notifiers/hipchat"
10
10
  require "gemometer/notifiers/slack"
11
+ require "gemometer/notifiers/mailgun"
11
12
 
12
13
  module Gemometer
13
14
  def self.notifiers
14
- (Notifiers.constants - [:Base]).map(&:downcase)
15
+ @notifiers ||= (Notifiers.constants - [:Base]).map{ |n| n.to_s.downcase }
15
16
  end
16
17
  end
@@ -5,36 +5,102 @@ require 'gemometer'
5
5
 
6
6
  module Gemometer
7
7
  class CLI
8
- NOTIFIERS = Gemometer.notifiers
9
- MANDATORY = %w[notifier url]
8
+ attr_reader :options, :notifier_name
9
+
10
+ def initialize(args)
11
+ @notifier_name = args.shift
12
+ @options = OpenStruct.new
13
+ parse_args(args)
14
+ end
10
15
 
11
16
  def self.start(args)
12
- @options = parse_args(args)
13
- notify
17
+ new(args).notify
18
+ end
19
+
20
+ def notify
21
+ begin
22
+ options.gems = gems
23
+ notifier_class.new(options.to_h).notify
24
+ rescue Gemometer::NotifyError => e
25
+ abort(e.message)
26
+ end
27
+ end
28
+
29
+ private
30
+
31
+ def parse_args(args)
32
+ begin
33
+ opt_parser.parse!(args)
34
+ verify_mandatory_options!
35
+ rescue OptionParser::InvalidArgument, OptionParser::MissingArgument, OptionParser::InvalidOption
36
+ # Friendly output when parsing fails
37
+ abort("\n#{$!}\n\n\n#{opt_parser}")
38
+ end
14
39
  end
15
40
 
16
- def self.parse_args(args)
17
- options = OpenStruct.new
41
+ def verify_mandatory_options!
42
+ missing = notifier_class.mandatory_options - options.to_h.keys
43
+ if missing.any?
44
+ abort("\nMissing options for '#{notifier_name}' notifier: #{missing.join(', ')}\n\n\n#{opt_parser}")
45
+ end
46
+ end
18
47
 
19
- opt_parser = OptionParser.new do |opts|
20
- opts.banner = 'Usage: gemometer [options]'
48
+ def gems
49
+ parser = Gemometer::Parser.new(Gemometer::System.bundle_outdated)
50
+ parser.parse
51
+ options.listed_only ? parser.gems.listed : parser.gems
52
+ end
53
+
54
+ def notifier_class
55
+ @notifier_class ||= if Gemometer.notifiers.include?(notifier_name)
56
+ Gemometer::Notifiers.const_get(notifier_name.capitalize)
57
+ else
58
+ abort("\nWrong notifier '#{notifier_name}'. Available notifiers: #{Gemometer.notifiers.join(', ')}\n\n\n#{opt_parser}")
59
+ end
60
+ end
61
+
62
+ def opt_parser
63
+ @opt_parser ||= OptionParser.new do |opts|
64
+ opts.banner = 'Usage: gemometer NOTIFIER [options]'
21
65
 
66
+ opts.separator ''
67
+ opts.separator "Available notifiers: #{Gemometer.notifiers.join(', ')}"
22
68
  opts.separator ''
23
69
  opts.separator 'Specific options:'
24
70
 
25
- opts.on('-n', '--notifier NOTIFIER', NOTIFIERS, {},
26
- 'Specify the notifier app', " (#{NOTIFIERS.join(', ')})") do |notifier|
27
- options.notifier = notifier
28
- end
29
-
30
71
  opts.on('-u', '--url URL',
31
- 'Specify the app notification url') do |url|
72
+ 'Specify the app notification url',
73
+ ' Mandatory for Slack and Hipchat.') do |url|
32
74
  options.url = url
33
75
  end
34
76
 
77
+ opts.on('-k', '--key API Key',
78
+ 'Specify the API Key',
79
+ ' Mandatory for mailgun.') do |key|
80
+ options.key = key
81
+ end
82
+
83
+ opts.on('-t', '--to EMAIL',
84
+ 'Specify the email address of the recipient(s). You can use commas to separate multiple recipients.',
85
+ ' Mandatory for mailgun.') do |to|
86
+ options.to = to
87
+ end
88
+
89
+ opts.on('-d', '--domain DOMAIN',
90
+ 'Specify the domain configured on mailgun.',
91
+ ' Mandatory for mailgun.') do |domain|
92
+ options.domain = domain
93
+ end
94
+
35
95
  opts.separator ''
36
96
  opts.separator 'Common options:'
37
97
 
98
+ opts.on('-l', '--listed-only', "Only verify gems listed directly on Gemfile (don't verify dependencies)") do
99
+ options.listed_only = true
100
+ end
101
+
102
+ opts.separator ''
103
+
38
104
  opts.on_tail('-h', '--help', 'Show this message') do
39
105
  puts opts
40
106
  exit
@@ -45,32 +111,6 @@ module Gemometer
45
111
  exit
46
112
  end
47
113
  end
48
-
49
- begin
50
- opt_parser.parse!(args)
51
- missing = MANDATORY.select{ |param| options.send(param).nil? }
52
- if missing.any?
53
- abort("\nMissing options: #{missing.join(', ')}\n\n\n#{opt_parser}")
54
- end
55
- rescue OptionParser::InvalidArgument, OptionParser::MissingArgument, OptionParser::InvalidOption
56
- # Friendly output when parsing fails
57
- abort("\n#{$!}\n\n\n#{opt_parser}")
58
- end
59
-
60
- options
61
- end
62
-
63
- def self.notify
64
- begin
65
- gems = Gemometer::Parser.new(Gemometer::System.bundle_outdated).parse
66
-
67
- Gemometer::Notifiers.const_get(@options.notifier.capitalize).new(
68
- gems: gems,
69
- url: @options.url
70
- ).notify
71
- rescue Gemometer::NotifyError => e
72
- abort(e.message)
73
- end
74
114
  end
75
115
  end
76
- end
116
+ end
@@ -0,0 +1,23 @@
1
+ module Gemometer
2
+ class Gem
3
+ attr_reader :name, :newest, :installed, :requested, :group
4
+
5
+ def initialize(attrs)
6
+ attrs.each { |key, value| instance_variable_set("@#{key}", value) }
7
+ end
8
+
9
+ def message_line
10
+ "(newest #{newest}, installed #{installed}#{requested_msg})#{group_msg}"
11
+ end
12
+
13
+ private
14
+
15
+ def requested_msg
16
+ requested ? ", requested: #{requested}" : ""
17
+ end
18
+
19
+ def group_msg
20
+ group ? " in group \"#{group}\"" : ""
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,7 @@
1
+ module Gemometer
2
+ class GemArray < Array
3
+ def listed
4
+ self.class.new(select(&:group))
5
+ end
6
+ end
7
+ end
@@ -6,35 +6,73 @@ require 'gemometer/errors'
6
6
  module Gemometer
7
7
  module Notifiers
8
8
  class Base
9
- attr_reader :gems, :url
9
+ attr_reader :gems, :url, :key, :username
10
10
 
11
11
  def initialize(opts)
12
- @gems = opts[:gems]
13
- @url = opts[:url]
12
+ @gems = opts[:gems]
13
+ @url = opts[:url]
14
+ @key = opts[:key]
15
+ @username = opts[:username]
14
16
  end
15
17
 
16
18
  def notify
17
19
  return false if gems.empty?
20
+ response = make_request
21
+ %w(204 200).include?(response.code) || raise(Gemometer::NotifyError.new("#{response.code}: #{response.message}"))
22
+ end
18
23
 
19
- uri = URI(url)
24
+ def self.mandatory_options
25
+ raise NotImplementedError
26
+ end
20
27
 
21
- http = Net::HTTP.new(uri.host, uri.port)
22
- http.use_ssl = (uri.scheme == "https")
28
+ private
23
29
 
24
- req = Net::HTTP::Post.new(uri)
25
- req.content_type = 'application/json'
30
+ def make_request
31
+ setup_auth
32
+ setup_data
33
+ http.request(request)
34
+ end
26
35
 
27
- res = http.request(req, JSON.generate(data))
36
+ def setup_auth
37
+ request.basic_auth(username, key) if require_auth?
38
+ end
28
39
 
29
- %w(204 200).include?(res.code) ||
30
- raise(Gemometer::NotifyError.new("#{res.code}: #{res.message}"))
40
+ def setup_data
41
+ if json?
42
+ request.content_type = 'application/json'
43
+ request.body = JSON.generate(data)
44
+ else
45
+ request.set_form_data(data)
46
+ end
31
47
  end
32
48
 
33
- private
49
+ def uri
50
+ @uri ||= URI(url)
51
+ end
34
52
 
35
- def data
36
- raise NotImplementedError
53
+ def http
54
+ @http ||= begin
55
+ _http = Net::HTTP.new(uri.host, uri.port)
56
+ _http.use_ssl = (uri.scheme == "https")
57
+ _http
37
58
  end
59
+ end
60
+
61
+ def request
62
+ @request ||= Net::HTTP::Post.new(uri)
63
+ end
64
+
65
+ def data
66
+ raise NotImplementedError
67
+ end
68
+
69
+ def json?
70
+ true
71
+ end
72
+
73
+ def require_auth?
74
+ false
75
+ end
38
76
  end
39
77
  end
40
- end
78
+ end
@@ -3,21 +3,24 @@ module Gemometer
3
3
  module Notifiers
4
4
  class Hipchat < Base
5
5
  def message
6
- html = '<p>Outdated gems:</p><ul>'
7
- gems.each do |g|
8
- html += "<li><a href='https://rubygems.org/gems/#{g[:name]}'>#{g[:name]}</a> (newest #{g[:newest]}, installed #{g[:installed]}"
9
- html += g[:requested] ? ", requested: #{g[:requested]})" : ")"
10
- html += " in group \"#{g[:group]}\"" if g[:group]
11
- html += "</li>"
12
- end
13
- html += '</ul>'
6
+ msg = '<p>Outdated gems:</p><ul>'
7
+ gems.each { |g| msg += "<li>#{ruby_gems_link(g.name)} #{g.message_line}</li>" }
8
+ msg += '</ul>'
9
+ end
10
+
11
+ def self.mandatory_options
12
+ [:url]
14
13
  end
15
14
 
16
15
  private
17
16
 
18
- def data
19
- { message: message }
20
- end
17
+ def data
18
+ { message: message }
19
+ end
20
+
21
+ def ruby_gems_link(name)
22
+ "<a href='https://rubygems.org/gems/#{name}'>#{name}</a>"
23
+ end
21
24
  end
22
25
  end
23
- end
26
+ end
@@ -0,0 +1,60 @@
1
+ # https://documentation.mailgun.com/api-sending.html
2
+ module Gemometer
3
+ module Notifiers
4
+ class Mailgun < Base
5
+ attr_reader :domain, :to
6
+
7
+ def initialize(opts)
8
+ @domain = opts[:domain]
9
+ @to = opts[:to]
10
+ super(opts)
11
+ end
12
+
13
+ def self.mandatory_options
14
+ [:domain, :to, :key]
15
+ end
16
+
17
+ def message
18
+ msg = '<p>Outdated gems:</p><ul>'
19
+ gems.each { |g| msg += "<li>#{ruby_gems_link(g.name)} #{g.message_line}</li>" }
20
+ msg += '</ul>'
21
+ end
22
+
23
+ def username
24
+ 'api'
25
+ end
26
+
27
+ def url
28
+ "https://api.mailgun.net/v3/#{domain}/messages"
29
+ end
30
+
31
+ private
32
+
33
+ def data
34
+ {
35
+ from: sender,
36
+ to: to,
37
+ html: message,
38
+ subject: 'Some gems are Outdated'
39
+ }
40
+ end
41
+
42
+ def sender
43
+ "Gemometer <gemometer@#{domain}>"
44
+ end
45
+
46
+ def ruby_gems_link(name)
47
+ "<a href='https://rubygems.org/gems/#{name}'>#{name}</a>"
48
+ end
49
+
50
+ def json?
51
+ false
52
+ end
53
+
54
+ def require_auth?
55
+ true
56
+ end
57
+ end
58
+ end
59
+ end
60
+
@@ -9,26 +9,30 @@ module Gemometer
9
9
  super(opts)
10
10
  end
11
11
 
12
+ def self.mandatory_options
13
+ [:url]
14
+ end
15
+
12
16
  def message
13
- html = "Outdated gems:\n"
14
- gems.each do |g|
15
- html += "\n <https://rubygems.org/gems/#{g[:name]}|#{g[:name]}> (newest #{g[:newest]}, installed #{g[:installed]}"
16
- html += g[:requested] ? ", requested: #{g[:requested]})" : ")"
17
- html += " in group \"#{g[:group]}\"" if g[:group]
18
- end
19
- html += "\n-"
17
+ msg = "Outdated gems:\n"
18
+ gems.each { |g| msg += "\n #{ruby_gems_link(g.name)} #{g.message_line}" }
19
+ msg += "\n-"
20
20
  end
21
21
 
22
22
  private
23
23
 
24
- def data
25
- {
26
- text: message,
27
- channel: channel,
28
- username: 'Gemometer'
29
- # icon_url: "https://TODO:add-icon.png"
30
- }.reject{ |k,v| v.nil? }
31
- end
24
+ def data
25
+ {
26
+ text: message,
27
+ channel: channel,
28
+ username: 'Gemometer'
29
+ # icon_url: "https://TODO:add-icon.png"
30
+ }.reject{ |_, v| v.nil? }
31
+ end
32
+
33
+ def ruby_gems_link(name)
34
+ "<https://rubygems.org/gems/#{name}|#{name}>"
32
35
  end
36
+ end
33
37
  end
34
- end
38
+ end
@@ -0,0 +1,58 @@
1
+ require 'net/smtp'
2
+
3
+ module Gemometer
4
+ module Notifiers
5
+ class Smtp
6
+ attr_reader :gems, :to, :sender, :server, :port, :domain, :username, :password, :scheme
7
+
8
+ def initialize(opts)
9
+ @gems = opts[:gems]
10
+ @to = opts[:to]
11
+ @sender = ENV['SMTP_SENDER']
12
+ @server = ENV['SMTP_SERVER']
13
+ @port = ENV['SMTP_PORT'] || SMTP.default_port
14
+ @domain = ENV['SMTP_DOMAIN']
15
+ @username = ENV['SMTP_USERNAME']
16
+ @password = ENV['SMTP_PASSWORD']
17
+ @scheme = ENV['SMTP_AUTH_SCHEME'] || :plain # :plain, :login, or :cram_md5
18
+ end
19
+
20
+ def notify
21
+
22
+ Net::SMTP.start(server, port, domain, username, password, scheme) do |smtp|
23
+ smtp.send_message(message, sender, to)
24
+ end
25
+ end
26
+
27
+ def message
28
+ header + body
29
+ end
30
+
31
+ def header
32
+ %{
33
+ From: Gemometer <#{sender}>
34
+ To: #{to.join(",")}
35
+ MIME-Version: 1.0
36
+ Content-Type: text/html; charset=utf-8
37
+ Subject: Some gems are Outdated
38
+ }
39
+ end
40
+
41
+ def to
42
+ @to.gsub("\s", '').split(",") if @to
43
+ end
44
+
45
+ def body
46
+ msg = '<p>Outdated gems:</p><ul>'
47
+ gems.each { |g| msg += "<li>#{ruby_gems_link(g.name)} #{g.message_line}</li>" }
48
+ msg += '</ul>'
49
+ end
50
+
51
+ private
52
+
53
+ def ruby_gems_link(name)
54
+ "<a href='https://rubygems.org/gems/#{name}'>#{name}</a>"
55
+ end
56
+ end
57
+ end
58
+ end
@@ -1,19 +1,23 @@
1
+ require_relative './gem_array'
2
+ require_relative './gem'
3
+
1
4
  module Gemometer
2
5
  class Parser
3
6
  REGEX=%r(\* ([^\s]+) \(newest ([0-9|\.]+), installed ([0-9|\.]+)[\)|,](?: requested (.*[0-9|\.]+)\) in group "(\w+)")?)
4
7
 
8
+ attr_reader :gems
9
+
5
10
  def initialize(str)
6
11
  @str = str
7
- @gems = []
12
+ @gems = GemArray.new
8
13
  end
9
14
 
10
15
  def parse
11
16
  if @gems.empty?
12
17
  @str.scan(REGEX) do |a, b, c, d, e|
13
- @gems << { name: a, newest: b, installed: c, requested: d, group: e }
18
+ @gems << Gem.new(name: a, newest: b, installed: c, requested: d, group: e)
14
19
  end
15
20
  end
16
- @gems
17
21
  end
18
22
  end
19
23
  end
@@ -1,3 +1,3 @@
1
1
  module Gemometer
2
- VERSION = "0.1.1"
2
+ VERSION = "1.0.0"
3
3
  end
metadata CHANGED
@@ -1,27 +1,27 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gemometer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hugo Maia Vieira
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-10-28 00:00:00.000000000 Z
11
+ date: 2017-01-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '1.10'
20
- type: :development
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
26
  version: '1.10'
27
27
  - !ruby/object:Gem::Dependency
@@ -30,28 +30,28 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '10.0'
33
+ version: '11.0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '10.0'
40
+ version: '11.0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: vcr
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '2.9'
47
+ version: '3.0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '2.9'
54
+ version: '3.0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: webmock
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -80,6 +80,34 @@ dependencies:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: simplecov
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: codeclimate-test-reporter
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 1.0.0
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 1.0.0
83
111
  description: Gemometer is intended to be used on your continuous integration server
84
112
  to notify when there are new versions of the gems used on your project.
85
113
  email:
@@ -90,8 +118,10 @@ extensions: []
90
118
  extra_rdoc_files: []
91
119
  files:
92
120
  - ".gitignore"
121
+ - ".gitlab-ci.yml"
93
122
  - ".rspec"
94
123
  - ".travis.yml"
124
+ - CHANGELOG.md
95
125
  - CODE_OF_CONDUCT.md
96
126
  - Gemfile
97
127
  - LICENSE.txt
@@ -104,13 +134,17 @@ files:
104
134
  - lib/gemometer.rb
105
135
  - lib/gemometer/cli.rb
106
136
  - lib/gemometer/errors.rb
137
+ - lib/gemometer/gem.rb
138
+ - lib/gemometer/gem_array.rb
107
139
  - lib/gemometer/notifiers/base.rb
108
140
  - lib/gemometer/notifiers/hipchat.rb
141
+ - lib/gemometer/notifiers/mailgun.rb
109
142
  - lib/gemometer/notifiers/slack.rb
143
+ - lib/gemometer/notifiers/smtp.rb
110
144
  - lib/gemometer/parser.rb
111
145
  - lib/gemometer/system.rb
112
146
  - lib/gemometer/version.rb
113
- homepage: https://github.com/hugomaiavieira/gemometer
147
+ homepage: https://gitlab.com/hugomaiavieira/_gemometer
114
148
  licenses:
115
149
  - MIT
116
150
  metadata: {}
@@ -130,7 +164,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
130
164
  version: '0'
131
165
  requirements: []
132
166
  rubyforge_project:
133
- rubygems_version: 2.4.5.1
167
+ rubygems_version: 2.5.2
134
168
  signing_key:
135
169
  specification_version: 4
136
170
  summary: Verify and notify about outdated dependencies based on project's Gemfile