rspec-openapi 0.26.0 → 0.28.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -27,7 +27,7 @@ class << RSpec::OpenAPI::SchemaCleaner = Object.new
27
27
  cleanup_hash!(base, spec, 'paths.*.*')
28
28
 
29
29
  # cleanup parameters
30
- cleanup_array!(base, spec, 'paths.*.*.parameters', %i[name in])
30
+ cleanup_array!(base, spec, 'paths.*.*.parameters', [:name, :in])
31
31
 
32
32
  # cleanup requestBody
33
33
  cleanup_hash!(base, spec, 'paths.*.*.requestBody.content.application/json.schema.properties.*')
@@ -27,12 +27,10 @@ class RSpec::OpenAPI::SchemaFile
27
27
  def read
28
28
  return {} unless File.exist?(@path)
29
29
 
30
- RSpec::OpenAPI::KeyTransformer.symbolize(
31
- YAML.safe_load(
32
- File.read(@path),
33
- permitted_classes: [Date, Time],
34
- ),
35
- ) # this can also parse JSON
30
+ content = YAML.safe_load(File.read(@path), permitted_classes: [Date, Time]) # this can also parse JSON
31
+ return {} if content.nil?
32
+
33
+ RSpec::OpenAPI::KeyTransformer.symbolize(content)
36
34
  end
37
35
 
38
36
  # @param [Hash] spec
@@ -25,37 +25,51 @@ class << RSpec::OpenAPI::SchemaMerger = Object.new
25
25
  return base
26
26
  end
27
27
 
28
- # When the new spec converts an object to a dictionary (introduces
29
- # `additionalProperties` on a node that previously had `properties` /
30
- # `required`), drop the stale fields so the merged result reflects the
31
- # new intent. We only prune when base does not already declare
32
- # `additionalProperties`, to preserve manual edits that intentionally
33
- # combine fixed and dynamic keys.
34
- if spec.is_a?(Hash) && spec.key?(:additionalProperties) && !base.key?(:additionalProperties)
35
- base.delete(:properties)
36
- base.delete(:required)
28
+ prune_stale_object_fields!(base, spec)
29
+
30
+ spec.each { |key, value| merge_entry!(base, key, value) }
31
+ base
32
+ end
33
+
34
+ # When the new spec converts an object to a dictionary (introduces
35
+ # `additionalProperties` on a node that previously had `properties` /
36
+ # `required`), drop the stale fields so the merged result reflects the
37
+ # new intent. We only prune when base does not already declare
38
+ # `additionalProperties`, to preserve manual edits that intentionally
39
+ # combine fixed and dynamic keys.
40
+ def prune_stale_object_fields!(base, spec)
41
+ return unless spec.is_a?(Hash) && spec.key?(:additionalProperties) && !base.key?(:additionalProperties)
42
+
43
+ base.delete(:properties)
44
+ base.delete(:required)
45
+ end
46
+
47
+ def merge_entry!(base, key, value)
48
+ if base[key].is_a?(Hash) && value.is_a?(Hash)
49
+ merge_hash_entry!(base, key, value)
50
+ elsif base[key].is_a?(Array) && value.is_a?(Array)
51
+ # parameters need to be merged as if `name` and `in` were the Hash keys.
52
+ merge_arrays(base, key, value)
53
+ elsif !skip_due_to_additional_properties?(base, key)
54
+ base[key] = value
37
55
  end
56
+ end
38
57
 
39
- spec.each do |key, value|
40
- if base[key].is_a?(Hash) && value.is_a?(Hash)
41
- # Handle example/examples conflict - convert to examples when mixed
42
- normalize_example_fields!(base[key], value)
43
-
44
- # If the new value has oneOf, replace the entire value instead of merging
45
- if value.key?(:oneOf)
46
- base[key] = value
47
- else
48
- merge_schema!(base[key], value) unless base[key].key?(:$ref)
49
- end
50
- elsif base[key].is_a?(Array) && value.is_a?(Array)
51
- # parameters need to be merged as if `name` and `in` were the Hash keys.
52
- merge_arrays(base, key, value)
53
- else
54
- # do not ADD `properties` or `required` fields if `additionalProperties` field is present
55
- base[key] = value unless base.key?(:additionalProperties) && %i[properties required].include?(key)
56
- end
58
+ def merge_hash_entry!(base, key, value)
59
+ # Handle example/examples conflict - convert to examples when mixed
60
+ normalize_example_fields!(base[key], value)
61
+
62
+ # If the new value has oneOf, replace the entire value instead of merging
63
+ if value.key?(:oneOf)
64
+ base[key] = value
65
+ elsif !base[key].key?(:$ref)
66
+ merge_schema!(base[key], value)
57
67
  end
58
- base
68
+ end
69
+
70
+ # do not ADD `properties` or `required` fields if `additionalProperties` field is present
71
+ def skip_due_to_additional_properties?(base, key)
72
+ base.key?(:additionalProperties) && [:properties, :required].include?(key)
59
73
  end
60
74
 
61
75
  def merge_arrays(base, key, value)
@@ -72,21 +86,33 @@ class << RSpec::OpenAPI::SchemaMerger = Object.new
72
86
  end
73
87
 
74
88
  def merge_parameters(base, key, value)
75
- all_parameters = value | base[key]
76
-
77
- unique_base_parameters = build_unique_params(base, key)
78
-
79
- all_parameters = all_parameters.map do |parameter|
80
- base_parameter = unique_base_parameters[[parameter[:name], parameter[:in]]] || {}
81
- if base_parameter.empty?
82
- parameter
89
+ base_params = index_parameters_by_identity(base[key])
90
+ new_params = index_parameters_by_identity(value)
91
+
92
+ base[key] = (base_params.keys | new_params.keys).map do |param_key|
93
+ base_param = base_params[param_key]
94
+ new_param = new_params[param_key]
95
+
96
+ if base_param && new_param
97
+ merge_parameter_with_schema(base_param, new_param)
98
+ elsif new_param
99
+ # Parameter only in the new spec. Treat as optional unless its `required: true`
100
+ # came from explicit `required_request_params` metadata — distinguishable only
101
+ # for `query`, where the schema_builder default is `required: false`. `header`
102
+ # defaults to `required: true`, so the value alone can't signal user intent.
103
+ new_param[:in] == 'query' && new_param[:required] ? new_param : mark_optional_unless_path(new_param)
83
104
  else
84
- merge_parameter_with_schema(base_parameter, parameter)
105
+ mark_optional_unless_path(base_param)
85
106
  end
86
107
  end
108
+ end
109
+
110
+ # OpenAPI requires `in: path` parameters to be `required: true`, so this leaves
111
+ # them untouched.
112
+ def mark_optional_unless_path(parameter)
113
+ return parameter if parameter[:in] == 'path'
87
114
 
88
- all_parameters.uniq! { |param| param.slice(:name, :in) }
89
- base[key] = all_parameters
115
+ parameter.merge(required: false)
90
116
  end
91
117
 
92
118
  def merge_parameter_with_schema(base_param, new_param)
@@ -94,12 +120,18 @@ class << RSpec::OpenAPI::SchemaMerger = Object.new
94
120
  new_schema = new_param[:schema]
95
121
 
96
122
  # If schemas have different types, create a oneOf
97
- if base_schema && new_schema && schemas_have_different_types?(base_schema, new_schema)
98
- merged_schema = merge_schemas_into_one_of(base_schema, new_schema)
99
- base_param.merge(new_param).merge(schema: merged_schema)
100
- else
101
- base_param.merge(new_param)
102
- end
123
+ merged = if base_schema && new_schema && schemas_have_different_types?(base_schema, new_schema)
124
+ merged_schema = merge_schemas_into_one_of(base_schema, new_schema)
125
+ base_param.merge(new_param).merge(schema: merged_schema)
126
+ else
127
+ base_param.merge(new_param)
128
+ end
129
+
130
+ # Once a parameter has been seen missing in any earlier test case, keep it optional
131
+ # even if later test cases mark it required again.
132
+ merged = mark_optional_unless_path(merged) if base_param[:required] == false || new_param[:required] == false
133
+
134
+ merged
103
135
  end
104
136
 
105
137
  def schemas_have_different_types?(schema1, schema2)
@@ -133,10 +165,8 @@ class << RSpec::OpenAPI::SchemaMerger = Object.new
133
165
  end
134
166
  end
135
167
 
136
- def build_unique_params(base, key)
137
- base[key].to_h do |parameter|
138
- [[parameter[:name], parameter[:in]], parameter]
139
- end
168
+ def index_parameters_by_identity(parameters)
169
+ parameters.to_h { |p| [[p[:name], p[:in]], p] }
140
170
  end
141
171
 
142
172
  # Normalize example/examples fields when there's a conflict
@@ -2,6 +2,6 @@
2
2
 
3
3
  module RSpec
4
4
  module OpenAPI
5
- VERSION = '0.26.0'
5
+ VERSION = '0.28.0'
6
6
  end
7
7
  end
data/lib/rspec/openapi.rb CHANGED
@@ -43,10 +43,10 @@ module RSpec::OpenAPI
43
43
  @request_headers = []
44
44
  @servers = []
45
45
  @security_schemes = []
46
- @example_types = %i[request]
46
+ @example_types = [:request]
47
47
  @response_headers = []
48
48
  @path_records = Hash.new { |h, k| h[k] = [] }
49
- @ignored_path_params = %i[controller action format]
49
+ @ignored_path_params = [:controller, :action, :format]
50
50
  @ignored_paths = []
51
51
  @post_process_hook = nil
52
52
 
@@ -22,10 +22,10 @@ Gem::Specification.new do |spec|
22
22
  }
23
23
 
24
24
  spec.files = Dir.chdir(File.expand_path(__dir__)) do
25
- `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
25
+ `git ls-files -z`.split("\x0").select do |f|
26
+ f.start_with?('lib/') || ['LICENSE.txt', 'README.md', 'rspec-openapi.gemspec'].include?(f)
27
+ end
26
28
  end
27
- spec.bindir = 'exe'
28
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
29
29
  spec.require_paths = ['lib']
30
30
 
31
31
  spec.add_dependency 'actionpack', '>= 5.2.0'
metadata CHANGED
@@ -1,12 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rspec-openapi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.26.0
4
+ version: 0.28.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Takashi Kokubun
8
8
  - TATSUNO Yasuhiro
9
- bindir: exe
9
+ bindir: bin
10
10
  cert_chain: []
11
11
  date: 1980-01-02 00:00:00.000000000 Z
12
12
  dependencies:
@@ -60,26 +60,8 @@ executables: []
60
60
  extensions: []
61
61
  extra_rdoc_files: []
62
62
  files:
63
- - ".github/dependabot.yml"
64
- - ".github/release.yaml"
65
- - ".github/workflows/codeql-analysis.yml"
66
- - ".github/workflows/create_release.yml"
67
- - ".github/workflows/publish.yml"
68
- - ".github/workflows/rubocop.yml"
69
- - ".github/workflows/test.yml"
70
- - ".github/workflows/validate-openapi.yml"
71
- - ".gitignore"
72
- - ".rspec"
73
- - ".rubocop.yml"
74
- - ".rubocop_todo.yml"
75
- - ".simplecov_spawn.rb"
76
- - CHANGELOG.md
77
- - Gemfile
78
63
  - LICENSE.txt
79
64
  - README.md
80
- - Rakefile
81
- - bin/console
82
- - bin/setup
83
65
  - lib/rspec/openapi.rb
84
66
  - lib/rspec/openapi/components_updater.rb
85
67
  - lib/rspec/openapi/default_schema.rb
@@ -97,24 +79,21 @@ files:
97
79
  - lib/rspec/openapi/result_recorder.rb
98
80
  - lib/rspec/openapi/rspec_hooks.rb
99
81
  - lib/rspec/openapi/schema_builder.rb
82
+ - lib/rspec/openapi/schema_builder/build_context.rb
100
83
  - lib/rspec/openapi/schema_cleaner.rb
101
84
  - lib/rspec/openapi/schema_file.rb
102
85
  - lib/rspec/openapi/schema_merger.rb
103
86
  - lib/rspec/openapi/schema_sorter.rb
104
87
  - lib/rspec/openapi/shared_hooks.rb
105
88
  - lib/rspec/openapi/version.rb
106
- - redocly.yaml
107
89
  - rspec-openapi.gemspec
108
- - scripts/rspec
109
- - scripts/rspec_with_simplecov
110
- - test.png
111
90
  homepage: https://github.com/exoego/rspec-openapi
112
91
  licenses:
113
92
  - MIT
114
93
  metadata:
115
94
  homepage_uri: https://github.com/exoego/rspec-openapi
116
95
  source_code_uri: https://github.com/exoego/rspec-openapi
117
- changelog_uri: https://github.com/exoego/rspec-openapi/releases/tag/v0.26.0
96
+ changelog_uri: https://github.com/exoego/rspec-openapi/releases/tag/v0.28.0
118
97
  rubygems_mfa_required: 'true'
119
98
  rdoc_options: []
120
99
  require_paths:
@@ -130,7 +109,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
130
109
  - !ruby/object:Gem::Version
131
110
  version: '0'
132
111
  requirements: []
133
- rubygems_version: 4.0.6
112
+ rubygems_version: 4.0.10
134
113
  specification_version: 4
135
114
  summary: Generate OpenAPI schema from RSpec request specs
136
115
  test_files: []
@@ -1,8 +0,0 @@
1
- version: 2
2
- updates:
3
- - package-ecosystem: "github-actions"
4
- directory: "/"
5
- schedule:
6
- interval: "monthly"
7
- labels:
8
- - "chore"
data/.github/release.yaml DELETED
@@ -1,24 +0,0 @@
1
- changelog:
2
- exclude:
3
- labels:
4
- - ignore-for-release
5
- authors:
6
- - octocat
7
- categories:
8
- - title: 🛠 Breaking Changes
9
- labels:
10
- - semver-major
11
- - breaking-change
12
- - title: 🎉 Exciting New Features
13
- labels:
14
- - semver-minor
15
- - enhancement
16
- - title: 🐞 Bugfixes
17
- labels:
18
- - bug
19
- - title: 📄 Documentation
20
- labels:
21
- - documentation
22
- - title: 📦 Other Changes
23
- labels:
24
- - "*"
@@ -1,39 +0,0 @@
1
- name: "CodeQL"
2
-
3
- on:
4
- push:
5
- branches: [ "master" ]
6
- pull_request:
7
- # The branches below must be a subset of the branches above
8
- branches: [ "master" ]
9
- schedule:
10
- - cron: '20 22 * * 2'
11
-
12
- jobs:
13
- analyze:
14
- name: Analyze
15
- runs-on: ubuntu-latest
16
- permissions:
17
- actions: read
18
- contents: read
19
- security-events: write
20
-
21
- strategy:
22
- fail-fast: false
23
- matrix:
24
- language: [ 'ruby' ]
25
-
26
- steps:
27
- - name: Checkout repository
28
- uses: actions/checkout@v6
29
-
30
- - name: Initialize CodeQL
31
- uses: github/codeql-action/init@v4
32
- with:
33
- languages: ${{ matrix.language }}
34
-
35
- - name: Autobuild
36
- uses: github/codeql-action/autobuild@v4
37
-
38
- - name: Perform CodeQL Analysis
39
- uses: github/codeql-action/analyze@v4
@@ -1,95 +0,0 @@
1
- name: prepare release
2
-
3
- on:
4
- workflow_dispatch:
5
- inputs:
6
- version:
7
- description: 'Version to release (e.g. 0.26.1 or 0.27.0)'
8
- required: true
9
-
10
- jobs:
11
- push:
12
- name: Prepare release PR
13
- runs-on: ubuntu-latest
14
-
15
- steps:
16
- - uses: actions/checkout@v6
17
- with:
18
- fetch-depth: 0
19
- token: ${{ secrets.PREPARE_RELEASE_PAT }}
20
-
21
- - name: Bump version.rb
22
- run: |
23
- set -euo pipefail
24
- version="${{ github.event.inputs.version }}"
25
- version="${version#v}"
26
-
27
- echo "VERSION_NO_V=$version" >> "$GITHUB_ENV"
28
- echo "VERSION_TAG=v$version" >> "$GITHUB_ENV"
29
-
30
- current_version=$(ruby -e "require_relative './lib/rspec/openapi/version'; puts RSpec::OpenAPI::VERSION")
31
- VERSION_NO_V="$version" CURRENT_VERSION="$current_version" ruby - <<'RUBY'
32
- version = ENV.fetch('VERSION_NO_V')
33
- unless version.match?(/\A\d+(?:\.\d+)*\z/)
34
- warn "Invalid version format: #{version}"
35
- exit 1
36
- end
37
-
38
- require 'rubygems'
39
- new_version = Gem::Version.new(version)
40
- current_version = Gem::Version.new(ENV.fetch('CURRENT_VERSION'))
41
- if new_version <= current_version
42
- warn "Given version (#{new_version}) must be newer than current version (#{current_version})"
43
- exit 1
44
- end
45
- RUBY
46
- ruby -pi -e "sub(/VERSION = .*/, \"VERSION = '$version'\")" lib/rspec/openapi/version.rb
47
-
48
- VERSION_NO_V="$version" ruby - <<'RUBY'
49
- version = ENV.fetch('VERSION_NO_V')
50
- segments = version.split('.').map(&:to_i)
51
- unless segments.size >= 3
52
- warn "Version must have at least major.minor.patch: #{version}"
53
- exit 1
54
- end
55
-
56
- major, minor, patch = segments
57
- patch_bump = [major, minor, patch + 1].join('.')
58
- minor_bump = [major, minor + 1, 0].join('.')
59
- example = "Version to release (e.g. #{patch_bump} or #{minor_bump})"
60
-
61
- path = ".github/workflows/create_release.yml"
62
- content = File.read(path)
63
- content.sub!(/description:\s*'Version to release \(e\.g\. [^']+\)'/,
64
- "description: '#{example}'")
65
- File.write(path, content)
66
- RUBY
67
- git status --short
68
-
69
- - name: Commit version bump
70
- run: |
71
- set -euo pipefail
72
- version="$VERSION_NO_V"
73
-
74
- release_branch="release/v${version}"
75
- echo "RELEASE_BRANCH=${release_branch}" >> "$GITHUB_ENV"
76
-
77
- git config user.name "github-actions[bot]"
78
- git config user.email "github-actions[bot]@users.noreply.github.com"
79
- git commit -am "Bump version to ${version}"
80
- git push origin "HEAD:${release_branch}"
81
-
82
- - name: Open release PR
83
- uses: peter-evans/create-pull-request@v8
84
- with:
85
- token: ${{ secrets.PREPARE_RELEASE_PAT }}
86
- add-paths: |
87
- lib/rspec/openapi/version.rb
88
- .github/workflows/create_release.yml
89
- branch: ${{ env.RELEASE_BRANCH }}
90
- title: Release v${{ env.VERSION_NO_V }}
91
- commit-message: Bump version to ${{ env.VERSION_NO_V }}
92
- body: |
93
- Automated release PR created by workflow_dispatch.
94
- - Version: v${{ env.VERSION_NO_V }}
95
- - Triggered by: ${{ github.actor }}
@@ -1,46 +0,0 @@
1
- name: Publish to RubyGems
2
-
3
- on:
4
- push:
5
- tags:
6
- - 'v*'
7
-
8
- jobs:
9
- publish:
10
- name: Publish gem and GitHub release
11
- runs-on: ubuntu-latest
12
-
13
- permissions:
14
- id-token: write # for RubyGems trusted publishing
15
- contents: write # to create GitHub release
16
-
17
- steps:
18
- - uses: actions/checkout@v6
19
- with:
20
- fetch-depth: 0
21
-
22
- - name: Set up Ruby
23
- uses: ruby/setup-ruby@v1
24
- with:
25
- bundler-cache: true
26
- ruby-version: '4.0'
27
-
28
- - name: Verify tag matches version.rb
29
- run: |
30
- set -euo pipefail
31
- tag="${GITHUB_REF_NAME}"
32
- version="${tag#v}"
33
- file_version=$(ruby -e "require_relative './lib/rspec/openapi/version'; puts RSpec::OpenAPI::VERSION")
34
- if [ "$version" != "$file_version" ]; then
35
- echo "Tag version ($version) does not match lib/rspec/openapi/version.rb ($file_version)" >&2
36
- exit 1
37
- fi
38
-
39
- - uses: rubygems/release-gem@v1
40
-
41
- - name: Create GitHub release
42
- uses: softprops/action-gh-release@v3
43
- with:
44
- tag_name: ${{ github.ref_name }}
45
- name: ${{ github.ref_name }}
46
- generate_release_notes: true
@@ -1,35 +0,0 @@
1
- name: "Rubocop"
2
-
3
- on:
4
- push:
5
- branches: [ "master" ]
6
- pull_request:
7
- branches: [ "master" ]
8
-
9
- jobs:
10
- rubocop:
11
- runs-on: ubuntu-latest
12
- strategy:
13
- fail-fast: false
14
-
15
- steps:
16
- - name: Checkout repository
17
- uses: actions/checkout@v6
18
-
19
- - name: Set up Ruby
20
- uses: ruby/setup-ruby@v1
21
- with:
22
- ruby-version: '4.0'
23
- bundler-cache: true
24
-
25
- - name: Rubocop run
26
- run: |
27
- bash -c "
28
- bundle exec rubocop --require code_scanning --format CodeScanning::SarifFormatter -o rubocop.sarif
29
- [[ $? -ne 2 ]]
30
- "
31
-
32
- - name: Upload Sarif output
33
- uses: github/codeql-action/upload-sarif@v4
34
- with:
35
- sarif_file: rubocop.sarif
@@ -1,50 +0,0 @@
1
- name: test
2
- on:
3
- push:
4
- branches:
5
- - master
6
- pull_request:
7
- types:
8
- - opened
9
- - synchronize
10
- - reopened
11
- jobs:
12
- test:
13
- runs-on: ubuntu-latest
14
- container: ${{ matrix.ruby }}
15
- strategy:
16
- fail-fast: false
17
- matrix:
18
- include:
19
- - ruby: ruby:2.7
20
- - ruby: ruby:3.0
21
- - ruby: ruby:3.1
22
- - ruby: ruby:3.1
23
- rails: 6.1.7
24
- - ruby: ruby:3.1
25
- rails: 7.0.8
26
- - ruby: ruby:3.3
27
- rails: 7.1.3.2
28
- - ruby: ruby:3.4
29
- rails: 8.0.2
30
- - ruby: ruby:4.0
31
- rails: 8.1.2
32
- coverage: coverage
33
- env:
34
- RAILS_VERSION: ${{ matrix.rails == '' && '6.1.6' || matrix.rails }}
35
- COVERAGE: ${{ matrix.coverage || '' }}
36
- steps:
37
- - uses: actions/checkout@v6
38
- - name: bundle install
39
- run: bundle install -j$(nproc) --retry 3
40
- - run: bundle exec rspec
41
- timeout-minutes: 1
42
- - run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
43
- name: codecov-action@v4 workaround
44
- - name: Upload coverage reports
45
- uses: codecov/codecov-action@v6
46
- if: matrix.coverage == 'coverage'
47
- with:
48
- fail_ci_if_error: true
49
- files: ./coverage/coverage.xml
50
- token: ${{ secrets.CODECOV_TOKEN }}
@@ -1,21 +0,0 @@
1
- name: validate-openapi
2
-
3
- on:
4
- push:
5
- branches:
6
- - master
7
- pull_request:
8
- types:
9
- - opened
10
- - synchronize
11
- - reopened
12
-
13
- jobs:
14
- redocly-lint:
15
- runs-on: ubuntu-latest
16
- steps:
17
- - uses: actions/checkout@v6
18
- - uses: actions/setup-node@v4
19
- with:
20
- node-version: '22'
21
- - run: npx --yes @redocly/cli@2.30.4 lint
data/.gitignore DELETED
@@ -1,18 +0,0 @@
1
- /.bundle/
2
- /.yardoc
3
- /_yardoc/
4
- /coverage/
5
- /doc/
6
- /pkg/
7
- /spec/reports/
8
- /tmp/
9
- /Gemfile.lock
10
- /vendor/
11
- .DS_Store
12
-
13
- # rspec failure tracking
14
- .rspec_status
15
-
16
- spec/apps/rails/log/
17
-
18
- /mise.toml
data/.rspec DELETED
@@ -1,4 +0,0 @@
1
- --exclude-pattern spec/requests/**/*_spec.rb
2
- --format documentation
3
- --require rspec/openapi
4
- --color