codeowners-checker 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.
data/Rakefile ADDED
@@ -0,0 +1,10 @@
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(:spec)
8
+ RuboCop::RakeTask.new(:rubocop)
9
+
10
+ task default: %i[spec rubocop]
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ $LOAD_PATH.unshift(File.expand_path('../lib', __dir__))
5
+
6
+ require 'codeowners/cli/main'
7
+
8
+ Codeowners::Cli::Main.start ARGV
data/bin/console ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'bundler/setup'
5
+ require 'code/ownership/checker'
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ # (If you use this, don't forget to add pry to your Gemfile!)
11
+ # require "pry"
12
+ # Pry.start
13
+
14
+ require 'irb'
15
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,34 @@
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 'codeowners/checker/version'
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = 'codeowners-checker'
9
+ spec.version = Codeowners::Checker::VERSION
10
+ spec.authors = ['Jônatas Davi Paganini', 'Eva Kadlecová', 'Michal Papis']
11
+ spec.email = ['open-source@toptal.com']
12
+
13
+ spec.summary = 'Check consistency of Github CODEOWNERS and git changes.'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
17
+ f.match(%r{^(test|spec|features)/})
18
+ end
19
+ spec.bindir = 'bin'
20
+ spec.executables = ['codeowners-checker']
21
+ spec.require_paths = ['lib']
22
+
23
+ spec.add_dependency 'fuzzy_match', '~> 2.1'
24
+ spec.add_dependency 'git', '~> 1.5'
25
+ spec.add_dependency 'thor', '~> 0.20.3'
26
+ spec.add_development_dependency 'bundler', '~> 1.16'
27
+ spec.add_development_dependency 'pry', '~> 0.12.2'
28
+ spec.add_development_dependency 'rake', '~> 10.0'
29
+ spec.add_development_dependency 'rb-readline', '~> 0.5.5'
30
+ spec.add_development_dependency 'rspec', '~> 3.0'
31
+ spec.add_development_dependency 'rubocop', '~> 0.61.1'
32
+ spec.add_development_dependency 'rubocop-rspec', '~> 1.30'
33
+ spec.add_development_dependency 'simplecov', '~> 0.16.1'
34
+ end
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1350" height="559.33"><rect width="1350" height="559.33" rx="5" ry="5" class="a"/><svg y="0%" x="0%"><circle cx="20" cy="20" r="6" fill="#ff5f58"/><circle cx="40" cy="20" r="6" fill="#ffbd2e"/><circle cx="60" cy="20" r="6" fill="#18c132"/></svg><svg height="499.33" viewBox="0 0 131 49.933" width="1310" x="15" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" y="50"><style>@keyframes j{0%{transform:translateX(0)}5.77%{transform:translateX(-131px)}5.91%{transform:translateX(-262px)}7.22%{transform:translateX(-393px)}7.84%{transform:translateX(-524px)}8.29%{transform:translateX(-655px)}8.9%{transform:translateX(-786px)}9.55%{transform:translateX(-917px)}10.2%{transform:translateX(-1048px)}12.57%{transform:translateX(-1179px)}14.02%{transform:translateX(-1310px)}15.87%{transform:translateX(-1441px)}16.16%{transform:translateX(-1572px)}16.83%{transform:translateX(-1703px)}17.22%{transform:translateX(-1834px)}18.26%{transform:translateX(-1965px)}26.12%{transform:translateX(-2096px)}27.78%{transform:translateX(-2227px)}30.13%{transform:translateX(-2489px)}34.33%{transform:translateX(-2620px)}35.58%{transform:translateX(-2751px)}36.16%{transform:translateX(-2882px)}36.9%{transform:translateX(-3013px)}37.79%{transform:translateX(-3144px)}38.28%{transform:translateX(-3275px)}38.74%{transform:translateX(-3406px)}39.27%{transform:translateX(-3537px)}41.32%{transform:translateX(-3668px)}42.11%{transform:translateX(-3799px)}42.64%{transform:translateX(-3930px)}43.68%{transform:translateX(-4061px)}44.3%{transform:translateX(-4192px)}44.96%{transform:translateX(-4323px)}45.97%{transform:translateX(-4454px)}46.61%{transform:translateX(-4585px)}47.51%{transform:translateX(-4716px)}48.07%{transform:translateX(-4847px)}48.77%{transform:translateX(-4978px)}49.52%{transform:translateX(-5109px)}49.94%{transform:translateX(-5240px)}50.81%{transform:translateX(-5633px)}55.56%{transform:translateX(-5764px)}57.47%{transform:translateX(-5895px)}57.48%{transform:translateX(-6026px)}62.68%{transform:translateX(-6157px)}64.07%{transform:translateX(-6419px)}66.81%{transform:translateX(-6550px)}68.72%{transform:translateX(-6681px)}69.53%{transform:translateX(-6812px)}70.4%{transform:translateX(-6943px)}71.26%{transform:translateX(-7074px)}71.8%{transform:translateX(-7205px)}72.31%{transform:translateX(-7336px)}72.74%{transform:translateX(-7467px)}74.57%{transform:translateX(-7598px)}75.81%{transform:translateX(-7729px)}76.82%{transform:translateX(-7860px)}77.46%{transform:translateX(-7991px)}78.04%{transform:translateX(-8122px)}78.62%{transform:translateX(-8253px)}79.11%{transform:translateX(-8384px)}79.56%{transform:translateX(-8515px)}80.52%{transform:translateX(-8646px)}81.39%{transform:translateX(-8777px)}81.6%{transform:translateX(-8908px)}81.88%{transform:translateX(-9039px)}82.32%{transform:translateX(-9170px)}83.52%{transform:translateX(-9432px)}88.21%{transform:translateX(-9563px)}89.78%{transform:translateX(-9694px)}90.14%{transform:translateX(-9825px)}95.23%{transform:translateX(-9956px)}96.45%{transform:translateX(-10087px)}96.64%{transform:translateX(-10218px)}96.75%{transform:translateX(-10349px)}to{transform:translateX(-10480px)}}.a{fill:#282d35}.f{fill:#b9c0cb}.g{fill:#a8cc8c}.l{fill:#b9c0cb;text-decoration:underline}.m{fill:#e88388;font-weight:700}</style><g font-size="1.67" font-family="Monaco,Consolas,Menlo,'Bitstream Vera Sans Mono','Powerline Symbols',monospace"><defs><symbol id="1"><text y="1.67" class="f">Evas-MBP%</text></symbol><symbol id="2"><text y="1.67" class="f">Evas-MBP%</text><text x="10.02" y="1.67" class="g">codeowners-checker</text><text x="29.058" y="1.67" class="f">check</text></symbol><symbol id="3"><text y="1.67" class="f">File</text><text x="5.01" y="1.67" class="f">added:</text><text x="12.024" y="1.67" class="f">&quot;app/controllers/application_controller.rb&quot;.</text><text x="57.114" y="1.67" class="f">Add</text><text x="61.122" y="1.67" class="f">owner</text><text x="67.134" y="1.67" class="f">to</text><text x="70.14" y="1.67" class="f">CODEOWNERS?</text><text x="82.164" y="1.67" class="f">y</text></symbol><symbol id="4"><text y="1.67" class="f">File</text><text x="5.01" y="1.67" class="f">owner(s):</text></symbol><symbol id="5"><text y="1.67" class="f">File</text><text x="5.01" y="1.67" class="f">owner(s):</text><text x="16.032" y="1.67" class="f">@</text></symbol><symbol id="6"><text y="1.67" class="f">File</text><text x="5.01" y="1.67" class="f">owner(s):</text><text x="16.032" y="1.67" class="f">@c</text></symbol><symbol id="7"><text y="1.67" class="f">File</text><text x="5.01" y="1.67" class="f">owner(s):</text><text x="16.032" y="1.67" class="f">@co</text></symbol><symbol id="8"><text y="1.67" class="f">File</text><text x="5.01" y="1.67" class="f">owner(s):</text><text x="16.032" y="1.67" class="f">@com</text></symbol><symbol id="9"><text y="1.67" class="f">File</text><text x="5.01" y="1.67" class="f">owner(s):</text><text x="16.032" y="1.67" class="f">@comp</text></symbol><symbol id="10"><text y="1.67" class="f">File</text><text x="5.01" y="1.67" class="f">owner(s):</text><text x="16.032" y="1.67" class="f">@compa</text></symbol><symbol id="11"><text y="1.67" class="f">File</text><text x="5.01" y="1.67" class="f">owner(s):</text><text x="16.032" y="1.67" class="f">@compan</text></symbol><symbol id="12"><text y="1.67" class="f">File</text><text x="5.01" y="1.67" class="f">owner(s):</text><text x="16.032" y="1.67" class="f">@company</text></symbol><symbol id="13"><text y="1.67" class="f">File</text><text x="5.01" y="1.67" class="f">owner(s):</text><text x="16.032" y="1.67" class="f">@company/</text></symbol><symbol id="14"><text y="1.67" class="f">File</text><text x="5.01" y="1.67" class="f">owner(s):</text><text x="16.032" y="1.67" class="f">@company/b</text></symbol><symbol id="15"><text y="1.67" class="f">File</text><text x="5.01" y="1.67" class="f">owner(s):</text><text x="16.032" y="1.67" class="f">@company/backend-devs</text></symbol><symbol id="16"><text y="1.67" class="f">Possible</text><text x="9.018" y="1.67" class="f">groups</text><text x="16.032" y="1.67" class="f">to</text><text x="19.038" y="1.67" class="f">which</text><text x="25.05" y="1.67" class="f">the</text><text x="29.058" y="1.67" class="f">pattern</text><text x="37.074" y="1.67" class="f">belongs:</text></symbol><symbol id="17"><text y="1.67" class="f">1</text><text x="2.004" y="1.67" class="f">-</text><text x="4.008" y="1.67" class="f">#</text><text x="6.012" y="1.67" class="f">Backend</text></symbol><symbol id="18"><text y="1.67" class="f">Choose</text><text x="7.014" y="1.67" class="f">group:</text><text x="15.03" y="1.67" class="f">1</text></symbol><symbol id="19"><text y="1.67" class="f">File</text><text x="5.01" y="1.67" class="f">added:</text><text x="12.024" y="1.67" class="f">&quot;lib/invoices.rb&quot;.</text><text x="31.062" y="1.67" class="f">Add</text><text x="35.07" y="1.67" class="f">owner</text><text x="41.082" y="1.67" class="f">to</text><text x="44.088" y="1.67" class="f">CODEOWNERS?</text><text x="56.112" y="1.67" class="f">y</text></symbol><symbol id="20"><text y="1.67" class="f">File</text><text x="5.01" y="1.67" class="f">owner(s):</text><text x="16.032" y="1.67" class="f">@company/billing-team</text></symbol><symbol id="21"><text y="1.67" class="f">Add</text><text x="4.008" y="1.67" class="f">to</text><text x="7.014" y="1.67" class="f">the</text><text x="11.022" y="1.67" class="f">end</text><text x="15.03" y="1.67" class="f">of</text><text x="18.036" y="1.67" class="f">the</text><text x="22.044" y="1.67" class="f">codeowners</text><text x="33.066" y="1.67" class="f">file?</text><text x="39.078" y="1.67" class="f">y</text></symbol><symbol id="22"><text y="1.67" class="f">Commit</text><text x="7.014" y="1.67" class="f">changes?</text><text x="16.032" y="1.67" class="f">y</text></symbol><symbol id="a"><path fill="transparent" d="M0 0h131v24H0z"/></symbol><symbol id="b"><path fill="#6f7683" d="M0 0h1.102v2.171H0z"/></symbol></defs><path class="a" d="M0 0h131v49.933H0z"/><g style="animation-duration:23.886376s;animation-iteration-count:infinite;animation-name:j;animation-timing-function:steps(1,end)"><svg width="10611"><svg><use xlink:href="#a"/><use xlink:href="#b" x="-.004"/></svg><svg x="131"><use xlink:href="#a"/><use xlink:href="#b" x="-.004"/></svg><svg x="262"><use xlink:href="#a"/><use xlink:href="#b" x="9.996"/><use xlink:href="#1"/></svg><svg x="393"><use xlink:href="#a"/><use xlink:href="#b" x="10.996"/><text y="1.67" class="f">Evas-MBP%</text><text x="10.02" y="1.67" class="l">c</text></svg><svg x="524"><use xlink:href="#a"/><use xlink:href="#b" x="11.996"/><text y="1.67" class="f">Evas-MBP%</text><text x="10.02" y="1.67" class="l">co</text></svg><svg x="655"><use xlink:href="#a"/><use xlink:href="#b" x="12.996"/><text y="1.67" class="f">Evas-MBP%</text><text x="10.02" y="1.67" class="m">cod</text></svg><svg x="786"><use xlink:href="#a"/><use xlink:href="#b" x="13.996"/><text y="1.67" class="f">Evas-MBP%</text><text x="10.02" y="1.67" class="g">code</text></svg><svg x="917"><use xlink:href="#a"/><use xlink:href="#b" x="14.996"/><text y="1.67" class="f">Evas-MBP%</text><text x="10.02" y="1.67" class="m">codeo</text></svg><svg x="1048"><use xlink:href="#a"/><use xlink:href="#b" x="15.996"/><text y="1.67" class="f">Evas-MBP%</text><text x="10.02" y="1.67" class="m">codeow</text></svg><svg x="1179"><use xlink:href="#a"/><use xlink:href="#b" x="28.996"/><text y="1.67" class="f">Evas-MBP%</text><text x="10.02" y="1.67" class="g">codeowners-checker</text></svg><svg x="1310"><use xlink:href="#a"/><use xlink:href="#b" x="29.996"/><text y="1.67" class="f">Evas-MBP%</text><text x="10.02" y="1.67" class="g">codeowners-checker</text><text x="29.058" y="1.67" class="l">c</text></svg><svg x="1441"><use xlink:href="#a"/><use xlink:href="#b" x="30.996"/><text y="1.67" class="f">Evas-MBP%</text><text x="10.02" y="1.67" class="g">codeowners-checker</text><text x="29.058" y="1.67" class="f">ch</text></svg><svg x="1572"><use xlink:href="#a"/><use xlink:href="#b" x="31.996"/><text y="1.67" class="f">Evas-MBP%</text><text x="10.02" y="1.67" class="g">codeowners-checker</text><text x="29.058" y="1.67" class="f">che</text></svg><svg x="1703"><use xlink:href="#a"/><use xlink:href="#b" x="32.996"/><text y="1.67" class="f">Evas-MBP%</text><text x="10.02" y="1.67" class="g">codeowners-checker</text><text x="29.058" y="1.67" class="f">chec</text></svg><svg x="1834"><use xlink:href="#a"/><use xlink:href="#b" x="33.996"/><use xlink:href="#2"/></svg><svg x="1965"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="2.146"/><use xlink:href="#2"/></svg><svg x="2096"><use xlink:href="#a"/><use xlink:href="#b" x="81.996" y="2.146"/><use xlink:href="#2"/><text y="3.841" class="f">File</text><text x="5.01" y="3.841" class="f">added:</text><text x="12.024" y="3.841" class="f">&quot;app/controllers/application_controller.rb&quot;.</text><text x="57.114" y="3.841" class="f">Add</text><text x="61.122" y="3.841" class="f">owner</text><text x="67.134" y="3.841" class="f">to</text><text x="70.14" y="3.841" class="f">CODEOWNERS?</text></svg><svg x="2227"><use xlink:href="#a"/><use xlink:href="#b" x="82.996" y="2.146"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/></svg><svg x="2358"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="4.317"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/></svg><svg x="2489"><use xlink:href="#a"/><use xlink:href="#b" x="15.996" y="4.317"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#4" y="4.342"/></svg><svg x="2620"><use xlink:href="#a"/><use xlink:href="#b" x="16.996" y="4.317"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#5" y="4.342"/></svg><svg x="2751"><use xlink:href="#a"/><use xlink:href="#b" x="17.996" y="4.317"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#6" y="4.342"/></svg><svg x="2882"><use xlink:href="#a"/><use xlink:href="#b" x="18.996" y="4.317"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#7" y="4.342"/></svg><svg x="3013"><use xlink:href="#a"/><use xlink:href="#b" x="19.996" y="4.317"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#8" y="4.342"/></svg><svg x="3144"><use xlink:href="#a"/><use xlink:href="#b" x="20.996" y="4.317"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#9" y="4.342"/></svg><svg x="3275"><use xlink:href="#a"/><use xlink:href="#b" x="21.996" y="4.317"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#10" y="4.342"/></svg><svg x="3406"><use xlink:href="#a"/><use xlink:href="#b" x="22.996" y="4.317"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#11" y="4.342"/></svg><svg x="3537"><use xlink:href="#a"/><use xlink:href="#b" x="23.996" y="4.317"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#12" y="4.342"/></svg><svg x="3668"><use xlink:href="#a"/><use xlink:href="#b" x="24.996" y="4.317"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#13" y="4.342"/></svg><svg x="3799"><use xlink:href="#a"/><use xlink:href="#b" x="25.996" y="4.317"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#14" y="4.342"/></svg><svg x="3930"><use xlink:href="#a"/><use xlink:href="#b" x="26.996" y="4.317"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><text y="6.012" class="f">File</text><text x="5.01" y="6.012" class="f">owner(s):</text><text x="16.032" y="6.012" class="f">@company/ba</text></svg><svg x="4061"><use xlink:href="#a"/><use xlink:href="#b" x="27.996" y="4.317"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><text y="6.012" class="f">File</text><text x="5.01" y="6.012" class="f">owner(s):</text><text x="16.032" y="6.012" class="f">@company/bac</text></svg><svg x="4192"><use xlink:href="#a"/><use xlink:href="#b" x="28.996" y="4.317"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><text y="6.012" class="f">File</text><text x="5.01" y="6.012" class="f">owner(s):</text><text x="16.032" y="6.012" class="f">@company/back</text></svg><svg x="4323"><use xlink:href="#a"/><use xlink:href="#b" x="29.996" y="4.317"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><text y="6.012" class="f">File</text><text x="5.01" y="6.012" class="f">owner(s):</text><text x="16.032" y="6.012" class="f">@company/backe</text></svg><svg x="4454"><use xlink:href="#a"/><use xlink:href="#b" x="30.996" y="4.317"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><text y="6.012" class="f">File</text><text x="5.01" y="6.012" class="f">owner(s):</text><text x="16.032" y="6.012" class="f">@company/backen</text></svg><svg x="4585"><use xlink:href="#a"/><use xlink:href="#b" x="31.996" y="4.317"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><text y="6.012" class="f">File</text><text x="5.01" y="6.012" class="f">owner(s):</text><text x="16.032" y="6.012" class="f">@company/backend</text></svg><svg x="4716"><use xlink:href="#a"/><use xlink:href="#b" x="32.996" y="4.317"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><text y="6.012" class="f">File</text><text x="5.01" y="6.012" class="f">owner(s):</text><text x="16.032" y="6.012" class="f">@company/backend-</text></svg><svg x="4847"><use xlink:href="#a"/><use xlink:href="#b" x="33.996" y="4.317"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><text y="6.012" class="f">File</text><text x="5.01" y="6.012" class="f">owner(s):</text><text x="16.032" y="6.012" class="f">@company/backend-d</text></svg><svg x="4978"><use xlink:href="#a"/><use xlink:href="#b" x="34.996" y="4.317"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><text y="6.012" class="f">File</text><text x="5.01" y="6.012" class="f">owner(s):</text><text x="16.032" y="6.012" class="f">@company/backend-de</text></svg><svg x="5109"><use xlink:href="#a"/><use xlink:href="#b" x="35.996" y="4.317"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><text y="6.012" class="f">File</text><text x="5.01" y="6.012" class="f">owner(s):</text><text x="16.032" y="6.012" class="f">@company/backend-dev</text></svg><svg x="5240"><use xlink:href="#a"/><use xlink:href="#b" x="36.996" y="4.317"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#15" y="4.342"/></svg><svg x="5371"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="6.488"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#15" y="4.342"/></svg><svg x="5502"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="10.83"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#15" y="4.342"/><use xlink:href="#16" y="6.513"/><use xlink:href="#17" y="8.684"/></svg><svg x="5633"><use xlink:href="#a"/><use xlink:href="#b" x="14.996" y="10.83"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#15" y="4.342"/><use xlink:href="#16" y="6.513"/><use xlink:href="#17" y="8.684"/><text y="12.525" class="f">Choose</text><text x="7.014" y="12.525" class="f">group:</text></svg><svg x="5764"><use xlink:href="#a"/><use xlink:href="#b" x="15.996" y="10.83"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#15" y="4.342"/><use xlink:href="#16" y="6.513"/><use xlink:href="#17" y="8.684"/><use xlink:href="#18" y="10.855"/></svg><svg x="5895"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="13.001"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#15" y="4.342"/><use xlink:href="#16" y="6.513"/><use xlink:href="#17" y="8.684"/><use xlink:href="#18" y="10.855"/></svg><svg x="6026"><use xlink:href="#a"/><use xlink:href="#b" x="55.996" y="13.001"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#15" y="4.342"/><use xlink:href="#16" y="6.513"/><use xlink:href="#17" y="8.684"/><use xlink:href="#18" y="10.855"/><text y="14.696" class="f">File</text><text x="5.01" y="14.696" class="f">added:</text><text x="12.024" y="14.696" class="f">&quot;lib/invoices.rb&quot;.</text><text x="31.062" y="14.696" class="f">Add</text><text x="35.07" y="14.696" class="f">owner</text><text x="41.082" y="14.696" class="f">to</text><text x="44.088" y="14.696" class="f">CODEOWNERS?</text></svg><svg x="6157"><use xlink:href="#a"/><use xlink:href="#b" x="56.996" y="13.001"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#15" y="4.342"/><use xlink:href="#16" y="6.513"/><use xlink:href="#17" y="8.684"/><use xlink:href="#18" y="10.855"/><use xlink:href="#19" y="13.026"/></svg><svg x="6288"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="15.172"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#15" y="4.342"/><use xlink:href="#16" y="6.513"/><use xlink:href="#17" y="8.684"/><use xlink:href="#18" y="10.855"/><use xlink:href="#19" y="13.026"/></svg><svg x="6419"><use xlink:href="#a"/><use xlink:href="#b" x="15.996" y="15.172"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#15" y="4.342"/><use xlink:href="#16" y="6.513"/><use xlink:href="#17" y="8.684"/><use xlink:href="#18" y="10.855"/><use xlink:href="#19" y="13.026"/><use xlink:href="#4" y="15.197"/></svg><svg x="6550"><use xlink:href="#a"/><use xlink:href="#b" x="16.996" y="15.172"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#15" y="4.342"/><use xlink:href="#16" y="6.513"/><use xlink:href="#17" y="8.684"/><use xlink:href="#18" y="10.855"/><use xlink:href="#19" y="13.026"/><use xlink:href="#5" y="15.197"/></svg><svg x="6681"><use xlink:href="#a"/><use xlink:href="#b" x="17.996" y="15.172"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#15" y="4.342"/><use xlink:href="#16" y="6.513"/><use xlink:href="#17" y="8.684"/><use xlink:href="#18" y="10.855"/><use xlink:href="#19" y="13.026"/><use xlink:href="#6" y="15.197"/></svg><svg x="6812"><use xlink:href="#a"/><use xlink:href="#b" x="18.996" y="15.172"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#15" y="4.342"/><use xlink:href="#16" y="6.513"/><use xlink:href="#17" y="8.684"/><use xlink:href="#18" y="10.855"/><use xlink:href="#19" y="13.026"/><use xlink:href="#7" y="15.197"/></svg><svg x="6943"><use xlink:href="#a"/><use xlink:href="#b" x="19.996" y="15.172"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#15" y="4.342"/><use xlink:href="#16" y="6.513"/><use xlink:href="#17" y="8.684"/><use xlink:href="#18" y="10.855"/><use xlink:href="#19" y="13.026"/><use xlink:href="#8" y="15.197"/></svg><svg x="7074"><use xlink:href="#a"/><use xlink:href="#b" x="20.996" y="15.172"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#15" y="4.342"/><use xlink:href="#16" y="6.513"/><use xlink:href="#17" y="8.684"/><use xlink:href="#18" y="10.855"/><use xlink:href="#19" y="13.026"/><use xlink:href="#9" y="15.197"/></svg><svg x="7205"><use xlink:href="#a"/><use xlink:href="#b" x="21.996" y="15.172"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#15" y="4.342"/><use xlink:href="#16" y="6.513"/><use xlink:href="#17" y="8.684"/><use xlink:href="#18" y="10.855"/><use xlink:href="#19" y="13.026"/><use xlink:href="#10" y="15.197"/></svg><svg x="7336"><use xlink:href="#a"/><use xlink:href="#b" x="22.996" y="15.172"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#15" y="4.342"/><use xlink:href="#16" y="6.513"/><use xlink:href="#17" y="8.684"/><use xlink:href="#18" y="10.855"/><use xlink:href="#19" y="13.026"/><use xlink:href="#11" y="15.197"/></svg><svg x="7467"><use xlink:href="#a"/><use xlink:href="#b" x="23.996" y="15.172"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#15" y="4.342"/><use xlink:href="#16" y="6.513"/><use xlink:href="#17" y="8.684"/><use xlink:href="#18" y="10.855"/><use xlink:href="#19" y="13.026"/><use xlink:href="#12" y="15.197"/></svg><svg x="7598"><use xlink:href="#a"/><use xlink:href="#b" x="24.996" y="15.172"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#15" y="4.342"/><use xlink:href="#16" y="6.513"/><use xlink:href="#17" y="8.684"/><use xlink:href="#18" y="10.855"/><use xlink:href="#19" y="13.026"/><use xlink:href="#13" y="15.197"/></svg><svg x="7729"><use xlink:href="#a"/><use xlink:href="#b" x="25.996" y="15.172"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#15" y="4.342"/><use xlink:href="#16" y="6.513"/><use xlink:href="#17" y="8.684"/><use xlink:href="#18" y="10.855"/><use xlink:href="#19" y="13.026"/><use xlink:href="#14" y="15.197"/></svg><svg x="7860"><use xlink:href="#a"/><use xlink:href="#b" x="26.996" y="15.172"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#15" y="4.342"/><use xlink:href="#16" y="6.513"/><use xlink:href="#17" y="8.684"/><use xlink:href="#18" y="10.855"/><use xlink:href="#19" y="13.026"/><text y="16.867" class="f">File</text><text x="5.01" y="16.867" class="f">owner(s):</text><text x="16.032" y="16.867" class="f">@company/bi</text></svg><svg x="7991"><use xlink:href="#a"/><use xlink:href="#b" x="27.996" y="15.172"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#15" y="4.342"/><use xlink:href="#16" y="6.513"/><use xlink:href="#17" y="8.684"/><use xlink:href="#18" y="10.855"/><use xlink:href="#19" y="13.026"/><text y="16.867" class="f">File</text><text x="5.01" y="16.867" class="f">owner(s):</text><text x="16.032" y="16.867" class="f">@company/bil</text></svg><svg x="8122"><use xlink:href="#a"/><use xlink:href="#b" x="28.996" y="15.172"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#15" y="4.342"/><use xlink:href="#16" y="6.513"/><use xlink:href="#17" y="8.684"/><use xlink:href="#18" y="10.855"/><use xlink:href="#19" y="13.026"/><text y="16.867" class="f">File</text><text x="5.01" y="16.867" class="f">owner(s):</text><text x="16.032" y="16.867" class="f">@company/bill</text></svg><svg x="8253"><use xlink:href="#a"/><use xlink:href="#b" x="29.996" y="15.172"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#15" y="4.342"/><use xlink:href="#16" y="6.513"/><use xlink:href="#17" y="8.684"/><use xlink:href="#18" y="10.855"/><use xlink:href="#19" y="13.026"/><text y="16.867" class="f">File</text><text x="5.01" y="16.867" class="f">owner(s):</text><text x="16.032" y="16.867" class="f">@company/billi</text></svg><svg x="8384"><use xlink:href="#a"/><use xlink:href="#b" x="30.996" y="15.172"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#15" y="4.342"/><use xlink:href="#16" y="6.513"/><use xlink:href="#17" y="8.684"/><use xlink:href="#18" y="10.855"/><use xlink:href="#19" y="13.026"/><text y="16.867" class="f">File</text><text x="5.01" y="16.867" class="f">owner(s):</text><text x="16.032" y="16.867" class="f">@company/billin</text></svg><svg x="8515"><use xlink:href="#a"/><use xlink:href="#b" x="31.996" y="15.172"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#15" y="4.342"/><use xlink:href="#16" y="6.513"/><use xlink:href="#17" y="8.684"/><use xlink:href="#18" y="10.855"/><use xlink:href="#19" y="13.026"/><text y="16.867" class="f">File</text><text x="5.01" y="16.867" class="f">owner(s):</text><text x="16.032" y="16.867" class="f">@company/billing</text></svg><svg x="8646"><use xlink:href="#a"/><use xlink:href="#b" x="32.996" y="15.172"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#15" y="4.342"/><use xlink:href="#16" y="6.513"/><use xlink:href="#17" y="8.684"/><use xlink:href="#18" y="10.855"/><use xlink:href="#19" y="13.026"/><text y="16.867" class="f">File</text><text x="5.01" y="16.867" class="f">owner(s):</text><text x="16.032" y="16.867" class="f">@company/billing-</text></svg><svg x="8777"><use xlink:href="#a"/><use xlink:href="#b" x="33.996" y="15.172"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#15" y="4.342"/><use xlink:href="#16" y="6.513"/><use xlink:href="#17" y="8.684"/><use xlink:href="#18" y="10.855"/><use xlink:href="#19" y="13.026"/><text y="16.867" class="f">File</text><text x="5.01" y="16.867" class="f">owner(s):</text><text x="16.032" y="16.867" class="f">@company/billing-t</text></svg><svg x="8908"><use xlink:href="#a"/><use xlink:href="#b" x="34.996" y="15.172"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#15" y="4.342"/><use xlink:href="#16" y="6.513"/><use xlink:href="#17" y="8.684"/><use xlink:href="#18" y="10.855"/><use xlink:href="#19" y="13.026"/><text y="16.867" class="f">File</text><text x="5.01" y="16.867" class="f">owner(s):</text><text x="16.032" y="16.867" class="f">@company/billing-te</text></svg><svg x="9039"><use xlink:href="#a"/><use xlink:href="#b" x="35.996" y="15.172"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#15" y="4.342"/><use xlink:href="#16" y="6.513"/><use xlink:href="#17" y="8.684"/><use xlink:href="#18" y="10.855"/><use xlink:href="#19" y="13.026"/><text y="16.867" class="f">File</text><text x="5.01" y="16.867" class="f">owner(s):</text><text x="16.032" y="16.867" class="f">@company/billing-tea</text></svg><svg x="9170"><use xlink:href="#a"/><use xlink:href="#b" x="36.996" y="15.172"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#15" y="4.342"/><use xlink:href="#16" y="6.513"/><use xlink:href="#17" y="8.684"/><use xlink:href="#18" y="10.855"/><use xlink:href="#19" y="13.026"/><use xlink:href="#20" y="15.197"/></svg><svg x="9301"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="17.343"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#15" y="4.342"/><use xlink:href="#16" y="6.513"/><use xlink:href="#17" y="8.684"/><use xlink:href="#18" y="10.855"/><use xlink:href="#19" y="13.026"/><use xlink:href="#20" y="15.197"/></svg><svg x="9432"><use xlink:href="#a"/><use xlink:href="#b" x="38.996" y="17.343"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#15" y="4.342"/><use xlink:href="#16" y="6.513"/><use xlink:href="#17" y="8.684"/><use xlink:href="#18" y="10.855"/><use xlink:href="#19" y="13.026"/><use xlink:href="#20" y="15.197"/><text y="19.038" class="f">Add</text><text x="4.008" y="19.038" class="f">to</text><text x="7.014" y="19.038" class="f">the</text><text x="11.022" y="19.038" class="f">end</text><text x="15.03" y="19.038" class="f">of</text><text x="18.036" y="19.038" class="f">the</text><text x="22.044" y="19.038" class="f">codeowners</text><text x="33.066" y="19.038" class="f">file?</text></svg><svg x="9563"><use xlink:href="#a"/><use xlink:href="#b" x="39.996" y="17.343"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#15" y="4.342"/><use xlink:href="#16" y="6.513"/><use xlink:href="#17" y="8.684"/><use xlink:href="#18" y="10.855"/><use xlink:href="#19" y="13.026"/><use xlink:href="#20" y="15.197"/><use xlink:href="#21" y="17.368"/></svg><svg x="9694"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="19.514"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#15" y="4.342"/><use xlink:href="#16" y="6.513"/><use xlink:href="#17" y="8.684"/><use xlink:href="#18" y="10.855"/><use xlink:href="#19" y="13.026"/><use xlink:href="#20" y="15.197"/><use xlink:href="#21" y="17.368"/></svg><svg x="9825"><use xlink:href="#a"/><use xlink:href="#b" x="15.996" y="19.514"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#15" y="4.342"/><use xlink:href="#16" y="6.513"/><use xlink:href="#17" y="8.684"/><use xlink:href="#18" y="10.855"/><use xlink:href="#19" y="13.026"/><use xlink:href="#20" y="15.197"/><use xlink:href="#21" y="17.368"/><text y="21.209" class="f">Commit</text><text x="7.014" y="21.209" class="f">changes?</text></svg><svg x="9956"><use xlink:href="#a"/><use xlink:href="#b" x="16.996" y="19.514"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#15" y="4.342"/><use xlink:href="#16" y="6.513"/><use xlink:href="#17" y="8.684"/><use xlink:href="#18" y="10.855"/><use xlink:href="#19" y="13.026"/><use xlink:href="#20" y="15.197"/><use xlink:href="#21" y="17.368"/><use xlink:href="#22" y="19.539"/></svg><svg x="10087"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="21.685"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#15" y="4.342"/><use xlink:href="#16" y="6.513"/><use xlink:href="#17" y="8.684"/><use xlink:href="#18" y="10.855"/><use xlink:href="#19" y="13.026"/><use xlink:href="#20" y="15.197"/><use xlink:href="#21" y="17.368"/><use xlink:href="#22" y="19.539"/></svg><svg x="10218"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="21.685"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#15" y="4.342"/><use xlink:href="#16" y="6.513"/><use xlink:href="#17" y="8.684"/><use xlink:href="#18" y="10.855"/><use xlink:href="#19" y="13.026"/><use xlink:href="#20" y="15.197"/><use xlink:href="#21" y="17.368"/><use xlink:href="#22" y="19.539"/></svg><svg x="10349"><use xlink:href="#a"/><use xlink:href="#b" x="9.996" y="21.685"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#15" y="4.342"/><use xlink:href="#16" y="6.513"/><use xlink:href="#17" y="8.684"/><use xlink:href="#18" y="10.855"/><use xlink:href="#19" y="13.026"/><use xlink:href="#20" y="15.197"/><use xlink:href="#21" y="17.368"/><use xlink:href="#22" y="19.539"/><use xlink:href="#1" y="21.71"/></svg><svg x="10480"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="23.856"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#15" y="4.342"/><use xlink:href="#16" y="6.513"/><use xlink:href="#17" y="8.684"/><use xlink:href="#18" y="10.855"/><use xlink:href="#19" y="13.026"/><use xlink:href="#20" y="15.197"/><use xlink:href="#21" y="17.368"/><use xlink:href="#22" y="19.539"/><use xlink:href="#1" y="21.71"/></svg></svg></g></g></svg></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1350" height="559.33"><rect width="1350" height="559.33" rx="5" ry="5" class="a"/><svg y="0%" x="0%"><circle cx="20" cy="20" r="6" fill="#ff5f58"/><circle cx="40" cy="20" r="6" fill="#ffbd2e"/><circle cx="60" cy="20" r="6" fill="#18c132"/></svg><svg height="499.33" viewBox="0 0 131 49.933" width="1310" x="15" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" y="50"><style>@keyframes j{0%{transform:translateX(0)}8.43%{transform:translateX(-131px)}8.58%{transform:translateX(-262px)}10.85%{transform:translateX(-393px)}11.44%{transform:translateX(-524px)}12.04%{transform:translateX(-655px)}12.8%{transform:translateX(-786px)}13.62%{transform:translateX(-917px)}15%{transform:translateX(-1048px)}16.64%{transform:translateX(-1179px)}17.48%{transform:translateX(-1310px)}18.07%{transform:translateX(-1441px)}19.02%{transform:translateX(-1572px)}19.68%{transform:translateX(-1703px)}21.08%{transform:translateX(-1834px)}31.09%{transform:translateX(-2096px)}43.03%{transform:translateX(-2227px)}44.85%{transform:translateX(-2358px)}44.9%{transform:translateX(-2620px)}50.66%{transform:translateX(-2751px)}53.08%{transform:translateX(-2882px)}53.19%{transform:translateX(-3144px)}63.72%{transform:translateX(-3275px)}65.64%{transform:translateX(-3537px)}71.26%{transform:translateX(-3668px)}72.87%{transform:translateX(-3799px)}73.88%{transform:translateX(-3930px)}74.34%{transform:translateX(-4061px)}75.12%{transform:translateX(-4192px)}75.81%{transform:translateX(-4323px)}76.63%{transform:translateX(-4454px)}77.8%{transform:translateX(-4585px)}80.16%{transform:translateX(-4716px)}81.24%{transform:translateX(-4847px)}82.02%{transform:translateX(-4978px)}82.24%{transform:translateX(-5109px)}85.12%{transform:translateX(-5371px)}89.93%{transform:translateX(-5502px)}92.02%{transform:translateX(-5633px)}92.37%{transform:translateX(-5764px)}92.49%{transform:translateX(-5895px)}to{transform:translateX(-6026px)}}.a{fill:#282d35}.f{fill:#b9c0cb}.g{fill:#a8cc8c}.l{fill:#b9c0cb;text-decoration:underline}.m{fill:#e88388;font-weight:700}</style><g font-size="1.67" font-family="Monaco,Consolas,Menlo,'Bitstream Vera Sans Mono','Powerline Symbols',monospace"><defs><symbol id="1"><text y="1.67" class="f">Evas-MBP%</text></symbol><symbol id="2"><text y="1.67" class="f">Evas-MBP%</text><text x="10.02" y="1.67" class="g">codeowners-checker</text><text x="29.058" y="1.67" class="f">check</text></symbol><symbol id="3"><text y="1.67" class="f">Pattern</text><text x="8.016" y="1.67" class="f">&quot;app/models/billng.rb&quot;</text><text x="31.062" y="1.67" class="f">doesn&apos;t</text><text x="39.078" y="1.67" class="f">match.</text></symbol><symbol id="4"><text y="1.67" class="f">Replace</text><text x="8.016" y="1.67" class="f">with:</text><text x="14.028" y="1.67" class="f">&quot;app/models/billing.rb&quot;?</text></symbol><symbol id="5"><text y="1.67" class="f">(y)</text><text x="4.008" y="1.67" class="f">yes</text></symbol><symbol id="6"><text y="1.67" class="f">(i)</text><text x="4.008" y="1.67" class="f">ignore</text></symbol><symbol id="7"><text y="1.67" class="f">(e)</text><text x="4.008" y="1.67" class="f">edit</text><text x="9.018" y="1.67" class="f">the</text><text x="13.026" y="1.67" class="f">pattern</text></symbol><symbol id="8"><text y="1.67" class="f">(d)</text><text x="4.008" y="1.67" class="f">delete</text><text x="11.022" y="1.67" class="f">the</text><text x="15.03" y="1.67" class="f">pattern</text></symbol><symbol id="9"><text x="1.002" y="1.67" class="f">[y,</text><text x="5.01" y="1.67" class="f">i,</text><text x="8.016" y="1.67" class="f">e,</text><text x="11.022" y="1.67" class="f">d]</text></symbol><symbol id="10"><text x="1.002" y="1.67" class="f">[y,</text><text x="5.01" y="1.67" class="f">i,</text><text x="8.016" y="1.67" class="f">e,</text><text x="11.022" y="1.67" class="f">d]</text><text x="14.028" y="1.67" class="f">y</text></symbol><symbol id="11"><text y="1.67" class="f">Pattern</text><text x="8.016" y="1.67" class="f">&quot;lib/security/*&quot;</text><text x="25.05" y="1.67" class="f">doesn&apos;t</text><text x="33.066" y="1.67" class="f">match.</text></symbol><symbol id="12"><text x="1.002" y="1.67" class="f">[i,</text><text x="5.01" y="1.67" class="f">e,</text><text x="8.016" y="1.67" class="f">d]</text><text x="11.022" y="1.67" class="f">d</text></symbol><symbol id="13"><text y="1.67" class="f">Pattern</text><text x="8.016" y="1.67" class="f">&quot;.rubo.yml&quot;</text><text x="20.04" y="1.67" class="f">doesn&apos;t</text><text x="28.056" y="1.67" class="f">match.</text></symbol><symbol id="14"><text y="1.67" class="f">Replace</text><text x="8.016" y="1.67" class="f">with:</text><text x="14.028" y="1.67" class="f">&quot;db&quot;?</text></symbol><symbol id="15"><text x="1.002" y="1.67" class="f">[y,</text><text x="5.01" y="1.67" class="f">i,</text><text x="8.016" y="1.67" class="f">e,</text><text x="11.022" y="1.67" class="f">d]</text><text x="14.028" y="1.67" class="f">e</text></symbol><symbol id="16"><text y="1.67" class="f">Replace</text><text x="8.016" y="1.67" class="f">pattern</text><text x="16.032" y="1.67" class="f">&quot;.rubo.yml&quot;</text><text x="28.056" y="1.67" class="f">with:</text><text x="35.07" y="1.67" class="f">.rubocop.yml</text></symbol><symbol id="17"><text y="1.67" class="f">Commit</text><text x="7.014" y="1.67" class="f">changes?</text><text x="16.032" y="1.67" class="f">y</text></symbol><symbol id="a"><path fill="transparent" d="M0 0h131v24H0z"/></symbol><symbol id="b"><path fill="#6f7683" d="M0 0h1.102v2.171H0z"/></symbol></defs><path class="a" d="M0 0h131v49.933H0z"/><g style="animation-duration:19.572061s;animation-iteration-count:infinite;animation-name:j;animation-timing-function:steps(1,end)"><svg width="6157"><svg><use xlink:href="#a"/><use xlink:href="#b" x="-.004"/></svg><svg x="131"><use xlink:href="#a"/><use xlink:href="#b" x="-.004"/></svg><svg x="262"><use xlink:href="#a"/><use xlink:href="#b" x="9.996"/><use xlink:href="#1"/></svg><svg x="393"><use xlink:href="#a"/><use xlink:href="#b" x="10.996"/><text y="1.67" class="f">Evas-MBP%</text><text x="10.02" y="1.67" class="l">c</text></svg><svg x="524"><use xlink:href="#a"/><use xlink:href="#b" x="11.996"/><text y="1.67" class="f">Evas-MBP%</text><text x="10.02" y="1.67" class="l">co</text></svg><svg x="655"><use xlink:href="#a"/><use xlink:href="#b" x="12.996"/><text y="1.67" class="f">Evas-MBP%</text><text x="10.02" y="1.67" class="m">cod</text></svg><svg x="786"><use xlink:href="#a"/><use xlink:href="#b" x="13.996"/><text y="1.67" class="f">Evas-MBP%</text><text x="10.02" y="1.67" class="g">code</text></svg><svg x="917"><use xlink:href="#a"/><use xlink:href="#b" x="14.996"/><text y="1.67" class="f">Evas-MBP%</text><text x="10.02" y="1.67" class="m">codeo</text></svg><svg x="1048"><use xlink:href="#a"/><use xlink:href="#b" x="28.996"/><text y="1.67" class="f">Evas-MBP%</text><text x="10.02" y="1.67" class="g">codeowners-checker</text></svg><svg x="1179"><use xlink:href="#a"/><use xlink:href="#b" x="29.996"/><text y="1.67" class="f">Evas-MBP%</text><text x="10.02" y="1.67" class="g">codeowners-checker</text><text x="29.058" y="1.67" class="l">c</text></svg><svg x="1310"><use xlink:href="#a"/><use xlink:href="#b" x="30.996"/><text y="1.67" class="f">Evas-MBP%</text><text x="10.02" y="1.67" class="g">codeowners-checker</text><text x="29.058" y="1.67" class="f">ch</text></svg><svg x="1441"><use xlink:href="#a"/><use xlink:href="#b" x="31.996"/><text y="1.67" class="f">Evas-MBP%</text><text x="10.02" y="1.67" class="g">codeowners-checker</text><text x="29.058" y="1.67" class="f">che</text></svg><svg x="1572"><use xlink:href="#a"/><use xlink:href="#b" x="32.996"/><text y="1.67" class="f">Evas-MBP%</text><text x="10.02" y="1.67" class="g">codeowners-checker</text><text x="29.058" y="1.67" class="f">chec</text></svg><svg x="1703"><use xlink:href="#a"/><use xlink:href="#b" x="33.996"/><use xlink:href="#2"/></svg><svg x="1834"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="2.146"/><use xlink:href="#2"/></svg><svg x="1965"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="4.317"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/></svg><svg x="2096"><use xlink:href="#a"/><use xlink:href="#b" x="13.996" y="15.172"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#4" y="4.342"/><use xlink:href="#5" y="6.513"/><use xlink:href="#6" y="8.684"/><use xlink:href="#7" y="10.855"/><use xlink:href="#8" y="13.026"/><use xlink:href="#9" y="15.197"/></svg><svg x="2227"><use xlink:href="#a"/><use xlink:href="#b" x="14.996" y="15.172"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#4" y="4.342"/><use xlink:href="#5" y="6.513"/><use xlink:href="#6" y="8.684"/><use xlink:href="#7" y="10.855"/><use xlink:href="#8" y="13.026"/><use xlink:href="#10" y="15.197"/></svg><svg x="2358"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="17.343"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#4" y="4.342"/><use xlink:href="#5" y="6.513"/><use xlink:href="#6" y="8.684"/><use xlink:href="#7" y="10.855"/><use xlink:href="#8" y="13.026"/><use xlink:href="#10" y="15.197"/></svg><svg x="2489"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="19.514"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#4" y="4.342"/><use xlink:href="#5" y="6.513"/><use xlink:href="#6" y="8.684"/><use xlink:href="#7" y="10.855"/><use xlink:href="#8" y="13.026"/><use xlink:href="#10" y="15.197"/><use xlink:href="#11" y="17.368"/></svg><svg x="2620"><use xlink:href="#a"/><use xlink:href="#b" x="10.996" y="26.027"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#4" y="4.342"/><use xlink:href="#5" y="6.513"/><use xlink:href="#6" y="8.684"/><use xlink:href="#7" y="10.855"/><use xlink:href="#8" y="13.026"/><use xlink:href="#10" y="15.197"/><use xlink:href="#11" y="17.368"/><use xlink:href="#7" y="19.539"/><use xlink:href="#8" y="21.71"/><use xlink:href="#6" y="23.881"/><text x="1.002" y="27.722" class="f">[i,</text><text x="5.01" y="27.722" class="f">e,</text><text x="8.016" y="27.722" class="f">d]</text></svg><svg x="2751"><use xlink:href="#a"/><use xlink:href="#b" x="11.996" y="26.027"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#4" y="4.342"/><use xlink:href="#5" y="6.513"/><use xlink:href="#6" y="8.684"/><use xlink:href="#7" y="10.855"/><use xlink:href="#8" y="13.026"/><use xlink:href="#10" y="15.197"/><use xlink:href="#11" y="17.368"/><use xlink:href="#7" y="19.539"/><use xlink:href="#8" y="21.71"/><use xlink:href="#6" y="23.881"/><use xlink:href="#12" y="26.052"/></svg><svg x="2882"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="28.198"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#4" y="4.342"/><use xlink:href="#5" y="6.513"/><use xlink:href="#6" y="8.684"/><use xlink:href="#7" y="10.855"/><use xlink:href="#8" y="13.026"/><use xlink:href="#10" y="15.197"/><use xlink:href="#11" y="17.368"/><use xlink:href="#7" y="19.539"/><use xlink:href="#8" y="21.71"/><use xlink:href="#6" y="23.881"/><use xlink:href="#12" y="26.052"/></svg><svg x="3013"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="30.369"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#4" y="4.342"/><use xlink:href="#5" y="6.513"/><use xlink:href="#6" y="8.684"/><use xlink:href="#7" y="10.855"/><use xlink:href="#8" y="13.026"/><use xlink:href="#10" y="15.197"/><use xlink:href="#11" y="17.368"/><use xlink:href="#7" y="19.539"/><use xlink:href="#8" y="21.71"/><use xlink:href="#6" y="23.881"/><use xlink:href="#12" y="26.052"/><use xlink:href="#13" y="28.223"/></svg><svg x="3144"><use xlink:href="#a"/><use xlink:href="#b" x="13.996" y="41.224"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#4" y="4.342"/><use xlink:href="#5" y="6.513"/><use xlink:href="#6" y="8.684"/><use xlink:href="#7" y="10.855"/><use xlink:href="#8" y="13.026"/><use xlink:href="#10" y="15.197"/><use xlink:href="#11" y="17.368"/><use xlink:href="#7" y="19.539"/><use xlink:href="#8" y="21.71"/><use xlink:href="#6" y="23.881"/><use xlink:href="#12" y="26.052"/><use xlink:href="#13" y="28.223"/><use xlink:href="#14" y="30.394"/><use xlink:href="#5" y="32.565"/><use xlink:href="#6" y="34.736"/><use xlink:href="#7" y="36.907"/><use xlink:href="#8" y="39.078"/><use xlink:href="#9" y="41.249"/></svg><svg x="3275"><use xlink:href="#a"/><use xlink:href="#b" x="14.996" y="41.224"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#4" y="4.342"/><use xlink:href="#5" y="6.513"/><use xlink:href="#6" y="8.684"/><use xlink:href="#7" y="10.855"/><use xlink:href="#8" y="13.026"/><use xlink:href="#10" y="15.197"/><use xlink:href="#11" y="17.368"/><use xlink:href="#7" y="19.539"/><use xlink:href="#8" y="21.71"/><use xlink:href="#6" y="23.881"/><use xlink:href="#12" y="26.052"/><use xlink:href="#13" y="28.223"/><use xlink:href="#14" y="30.394"/><use xlink:href="#5" y="32.565"/><use xlink:href="#6" y="34.736"/><use xlink:href="#7" y="36.907"/><use xlink:href="#8" y="39.078"/><use xlink:href="#15" y="41.249"/></svg><svg x="3406"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="43.395"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#4" y="4.342"/><use xlink:href="#5" y="6.513"/><use xlink:href="#6" y="8.684"/><use xlink:href="#7" y="10.855"/><use xlink:href="#8" y="13.026"/><use xlink:href="#10" y="15.197"/><use xlink:href="#11" y="17.368"/><use xlink:href="#7" y="19.539"/><use xlink:href="#8" y="21.71"/><use xlink:href="#6" y="23.881"/><use xlink:href="#12" y="26.052"/><use xlink:href="#13" y="28.223"/><use xlink:href="#14" y="30.394"/><use xlink:href="#5" y="32.565"/><use xlink:href="#6" y="34.736"/><use xlink:href="#7" y="36.907"/><use xlink:href="#8" y="39.078"/><use xlink:href="#15" y="41.249"/></svg><svg x="3537"><use xlink:href="#a"/><use xlink:href="#b" x="34.996" y="43.395"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#4" y="4.342"/><use xlink:href="#5" y="6.513"/><use xlink:href="#6" y="8.684"/><use xlink:href="#7" y="10.855"/><use xlink:href="#8" y="13.026"/><use xlink:href="#10" y="15.197"/><use xlink:href="#11" y="17.368"/><use xlink:href="#7" y="19.539"/><use xlink:href="#8" y="21.71"/><use xlink:href="#6" y="23.881"/><use xlink:href="#12" y="26.052"/><use xlink:href="#13" y="28.223"/><use xlink:href="#14" y="30.394"/><use xlink:href="#5" y="32.565"/><use xlink:href="#6" y="34.736"/><use xlink:href="#7" y="36.907"/><use xlink:href="#8" y="39.078"/><use xlink:href="#15" y="41.249"/><text y="45.09" class="f">Replace</text><text x="8.016" y="45.09" class="f">pattern</text><text x="16.032" y="45.09" class="f">&quot;.rubo.yml&quot;</text><text x="28.056" y="45.09" class="f">with:</text></svg><svg x="3668"><use xlink:href="#a"/><use xlink:href="#b" x="35.996" y="43.395"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#4" y="4.342"/><use xlink:href="#5" y="6.513"/><use xlink:href="#6" y="8.684"/><use xlink:href="#7" y="10.855"/><use xlink:href="#8" y="13.026"/><use xlink:href="#10" y="15.197"/><use xlink:href="#11" y="17.368"/><use xlink:href="#7" y="19.539"/><use xlink:href="#8" y="21.71"/><use xlink:href="#6" y="23.881"/><use xlink:href="#12" y="26.052"/><use xlink:href="#13" y="28.223"/><use xlink:href="#14" y="30.394"/><use xlink:href="#5" y="32.565"/><use xlink:href="#6" y="34.736"/><use xlink:href="#7" y="36.907"/><use xlink:href="#8" y="39.078"/><use xlink:href="#15" y="41.249"/><text y="45.09" class="f">Replace</text><text x="8.016" y="45.09" class="f">pattern</text><text x="16.032" y="45.09" class="f">&quot;.rubo.yml&quot;</text><text x="28.056" y="45.09" class="f">with:</text><text x="35.07" y="45.09" class="f">.</text></svg><svg x="3799"><use xlink:href="#a"/><use xlink:href="#b" x="36.996" y="43.395"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#4" y="4.342"/><use xlink:href="#5" y="6.513"/><use xlink:href="#6" y="8.684"/><use xlink:href="#7" y="10.855"/><use xlink:href="#8" y="13.026"/><use xlink:href="#10" y="15.197"/><use xlink:href="#11" y="17.368"/><use xlink:href="#7" y="19.539"/><use xlink:href="#8" y="21.71"/><use xlink:href="#6" y="23.881"/><use xlink:href="#12" y="26.052"/><use xlink:href="#13" y="28.223"/><use xlink:href="#14" y="30.394"/><use xlink:href="#5" y="32.565"/><use xlink:href="#6" y="34.736"/><use xlink:href="#7" y="36.907"/><use xlink:href="#8" y="39.078"/><use xlink:href="#15" y="41.249"/><text y="45.09" class="f">Replace</text><text x="8.016" y="45.09" class="f">pattern</text><text x="16.032" y="45.09" class="f">&quot;.rubo.yml&quot;</text><text x="28.056" y="45.09" class="f">with:</text><text x="35.07" y="45.09" class="f">.r</text></svg><svg x="3930"><use xlink:href="#a"/><use xlink:href="#b" x="37.996" y="43.395"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#4" y="4.342"/><use xlink:href="#5" y="6.513"/><use xlink:href="#6" y="8.684"/><use xlink:href="#7" y="10.855"/><use xlink:href="#8" y="13.026"/><use xlink:href="#10" y="15.197"/><use xlink:href="#11" y="17.368"/><use xlink:href="#7" y="19.539"/><use xlink:href="#8" y="21.71"/><use xlink:href="#6" y="23.881"/><use xlink:href="#12" y="26.052"/><use xlink:href="#13" y="28.223"/><use xlink:href="#14" y="30.394"/><use xlink:href="#5" y="32.565"/><use xlink:href="#6" y="34.736"/><use xlink:href="#7" y="36.907"/><use xlink:href="#8" y="39.078"/><use xlink:href="#15" y="41.249"/><text y="45.09" class="f">Replace</text><text x="8.016" y="45.09" class="f">pattern</text><text x="16.032" y="45.09" class="f">&quot;.rubo.yml&quot;</text><text x="28.056" y="45.09" class="f">with:</text><text x="35.07" y="45.09" class="f">.ru</text></svg><svg x="4061"><use xlink:href="#a"/><use xlink:href="#b" x="38.996" y="43.395"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#4" y="4.342"/><use xlink:href="#5" y="6.513"/><use xlink:href="#6" y="8.684"/><use xlink:href="#7" y="10.855"/><use xlink:href="#8" y="13.026"/><use xlink:href="#10" y="15.197"/><use xlink:href="#11" y="17.368"/><use xlink:href="#7" y="19.539"/><use xlink:href="#8" y="21.71"/><use xlink:href="#6" y="23.881"/><use xlink:href="#12" y="26.052"/><use xlink:href="#13" y="28.223"/><use xlink:href="#14" y="30.394"/><use xlink:href="#5" y="32.565"/><use xlink:href="#6" y="34.736"/><use xlink:href="#7" y="36.907"/><use xlink:href="#8" y="39.078"/><use xlink:href="#15" y="41.249"/><text y="45.09" class="f">Replace</text><text x="8.016" y="45.09" class="f">pattern</text><text x="16.032" y="45.09" class="f">&quot;.rubo.yml&quot;</text><text x="28.056" y="45.09" class="f">with:</text><text x="35.07" y="45.09" class="f">.rub</text></svg><svg x="4192"><use xlink:href="#a"/><use xlink:href="#b" x="39.996" y="43.395"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#4" y="4.342"/><use xlink:href="#5" y="6.513"/><use xlink:href="#6" y="8.684"/><use xlink:href="#7" y="10.855"/><use xlink:href="#8" y="13.026"/><use xlink:href="#10" y="15.197"/><use xlink:href="#11" y="17.368"/><use xlink:href="#7" y="19.539"/><use xlink:href="#8" y="21.71"/><use xlink:href="#6" y="23.881"/><use xlink:href="#12" y="26.052"/><use xlink:href="#13" y="28.223"/><use xlink:href="#14" y="30.394"/><use xlink:href="#5" y="32.565"/><use xlink:href="#6" y="34.736"/><use xlink:href="#7" y="36.907"/><use xlink:href="#8" y="39.078"/><use xlink:href="#15" y="41.249"/><text y="45.09" class="f">Replace</text><text x="8.016" y="45.09" class="f">pattern</text><text x="16.032" y="45.09" class="f">&quot;.rubo.yml&quot;</text><text x="28.056" y="45.09" class="f">with:</text><text x="35.07" y="45.09" class="f">.rubo</text></svg><svg x="4323"><use xlink:href="#a"/><use xlink:href="#b" x="40.996" y="43.395"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#4" y="4.342"/><use xlink:href="#5" y="6.513"/><use xlink:href="#6" y="8.684"/><use xlink:href="#7" y="10.855"/><use xlink:href="#8" y="13.026"/><use xlink:href="#10" y="15.197"/><use xlink:href="#11" y="17.368"/><use xlink:href="#7" y="19.539"/><use xlink:href="#8" y="21.71"/><use xlink:href="#6" y="23.881"/><use xlink:href="#12" y="26.052"/><use xlink:href="#13" y="28.223"/><use xlink:href="#14" y="30.394"/><use xlink:href="#5" y="32.565"/><use xlink:href="#6" y="34.736"/><use xlink:href="#7" y="36.907"/><use xlink:href="#8" y="39.078"/><use xlink:href="#15" y="41.249"/><text y="45.09" class="f">Replace</text><text x="8.016" y="45.09" class="f">pattern</text><text x="16.032" y="45.09" class="f">&quot;.rubo.yml&quot;</text><text x="28.056" y="45.09" class="f">with:</text><text x="35.07" y="45.09" class="f">.ruboc</text></svg><svg x="4454"><use xlink:href="#a"/><use xlink:href="#b" x="41.996" y="43.395"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#4" y="4.342"/><use xlink:href="#5" y="6.513"/><use xlink:href="#6" y="8.684"/><use xlink:href="#7" y="10.855"/><use xlink:href="#8" y="13.026"/><use xlink:href="#10" y="15.197"/><use xlink:href="#11" y="17.368"/><use xlink:href="#7" y="19.539"/><use xlink:href="#8" y="21.71"/><use xlink:href="#6" y="23.881"/><use xlink:href="#12" y="26.052"/><use xlink:href="#13" y="28.223"/><use xlink:href="#14" y="30.394"/><use xlink:href="#5" y="32.565"/><use xlink:href="#6" y="34.736"/><use xlink:href="#7" y="36.907"/><use xlink:href="#8" y="39.078"/><use xlink:href="#15" y="41.249"/><text y="45.09" class="f">Replace</text><text x="8.016" y="45.09" class="f">pattern</text><text x="16.032" y="45.09" class="f">&quot;.rubo.yml&quot;</text><text x="28.056" y="45.09" class="f">with:</text><text x="35.07" y="45.09" class="f">.ruboco</text></svg><svg x="4585"><use xlink:href="#a"/><use xlink:href="#b" x="42.996" y="43.395"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#4" y="4.342"/><use xlink:href="#5" y="6.513"/><use xlink:href="#6" y="8.684"/><use xlink:href="#7" y="10.855"/><use xlink:href="#8" y="13.026"/><use xlink:href="#10" y="15.197"/><use xlink:href="#11" y="17.368"/><use xlink:href="#7" y="19.539"/><use xlink:href="#8" y="21.71"/><use xlink:href="#6" y="23.881"/><use xlink:href="#12" y="26.052"/><use xlink:href="#13" y="28.223"/><use xlink:href="#14" y="30.394"/><use xlink:href="#5" y="32.565"/><use xlink:href="#6" y="34.736"/><use xlink:href="#7" y="36.907"/><use xlink:href="#8" y="39.078"/><use xlink:href="#15" y="41.249"/><text y="45.09" class="f">Replace</text><text x="8.016" y="45.09" class="f">pattern</text><text x="16.032" y="45.09" class="f">&quot;.rubo.yml&quot;</text><text x="28.056" y="45.09" class="f">with:</text><text x="35.07" y="45.09" class="f">.rubocop</text></svg><svg x="4716"><use xlink:href="#a"/><use xlink:href="#b" x="43.996" y="43.395"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#4" y="4.342"/><use xlink:href="#5" y="6.513"/><use xlink:href="#6" y="8.684"/><use xlink:href="#7" y="10.855"/><use xlink:href="#8" y="13.026"/><use xlink:href="#10" y="15.197"/><use xlink:href="#11" y="17.368"/><use xlink:href="#7" y="19.539"/><use xlink:href="#8" y="21.71"/><use xlink:href="#6" y="23.881"/><use xlink:href="#12" y="26.052"/><use xlink:href="#13" y="28.223"/><use xlink:href="#14" y="30.394"/><use xlink:href="#5" y="32.565"/><use xlink:href="#6" y="34.736"/><use xlink:href="#7" y="36.907"/><use xlink:href="#8" y="39.078"/><use xlink:href="#15" y="41.249"/><text y="45.09" class="f">Replace</text><text x="8.016" y="45.09" class="f">pattern</text><text x="16.032" y="45.09" class="f">&quot;.rubo.yml&quot;</text><text x="28.056" y="45.09" class="f">with:</text><text x="35.07" y="45.09" class="f">.rubocop.</text></svg><svg x="4847"><use xlink:href="#a"/><use xlink:href="#b" x="44.996" y="43.395"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#4" y="4.342"/><use xlink:href="#5" y="6.513"/><use xlink:href="#6" y="8.684"/><use xlink:href="#7" y="10.855"/><use xlink:href="#8" y="13.026"/><use xlink:href="#10" y="15.197"/><use xlink:href="#11" y="17.368"/><use xlink:href="#7" y="19.539"/><use xlink:href="#8" y="21.71"/><use xlink:href="#6" y="23.881"/><use xlink:href="#12" y="26.052"/><use xlink:href="#13" y="28.223"/><use xlink:href="#14" y="30.394"/><use xlink:href="#5" y="32.565"/><use xlink:href="#6" y="34.736"/><use xlink:href="#7" y="36.907"/><use xlink:href="#8" y="39.078"/><use xlink:href="#15" y="41.249"/><text y="45.09" class="f">Replace</text><text x="8.016" y="45.09" class="f">pattern</text><text x="16.032" y="45.09" class="f">&quot;.rubo.yml&quot;</text><text x="28.056" y="45.09" class="f">with:</text><text x="35.07" y="45.09" class="f">.rubocop.y</text></svg><svg x="4978"><use xlink:href="#a"/><use xlink:href="#b" x="45.996" y="43.395"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#4" y="4.342"/><use xlink:href="#5" y="6.513"/><use xlink:href="#6" y="8.684"/><use xlink:href="#7" y="10.855"/><use xlink:href="#8" y="13.026"/><use xlink:href="#10" y="15.197"/><use xlink:href="#11" y="17.368"/><use xlink:href="#7" y="19.539"/><use xlink:href="#8" y="21.71"/><use xlink:href="#6" y="23.881"/><use xlink:href="#12" y="26.052"/><use xlink:href="#13" y="28.223"/><use xlink:href="#14" y="30.394"/><use xlink:href="#5" y="32.565"/><use xlink:href="#6" y="34.736"/><use xlink:href="#7" y="36.907"/><use xlink:href="#8" y="39.078"/><use xlink:href="#15" y="41.249"/><text y="45.09" class="f">Replace</text><text x="8.016" y="45.09" class="f">pattern</text><text x="16.032" y="45.09" class="f">&quot;.rubo.yml&quot;</text><text x="28.056" y="45.09" class="f">with:</text><text x="35.07" y="45.09" class="f">.rubocop.ym</text></svg><svg x="5109"><use xlink:href="#a"/><use xlink:href="#b" x="46.996" y="43.395"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#4" y="4.342"/><use xlink:href="#5" y="6.513"/><use xlink:href="#6" y="8.684"/><use xlink:href="#7" y="10.855"/><use xlink:href="#8" y="13.026"/><use xlink:href="#10" y="15.197"/><use xlink:href="#11" y="17.368"/><use xlink:href="#7" y="19.539"/><use xlink:href="#8" y="21.71"/><use xlink:href="#6" y="23.881"/><use xlink:href="#12" y="26.052"/><use xlink:href="#13" y="28.223"/><use xlink:href="#14" y="30.394"/><use xlink:href="#5" y="32.565"/><use xlink:href="#6" y="34.736"/><use xlink:href="#7" y="36.907"/><use xlink:href="#8" y="39.078"/><use xlink:href="#15" y="41.249"/><use xlink:href="#16" y="43.42"/></svg><svg x="5240"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="45.566"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#4" y="4.342"/><use xlink:href="#5" y="6.513"/><use xlink:href="#6" y="8.684"/><use xlink:href="#7" y="10.855"/><use xlink:href="#8" y="13.026"/><use xlink:href="#10" y="15.197"/><use xlink:href="#11" y="17.368"/><use xlink:href="#7" y="19.539"/><use xlink:href="#8" y="21.71"/><use xlink:href="#6" y="23.881"/><use xlink:href="#12" y="26.052"/><use xlink:href="#13" y="28.223"/><use xlink:href="#14" y="30.394"/><use xlink:href="#5" y="32.565"/><use xlink:href="#6" y="34.736"/><use xlink:href="#7" y="36.907"/><use xlink:href="#8" y="39.078"/><use xlink:href="#15" y="41.249"/><use xlink:href="#16" y="43.42"/></svg><svg x="5371"><use xlink:href="#a"/><use xlink:href="#b" x="15.996" y="45.566"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#4" y="4.342"/><use xlink:href="#5" y="6.513"/><use xlink:href="#6" y="8.684"/><use xlink:href="#7" y="10.855"/><use xlink:href="#8" y="13.026"/><use xlink:href="#10" y="15.197"/><use xlink:href="#11" y="17.368"/><use xlink:href="#7" y="19.539"/><use xlink:href="#8" y="21.71"/><use xlink:href="#6" y="23.881"/><use xlink:href="#12" y="26.052"/><use xlink:href="#13" y="28.223"/><use xlink:href="#14" y="30.394"/><use xlink:href="#5" y="32.565"/><use xlink:href="#6" y="34.736"/><use xlink:href="#7" y="36.907"/><use xlink:href="#8" y="39.078"/><use xlink:href="#15" y="41.249"/><use xlink:href="#16" y="43.42"/><text y="47.261" class="f">Commit</text><text x="7.014" y="47.261" class="f">changes?</text></svg><svg x="5502"><use xlink:href="#a"/><use xlink:href="#b" x="16.996" y="45.566"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#4" y="4.342"/><use xlink:href="#5" y="6.513"/><use xlink:href="#6" y="8.684"/><use xlink:href="#7" y="10.855"/><use xlink:href="#8" y="13.026"/><use xlink:href="#10" y="15.197"/><use xlink:href="#11" y="17.368"/><use xlink:href="#7" y="19.539"/><use xlink:href="#8" y="21.71"/><use xlink:href="#6" y="23.881"/><use xlink:href="#12" y="26.052"/><use xlink:href="#13" y="28.223"/><use xlink:href="#14" y="30.394"/><use xlink:href="#5" y="32.565"/><use xlink:href="#6" y="34.736"/><use xlink:href="#7" y="36.907"/><use xlink:href="#8" y="39.078"/><use xlink:href="#15" y="41.249"/><use xlink:href="#16" y="43.42"/><use xlink:href="#17" y="45.591"/></svg><svg x="5633"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="47.737"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#4" y="4.342"/><use xlink:href="#5" y="6.513"/><use xlink:href="#6" y="8.684"/><use xlink:href="#7" y="10.855"/><use xlink:href="#8" y="13.026"/><use xlink:href="#10" y="15.197"/><use xlink:href="#11" y="17.368"/><use xlink:href="#7" y="19.539"/><use xlink:href="#8" y="21.71"/><use xlink:href="#6" y="23.881"/><use xlink:href="#12" y="26.052"/><use xlink:href="#13" y="28.223"/><use xlink:href="#14" y="30.394"/><use xlink:href="#5" y="32.565"/><use xlink:href="#6" y="34.736"/><use xlink:href="#7" y="36.907"/><use xlink:href="#8" y="39.078"/><use xlink:href="#15" y="41.249"/><use xlink:href="#16" y="43.42"/><use xlink:href="#17" y="45.591"/></svg><svg x="5764"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="47.737"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#4" y="4.342"/><use xlink:href="#5" y="6.513"/><use xlink:href="#6" y="8.684"/><use xlink:href="#7" y="10.855"/><use xlink:href="#8" y="13.026"/><use xlink:href="#10" y="15.197"/><use xlink:href="#11" y="17.368"/><use xlink:href="#7" y="19.539"/><use xlink:href="#8" y="21.71"/><use xlink:href="#6" y="23.881"/><use xlink:href="#12" y="26.052"/><use xlink:href="#13" y="28.223"/><use xlink:href="#14" y="30.394"/><use xlink:href="#5" y="32.565"/><use xlink:href="#6" y="34.736"/><use xlink:href="#7" y="36.907"/><use xlink:href="#8" y="39.078"/><use xlink:href="#15" y="41.249"/><use xlink:href="#16" y="43.42"/><use xlink:href="#17" y="45.591"/></svg><svg x="5895"><use xlink:href="#a"/><use xlink:href="#b" x="9.996" y="47.737"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#4" y="4.342"/><use xlink:href="#5" y="6.513"/><use xlink:href="#6" y="8.684"/><use xlink:href="#7" y="10.855"/><use xlink:href="#8" y="13.026"/><use xlink:href="#10" y="15.197"/><use xlink:href="#11" y="17.368"/><use xlink:href="#7" y="19.539"/><use xlink:href="#8" y="21.71"/><use xlink:href="#6" y="23.881"/><use xlink:href="#12" y="26.052"/><use xlink:href="#13" y="28.223"/><use xlink:href="#14" y="30.394"/><use xlink:href="#5" y="32.565"/><use xlink:href="#6" y="34.736"/><use xlink:href="#7" y="36.907"/><use xlink:href="#8" y="39.078"/><use xlink:href="#15" y="41.249"/><use xlink:href="#16" y="43.42"/><use xlink:href="#17" y="45.591"/><use xlink:href="#1" y="47.762"/></svg><svg x="6026"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="49.908"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#4" y="4.342"/><use xlink:href="#5" y="6.513"/><use xlink:href="#6" y="8.684"/><use xlink:href="#7" y="10.855"/><use xlink:href="#8" y="13.026"/><use xlink:href="#10" y="15.197"/><use xlink:href="#11" y="17.368"/><use xlink:href="#7" y="19.539"/><use xlink:href="#8" y="21.71"/><use xlink:href="#6" y="23.881"/><use xlink:href="#12" y="26.052"/><use xlink:href="#13" y="28.223"/><use xlink:href="#14" y="30.394"/><use xlink:href="#5" y="32.565"/><use xlink:href="#6" y="34.736"/><use xlink:href="#7" y="36.907"/><use xlink:href="#8" y="39.078"/><use xlink:href="#15" y="41.249"/><use xlink:href="#16" y="43.42"/><use xlink:href="#17" y="45.591"/><use xlink:href="#1" y="47.762"/></svg></svg></g></g></svg></svg>
@@ -0,0 +1,123 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'git'
4
+ require 'logger'
5
+
6
+ require_relative 'checker/code_owners'
7
+ require_relative 'checker/file_as_array'
8
+ require_relative 'checker/group'
9
+
10
+ module Codeowners
11
+ # Check if code owners are consistent between a git repository and the CODEOWNERS file.
12
+ # It compares what's being changed in the PR and check if the current files and folders
13
+ # are also being declared in the CODEOWNERS file.
14
+ class Checker
15
+ attr_accessor :when_useless_pattern, :when_new_file
16
+
17
+ # Get repo metadata and compare with the owners
18
+ def initialize(repo, from, to)
19
+ @git = Git.open(repo, log: Logger.new(IO::NULL))
20
+ @repo_dir = repo
21
+ @from = from || 'HEAD'
22
+ @to = to
23
+ end
24
+
25
+ def transformers
26
+ @transformers ||= []
27
+ end
28
+
29
+ def changes_to_analyze
30
+ @git.diff(@from, @to).name_status
31
+ end
32
+
33
+ def added_files
34
+ changes_to_analyze.select { |_k, v| v == 'A' }.keys
35
+ end
36
+
37
+ def check!
38
+ {
39
+ missing_ref: missing_reference,
40
+ useless_pattern: useless_pattern
41
+ }
42
+ end
43
+
44
+ def changes_for_patterns(patterns)
45
+ @git.diff(@from, @to).path(patterns).name_status.keys
46
+ end
47
+
48
+ def patterns_by_owner
49
+ @patterns_by_owner ||=
50
+ codeowners.each_with_object(hash_of_arrays) do |line, patterns_by_owner|
51
+ next unless line.pattern?
52
+
53
+ line.owners.each { |owner| patterns_by_owner[owner] << line.pattern }
54
+ end
55
+ end
56
+
57
+ def hash_of_arrays
58
+ Hash.new { |h, k| h[k] = [] }
59
+ end
60
+
61
+ def changes_with_ownership(owner = '')
62
+ patterns_by_owner.each_with_object({}) do |(own, patterns), changes_with_owners|
63
+ next if (owner != '') && (own != owner)
64
+
65
+ changes_with_owners[own] = changes_for_patterns(patterns)
66
+ end
67
+ end
68
+
69
+ def useless_pattern
70
+ codeowners.select do |line|
71
+ next unless line.pattern?
72
+
73
+ unless pattern_has_files(line.pattern)
74
+ @when_useless_pattern&.call(line)
75
+ true
76
+ end
77
+ end
78
+ end
79
+
80
+ def missing_reference
81
+ added_files.reject(&method(:defined_owner?))
82
+ end
83
+
84
+ def pattern_has_files(pattern)
85
+ @git.ls_files(pattern).any?
86
+ end
87
+
88
+ def defined_owner?(file)
89
+ codeowners.find do |line|
90
+ next unless line.pattern?
91
+
92
+ return true if line.match_file?(file)
93
+ end
94
+
95
+ @when_new_file&.call(file) if @when_new_file
96
+ false
97
+ end
98
+
99
+ def codeowners
100
+ @codeowners ||= CodeOwners.new(
101
+ FileAsArray.new(codeowners_filename),
102
+ transformers: transformers
103
+ )
104
+ end
105
+
106
+ def main_group
107
+ codeowners.main_group
108
+ end
109
+
110
+ def commit_changes!
111
+ @git.add(codeowners_filename)
112
+ @git.commit('Fix pattern :robot:')
113
+ end
114
+
115
+ private
116
+
117
+ def codeowners_filename
118
+ directories = ['', '.github', 'docs', '.gitlab']
119
+ paths = directories.map { |dir| File.join(@repo_dir, dir, 'CODEOWNERS') }
120
+ Dir.glob(paths).first || paths.first
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Codeowners
4
+ class Checker
5
+ # Array.delete in contrary to Ruby documentation uses == instead of equal? for comparison.
6
+ # safe_delete removes an object from an array comparing objects by equal? method.
7
+ module Array
8
+ def safe_delete(object)
9
+ delete_at(index { |item| item.equal?(object) })
10
+ end
11
+ end
12
+ end
13
+ end
14
+
15
+ Array.prepend(Codeowners::Checker::Array)
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'group'
4
+ require_relative 'array'
5
+
6
+ module Codeowners
7
+ class Checker
8
+ # Manage CODEOWNERS file reading and re-writing.
9
+ class CodeOwners
10
+ include Enumerable
11
+
12
+ attr_reader :file_manager, :transform_line_procs
13
+
14
+ def initialize(file_manager, transformers: nil)
15
+ @file_manager = file_manager
16
+ @transform_line_procs = [
17
+ method(:build_line),
18
+ *transformers
19
+ ]
20
+ end
21
+
22
+ def persist!
23
+ file_manager.content = to_content
24
+ end
25
+
26
+ def main_group
27
+ @main_group ||= Group.parse(list)
28
+ end
29
+
30
+ def each(&block)
31
+ main_group.each(&block)
32
+ end
33
+
34
+ def to_content
35
+ main_group.to_content
36
+ end
37
+
38
+ private
39
+
40
+ def list
41
+ @list ||= @file_manager.content.yield_self do |list|
42
+ transform_line_procs.each do |transform_line_proc|
43
+ list = list.flat_map { |line| transform_line_proc.call(line) }.compact
44
+ end
45
+ list
46
+ end
47
+ end
48
+
49
+ def build_line(line)
50
+ Codeowners::Checker::Group::Line.build(line)
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Codeowners
4
+ class Checker
5
+ # Convert CODEOWNERS file content to an array.
6
+ class FileAsArray
7
+ def initialize(file)
8
+ @file = file
9
+ @target_dir, = File.split(@file)
10
+ end
11
+
12
+ def content
13
+ @content ||= File.readlines(@file).map(&:chomp)
14
+ rescue Errno::ENOENT
15
+ @content = []
16
+ end
17
+
18
+ def content=(content)
19
+ @content = content
20
+
21
+ Dir.mkdir(@target_dir) unless Dir.exist?(@target_dir)
22
+
23
+ File.open(@file, 'w+') do |f|
24
+ f.puts content
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,148 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'line_grouper'
4
+ require_relative 'group/line'
5
+ require_relative 'array'
6
+
7
+ module Codeowners
8
+ class Checker
9
+ # Manage the groups content and handle operations on the groups.
10
+ class Group
11
+ include Enumerable
12
+
13
+ attr_accessor :parent
14
+
15
+ def self.parse(lines)
16
+ new.parse(lines)
17
+ end
18
+
19
+ def initialize
20
+ @list = []
21
+ end
22
+
23
+ def each(&block)
24
+ @list.each do |object|
25
+ if object.is_a?(Group)
26
+ object.each(&block)
27
+ else
28
+ block.call(object)
29
+ end
30
+ end
31
+ end
32
+
33
+ def parse(lines)
34
+ LineGrouper.call(self, lines)
35
+ end
36
+
37
+ def to_content
38
+ @list.flat_map(&:to_content)
39
+ end
40
+
41
+ # Returns an array of strings representing the structure of the group.
42
+ # It indent internal subgroups for readability and debugging purposes.
43
+ def to_tree(indentation = '')
44
+ @list.each_with_index.flat_map do |item, index|
45
+ if indentation.empty?
46
+ item.to_tree(indentation + ' ')
47
+ elsif index.zero?
48
+ item.to_tree(indentation + '+ ')
49
+ elsif index == @list.length - 1
50
+ item.to_tree(indentation + '\\ ')
51
+ else
52
+ item.to_tree(indentation + '| ')
53
+ end
54
+ end
55
+ end
56
+
57
+ def owner
58
+ owners.first
59
+ end
60
+
61
+ # Owners are ordered by the amount of occurrences
62
+ def owners
63
+ all_owners.group_by(&:itself).sort_by do |_owner, occurrences|
64
+ -occurrences.count
65
+ end.map(&:first)
66
+ end
67
+
68
+ def subgroups_owned_by(owner)
69
+ @list.flat_map do |item|
70
+ return [] unless item.is_a?(Group)
71
+
72
+ a = []
73
+ a << item if item.owner == owner
74
+ a += item.subgroups_owned_by(owner)
75
+ a
76
+ end.compact
77
+ end
78
+
79
+ def title
80
+ @list.first.to_s
81
+ end
82
+
83
+ def create_subgroup
84
+ group = self.class.new
85
+ group.parent = self
86
+ @list << group
87
+ group
88
+ end
89
+
90
+ def add(line)
91
+ line.parent = self
92
+ @list << line
93
+ end
94
+
95
+ def insert(line)
96
+ line.parent = self
97
+ index = insert_at_index(line)
98
+ @list.insert(index, line)
99
+ end
100
+
101
+ def remove(line)
102
+ @list.safe_delete(line)
103
+ remove! unless any?(Pattern)
104
+ end
105
+
106
+ def remove!
107
+ @list.clear
108
+ parent&.remove(self)
109
+ self.parent = nil
110
+ end
111
+
112
+ def ==(other)
113
+ other.kind_of?(Group) && other.list == list
114
+ end
115
+
116
+ protected
117
+
118
+ attr_accessor :list
119
+
120
+ private
121
+
122
+ def all_owners
123
+ flat_map do |item|
124
+ item.owners if item.pattern?
125
+ end.compact
126
+ end
127
+
128
+ def insert_at_index(line)
129
+ patterns = @list.grep(Pattern)
130
+ new_patterns_sorted = patterns.dup.push(line).sort
131
+ new_pattern_index = new_patterns_sorted.index { |l| l.equal? line }
132
+
133
+ if new_pattern_index > 0 # rubocop:disable Style/NumericPredicate
134
+ new_pattern_index + 1
135
+ else
136
+ find_last_line_of_initial_comments
137
+ end
138
+ end
139
+
140
+ def find_last_line_of_initial_comments
141
+ @list.each_with_index do |item, index|
142
+ return index unless item.is_a?(Comment)
143
+ end
144
+ 0
145
+ end
146
+ end
147
+ end
148
+ end