# RBS Collection manager

`rbs collection` sub command manages third party gems' RBS. In short, it is `bundler` for RBS.

## Requirements

* `git(1)`
* `Gemfile.lock`

## Usage

### Setup

First, generate the configuration file, `rbs_collection.yaml`, with `rbs collection init`.

```console
$ rbs collection init
created: rbs_collection.yaml

$ cat rbs_collection.yaml
# Download sources
sources:
  - name: ruby/gem_rbs_collection
    remote: https://github.com/ruby/gem_rbs_collection.git
    revision: main
    repo_dir: gems

# A directory to install the downloaded RBSs
path: .gem_rbs_collection

# gems:
#   # If you want to avoid installing rbs files for gems, you can specify them here.
#   - name: GEM_NAME
#     ignore: true
```

I also recommend updating `.gitignore`.

```console
$ echo /.gem_rbs_collection/ >> .gitignore
```

### Install dependencies

Then, install gems' RBS with `rbs collection install`! It copies RBS from [the gem RBS repository](https://github.com/ruby/gem_rbs_collection) to `.gem_rbs_collection/` directory by default.
I recommend to ignore `.gem_rbs_collection/` from version control system, such as Git.

```console
$ rbs collection install
Installing ast:2.4 (ruby/gem_rbs_collection@4b1a2a2f64c)
...
It's done! 42 gems's RBSs now installed.
```

Finally the third party RBSs are available! `rbs` commands, such as `rbs validate`, automatically load the third party RBSs.

### Other commands

`rbs collection` has two more commands.

* `rbs collection update` updates `rbs_collection.lock.yaml`.
* `rbs collection clean` removes unnecessary rbs from `.gem_rbs_collection` directory.

## Configuration

### `rbs_collection.yaml`

Configure `rbs collection` with editing `rbs_collection.yaml`.

```yaml
# rbs_collection.yaml

# Download sources.
# You can add own collection git repository.
sources:
  - name: ruby/gem_rbs_collection
    remote: https://github.com/ruby/gem_rbs_collection.git
    revision: main
    repo_dir: gems

  # You can also add a local path as a collection source optionally.
  - type: local
    path: path/to/local/dir

# A directory to install the downloaded RBSs
path: .gem_rbs_collection

gems:
  # If the Gemfile.lock doesn't contain csv gem but you use csv gem,
  # you can write the gem name explicitly to install RBS of the gem.
  - name: csv

  # If the Gemfile.lock contains nokogiri gem but you don't want to use the RBS,
  # you can ignore the gem.
  # `rbs collection` avoids to install nokogiri gem's RBS by this change.
  # It is useful if the nokogiri RBS has a problem, such as compatibility issue with other RBS.
  - name: nokogiri
    ignore: true
```

### Avoid installing RBS

There are two ways to avoid RBS installation.

#### `require: false` in `Gemfile`

First, you can specify `require: false` in `Gemfile`. It is the recommended way to avoid installing RBS.
For example:

```ruby
# Gemfile

gem 'GEM_NAME', require: false
```

In this case, `rbs collection` doesn't install the RBS of `GEM_NAME`.
We recommend to specify `require: false` for `rbs` gem itself because `rbs` gem's RBS file is not necessary in most cases.

#### `ignore: true` in `rbs_collection.yaml`

Second, you can write `ignore: true` in `rbs_collection.yaml`. It is useful if you want to avoid installing RBS but you need to require the gem.

```yaml
# rbs_collection.yaml

gems:
  - name: GEM_NAME
    ignore: true
```

#### Load RBS specified `require: false`

You can also use `ignore: false` if you want to install RBS for a gem which you specify `require: false` in `Gemfile`.
For example:

```ruby
# Gemfile

gem 'GEM_NAME', require: false
```

```yaml
# rbs_collection.yaml

gems:
  - name: GEM_NAME
    ignore: false
```

In this case, `rbs collection` installs the RBS of `GEM_NAME`.

### `manifest.yaml`

If you are a gem maintainer, you can write `manifest.yaml`.
You need to put the file if the gem has implicit dependencies, which don't appear in `Gemfile.lock`. You have to write standard libraries' dependencies in most cases.
For example:

```yaml
# manifest.yaml

dependencies:
  # If your gem depends on pathname but the gemspec doesn't include pathname,
  # you need to write the following.
  - name: pathname
```

If the gem's RBS is managed with [ruby/gem_rbs_collection](https://github.com/ruby/gem_rbs_collection), put it as `gems/GEM_NAME/VERSION/manifest.yaml`.  For example, `gems/activesupport/6.0/manifest.yaml`.
If the gem's RBS is included in the gem package, put it as `sig/manifest.yaml`.


## Files / Directories

* `rbs_collection.yaml`
  * The configuration file.
  * You need to edit it if:
    * You don't want to ignore gem's RBS.
    * You want to add gem's RBS explicitly.
  * You can change the file path with `--collection` option. e.g. `rbs --collection another_conf.yaml collection install`.
* `rbs_collection.lock.yaml`
  * RBS installs and loads RBS files with this file.
  * It is auto-generated file. Do not edit this file.
  * I recommend to manage it with VCS such as git.
* `.gem_rbs_collection/`
  * RBS installs third party RBS files to the directory.
  * I recommend to ignore it from VCS.
  * You can change the path with `path` option of `rbs_collection.yaml` file.


## How it works

`rbs collection` is integrated with Bundler.
`rbs collection install` command generates `gem_rbs_collection.lock.yaml` from `gem_rbs_collection.yaml` and `Gemfile.lock`. It uses `Gemfile.lock` to detects dependencies.
