toptal / codeowners-checker Goto Github PK
View Code? Open in Web Editor NEWCheck .github/CODEOWNERS consistency
License: MIT License
Check .github/CODEOWNERS consistency
License: MIT License
codeowners-checker
uses yield_self
, which requires Ruby 2.5. However, it happily installs under Ruby 2.4.
$ ruby -v
ruby 2.4.4p296 (2018-03-28 revision 63013) [x86_64-linux]
$ codeowners-checker check
/home/test-user/.gem/ruby/gems/codeowners-checker-1.0.1/lib/codeowners/checker/code_owners.rb:41:in `list': undefined method `yield_self' for []:Array (NoMethodError)
When running the fetch command via CLI, an error indicates the command does not exist:
$ codeowners-checker fetch
Could not find command "fetch".
I installed via gem install codeowners-checker
, which may not have updated the gemspec since the change was made (?)
http://egonschiele.github.io/contracts.ruby
Optionally we could use method overloading
Add options for executing only one action of the checker instead of always running all of them. Use --only
or --except
options for checking only for added or deleted files.
I have a scenario in my CODEOWNERS file, which I define as the owner of a path is @ghost because it's a trick to avoid getting review requests. The problem is that when I run the checker through GH actions, it returns this error:
[err] line 13: User "@ghost" is not a member of the organization
(because in fact, this "user" does not exist)
Reading the documentation, I thought that perhaps not_owned_checker_skip_patterns
could solve this problem. But I couldn't solve it ๐ข
Do you have any other ideas?
Thanks ๐ท
Right now descendant's of Line
use parse
in initialize
(mostly Pattern
) and the initialize
method always takes a raw line as param. Because of this we can not initialize the Pattern with pattern, *owners
and always need to parse.
Move the parse
to be class method so in Line.build
would call return klass.parse(line) if klass.match?(line)
and for patterns Pattern.parse
would call Pattern.new(pattern, *owners)
and now Pattern.new
becomes available for building pattern lines.
When running the checker with --no-interactive
option, it lists new files which were introduced and patterns which are contained in the CODEOWNERS file but missing in the repository. However, when an unrecognized line is found it is not listed as an inconsistency.
The unrecognized lines should be listed as part of the inconsistencies.
Some PR's with a lot of files are triggered by Github to be reviewed by multiple teams, add an option to show a list of files give a PR and team / person (might be hard to interpolate person from team)
Simplecov
When checking for new files and suggesting subgroups, if a pattern is chosen to be added at end of the CODEOWNERS file once, the method subgroups_owned_by
always returns an empty array for the following patterns even if groups should be found. As a result, the only option is to add the patterns at the end of the file.
codeowners-checker/lib/codeowners/checker.rb
Line 118 in 2115f48
Github and Gitlab have different ideas on where to look for the CODEOWNERS
file:
Find out which order we should use and fix it, if necessary contact Github/Gitlab to fix the order.
It is possible we might need to check the repository remote(s) to decide on an order.
Another consideration is we might actually issue a warning if there are multiple files. (add tests for having multiple files)
Hi Folks, I want to share some thoughts that I've been having while playing around with this gem and implementing the cleanup command.
The reason for opening an issue here is to open space for discussion on these sensitive topics and then we should follow up by creating issues per thing we want to actually do.
DISCLAIMER: This is an attempt to do a mental dump of what is in my head, so I probably missed a lot of points. Also, I've been looking at this thing for less than one week, so I probably made a lot of mistakes, please feel free to correct me. This is the reason why I'm creating the issue. To discuss.
A wild guess is that the direction we want to take with this tool changed drastically over time. It probably started as way to manage CODEOWNERS
in a "easier way" but still very manual, therefore the "interactive mode" and overtime started drifting more towards just reporting errors and automating some fixes (Like rubocop -a
I'd say).
My guess comes from the fact that interactive mode is the default and should be disabled with --no-interactive
.
As all projects as they evolve, a lot of complexity arises and here I'll make some bold suggestions on removing features to make the code simpler and then being able to move forward in a smooth way.
Take these suggestions with a grain of salt as they come from my very narrow experience with this and talks with @jonatas and @dennissivia.
With that in mind, the two things I'd remove are:
CODEOWNERS
: I don't see value on extending the "AST" of a CODEOWNERS file to make it look like it is structured with "groups". We are "inventing" special comments to group things. I'd just treat the CODEOWNERS file as it is: a list of rules, comments and blank lines (and occasionally, some malformed lines that should be reported). I think this is not that complex.Again, this is based on my conversations with @jonatas and @dennissivia, so take again with a grain of salt.
We want to:
With that in mind, I I'd like to make some suggestions on features/architectural changes we should do before:
--from
and --to
--from
and --to
), and somehow diffing the generated problemsWe have currently 4 checks that we implement:
As far as #80 goes, I think the best way to address some of it's points are by creating new checks:
@name
, @org/team
, [email protected]
)file @owner @owner
, fix: remove duplicate occurrences)!a
is a valid pathspec, but it is not valid to have a in a CODEOWNERS file, and according to the comment of Github staff on this question would make the file unparseable. (fix: just remove the line)If we organize our code with the "Check" and "Problem" model, then I think a nice way of automating fixes in a predictable and discoverable CLI interface is to use the name of the check and maybe some strategy on input. Exemples:
codeowners-check \
--on-rule-without-file remove-rule \
--on-rule-with-nonexistent-owner set-to:@owner \
--on-invalid-rule remove-rule \
--on-file-without-rule set-to:@owner \
--on-duplicate-rule keep-first \
--on-duplicate-owner remove-duplicates
The default behavior would be just warn
or nothing
, which means no fix would be made and the problem would just be warned.
With that, the check could also be disabled altogether. Some suggestions on how to do it
codeowners-check --disable-rule-without-file --disable-invalid-rule
codeowners-check --rule-without-file=false --invalid-rule=false
codeowners-check --disable-checks=rule-without-file,invalid-rule
codeowners-check --checks={all but rule-without-file and invalid-rule}
After some discussion I am suggesting to add a cleanup command to tackle the following problems:
When a CODEOWNERS file becomes bigger the following problems arise:
Add a new command --cleanup
to do the following things.
sorting
Our initial discussion lead to the following proposal:
#21 also asks for some of these topics.
no_whitespace
, preserve
and enforce
example whitespace painting:
/file.rb @owner
/dir/another.rb @owner
Right now the real lib code mixes with the cli code, it would make it easier to navigate through the sources if they were separated
# Everything
* @owner
# Group1
## Group2
### Group3
directory/alien_file.rb @Michal
=>
# Everything
* @owner
Array.delete
has a bug - it uses ==
to compare objects for removal, but the docs state it uses equal?
- which is not right, we need to open a PR to fix the code / documentation for it.
Solution to this problem we are now using in our code:
https://github.com/toptal/codeowners-checker/blob/20dc8cdd53066228de79bc1ccf90ceae1e91099f/lib/codeowners/checker/array.rb
Examples:
Problems:
CODEOWNERS
or docs/CODEOWNERS
or .github/CODEOWNERS
Ideas:
#!/bin/bash
mkdir .github/
printf "lib/ @jonatas\nspec/ @other" > .github/CODEOWNERS
printf "@jonatas\n@other" > .github/OWNERS
touch lib/foobar.rb
touch spec/foobar.rb
git add lib spec
git commit -m "test"
bin/codeowners-checker check .
# NOTE: Gem recognize new file as the missing owner but they should be identified by the pattern
File added: "lib/foobar.rb". Add owner to the CODEOWNERS file?
(y) yes
(i) ignore
(q) quit and save
[y, i, q] y
Owners:
1 - @jonatas
2 - @other
Choose owner, add new one or leave empty to use "".
New owner: 1
Possible groups to which the pattern belongs:
# NOTE: Gem recognizes the possible group for that file but for spec/foobar.rb it's missing
1 - lib/ @jonatas
Choose group: 1
File added: "spec/foobar.rb". Add owner to the CODEOWNERS file?
(y) yes
(i) ignore
(q) quit and save
[y, i, q] y
Owners:
1 - @jonatas
2 - @other
Choose owner, add new one or leave empty to use "".
New owner: 2
Add to the end of the CODEOWNERS file?
Commit changes? n
as we have matching owners for these new files via patterns I think codeowners shouldn't complain about that so the next output seems what we need to have in this case
โ
File is consistent
Right now when adding a pattern users can specify into which group the pattern should be added, add an option to create new group (and ask where to put it). Main::suggest_subgroups_for_pattern
In https://github.com/toptal/code-ownership-checker#check-file-consistency
We have mentioned binary code-ownership-checker
but the binary in repo is named code-owners-checker
(https://github.com/toptal/code-ownership-checker/blob/master/bin/code-owners-checker)
We have to_tree
implemented already, it would be nice to have a viewer with the groups nesting shown.
Try to find out if there are better charracters to represent the tree then the current:
+ group start
| group continuation (0-*)
\ group end
At the moment all files that do not have an owner are always taking into consideration for the final result. We also introduced a whitelist concept to ignore certain files/directories.
However, for a code-base with a lot of a legacy fixing exiting issues would just block their progress. This is why tools like pronto allow rubocop and other linters to only run against "changed files".
Thus I suggest to add a similar mode for the codeowners-checker so that we can only test the files that have been changed. That flag could be named --pr-mode
or --changed-only
to indicate that only changed files are checked.
This should also have the benefit of being much faster for big code bases.
codeowners-checker/lib/codeowners/checker.rb
Line 117 in 2115f48
This method belongs more as a class method in CodeOwners
class.
for Config
class to work correctly we had to patch the Git tickets are:
after those tickets get merged we can cleanup our patches
When adding a new line / pattern, we need to define the owner. If we already configured it, we could adopt the configuration instead of re-type it.
We could say:
File owner (leave empty to use <configured-owner>):
Or we could say:
New line: pattern @default_owner
With line editing from: https://github.com/piotrmurach/tty-reader
There was one instance where owner/team was wrong and it broke the automatic reviewers process on Github, we should be able to validate owners with either a file or when possible external APIs like Github or Gitlab.
As a first step we could add regexp to validate one of: @person
@company/team
[email protected]
.
The tests are failing for ./spec/codeowners/checker/group/pattern_spec.rb
.
File.fnmatch
for matching patterns
git ignore
for the validations?/
[a-z]
or ?
Is this project no longer being supported? Dependencies are outdated and becoming a problem for utilization.
Our current implementation of matching files using ruby-git is not optimal and is inconsistent with gitignore definition. It ignores /
at the beginning of patterns and doesn't differentiate between *
and **
.
Ideas:
Depends on #21 - configuring which checks to enable
Consider using plugin architecture for finding the checks so the checker can be configured with external gems / libs that can be private or are very specific to a group/company
Usually, you need to check
in the current folder
current changes
against remote master
it is easier to write Code::Ownership::Checker.check!
than providing the same parameters each time.
The current configuration creates a default team in a git config file and we're probably going to expand to multiple teams and other details.
The intent here is to extend and introduce a decent configuration level:
Extending configuration can be also useful for future ideas like blacklist or ignore certain folders or files that the code owners will never cover.
Dependabot can't evaluate your Ruby dependency files.
As a result, Dependabot couldn't check whether any of your dependencies are out-of-date.
The error Dependabot encountered was:
Bundler::Dsl::DSLError with message:
[!] There was an error parsing `Gemfile`:
[!] There was an error while loading `codeowners-checker.gemspec`: uninitialized constant Codeowners. Bundler cannot continue.
# from /home/dependabot/dependabot-updater/dependabot_tmp_dir/codeowners-checker.gemspec:42
# -------------------------------------------
# unless ENV['TRAVIS']
> unless Codeowners::Cli::SuggestFileFromPattern.installed_fzf?
# "sanitized"
# -------------------------------------------
. Bundler cannot continue.
# from /home/dependabot/dependabot-updater/dependabot_tmp_dir/Gemfile:5
# -------------------------------------------
#
> gemspec
# -------------------------------------------
You can mention @dependabot in the comments below to contact the Dependabot team.
I'm using a GitHub app to make API requests, which gives allows me to set finer permissions than through a personal access token. As I was looking through the code I didn't see the ability to pass a bearer token to the tool.
Would you merge the feature to authenticate with a bearer token if I would build it out?
Replace all user interaction with tty-reader gem.
Make sure we also consider this.
The https://github.com/toptal/codeowners-checker seems like a great candidate to be open source.
The code is not related to our core and the tool can be useful for other companies that use the same ownership boundaries.
The objective of the task is:
I suggest adding a command to automatically add changed files (that don't match any existing rule) to the given owner. This would allow a contributor to assign all the changes to a given team.
Instead of manual changes, the author would be able to just assign all changed files to a given team.
This is just a suggestion to have a concrete examples, I would be happy to discuss better options
codeowners-checker --auto-add @mycomp/team1
The checker will automatically find all files, create the smallest amount of patterns (optional)
and add these rules to the codeowners file. Since inferring the most effective pattern seems hard, we could also start with simple approaches and automatically open an editor or something like that.
Checks should be executed in this order:
It should be possible to configure which checks to run (git config?)
We created an example of a useless pattern named Gumfile
that should suggest Gemfile
but the Gemfile is already in place in the code owners file. In this case, it should suggest to add one more owner instead of adding a new line to the owners' file. Or suggest to delete the line, or ignore the suggestion.
We're not sure about the best approach, we need to research and see what fits better for our flow.
Analyzing the issue we brought the following points:
If we suggest something that is already in the code owners we're going to duplicate the ownership lines.
If we find multiple patterns matching the same file, and the pattern is generic, covering a folder, it's ok.
But, if the pattern is only covering one file and it's duplicated in the code owners definition we could merge the owners and make it a single line.
We're confused with the direction of the implementation:
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.