Commit a33ef767 authored by Vasilii Iakliushin's avatar Vasilii Iakliushin

Expose language field in GraphQL blob type

Contributes to https://gitlab.com/gitlab-org/gitlab/-/issues/348145

Return the language of the blob for syntax highligher.

Changelog: added
parent 63a7d839
......@@ -125,6 +125,12 @@ module Types
field :archived, GraphQL::Types::Boolean, null: true, method: :archived?,
description: 'Whether the current project is archived.'
field :language, GraphQL::Types::String,
description: 'Blob language.',
method: :blob_language,
null: true,
calls_gitaly: true
def raw_text_blob
object.data unless object.binary?
end
......
......@@ -32,7 +32,7 @@ class BlobPresenter < Gitlab::View::Presenter::Delegated
end
def blob_language
@_blob_language ||= Gitlab::Diff::CustomDiff.transformed_blob_language(blob) || language
@_blob_language ||= Gitlab::Diff::CustomDiff.transformed_blob_language(blob) || gitattr_language || detect_language
end
def raw_plain_data
......@@ -166,9 +166,15 @@ class BlobPresenter < Gitlab::View::Presenter::Delegated
@all_lines ||= blob.data.lines
end
def language
def gitattr_language
blob.language_from_gitattributes
end
def detect_language
return if blob.binary?
Rouge::Lexer.guess(filename: blob.path, source: blob_data(nil)) { |lex| lex.min_by(&:tag) }.tag
end
end
BlobPresenter.prepend_mod_with('BlobPresenter')
......@@ -33,7 +33,7 @@ class SnippetBlobPresenter < BlobPresenter
blob.container
end
def language
def gitattr_language
nil
end
......
......@@ -14632,6 +14632,7 @@ Returns [`Tree`](#tree).
| <a id="repositoryblobid"></a>`id` | [`ID!`](#id) | ID of the blob. |
| <a id="repositoryblobideeditpath"></a>`ideEditPath` | [`String`](#string) | Web path to edit this blob in the Web IDE. |
| <a id="repositoryblobideforkandeditpath"></a>`ideForkAndEditPath` | [`String`](#string) | Web path to edit this blob in the Web IDE using a forked project. |
| <a id="repositorybloblanguage"></a>`language` | [`String`](#string) | Blob language. |
| <a id="repositorybloblfsoid"></a>`lfsOid` | [`String`](#string) | LFS OID of the blob. |
| <a id="repositoryblobmode"></a>`mode` | [`String`](#string) | Blob mode. |
| <a id="repositoryblobname"></a>`name` | [`String`](#string) | Blob name. |
......@@ -80,6 +80,10 @@ module Gitlab
super(presenter_class: BlobPresenter)
end
def binary?
false
end
def fetch_blob
path = [ref, blob_path]
missing_blob = { binary_path: blob_path }
......
......@@ -41,7 +41,8 @@ RSpec.describe Types::Repository::BlobType do
:ide_edit_path,
:external_storage_url,
:fork_and_edit_path,
:ide_fork_and_edit_path
:ide_fork_and_edit_path,
:language
)
end
end
......@@ -170,13 +170,13 @@ RSpec.describe BlobPresenter do
let(:git_blob) { blob.__getobj__ }
it 'returns highlighted content' do
expect(Gitlab::Highlight).to receive(:highlight).with('files/ruby/regex.rb', git_blob.data, plain: nil, language: nil)
expect(Gitlab::Highlight).to receive(:highlight).with('files/ruby/regex.rb', git_blob.data, plain: nil, language: 'ruby')
presenter.highlight
end
it 'returns plain content when :plain is true' do
expect(Gitlab::Highlight).to receive(:highlight).with('files/ruby/regex.rb', git_blob.data, plain: true, language: nil)
expect(Gitlab::Highlight).to receive(:highlight).with('files/ruby/regex.rb', git_blob.data, plain: true, language: 'ruby')
presenter.highlight(plain: true)
end
......@@ -189,7 +189,7 @@ RSpec.describe BlobPresenter do
end
it 'returns limited highlighted content' do
expect(Gitlab::Highlight).to receive(:highlight).with('files/ruby/regex.rb', "line one\n", plain: nil, language: nil)
expect(Gitlab::Highlight).to receive(:highlight).with('files/ruby/regex.rb', "line one\n", plain: nil, language: 'ruby')
presenter.highlight(to: 1)
end
......@@ -247,6 +247,36 @@ RSpec.describe BlobPresenter do
end
end
describe '#blob_language' do
subject { presenter.blob_language }
it { is_expected.to eq('ruby') }
context 'gitlab-language contains a match' do
before do
allow(blob).to receive(:language_from_gitattributes).and_return('cpp')
end
it { is_expected.to eq('cpp') }
end
context 'when blob is ipynb' do
let(:blob) { repository.blob_at('f6b7a707', 'files/ipython/markdown-table.ipynb') }
before do
allow(Gitlab::Diff::CustomDiff).to receive(:transformed_for_diff?).and_return(true)
end
it { is_expected.to eq('md') }
end
context 'when blob is binary' do
let(:blob) { repository.blob_at('HEAD', 'Gemfile.zip') }
it { is_expected.to be_nil }
end
end
describe '#raw_plain_data' do
let(:blob) { repository.blob_at('HEAD', file) }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment