codeowners-checker 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +12 -0
- data/.projections.json +4 -0
- data/.rspec +3 -0
- data/.rubocop.yml +28 -0
- data/.travis.yml +5 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +78 -0
- data/Guardfile +39 -0
- data/LICENSE.txt +21 -0
- data/README.md +171 -0
- data/Rakefile +10 -0
- data/bin/codeowners-checker +8 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/codeowners-checker.gemspec +34 -0
- data/demos/missing_reference.svg +1 -0
- data/demos/useless_pattern.svg +1 -0
- data/lib/codeowners/checker.rb +123 -0
- data/lib/codeowners/checker/array.rb +15 -0
- data/lib/codeowners/checker/code_owners.rb +54 -0
- data/lib/codeowners/checker/file_as_array.rb +29 -0
- data/lib/codeowners/checker/group.rb +148 -0
- data/lib/codeowners/checker/group/comment.rb +32 -0
- data/lib/codeowners/checker/group/empty.rb +16 -0
- data/lib/codeowners/checker/group/group_begin_comment.rb +17 -0
- data/lib/codeowners/checker/group/group_end_comment.rb +17 -0
- data/lib/codeowners/checker/group/line.rb +83 -0
- data/lib/codeowners/checker/group/pattern.rb +46 -0
- data/lib/codeowners/checker/group/unrecognized_line.rb +13 -0
- data/lib/codeowners/checker/line_grouper.rb +106 -0
- data/lib/codeowners/checker/version.rb +7 -0
- data/lib/codeowners/cli/base.rb +34 -0
- data/lib/codeowners/cli/check.rb +8 -0
- data/lib/codeowners/cli/config.rb +24 -0
- data/lib/codeowners/cli/filter.rb +63 -0
- data/lib/codeowners/cli/main.rb +183 -0
- data/lib/codeowners/config.rb +48 -0
- metadata +239 -0
data/Rakefile
ADDED
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,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">"app/controllers/application_controller.rb".</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">"lib/invoices.rb".</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">"app/controllers/application_controller.rb".</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">"lib/invoices.rb".</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">"app/models/billng.rb"</text><text x="31.062" y="1.67" class="f">doesn'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">"app/models/billing.rb"?</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">"lib/security/*"</text><text x="25.05" y="1.67" class="f">doesn'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">".rubo.yml"</text><text x="20.04" y="1.67" class="f">doesn'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">"db"?</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">".rubo.yml"</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">".rubo.yml"</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">".rubo.yml"</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">".rubo.yml"</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">".rubo.yml"</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">".rubo.yml"</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">".rubo.yml"</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">".rubo.yml"</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">".rubo.yml"</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">".rubo.yml"</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">".rubo.yml"</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">".rubo.yml"</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">".rubo.yml"</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
|