diff --git a/app/graphql/types/repository/blob_type.rb b/app/graphql/types/repository/blob_type.rb
index 508389715f2644bccb0d9311cbc7887e12098b58..004bceea154025f0b2a9f8e3f815abeb1cce9082 100644
--- a/app/graphql/types/repository/blob_type.rb
+++ b/app/graphql/types/repository/blob_type.rb
@@ -67,6 +67,11 @@ class BlobType < BaseObject
description: 'Blob content rich viewer.',
null: true
+ field :plain_data, GraphQL::STRING_TYPE,
+ description: 'Blob plain highlighted data.',
+ null: true,
+ calls_gitaly: true
+
def raw_text_blob
object.data unless object.binary?
end
diff --git a/app/presenters/blob_presenter.rb b/app/presenters/blob_presenter.rb
index 000fc8214aa9c168019bf5c082cc25271466ea83..cfe2bba8aa5b76cf06fb6f3942df05a6d5316a72 100644
--- a/app/presenters/blob_presenter.rb
+++ b/app/presenters/blob_presenter.rb
@@ -14,6 +14,12 @@ def highlight(to: nil, plain: nil)
)
end
+ def plain_data
+ return if blob.binary?
+
+ highlight(plain: false)
+ end
+
def web_url
url_helpers.project_blob_url(project, ref_qualified_path)
end
diff --git a/app/presenters/snippet_blob_presenter.rb b/app/presenters/snippet_blob_presenter.rb
index 597ef6ebc39f79d2fc3263cf6fea46a79c1fe027..e9c710e4a0fdf2ae999e073429e4c97f8562491a 100644
--- a/app/presenters/snippet_blob_presenter.rb
+++ b/app/presenters/snippet_blob_presenter.rb
@@ -9,12 +9,6 @@ def rich_data
render_rich_partial
end
- def plain_data
- return if blob.binary?
-
- highlight(plain: false)
- end
-
def raw_path
snippet_blob_raw_route(only_path: true)
end
diff --git a/changelogs/unreleased/323195-add-blob-plain-data-attribute.yml b/changelogs/unreleased/323195-add-blob-plain-data-attribute.yml
new file mode 100644
index 0000000000000000000000000000000000000000..01bb0ca5f6edaa8eb248abe7def9b0a1853c8393
--- /dev/null
+++ b/changelogs/unreleased/323195-add-blob-plain-data-attribute.yml
@@ -0,0 +1,5 @@
+---
+title: Expose blob plain data in GraphQL
+merge_request: 61016
+author:
+type: added
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index 7f9bd21722406b096002fdf8c36daa5f5fa93f3c..9a3776ae262f909a437a396c97391706e9e96544 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -11744,6 +11744,7 @@ Returns [`Tree`](#tree).
| `name` | [`String`](#string) | Blob name. |
| `oid` | [`String!`](#string) | OID of the blob. |
| `path` | [`String!`](#string) | Path of the blob. |
+| `plainData` | [`String`](#string) | Blob plain highlighted data. |
| `rawBlob` | [`String`](#string) | The raw content of the blob. |
| `rawPath` | [`String`](#string) | Web path to download the raw blob. |
| `rawSize` | [`Int`](#int) | Size (in bytes) of the blob, or the blob target if stored externally. |
diff --git a/spec/graphql/types/repository/blob_type_spec.rb b/spec/graphql/types/repository/blob_type_spec.rb
index 8accee90fa33e2feb3e92a10e280816cf60708fa..c588f8230de00b8f6c346dd5448f133b5e330c7c 100644
--- a/spec/graphql/types/repository/blob_type_spec.rb
+++ b/spec/graphql/types/repository/blob_type_spec.rb
@@ -24,7 +24,8 @@
:raw_path,
:replace_path,
:simple_viewer,
- :rich_viewer
+ :rich_viewer,
+ :plain_data
)
end
end
diff --git a/spec/presenters/blob_presenter_spec.rb b/spec/presenters/blob_presenter_spec.rb
index d6acc20396f3ad0aace132f043e6a16a6b7c1ac9..1fdd31b1f925ed09eeb501fb2c602a5591398c3d 100644
--- a/spec/presenters/blob_presenter_spec.rb
+++ b/spec/presenters/blob_presenter_spec.rb
@@ -83,4 +83,43 @@
end
end
end
+
+ describe '#plain_data' do
+ let(:blob) { repository.blob_at('HEAD', file) }
+
+ subject { described_class.new(blob).plain_data }
+
+ context 'when blob is binary' do
+ let(:file) { 'files/images/logo-black.png' }
+
+ it 'returns nil' do
+ expect(subject).to be_nil
+ end
+ end
+
+ context 'when blob is markup' do
+ let(:file) { 'README.md' }
+
+ it 'returns plain content' do
+ expect(subject).to include('')
+ end
+ end
+
+ context 'when blob has syntax' do
+ let(:file) { 'files/ruby/regex.rb' }
+
+ it 'returns highlighted syntax content' do
+ expect(subject)
+ .to include 'module Gitlab'
+ end
+ end
+
+ context 'when blob has plain data' do
+ let(:file) { 'LICENSE' }
+
+ it 'returns plain text highlighted content' do
+ expect(subject).to include('The MIT License (MIT)')
+ end
+ end
+ end
end
diff --git a/spec/presenters/snippet_blob_presenter_spec.rb b/spec/presenters/snippet_blob_presenter_spec.rb
index 83fe37effc0822d8788bf14bd00ac4189ead09c2..42eca6b5a4988918ab1ccdcd4ae32ef0a3c17d69 100644
--- a/spec/presenters/snippet_blob_presenter_spec.rb
+++ b/spec/presenters/snippet_blob_presenter_spec.rb
@@ -80,45 +80,6 @@
end
end
- describe '#plain_data' do
- let(:blob) { blob_at(file) }
-
- subject { described_class.new(blob).plain_data }
-
- context 'when blob is binary' do
- let(:file) { 'files/images/logo-black.png' }
-
- it 'returns nil' do
- expect(subject).to be_nil
- end
- end
-
- context 'when blob is markup' do
- let(:file) { 'README.md' }
-
- it 'returns plain content' do
- expect(subject).to include('')
- end
- end
-
- context 'when blob has syntax' do
- let(:file) { 'files/ruby/regex.rb' }
-
- it 'returns highlighted syntax content' do
- expect(subject)
- .to include 'module Gitlab'
- end
- end
-
- context 'when blob has plain data' do
- let(:file) { 'LICENSE' }
-
- it 'returns plain text highlighted content' do
- expect(subject).to include('The MIT License (MIT)')
- end
- end
- end
-
describe 'route helpers' do
let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user) }