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.
- 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
|