summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlessio Caiazza <acaiazza@gitlab.com>2019-09-09 20:16:10 +0200
committerAlessio Caiazza <acaiazza@gitlab.com>2019-09-10 10:45:48 +0200
commit685f16a7092058477120d73453babc67a794c6aa (patch)
tree6a8bd5919617b10e304a39534e0358639deb5307
parent4d542db508e454d4ed3a2cdb0a91aee67e1c5cd8 (diff)
downloadgitlab-ce-ac-cop-scalability-api-files.tar.gz
Add Scalability/FileUploads copac-cop-scalability-api-files
This cop prevents you from using file in API, it points you to the development documentation about workhorse file acceleration.
-rw-r--r--.rubocop.yml5
-rw-r--r--rubocop/cop/scalability/file_uploads.rb61
-rw-r--r--rubocop/rubocop.rb1
-rw-r--r--spec/rubocop/cop/scalability/file_uploads_spec.rb54
4 files changed, 121 insertions, 0 deletions
diff --git a/.rubocop.yml b/.rubocop.yml
index f24cbb6ce92..73743ebf9a2 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -275,3 +275,8 @@ RSpec/BeSuccessMatcher:
- 'ee/spec/support/shared_examples/controllers/**/*'
- 'spec/support/controllers/**/*'
- 'ee/spec/support/controllers/**/*'
+Scalability/FileUploads:
+ Enabled: true
+ Include:
+ - 'lib/api/**/*.rb'
+ - 'ee/lib/api/**/*.rb'
diff --git a/rubocop/cop/scalability/file_uploads.rb b/rubocop/cop/scalability/file_uploads.rb
new file mode 100644
index 00000000000..83017217e32
--- /dev/null
+++ b/rubocop/cop/scalability/file_uploads.rb
@@ -0,0 +1,61 @@
+# frozen_string_literal: true
+
+module RuboCop
+ module Cop
+ module Scalability
+ # This cop checks for `File` params in API
+ #
+ # @example
+ #
+ # # bad
+ # params do
+ # requires :file, type: File
+ # end
+ #
+ # params do
+ # optional :file, type: File
+ # end
+ #
+ # # good
+ # params do
+ # requires :file, type: ::API::Validations::Types::WorkhorseFile
+ # end
+ #
+ # params do
+ # optional :file, type: ::API::Validations::Types::WorkhorseFile
+ # end
+ #
+ class FileUploads < RuboCop::Cop::Cop
+ MSG = 'Do not upload files without workhorse acceleration. Please refer to https://docs.gitlab.com/ee/development/uploads.html'
+
+ def_node_search :file_type_params?, <<~PATTERN
+ (send nil? {:requires :optional} (sym _) (hash <(pair (sym :type)(const nil? :File)) ...>))
+ PATTERN
+
+ def_node_search :file_types_params?, <<~PATTERN
+ (send nil? {:requires :optional} (sym _) (hash <(pair (sym :types)(array <(const nil? :File) ...>)) ...>))
+ PATTERN
+
+ def be_file_param_usage?(node)
+ file_type_params?(node) || file_types_params?(node)
+ end
+
+ def on_send(node)
+ return unless be_file_param_usage?(node)
+
+ add_offense(find_file_param(node), location: :expression)
+ end
+
+ private
+
+ def find_file_param(node)
+ node.each_descendant.find { |children| file_node_pattern.match(children) }
+ end
+
+ def file_node_pattern
+ @file_node_pattern ||= RuboCop::NodePattern.new("(const nil? :File)")
+ end
+ end
+ end
+ end
+end
diff --git a/rubocop/rubocop.rb b/rubocop/rubocop.rb
index c342df6d6c9..9d97aa86bf6 100644
--- a/rubocop/rubocop.rb
+++ b/rubocop/rubocop.rb
@@ -37,6 +37,7 @@ require_relative 'cop/rspec/factories_in_migration_specs'
require_relative 'cop/rspec/top_level_describe_path'
require_relative 'cop/qa/element_with_pattern'
require_relative 'cop/sidekiq_options_queue'
+require_relative 'cop/scalability/file_uploads'
require_relative 'cop/destroy_all'
require_relative 'cop/ruby_interpolation_in_translation'
require_relative 'code_reuse_helpers'
diff --git a/spec/rubocop/cop/scalability/file_uploads_spec.rb b/spec/rubocop/cop/scalability/file_uploads_spec.rb
new file mode 100644
index 00000000000..2a94fde5ba2
--- /dev/null
+++ b/spec/rubocop/cop/scalability/file_uploads_spec.rb
@@ -0,0 +1,54 @@
+# frozen_string_literal: true
+
+require 'fast_spec_helper'
+require 'rubocop'
+require_relative '../../../support/helpers/expect_offense'
+require_relative '../../../../rubocop/cop/scalability/file_uploads'
+
+describe RuboCop::Cop::Scalability::FileUploads do
+ include CopHelper
+ include ExpectOffense
+
+ subject(:cop) { described_class.new }
+ let(:message) { 'Do not upload files without workhorse acceleration. Please refer to https://docs.gitlab.com/ee/development/uploads.html' }
+
+ context 'with required params' do
+ it 'detects File in types array' do
+ expect_offense(<<~PATTERN.strip_indent)
+ params do
+ requires :certificate, allow_blank: false, types: [String, File]
+ ^^^^ #{message}
+ end
+ PATTERN
+ end
+
+ it 'detects File as type argument' do
+ expect_offense(<<~PATTERN.strip_indent)
+ params do
+ requires :attachment, type: File
+ ^^^^ #{message}
+ end
+ PATTERN
+ end
+ end
+
+ context 'with optional params' do
+ it 'detects File in types array' do
+ expect_offense(<<~PATTERN.strip_indent)
+ params do
+ optional :certificate, allow_blank: false, types: [String, File]
+ ^^^^ #{message}
+ end
+ PATTERN
+ end
+
+ it 'detects File as type argument' do
+ expect_offense(<<~PATTERN.strip_indent)
+ params do
+ optional :attachment, type: File
+ ^^^^ #{message}
+ end
+ PATTERN
+ end
+ end
+end