Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
* [#2554](https://github.com/ruby-grape/grape/pull/2554): Remove `Grape::Http::Headers` and `Grape::Util::Lazy::Object` - [@ericproulx](https://github.com/ericproulx).
* [#2556](https://github.com/ruby-grape/grape/pull/2556): Remove unused `Grape::Request::DEFAULT_PARAMS_BUILDER` constant - [@eriklovmo](https://github.com/eriklovmo).
* [#2558](https://github.com/ruby-grape/grape/pull/2558): Add Ruby's option `enable_frozen_string_literal` in CI - [@ericproulx](https://github.com/ericproulx).
* [#2557](https://github.com/ruby-grape/grape/pull/2557): Add lint! - [@ericproulx](https://github.com/ericproulx).
* Your contribution here.

#### Fixes
Expand Down
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
- [Header](#header)
- [Accept-Version Header](#accept-version-header)
- [Param](#param)
- [Linting](#linting)
- [Bug in Rack::ETag under Rack 3.X](#bug-in-racketag-under-rack-3x)
- [Describing Methods](#describing-methods)
- [Configuration](#configuration)
- [Parameters](#parameters)
Expand Down Expand Up @@ -650,6 +652,25 @@ version 'v1', using: :param, parameter: 'v'
curl http://localhost:9292/statuses/public_timeline?v=v1


## Linting

You can check if your API is in conformance with [Rack's specification](https://github.com/rack/rack/blob/main/SPEC.rdoc) by calling `lint!` at the API level or through [configuration](#configuration):
```ruby
# API Level
class Api < Grape::API
lint!
end
# OR through configuration
Grape.configure do |config|
config.lint = true
end
# OR
Grape.config.lint = true
```

### Bug in Rack::ETag under Rack 3.X
If you're using Rack 3.X and the `Rack::Etag` middleware (used by [Rails](https://guides.rubyonrails.org/rails_on_rack.html#inspecting-middleware-stack)), a [bug](https://github.com/rack/rack/pull/2324) related to linting has been fixed in [3.1.13](https://github.com/rack/rack/blob/v3.1.13/CHANGELOG.md#3113---2025-04-13) and [3.0.15](https://github.com/rack/rack/blob/v3.1.13/CHANGELOG.md#3015---2025-04-13) respectively.

## Describing Methods

You can add a description to API methods and namespaces. The description would be used by [grape-swagger][grape-swagger] to generate swagger compliant documentation.
Expand Down
2 changes: 1 addition & 1 deletion UPGRADING.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ When using together with `Grape::Extensions::Hash::ParamBuilder`, `route_param`
This was a regression introduced by [#2326](https://github.com/ruby-grape/grape/pull/2326) in Grape v1.8.0.

```ruby
grape.configure do |config|
Grape.configure do |config|
config.param_builder = Grape::Extensions::Hash::ParamBuilder
end

Expand Down
2 changes: 1 addition & 1 deletion docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ ENV RUBYOPT --enable-frozen-string-literal --yjit
ENV LD_PRELOAD libjemalloc.so.2
ENV MALLOC_CONF dirty_decay_ms:1000,narenas:2,background_thread:true

RUN apk add --update --no-cache make gcc git libc-dev gcompat jemalloc && \
RUN apk add --update --no-cache make gcc git libc-dev yaml-dev gcompat jemalloc && \
gem update --system && gem install bundler

WORKDIR $LIB_PATH
Expand Down
1 change: 1 addition & 0 deletions lib/grape.rb
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ def self.deprecator

configure do |config|
config.param_builder = :hash_with_indifferent_access
config.lint = false
config.compile_methods!
end
end
Expand Down
4 changes: 4 additions & 0 deletions lib/grape/dsl/routing.rb
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ def do_not_route_options!
namespace_inheritable(:do_not_route_options, true)
end

def lint!
namespace_inheritable(:lint, true)
end

def do_not_document!
namespace_inheritable(:do_not_document, true)
end
Expand Down
5 changes: 5 additions & 0 deletions lib/grape/endpoint.rb
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,7 @@ def build_stack(helpers)
format = namespace_inheritable(:format)

stack.use Rack::Head
stack.use Rack::Lint if lint?
stack.use Class.new(Grape::Middleware::Error),
helpers: helpers,
format: format,
Expand Down Expand Up @@ -408,5 +409,9 @@ def build_response_cookies
Rack::Utils.set_cookie_header! header, name, cookie_value
end
end

def lint?
namespace_inheritable(:lint) || Grape.config.lint
end
end
end
22 changes: 22 additions & 0 deletions spec/grape/api_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4738,4 +4738,26 @@ def uniqe_id_route
expect(last_response.body).to eq('unknown params_builder: unknown')
end
end

describe '.lint!' do
let(:app) do
Class.new(described_class) do
lint!
get '/' do
status 42
end
end
end

around do |example|
Grape.config.lint = false
example.run
Grape.config.lint = true
end

it 'raises a Rack::Lint error' do
# Status must be an Integer >= 100
expect { get '/' }.to raise_error(Rack::Lint::LintError)
end
end
end
7 changes: 4 additions & 3 deletions spec/integration/rails/mounting_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
ActiveSupport::Dependencies.autoload_paths = []
ActiveSupport::Dependencies.autoload_once_paths = []

Class.new(Rails::Application) do
app = Class.new(Rails::Application) do
config.eager_load = false
config.load_defaults "#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}"
config.api_only = true
Expand All @@ -28,15 +28,16 @@
mount GrapeApi => '/'

get 'up', to: lambda { |_env|
['200', {}, ['hello world']]
[200, {}, ['hello world']]
}
end
end
app.initialize!
Rack::Lint.new(app)
end

before do
stub_const('GrapeApi', api)
app.initialize!
end

it 'cascades' do
Expand Down
1 change: 1 addition & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
end
end

Grape.config.lint = true # lint all apis by default
Grape::Util::Registry.include(Deregister)
# issue with ruby 2.7 with ^. We need to extend it again
Grape::Validations.extend(Grape::Util::Registry) if Gem::Version.new(RUBY_VERSION).release < Gem::Version.new('3.0')
Expand Down