danger-gem_changes 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: b90abf7d1a201531f08f7af72190e138cf14c5f4f47dd238145fa9ba47b8f70e
4
+ data.tar.gz: e2621d8f5b4ab6fd712c0b664e93922157f213f5260d9803faf85bec77056a79
5
+ SHA512:
6
+ metadata.gz: 5cad6310e609b0fb0278ac24b8e03b7057481d7799acdf33c5d1cac77e0270089b660625549bc7f51ee08a72ecb257a74b69885233dc2959470d76a9080c6e17
7
+ data.tar.gz: 92a1e2d83779561eafa148d4eab18c2ae618750a178e50a5a4b0c8d6726b63906c64a47d385bffe0e5e11a1d5dc000faa7473a64979abec90d4b0f2a25108038
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ .DS_Store
2
+ pkg
3
+ .idea/
4
+ .yardoc
data/.rubocop.yml ADDED
@@ -0,0 +1,153 @@
1
+ # Defaults can be found here: https://github.com/bbatsov/rubocop/blob/master/config/default.yml
2
+
3
+ # If you don't like these settings, just delete this file :)
4
+
5
+ require:
6
+ - rubocop-rake
7
+ - rubocop-rspec
8
+
9
+ AllCops:
10
+ TargetRubyVersion: 2.7
11
+ NewCops: enable
12
+
13
+ Style/StringLiterals:
14
+ EnforcedStyle: double_quotes
15
+ Enabled: true
16
+
17
+ # kind_of? is a good way to check a type
18
+ Style/ClassCheck:
19
+ EnforcedStyle: kind_of?
20
+
21
+ # specs sometimes have useless assignments, which is fine
22
+ Lint/UselessAssignment:
23
+ Exclude:
24
+ - '**/spec/**/*'
25
+
26
+ # We could potentially enable the 2 below:
27
+ Layout/FirstHashElementIndentation:
28
+ Enabled: false
29
+
30
+ Layout/HashAlignment:
31
+ Enabled: false
32
+
33
+ # HoundCI doesn't like this rule
34
+ Layout/DotPosition:
35
+ Enabled: false
36
+
37
+ # We allow !! as it's an easy way to convert ot boolean
38
+ Style/DoubleNegation:
39
+ Enabled: false
40
+
41
+ # Cop supports --auto-correct.
42
+ Lint/UnusedBlockArgument:
43
+ Enabled: false
44
+
45
+ # We want to allow class Fastlane::Class
46
+ Style/ClassAndModuleChildren:
47
+ Enabled: false
48
+
49
+ Metrics/AbcSize:
50
+ Max: 60
51
+
52
+ # The %w might be confusing for new users
53
+ Style/WordArray:
54
+ MinSize: 19
55
+
56
+ # raise and fail are both okay
57
+ Style/SignalException:
58
+ Enabled: false
59
+
60
+ # Better too much 'return' than one missing
61
+ Style/RedundantReturn:
62
+ Enabled: false
63
+
64
+ # Having if in the same line might not always be good
65
+ Style/IfUnlessModifier:
66
+ Enabled: false
67
+
68
+ # and and or is okay
69
+ Style/AndOr:
70
+ Enabled: false
71
+
72
+ # Configuration parameters: CountComments.
73
+ Metrics/ClassLength:
74
+ Max: 350
75
+
76
+ Metrics/CyclomaticComplexity:
77
+ Max: 17
78
+
79
+ # Configuration parameters: AllowURI, URISchemes.
80
+ Layout/LineLength:
81
+ Max: 370
82
+
83
+ # Configuration parameters: CountKeywordArgs.
84
+ Metrics/ParameterLists:
85
+ Max: 10
86
+
87
+ Metrics/PerceivedComplexity:
88
+ Max: 18
89
+
90
+ # Sometimes it's easier to read without guards
91
+ Style/GuardClause:
92
+ Enabled: false
93
+
94
+ # something = if something_else
95
+ # that's confusing
96
+ Style/ConditionalAssignment:
97
+ Enabled: false
98
+
99
+ # Better to have too much self than missing a self
100
+ Style/RedundantSelf:
101
+ Enabled: false
102
+
103
+ Metrics/MethodLength:
104
+ Max: 60
105
+
106
+ # We're not there yet
107
+ Style/Documentation:
108
+ Enabled: false
109
+
110
+ # Adds complexity
111
+ Style/IfInsideElse:
112
+ Enabled: false
113
+
114
+ # danger specific
115
+
116
+ Style/BlockComments:
117
+ Enabled: false
118
+
119
+ Layout/MultilineMethodCallIndentation:
120
+ EnforcedStyle: indented
121
+
122
+ # FIXME: 25
123
+ Metrics/BlockLength:
124
+ Max: 345
125
+ Exclude:
126
+ - "**/*_spec.rb"
127
+
128
+ Style/MixinGrouping:
129
+ Enabled: false
130
+
131
+ Naming/FileName:
132
+ Enabled: false
133
+
134
+ Layout/HeredocIndentation:
135
+ Enabled: false
136
+
137
+ Style/SpecialGlobalVars:
138
+ Enabled: false
139
+
140
+ Style/PercentLiteralDelimiters:
141
+ PreferredDelimiters:
142
+ "%": ()
143
+ "%i": ()
144
+ "%q": ()
145
+ "%Q": ()
146
+ "%r": "{}"
147
+ "%s": ()
148
+ "%w": ()
149
+ "%W": ()
150
+ "%x": ()
151
+
152
+ Security/YAMLLoad:
153
+ Enabled: false
data/.travis.yml ADDED
@@ -0,0 +1,10 @@
1
+ language: ruby
2
+ cache:
3
+ directories:
4
+ - bundle
5
+
6
+ rvm:
7
+ - 2.7
8
+
9
+ script:
10
+ - bundle exec rake spec
data/Gemfile ADDED
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ # Specify your gem's dependencies in danger-gems.gemspec
6
+ gemspec
7
+
8
+ # General ruby development
9
+ gem "bundler"
10
+ gem "rake"
11
+
12
+ # Testing support
13
+ gem "rspec"
14
+
15
+ # Linting code and docs
16
+ gem "rubocop"
17
+ gem "rubocop-rake"
18
+ gem "rubocop-rspec"
19
+ gem "yard"
20
+
21
+ # Makes testing easy via `bundle exec guard`
22
+ gem "guard"
23
+ gem "guard-rspec"
24
+
25
+ # If you want to work on older builds of ruby
26
+ gem "listen"
27
+
28
+ gem "debug"
data/Gemfile.lock ADDED
@@ -0,0 +1,200 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ danger-gem_changes (0.0.1)
5
+ danger-plugin-api (~> 1.0)
6
+ nokogiri (~> 1.0)
7
+ open-uri (~> 0.4)
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ addressable (2.8.6)
13
+ public_suffix (>= 2.0.2, < 6.0)
14
+ ast (2.4.2)
15
+ base64 (0.2.0)
16
+ claide (1.1.0)
17
+ claide-plugins (0.9.2)
18
+ cork
19
+ nap
20
+ open4 (~> 1.3)
21
+ coderay (1.1.3)
22
+ colored2 (3.1.2)
23
+ cork (0.3.0)
24
+ colored2 (~> 3.1)
25
+ danger (9.4.3)
26
+ claide (~> 1.0)
27
+ claide-plugins (>= 0.9.2)
28
+ colored2 (~> 3.1)
29
+ cork (~> 0.1)
30
+ faraday (>= 0.9.0, < 3.0)
31
+ faraday-http-cache (~> 2.0)
32
+ git (~> 1.13)
33
+ kramdown (~> 2.3)
34
+ kramdown-parser-gfm (~> 1.0)
35
+ no_proxy_fix
36
+ octokit (>= 4.0)
37
+ terminal-table (>= 1, < 4)
38
+ danger-plugin-api (1.0.0)
39
+ danger (> 2.0)
40
+ date (3.3.4)
41
+ debug (1.9.2)
42
+ irb (~> 1.10)
43
+ reline (>= 0.3.8)
44
+ diff-lcs (1.5.1)
45
+ faraday (2.9.0)
46
+ faraday-net_http (>= 2.0, < 3.2)
47
+ faraday-http-cache (2.5.1)
48
+ faraday (>= 0.8)
49
+ faraday-net_http (3.1.0)
50
+ net-http
51
+ ffi (1.16.3)
52
+ formatador (1.1.0)
53
+ git (1.19.1)
54
+ addressable (~> 2.8)
55
+ rchardet (~> 1.8)
56
+ guard (2.18.1)
57
+ formatador (>= 0.2.4)
58
+ listen (>= 2.7, < 4.0)
59
+ lumberjack (>= 1.0.12, < 2.0)
60
+ nenv (~> 0.1)
61
+ notiffany (~> 0.0)
62
+ pry (>= 0.13.0)
63
+ shellany (~> 0.0)
64
+ thor (>= 0.18.1)
65
+ guard-compat (1.2.1)
66
+ guard-rspec (4.7.3)
67
+ guard (~> 2.1)
68
+ guard-compat (~> 1.1)
69
+ rspec (>= 2.99.0, < 4.0)
70
+ io-console (0.7.2)
71
+ irb (1.13.1)
72
+ rdoc (>= 4.0.0)
73
+ reline (>= 0.4.2)
74
+ json (2.7.2)
75
+ kramdown (2.4.0)
76
+ rexml
77
+ kramdown-parser-gfm (1.1.0)
78
+ kramdown (~> 2.0)
79
+ language_server-protocol (3.17.0.3)
80
+ listen (3.9.0)
81
+ rb-fsevent (~> 0.10, >= 0.10.3)
82
+ rb-inotify (~> 0.9, >= 0.9.10)
83
+ lumberjack (1.2.10)
84
+ method_source (1.1.0)
85
+ nap (1.1.0)
86
+ nenv (0.3.0)
87
+ net-http (0.4.1)
88
+ uri
89
+ no_proxy_fix (0.1.2)
90
+ nokogiri (1.16.4-arm64-darwin)
91
+ racc (~> 1.4)
92
+ notiffany (0.1.3)
93
+ nenv (~> 0.1)
94
+ shellany (~> 0.0)
95
+ octokit (8.1.0)
96
+ base64
97
+ faraday (>= 1, < 3)
98
+ sawyer (~> 0.9)
99
+ open-uri (0.4.1)
100
+ stringio
101
+ time
102
+ uri
103
+ open4 (1.3.4)
104
+ parallel (1.24.0)
105
+ parser (3.3.1.0)
106
+ ast (~> 2.4.1)
107
+ racc
108
+ pry (0.14.2)
109
+ coderay (~> 1.1)
110
+ method_source (~> 1.0)
111
+ psych (5.1.2)
112
+ stringio
113
+ public_suffix (5.0.5)
114
+ racc (1.7.3)
115
+ rainbow (3.1.1)
116
+ rake (13.2.1)
117
+ rb-fsevent (0.11.2)
118
+ rb-inotify (0.10.1)
119
+ ffi (~> 1.0)
120
+ rchardet (1.8.0)
121
+ rdoc (6.6.3.1)
122
+ psych (>= 4.0.0)
123
+ regexp_parser (2.9.0)
124
+ reline (0.5.6)
125
+ io-console (~> 0.5)
126
+ rexml (3.2.6)
127
+ rspec (3.13.0)
128
+ rspec-core (~> 3.13.0)
129
+ rspec-expectations (~> 3.13.0)
130
+ rspec-mocks (~> 3.13.0)
131
+ rspec-core (3.13.0)
132
+ rspec-support (~> 3.13.0)
133
+ rspec-expectations (3.13.0)
134
+ diff-lcs (>= 1.2.0, < 2.0)
135
+ rspec-support (~> 3.13.0)
136
+ rspec-mocks (3.13.1)
137
+ diff-lcs (>= 1.2.0, < 2.0)
138
+ rspec-support (~> 3.13.0)
139
+ rspec-support (3.13.1)
140
+ rubocop (1.63.5)
141
+ json (~> 2.3)
142
+ language_server-protocol (>= 3.17.0)
143
+ parallel (~> 1.10)
144
+ parser (>= 3.3.0.2)
145
+ rainbow (>= 2.2.2, < 4.0)
146
+ regexp_parser (>= 1.8, < 3.0)
147
+ rexml (>= 3.2.5, < 4.0)
148
+ rubocop-ast (>= 1.31.1, < 2.0)
149
+ ruby-progressbar (~> 1.7)
150
+ unicode-display_width (>= 2.4.0, < 3.0)
151
+ rubocop-ast (1.31.3)
152
+ parser (>= 3.3.1.0)
153
+ rubocop-capybara (2.20.0)
154
+ rubocop (~> 1.41)
155
+ rubocop-factory_bot (2.25.1)
156
+ rubocop (~> 1.41)
157
+ rubocop-rake (0.6.0)
158
+ rubocop (~> 1.0)
159
+ rubocop-rspec (2.29.2)
160
+ rubocop (~> 1.40)
161
+ rubocop-capybara (~> 2.17)
162
+ rubocop-factory_bot (~> 2.22)
163
+ rubocop-rspec_rails (~> 2.28)
164
+ rubocop-rspec_rails (2.28.3)
165
+ rubocop (~> 1.40)
166
+ ruby-progressbar (1.13.0)
167
+ sawyer (0.9.2)
168
+ addressable (>= 2.3.5)
169
+ faraday (>= 0.17.3, < 3)
170
+ shellany (0.0.1)
171
+ stringio (3.1.0)
172
+ terminal-table (3.0.2)
173
+ unicode-display_width (>= 1.1.1, < 3)
174
+ thor (1.3.1)
175
+ time (0.3.0)
176
+ date
177
+ unicode-display_width (2.5.0)
178
+ uri (0.13.0)
179
+ yard (0.9.36)
180
+
181
+ PLATFORMS
182
+ arm64-darwin-22
183
+ ruby
184
+
185
+ DEPENDENCIES
186
+ bundler
187
+ danger-gem_changes!
188
+ debug
189
+ guard
190
+ guard-rspec
191
+ listen
192
+ rake
193
+ rspec
194
+ rubocop
195
+ rubocop-rake
196
+ rubocop-rspec
197
+ yard
198
+
199
+ BUNDLED WITH
200
+ 2.5.6
data/Guardfile ADDED
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ # A guardfile for making Danger Plugins
4
+ # For more info see https://github.com/guard/guard#readme
5
+
6
+ # To run, use `bundle exec guard`.
7
+
8
+ guard :rspec, cmd: "bundle exec rspec" do
9
+ require "guard/rspec/dsl"
10
+ dsl = Guard::RSpec::Dsl.new(self)
11
+
12
+ # RSpec files
13
+ rspec = dsl.rspec
14
+ watch(rspec.spec_helper) { rspec.spec_dir }
15
+ watch(rspec.spec_support) { rspec.spec_dir }
16
+ watch(rspec.spec_files)
17
+
18
+ # Ruby files
19
+ ruby = dsl.ruby
20
+ dsl.watch_spec_files_for(ruby.lib_files)
21
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2024 John DeSilva <john@aesthetikx.info>
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,20 @@
1
+ # danger-gem_changes
2
+
3
+ A description of danger-gem_changes.
4
+
5
+ ## Installation
6
+
7
+ $ gem install danger-gem_changes
8
+
9
+ ## Usage
10
+
11
+ Methods and attributes from this plugin are available in
12
+ your `Dangerfile` under the `gem_changes` namespace.
13
+
14
+ ## Development
15
+
16
+ 1. Clone this repo
17
+ 2. Run `bundle install` to setup dependencies.
18
+ 3. Run `bundle exec rake spec` to run the tests.
19
+ 4. Use `bundle exec guard` to automatically have tests run as you make changes.
20
+ 5. Make your changes.
data/Rakefile ADDED
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+ require "rubocop/rake_task"
6
+
7
+ RSpec::Core::RakeTask.new(:specs)
8
+
9
+ task :default do
10
+ Rake::Task["specs"].invoke
11
+ Rake::Task["rubocop"].invoke
12
+ Rake::Task["spec_docs"].invoke
13
+ end
14
+
15
+ desc "Run RuboCop on the lib/specs directory"
16
+ RuboCop::RakeTask.new(:rubocop) do |task|
17
+ task.patterns = ["lib/**/*.rb", "spec/**/*.rb"]
18
+ end
19
+
20
+ desc "Ensure that the plugin passes `danger plugins lint`"
21
+ task :spec_docs do
22
+ sh "bundle exec danger plugins lint"
23
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path("lib", __dir__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require "gem_changes/version"
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = "danger-gem_changes"
9
+ spec.version = GemChanges::VERSION
10
+ spec.authors = ["John DeSilva"]
11
+ spec.email = ["john@aesthetikx.info"]
12
+ spec.description = "A danger plugin for helping review gem depencency changes."
13
+ spec.summary = spec.description
14
+ spec.homepage = "https://github.com/Aesthetikx/danger-gem_changes"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files`.split($/)
18
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.metadata["rubygems_mfa_required"] = "true"
22
+ spec.required_ruby_version = ">= 2.7"
23
+ spec.add_runtime_dependency "danger-plugin-api", "~> 1.0"
24
+ spec.add_runtime_dependency "nokogiri", "~> 1.0"
25
+ spec.add_runtime_dependency "open-uri", "~> 0.4"
26
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "gem_changes"
4
+
5
+ module Danger
6
+ # This is your plugin class. Any attributes or methods you expose here will
7
+ # be available from within your Dangerfile.
8
+ #
9
+ # To be published on the Danger plugins site, you will need to have
10
+ # the public interface documented. Danger uses [YARD](http://yardoc.org/)
11
+ # for generating documentation from your plugin source, and you can verify
12
+ # by running `danger plugins lint` or `bundle exec rake spec`.
13
+ #
14
+ # You should replace these comments with a public description of your library.
15
+ #
16
+ # @example Ensure people are well warned about merging on Mondays
17
+ #
18
+ # my_plugin.warn_on_mondays
19
+ #
20
+ # @see Aesthetikx/danger-gems
21
+ # @tags monday, weekends, time, rattata
22
+ #
23
+ class DangerGemChanges < Plugin
24
+ def summarize_changes(changes: self.changes, title: "Gemfile.lock Changes")
25
+ return if changes.empty?
26
+
27
+ string = "### #{title}\n"
28
+
29
+ string += GemChanges::SummaryTable.new(changes: changes).markdown
30
+
31
+ markdown string
32
+ end
33
+
34
+ def changes
35
+ GemChanges::Gemfile.changes(git: git)
36
+ end
37
+
38
+ def additions
39
+ changes.select(&:addition?)
40
+ end
41
+
42
+ def removals
43
+ changes.select(&:removal?)
44
+ end
45
+
46
+ def upgrades
47
+ changes.select(&:upgrade?)
48
+ end
49
+
50
+ def downgrades
51
+ changes.select(&:downgrade?)
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GemChanges
4
+ Change = Struct.new(:gem, :from, :to, keyword_init: true) do
5
+ def initialize(gem:, from:, to:)
6
+ super(gem: gem, from: Version(from), to: Version(to))
7
+ end
8
+
9
+ def change?
10
+ to and from
11
+ end
12
+
13
+ def addition?
14
+ from.nil?
15
+ end
16
+
17
+ def removal?
18
+ to.nil?
19
+ end
20
+
21
+ def upgrade?
22
+ change? and to > from
23
+ end
24
+
25
+ def downgrade?
26
+ change? and to < from
27
+ end
28
+
29
+ private
30
+
31
+ def Version(something)
32
+ case something
33
+ when nil then nil
34
+ when ::Gem::Version then something
35
+ else ::Gem::Version.new(something)
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "nokogiri"
4
+ require "open-uri"
5
+
6
+ module GemChanges
7
+ Gem = Struct.new(:name, keyword_init: true) do
8
+ def rubygems_uri
9
+ "https://rubygems.org/gems/#{name}"
10
+ end
11
+
12
+ def changelog_uri
13
+ rubygems_document.css("a#changelog").first["href"]
14
+ rescue StandardError
15
+ nil
16
+ end
17
+
18
+ def source_code_uri
19
+ github_span = rubygems_document.at_css("span.github-btn")
20
+
21
+ if github_span
22
+ user = github_span.attr("data-user")
23
+ repo = github_span.attr("data-repo")
24
+ return "https://github.com/#{user}/#{repo}"
25
+ end
26
+
27
+ code = rubygems_document.at_css("a#code")&.attr("href")
28
+ home = rubygems_document.at_css("a#home")&.attr("href")
29
+
30
+ [code, home].compact.first
31
+ rescue StandardError
32
+ nil
33
+ end
34
+
35
+ private
36
+
37
+ def rubygems_document
38
+ @rubygems_document ||= Nokogiri::HTML(rubygems_html)
39
+ end
40
+
41
+ def rubygems_html
42
+ OpenURI.open_uri(rubygems_uri).read
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GemChanges
4
+ module Gemfile
5
+ REMOVAL_REGEX = /^- ([^ ]*) \((.*)\)/.freeze
6
+ ADDITION_REGEX = /^\+ ([^ ]*) \((.*)\)/.freeze
7
+
8
+ module_function def changes(git:)
9
+ diff = git.diff_for_file("Gemfile.lock")
10
+
11
+ return [] if diff.nil?
12
+
13
+ added = {}
14
+
15
+ diff.patch.scan(ADDITION_REGEX).each do |match|
16
+ added[match[0]] = match[1]
17
+ end
18
+
19
+ removed = {}
20
+
21
+ diff.patch.scan(REMOVAL_REGEX).each do |match|
22
+ removed[match[0]] = match[1]
23
+ end
24
+
25
+ all_gems = added.keys | removed.keys
26
+
27
+ all_gems.map do |gem_name|
28
+ gem = Gem.new(name: gem_name)
29
+
30
+ Change.new(gem: gem, from: removed[gem_name], to: added[gem_name])
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,95 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GemChanges
4
+ class SummaryTable
5
+ attr_reader :changes
6
+
7
+ def initialize(changes:)
8
+ @changes = changes
9
+ end
10
+
11
+ def markdown
12
+ string = ""
13
+
14
+ string += "| Gem | Source | Changelog | Change |\n"
15
+ string += "| --- | ------ | --------- | ------ |\n"
16
+
17
+ rows = changes.map { |change| Row.new(change: change) }
18
+
19
+ string += rows.map(&:markdown).join
20
+
21
+ string
22
+ end
23
+
24
+ class Row
25
+ attr_reader :gem, :change
26
+
27
+ def initialize(change:)
28
+ @change = change
29
+ @gem = change.gem
30
+ end
31
+
32
+ def markdown
33
+ string = "| "
34
+
35
+ string += [
36
+ rubygems_link,
37
+ source_link,
38
+ changelog_link,
39
+ change_link
40
+ ].join(" | ")
41
+
42
+ string += " |\n"
43
+
44
+ string
45
+ end
46
+
47
+ def rubygems_link
48
+ "[#{gem.name}](#{gem.rubygems_uri})"
49
+ end
50
+
51
+ def source_link
52
+ "[Source](#{gem.source_code_uri})"
53
+ end
54
+
55
+ def changelog_link
56
+ "[Changelog](#{gem.changelog_uri})"
57
+ end
58
+
59
+ def change_link
60
+ text = change_text
61
+ link = compare_uri
62
+
63
+ if link
64
+ "[#{text}](#{link})"
65
+ else
66
+ text
67
+ end
68
+ end
69
+
70
+ private
71
+
72
+ def change_text
73
+ if change.addition?
74
+ "Added at #{change.to}"
75
+ elsif change.removal?
76
+ "Removed at #{change.from}"
77
+ elsif change.upgrade?
78
+ "v#{change.from} -> v#{change.to}"
79
+ elsif change.downgrade?
80
+ "v#{change.to} <- v#{change.from}"
81
+ else
82
+ fail "Unknown change type"
83
+ end
84
+ end
85
+
86
+ def compare_uri
87
+ return nil unless change.change?
88
+
89
+ from, to = [change.from, change.to].sort
90
+
91
+ "#{gem.source_code_uri}/compare/v#{from}...v#{to}"
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GemChanges
4
+ VERSION = "0.0.1"
5
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "gem_changes/change"
4
+ require "gem_changes/gem"
5
+ require "gem_changes/gemfile"
6
+ require "gem_changes/summary_table"
7
+ require "gem_changes/version"
@@ -0,0 +1,30 @@
1
+ commit 7e4433828eb92cb8e8d6239bf9ab93e1c767e2e8
2
+ Author: John DeSilva <desilvjo@umich.edu>
3
+ Date: Fri May 10 21:47:39 2024 -0400
4
+
5
+ Install rubocop-performance
6
+
7
+ diff --git a/Gemfile.lock b/Gemfile.lock
8
+ index eabec13..f4353d2 100644
9
+ --- a/Gemfile.lock
10
+ +++ b/Gemfile.lock
11
+ @@ -145,6 +145,9 @@ GEM
12
+ rubocop (~> 1.41)
13
+ - rubocop-factory_bot (2.25.1)
14
+ + rubocop-factory_bot (2.25.0)
15
+ rubocop (~> 1.41)
16
+ + rubocop-performance (1.21.0)
17
+ + rubocop (>= 1.48.1, < 2.0)
18
+ + rubocop-ast (>= 1.31.1, < 2.0)
19
+ - rubocop-rake (0.6.0)
20
+ + rubocop-rake (0.6.1)
21
+ rubocop (~> 1.0)
22
+ - rubocop-rspec (2.29.2)
23
+ @@ -181,6 +184,7 @@ DEPENDENCIES
24
+ rake
25
+ rspec
26
+ rubocop
27
+ + rubocop-performance
28
+ rubocop-rake
29
+ - rubocop-rspec
30
+ yard
@@ -0,0 +1,107 @@
1
+ # frozen_string_literal: true
2
+
3
+ require File.expand_path("spec_helper", __dir__)
4
+
5
+ module Danger
6
+ describe Danger::DangerGemChanges do
7
+ it "is a plugin" do
8
+ expect(described_class.new(nil)).to be_a Danger::Plugin
9
+ end
10
+
11
+ describe "with Dangerfile" do
12
+ before do
13
+ @dangerfile = testing_dangerfile
14
+ @my_plugin = @dangerfile.gem_changes
15
+
16
+ modified_gemfile_lock = Git::Diff::DiffFile.new(
17
+ "base",
18
+ path: "Gemfile.lock",
19
+ patch: File.read("spec/fixtures/Gemfile.lock.patch")
20
+ )
21
+
22
+ allow(@dangerfile.git).to \
23
+ receive(:diff_for_file)
24
+ .with("Gemfile.lock")
25
+ .and_return(modified_gemfile_lock)
26
+ end
27
+
28
+ it "knows about changes" do
29
+ changes = @my_plugin.changes
30
+
31
+ expect(changes.count).to eq(4)
32
+ end
33
+
34
+ it "knows about additions" do
35
+ additions = @my_plugin.additions
36
+
37
+ expect(additions).to eq(
38
+ [
39
+ GemChanges::Change.new(
40
+ gem: GemChanges::Gem.new(name: "rubocop-performance"),
41
+ from: nil,
42
+ to: "1.21.0"
43
+ )
44
+ ]
45
+ )
46
+ end
47
+
48
+ it "knows about removals" do
49
+ removals = @my_plugin.removals
50
+
51
+ expect(removals).to eq(
52
+ [
53
+ GemChanges::Change.new(
54
+ gem: GemChanges::Gem.new(name: "rubocop-rspec"),
55
+ from: "2.29.2",
56
+ to: nil
57
+ )
58
+ ]
59
+ )
60
+ end
61
+
62
+ it "knows about upgrades" do
63
+ upgrades = @my_plugin.upgrades
64
+
65
+ expect(upgrades).to eq(
66
+ [
67
+ GemChanges::Change.new(
68
+ gem: GemChanges::Gem.new(name: "rubocop-rake"),
69
+ from: "0.6.0",
70
+ to: "0.6.1"
71
+ )
72
+ ]
73
+ )
74
+ end
75
+
76
+ it "knows about downgrades" do
77
+ downgrades = @my_plugin.downgrades
78
+
79
+ expect(downgrades).to eq(
80
+ [
81
+ GemChanges::Change.new(
82
+ gem: GemChanges::Gem.new(name: "rubocop-factory_bot"),
83
+ from: "2.25.1",
84
+ to: "2.25.0"
85
+ )
86
+ ]
87
+ )
88
+ end
89
+
90
+ it "can generate a markdown table" do
91
+ @my_plugin.summarize_changes
92
+
93
+ markdown = @dangerfile.status_report[:markdowns].last.message
94
+
95
+ expect(markdown).to eq(<<~MARKDOWN)
96
+ ### Gemfile.lock Changes
97
+ | Gem | Source | Changelog | Change |
98
+ | --- | ------ | --------- | ------ |
99
+ | [rubocop-factory_bot](https://rubygems.org/gems/rubocop-factory_bot) | [Source](https://github.com/rubocop/rubocop-factory_bot) | [Changelog](https://github.com/rubocop/rubocop-factory_bot/blob/master/CHANGELOG.md) | [v2.25.0 <- v2.25.1](https://github.com/rubocop/rubocop-factory_bot/compare/v2.25.0...v2.25.1) |
100
+ | [rubocop-performance](https://rubygems.org/gems/rubocop-performance) | [Source](https://github.com/rubocop/rubocop-performance/) | [Changelog](https://github.com/rubocop/rubocop-performance/blob/master/CHANGELOG.md) | Added at 1.21.0 |
101
+ | [rubocop-rake](https://rubygems.org/gems/rubocop-rake) | [Source](https://github.com/rubocop/rubocop-rake) | [Changelog](https://github.com/rubocop/rubocop-rake/blob/master/CHANGELOG.md) | [v0.6.0 -> v0.6.1](https://github.com/rubocop/rubocop-rake/compare/v0.6.0...v0.6.1) |
102
+ | [rubocop-rspec](https://rubygems.org/gems/rubocop-rspec) | [Source](https://github.com/rubocop/rubocop-rspec) | [Changelog](https://github.com/rubocop/rubocop-rspec/blob/master/CHANGELOG.md) | Removed at 2.29.2 |
103
+ MARKDOWN
104
+ end
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "pathname"
4
+ ROOT = Pathname.new(File.expand_path("..", __dir__))
5
+ $:.unshift("#{ROOT}lib".to_s)
6
+ $:.unshift("#{ROOT}spec".to_s)
7
+
8
+ require "bundler/setup"
9
+ require "debug"
10
+
11
+ require "rspec"
12
+ require "danger"
13
+
14
+ if `git remote -v` == ""
15
+ puts "You cannot run tests without setting a local git remote on this repo"
16
+ puts "It's a weird side-effect of Danger's internals."
17
+ exit(0)
18
+ end
19
+
20
+ # Use coloured output, it's the best.
21
+ RSpec.configure do |config|
22
+ config.filter_gems_from_backtrace "bundler"
23
+ config.color = true
24
+ config.tty = true
25
+ end
26
+
27
+ require "danger_plugin"
28
+
29
+ # These functions are a subset of https://github.com/danger/danger/blob/master/spec/spec_helper.rb
30
+ # If you are expanding these files, see if it's already been done ^.
31
+
32
+ # A silent version of the user interface,
33
+ # it comes with an extra function `.string` which will
34
+ # strip all ANSI colours from the string.
35
+
36
+ # rubocop:disable Lint/NestedMethodDefinition
37
+ def testing_ui
38
+ @output = StringIO.new
39
+ def @output.winsize
40
+ [20, 9999]
41
+ end
42
+
43
+ cork = Cork::Board.new(out: @output)
44
+ def cork.string
45
+ out.string.gsub(/\e\[([;\d]+)?m/, "")
46
+ end
47
+ cork
48
+ end
49
+ # rubocop:enable Lint/NestedMethodDefinition
50
+
51
+ # Example environment (ENV) that would come from
52
+ # running a PR on TravisCI
53
+ def testing_env
54
+ {
55
+ "HAS_JOSH_K_SEAL_OF_APPROVAL" => "true",
56
+ "TRAVIS_PULL_REQUEST" => "800",
57
+ "TRAVIS_REPO_SLUG" => "artsy/eigen",
58
+ "TRAVIS_COMMIT_RANGE" => "759adcbd0d8f...13c4dc8bb61d",
59
+ "DANGER_GITHUB_API_TOKEN" => "123sbdq54erfsd3422gdfio"
60
+ }
61
+ end
62
+
63
+ # A stubbed out Dangerfile for use in tests
64
+ def testing_dangerfile
65
+ env = Danger::EnvironmentManager.new(testing_env)
66
+ Danger::Dangerfile.new(env, testing_ui)
67
+ end
metadata ADDED
@@ -0,0 +1,106 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: danger-gem_changes
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - John DeSilva
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2024-05-12 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: danger-plugin-api
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: nokogiri
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: open-uri
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.4'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.4'
55
+ description: A danger plugin for helping review gem depencency changes.
56
+ email:
57
+ - john@aesthetikx.info
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - ".rubocop.yml"
64
+ - ".travis.yml"
65
+ - Gemfile
66
+ - Gemfile.lock
67
+ - Guardfile
68
+ - LICENSE.txt
69
+ - README.md
70
+ - Rakefile
71
+ - danger-gem_changes.gemspec
72
+ - lib/danger_plugin.rb
73
+ - lib/gem_changes.rb
74
+ - lib/gem_changes/change.rb
75
+ - lib/gem_changes/gem.rb
76
+ - lib/gem_changes/gemfile.rb
77
+ - lib/gem_changes/summary_table.rb
78
+ - lib/gem_changes/version.rb
79
+ - spec/fixtures/Gemfile.lock.patch
80
+ - spec/gem_changes_spec.rb
81
+ - spec/spec_helper.rb
82
+ homepage: https://github.com/Aesthetikx/danger-gem_changes
83
+ licenses:
84
+ - MIT
85
+ metadata:
86
+ rubygems_mfa_required: 'true'
87
+ post_install_message:
88
+ rdoc_options: []
89
+ require_paths:
90
+ - lib
91
+ required_ruby_version: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '2.7'
96
+ required_rubygems_version: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ version: '0'
101
+ requirements: []
102
+ rubygems_version: 3.4.10
103
+ signing_key:
104
+ specification_version: 4
105
+ summary: A danger plugin for helping review gem depencency changes.
106
+ test_files: []