|
1 |
| -# code_ownership |
| 1 | +# CodeOwnership |
| 2 | +This gem helps engineering teams declare ownership of code. |
| 3 | + |
| 4 | +Check out `lib/code_ownership.rb` to see the public API. |
| 5 | + |
| 6 | +Check out `code_ownership_spec.rb` to see examples of how code ownership is used. |
| 7 | + |
| 8 | +## Usage: Declaring Ownership |
| 9 | +There are three ways to declare code ownership using this gem. |
| 10 | +### Package-Based Ownership |
| 11 | +Package based ownership integrates [`packwerk`](https://github.com/Shopify/packwerk) and has ownership defined per package. To define that all files within a package are owned by one team, configure your `package.yml` like this: |
| 12 | +```yml |
| 13 | +enforce_dependency: true |
| 14 | +enforce_privacy: true |
| 15 | +metadata: |
| 16 | + owner: Team |
| 17 | +``` |
| 18 | +
|
| 19 | +### Glob-Based Ownership |
| 20 | +In your team's configured YML (see [`bigrails-teams`](https://github.com/bigrails/bigrails-teams)), you can set `owned_globs` to be a glob of files your team owns. For example, in `my_team.yml`: |
| 21 | +```yml |
| 22 | +name: My Team |
| 23 | +owned_globs: |
| 24 | + - app/services/stuff_belonging_to_my_team/**/** |
| 25 | + - app/controllers/other_stuff_belonging_to_my_team/**/** |
| 26 | +``` |
| 27 | +### File-Annotation Based Ownership |
| 28 | +File annotations are a last resort if there is no clear home for your code. File annotations go at the top of your file, and look like this: |
| 29 | +```ruby |
| 30 | +# @team MyTeam |
| 31 | +``` |
| 32 | +## Usage: Reading CodeOwnership |
| 33 | +### `for_file` |
| 34 | +`CodeOwnership.for_file`, given a relative path to a file returns a `Teams::Team` if there is a team that owns the file, `nil` otherwise. |
| 35 | + |
| 36 | +```ruby |
| 37 | +CodeOwnership.for_file('path/to/file/relative/to/application/root.rb') |
| 38 | +``` |
| 39 | + |
| 40 | +Contributor note: If you are making updates to this method or the methods getting used here, please benchmark the performance of the new implementation against the current for both `for_files` and `for_file` (with 1, 100, 1000 files). |
| 41 | + |
| 42 | +See `code_ownership_spec.rb` for examples. |
| 43 | + |
| 44 | +### `for_backtrace` |
| 45 | +`CodeOwnership.for_backtrace` can be given a backtrace and will either return `nil`, or a `Teams::Team`. |
| 46 | + |
| 47 | +```ruby |
| 48 | +CodeOwnership.for_backtrace(exception.backtrace) |
| 49 | +``` |
| 50 | + |
| 51 | +This will go through the backtrace, and return the first found owner of the files associated with frames within the backtrace. |
| 52 | + |
| 53 | +See `code_ownership_spec.rb` for an example. |
| 54 | + |
| 55 | +### `for_class` |
| 56 | + |
| 57 | +`CodeOwnership.for_class` can be given a class and will either return `nil`, or a `Teams::Team`. |
| 58 | + |
| 59 | +```ruby |
| 60 | +CodeOwnership.for_class(MyClass.name) |
| 61 | +``` |
| 62 | + |
| 63 | +Under the hood, this finds the file where the class is defined and returns the owner of that file. |
| 64 | + |
| 65 | +See `code_ownership_spec.rb` for an example. |
| 66 | + |
| 67 | +## Usage: Generating a `CODEOWNERS` file |
| 68 | + |
| 69 | +A `CODEOWNERS` file defines who owns specific files or paths in a repository. When you run `bin/codeownership validate`, a `.github/CODEOWNERS` file will automatically be generated and updated. |
| 70 | + |
| 71 | +## Proper Configuration & Validation |
| 72 | +CodeOwnership comes with a validation function to ensure the following things are true: |
| 73 | +1) Only one mechanism is defining file ownership. That is -- you can't have a file annotation on a file owned via package-based or glob-based ownership. This helps make ownership behavior more clear by avoiding concerns about precedence. |
| 74 | +2) All teams referenced as an owner for any file or package is a valid team (i.e. it's in the list of `Teams.all`). |
| 75 | +3) All files have ownership. You can specify in `unowned_globs` to represent a TODO list of files to add ownership to. |
| 76 | +3) The `.github/CODEOWNERS` file is up to date. This is automatically corrected and staged unless specified otherwise with `bin/codeownership validate --skip-autocorrect --skip-stage`. You can turn this validation off by setting `skip_codeowners_validation: true` in `code_ownership.yml`. |
| 77 | + |
| 78 | +CodeOwnership also allows you to specify which globs and file extensions should be considered ownable. |
| 79 | + |
| 80 | +Here is an example `config/code_ownership.yml`. |
| 81 | +```yml |
| 82 | +owned_globs: |
| 83 | + - '{app,components,config,frontend,lib,packs,spec}/**/*.{rb,rake,js,jsx,ts,tsx}' |
| 84 | +unowned_globs: |
| 85 | + - db/**/* |
| 86 | + - app/services/some_file1.rb |
| 87 | + - app/services/some_file2.rb |
| 88 | + - frontend/javascripts/**/__generated__/**/* |
| 89 | +``` |
| 90 | +You can call the validation function with the Ruby API |
| 91 | +```ruby |
| 92 | +CodeOwnership.validate! |
| 93 | +``` |
| 94 | +or the CLI |
| 95 | +``` |
| 96 | +bin/codeownership validate |
| 97 | +``` |
| 98 | +
|
| 99 | +## Development |
| 100 | +
|
| 101 | +Please add to `CHANGELOG.md` and this `README.md` when you make make changes. |
0 commit comments