= Bundler

== Bundler/DuplicatedGem

|===
| Enabled by default | Safe | Supports autocorrection | Version Added | Version Changed

| Enabled
| Yes
| No
| 0.46
| -
|===

A Gem's requirements should be listed only once in a Gemfile.

=== Examples

[source,ruby]
----
# bad
gem 'rubocop'
gem 'rubocop'

# bad
group :development do
  gem 'rubocop'
end

group :test do
  gem 'rubocop'
end

# good
group :development, :test do
  gem 'rubocop'
end

# good
gem 'rubocop', groups: [:development, :test]

# good - conditional declaration
if Dir.exist?(local)
  gem 'rubocop', path: local
elsif ENV['RUBOCOP_VERSION'] == 'master'
  gem 'rubocop', git: 'https://github.com/rubocop/rubocop.git'
else
  gem 'rubocop', '~> 0.90.0'
end
----

=== Configurable attributes

|===
| Name | Default value | Configurable values

| Include
| `+**/*.gemfile+`, `+**/Gemfile+`, `+**/gems.rb+`
| Array
|===

== Bundler/GemComment

|===
| Enabled by default | Safe | Supports autocorrection | Version Added | Version Changed

| Disabled
| Yes
| No
| 0.59
| 0.85
|===

Each gem in the Gemfile should have a comment explaining
its purpose in the project, or the reason for its version
or source.

The optional "OnlyFor" configuration array
can be used to only register offenses when the gems
use certain options or have version specifiers.

When "version_specifiers" is included, a comment
will be enforced if the gem has any version specifier.

When "restrictive_version_specifiers" is included, a comment
will be enforced if the gem has a version specifier that
holds back the version of the gem.

For any other value in the array, a comment will be enforced for
a gem if an option by the same name is present.
A useful use case is to enforce a comment when using
options that change the source of a gem:

- `bitbucket`
- `gist`
- `git`
- `github`
- `source`

For a full list of options supported by bundler,
see https://bundler.io/man/gemfile.5.html
.

=== Examples

==== OnlyFor: [] (default)

[source,ruby]
----
# bad

gem 'foo'

# good

# Helpers for the foo things.
gem 'foo'
----

==== OnlyFor: ['version_specifiers']

[source,ruby]
----
# bad

gem 'foo', '< 2.1'

# good

# Version 2.1 introduces breaking change baz
gem 'foo', '< 2.1'
----

==== OnlyFor: ['restrictive_version_specifiers']

[source,ruby]
----
# bad

gem 'foo', '< 2.1'

# good

gem 'foo', '>= 1.0'

# Version 2.1 introduces breaking change baz
gem 'foo', '< 2.1'
----

==== OnlyFor: ['version_specifiers', 'github']

[source,ruby]
----
# bad

gem 'foo', github: 'some_account/some_fork_of_foo'

gem 'bar', '< 2.1'

# good

# Using this fork because baz
gem 'foo', github: 'some_account/some_fork_of_foo'

# Version 2.1 introduces breaking change baz
gem 'bar', '< 2.1'
----

=== Configurable attributes

|===
| Name | Default value | Configurable values

| Include
| `+**/*.gemfile+`, `+**/Gemfile+`, `+**/gems.rb+`
| Array

| IgnoredGems
| `[]`
| Array

| OnlyFor
| `[]`
| Array
|===

== Bundler/GemFilename

|===
| Enabled by default | Safe | Supports autocorrection | Version Added | Version Changed

| Enabled
| Yes
| No
| 1.20
| -
|===

Verifies that a project contains Gemfile or gems.rb file and correct
associated lock file based on the configuration.

=== Examples

==== EnforcedStyle: Gemfile (default)

[source,ruby]
----
# bad
Project contains gems.rb and gems.locked files

# bad
Project contains Gemfile and gems.locked file

# good
Project contains Gemfile and Gemfile.lock
----

==== EnforcedStyle: gems.rb

[source,ruby]
----
# bad
Project contains Gemfile and Gemfile.lock files

# bad
Project contains gems.rb and Gemfile.lock file

# good
Project contains gems.rb and gems.locked files
----

=== Configurable attributes

|===
| Name | Default value | Configurable values

| EnforcedStyle
| `Gemfile`
| `Gemfile`, `gems.rb`

| Include
| `+**/Gemfile+`, `+**/gems.rb+`, `+**/Gemfile.lock+`, `+**/gems.locked+`
| Array
|===

== Bundler/GemVersion

|===
| Enabled by default | Safe | Supports autocorrection | Version Added | Version Changed

| Disabled
| Yes
| No
| 1.14
| -
|===

Enforce that Gem version specifications or a commit reference (branch,
ref, or tag) are either required or forbidden.

=== Examples

==== EnforcedStyle: required (default)

[source,ruby]
----
# bad
gem 'rubocop'

# good
gem 'rubocop', '~> 1.12'

# good
gem 'rubocop', '>= 1.10.0'

# good
gem 'rubocop', '>= 1.5.0', '< 1.10.0'

# good
gem 'rubocop', branch: 'feature-branch'

# good
gem 'rubocop', ref: '74b5bfbb2c4b6fd6cdbbc7254bd7084b36e0c85b'

# good
gem 'rubocop', tag: 'v1.17.0'
----

==== EnforcedStyle: forbidden

[source,ruby]
----
# good
gem 'rubocop'

# bad
gem 'rubocop', '~> 1.12'

# bad
gem 'rubocop', '>= 1.10.0'

# bad
gem 'rubocop', '>= 1.5.0', '< 1.10.0'

# bad
gem 'rubocop', branch: 'feature-branch'

# bad
gem 'rubocop', ref: '74b5bfbb2c4b6fd6cdbbc7254bd7084b36e0c85b'

# bad
gem 'rubocop', tag: 'v1.17.0'
----

=== Configurable attributes

|===
| Name | Default value | Configurable values

| EnforcedStyle
| `required`
| `required`, `forbidden`

| Include
| `+**/*.gemfile+`, `+**/Gemfile+`, `+**/gems.rb+`
| Array

| AllowedGems
| `[]`
| Array
|===

== Bundler/InsecureProtocolSource

|===
| Enabled by default | Safe | Supports autocorrection | Version Added | Version Changed

| Enabled
| Yes
| Yes
| 0.50
| -
|===

Passing symbol arguments to `source` (e.g. `source :rubygems`) is
deprecated because they default to using HTTP requests. Instead, specify
`'https://rubygems.org'` if possible, or `'http://rubygems.org'` if not.

When autocorrecting, this cop will replace symbol arguments with
`'https://rubygems.org'`.

This cop will not replace existing sources that use `http://`. This may
be necessary where HTTPS is not available. For example, where using an
internal gem server via an intranet, or where HTTPS is prohibited.
However, you should strongly prefer `https://` where possible, as it is
more secure.

If you don't allow `http://`, please set `false` to `AllowHttpProtocol`.
This option is `true` by default for safe autocorrection.

=== Examples

[source,ruby]
----
# bad
source :gemcutter
source :rubygems
source :rubyforge

# good
source 'https://rubygems.org' # strongly recommended
----

==== AllowHttpProtocol: true (default)

[source,ruby]
----
# good
source 'http://rubygems.org' # use only if HTTPS is unavailable
----

==== AllowHttpProtocol: false

[source,ruby]
----
# bad
source 'http://rubygems.org'
----

=== Configurable attributes

|===
| Name | Default value | Configurable values

| AllowHttpProtocol
| `true`
| Boolean

| Include
| `+**/*.gemfile+`, `+**/Gemfile+`, `+**/gems.rb+`
| Array
|===

== Bundler/OrderedGems

|===
| Enabled by default | Safe | Supports autocorrection | Version Added | Version Changed

| Enabled
| Yes
| Yes
| 0.46
| 0.47
|===

Gems should be alphabetically sorted within groups.

=== Examples

[source,ruby]
----
# bad
gem 'rubocop'
gem 'rspec'

# good
gem 'rspec'
gem 'rubocop'

# good
gem 'rubocop'

gem 'rspec'

# good only if TreatCommentsAsGroupSeparators is true
# For code quality
gem 'rubocop'
# For tests
gem 'rspec'
----

=== Configurable attributes

|===
| Name | Default value | Configurable values

| TreatCommentsAsGroupSeparators
| `true`
| Boolean

| ConsiderPunctuation
| `false`
| Boolean

| Include
| `+**/*.gemfile+`, `+**/Gemfile+`, `+**/gems.rb+`
| Array
|===
