Class: Blob
- Inherits:
-
SimpleDelegator
- Object
- SimpleDelegator
- Blob
- Includes:
- BlobActiveModel, BlobLanguageFromGitAttributes, GlobalID::Identification, Presentable
- Defined in:
- app/models/blob.rb
Overview
Blob is a Rails-specific wrapper around Gitlab::Git::Blob, SnippetBlob and Ci::ArtifactBlob
Direct Known Subclasses
Constant Summary collapse
- MODE_SYMLINK =
The STRING 120000 is the git-reported octal filemode for a symlink
'120000'
- MODE_EXECUTABLE =
The STRING 100755 is the git-reported octal filemode for an executable file
'100755'
- CACHE_TIME =
Cache raw blobs referred to by a (mutable) ref for 1 minute
60
- CACHE_TIME_IMMUTABLE =
Cache blobs referred to by an immutable reference for 1 hour
3600
- RICH_VIEWERS =
Finding a viewer for a blob happens based only on extension and whether the blob is binary or text, which means 1 blob should only be matched by 1 viewer, and the order of these viewers doesn’t really matter.
However, when the blob is an LFS pointer, we cannot know for sure whether the file being pointed to is binary or text. In this case, we match only on extension, preferring binary viewers over text ones if both exist, since the large files referred to in “Large File Storage” are much more likely to be binary than text.
‘.stl` files, for example, exist in both binary and text forms, and are handled by different viewers (`BinarySTL` and `TextSTL`) depending on blob type. LFS pointers to `.stl` files are assumed to always be the binary kind, and use the `BinarySTL` viewer.
[ BlobViewer::CSV, BlobViewer::Markup, BlobViewer::Notebook, BlobViewer::SVG, BlobViewer::OpenApi, BlobViewer::GeoJson, BlobViewer::Image, BlobViewer::Sketch, BlobViewer::Video, BlobViewer::Audio, BlobViewer::PDF, BlobViewer::BinarySTL, BlobViewer::TextSTL ].sort_by { |v| v.binary? ? 0 : 1 }.freeze
- AUXILIARY_VIEWERS =
[ BlobViewer::GitlabCiYml, BlobViewer::RouteMap, BlobViewer::Readme, BlobViewer::License, BlobViewer::Contributing, BlobViewer::Changelog, BlobViewer::CargoToml, BlobViewer::Cartfile, BlobViewer::ComposerJson, BlobViewer::Gemfile, BlobViewer::Gemspec, BlobViewer::GodepsJson, BlobViewer::GoMod, BlobViewer::PackageJson, BlobViewer::Podfile, BlobViewer::Podspec, BlobViewer::PodspecJson, BlobViewer::RequirementsTxt, BlobViewer::YarnLock ].freeze
Instance Attribute Summary collapse
-
#container ⇒ Object
readonly
Returns the value of attribute container.
-
#ref_type ⇒ Object
Returns the value of attribute ref_type.
Class Method Summary collapse
-
.decorate(blob, container = nil) ⇒ Object
Wrap a Gitlab::Git::Blob object, or return nil when given nil.
- .lazy(repository, commit_id, path, blob_size_limit: Gitlab::Git::Blob::MAX_DATA_DISPLAY_SIZE) ⇒ Object
Instance Method Summary collapse
- #audio? ⇒ Boolean
- #auxiliary_viewer ⇒ Object
-
#binary? ⇒ Boolean
Returns whether the file that this blob represents is binary.
-
#data ⇒ Object
Returns the data of the blob.
- #empty? ⇒ Boolean
- #executable? ⇒ Boolean
- #expand! ⇒ Object
- #expanded? ⇒ Boolean
- #extension ⇒ Object
- #external_storage_error? ⇒ Boolean
- #file_type ⇒ Object
-
#initialize(blob, container = nil) ⇒ Blob
constructor
A new instance of Blob.
- #inspect ⇒ Object
- #load_all_data! ⇒ Object
-
#raw_size ⇒ Object
Returns the size of the file that this blob represents.
- #readable_text? ⇒ Boolean
- #rendered_as_text?(ignore_errors: true) ⇒ Boolean
- #rich_viewer ⇒ Object
- #show_viewer_switcher? ⇒ Boolean
- #simple_viewer ⇒ Object
- #stored_externally? ⇒ Boolean
- #symlink? ⇒ Boolean
- #video? ⇒ Boolean
Methods included from BlobActiveModel
Methods included from BlobLanguageFromGitAttributes
Methods included from Presentable
Constructor Details
#initialize(blob, container = nil) ⇒ Blob
Returns a new instance of Blob.
104 105 106 107 108 |
# File 'app/models/blob.rb', line 104 def initialize(blob, container = nil) @container = container super(blob) end |
Instance Attribute Details
#container ⇒ Object (readonly)
Returns the value of attribute container.
74 75 76 |
# File 'app/models/blob.rb', line 74 def container @container end |
#ref_type ⇒ Object
Returns the value of attribute ref_type.
75 76 77 |
# File 'app/models/blob.rb', line 75 def ref_type @ref_type end |
Class Method Details
.decorate(blob, container = nil) ⇒ Object
90 91 92 93 94 |
# File 'app/models/blob.rb', line 90 def self.decorate(blob, container = nil) return if blob.nil? new(blob, container) end |
.lazy(repository, commit_id, path, blob_size_limit: Gitlab::Git::Blob::MAX_DATA_DISPLAY_SIZE) ⇒ Object
96 97 98 99 100 101 102 |
# File 'app/models/blob.rb', line 96 def self.lazy(repository, commit_id, path, blob_size_limit: Gitlab::Git::Blob::MAX_DATA_DISPLAY_SIZE) BatchLoader.for([commit_id, path]).batch(key: [:repository_blobs, repository]) do |items, loader, args| args[:key].last.blobs_at(items, blob_size_limit: blob_size_limit).each do |blob| loader.call([blob.commit_id, blob.path], blob) if blob end end end |
Instance Method Details
#audio? ⇒ Boolean
204 205 206 |
# File 'app/models/blob.rb', line 204 def audio? UploaderHelper::SAFE_AUDIO_EXT.include?(extension) end |
#auxiliary_viewer ⇒ Object
222 223 224 225 226 |
# File 'app/models/blob.rb', line 222 def auxiliary_viewer return @auxiliary_viewer if defined?(@auxiliary_viewer) @auxiliary_viewer = auxiliary_viewer_class&.new(self) end |
#binary? ⇒ Boolean
Returns whether the file that this blob represents is binary. If this blob is an LFS pointer, we assume the file stored in LFS is binary, unless a text-based rich blob viewer matched on the file’s extension. Otherwise, this depends on the type of the blob itself.
166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 |
# File 'app/models/blob.rb', line 166 def binary? if stored_externally? if rich_viewer rich_viewer.binary? elsif known_extension? false elsif _mime_type _mime_type.binary? else true end else binary_in_repo? end end |
#data ⇒ Object
Returns the data of the blob.
If the blob is a text based blob the content is converted to UTF-8 and any invalid byte sequences are replaced.
118 119 120 121 122 123 124 |
# File 'app/models/blob.rb', line 118 def data if binary_in_repo? super else @data ||= super.encode(Encoding::UTF_8, invalid: :replace, undef: :replace) end end |
#empty? ⇒ Boolean
133 134 135 |
# File 'app/models/blob.rb', line 133 def empty? raw_size == 0 end |
#executable? ⇒ Boolean
186 187 188 |
# File 'app/models/blob.rb', line 186 def executable? mode == MODE_EXECUTABLE end |
#expand! ⇒ Object
240 241 242 |
# File 'app/models/blob.rb', line 240 def @expanded = true end |
#expanded? ⇒ Boolean
236 237 238 |
# File 'app/models/blob.rb', line 236 def !!@expanded end |
#extension ⇒ Object
190 191 192 |
# File 'app/models/blob.rb', line 190 def extension @extension ||= extname.downcase.delete('.') end |
#external_storage_error? ⇒ Boolean
137 138 139 140 141 142 143 |
# File 'app/models/blob.rb', line 137 def external_storage_error? if external_storage == :lfs !repository.lfs_enabled? else false end end |
#file_type ⇒ Object
194 195 196 197 198 |
# File 'app/models/blob.rb', line 194 def file_type name = File.basename(path) Gitlab::FileDetector.type_of(path) || Gitlab::FileDetector.type_of(name) end |
#inspect ⇒ Object
110 111 112 |
# File 'app/models/blob.rb', line 110 def inspect "#<#{self.class.name} oid:#{id[0..8]} commit:#{commit_id[0..8]} path:#{path}>" end |
#load_all_data! ⇒ Object
126 127 128 129 130 131 |
# File 'app/models/blob.rb', line 126 def load_all_data! # Endpoint needed: https://gitlab.com/gitlab-org/gitaly/issues/756 Gitlab::GitalyClient.allow_n_plus_1_calls do super(repository) if container end end |
#raw_size ⇒ Object
Returns the size of the file that this blob represents. If this blob is an LFS pointer, this is the size of the file stored in LFS. Otherwise, this is the size of the blob itself.
154 155 156 157 158 159 160 |
# File 'app/models/blob.rb', line 154 def raw_size if stored_externally? external_size else size end end |
#readable_text? ⇒ Boolean
208 209 210 |
# File 'app/models/blob.rb', line 208 def readable_text? text_in_repo? && !stored_externally? && !truncated? end |
#rendered_as_text?(ignore_errors: true) ⇒ Boolean
228 229 230 |
# File 'app/models/blob.rb', line 228 def rendered_as_text?(ignore_errors: true) simple_viewer.is_a?(BlobViewer::Text) && (ignore_errors || simple_viewer.render_error.nil?) end |
#rich_viewer ⇒ Object
216 217 218 219 220 |
# File 'app/models/blob.rb', line 216 def rich_viewer return @rich_viewer if defined?(@rich_viewer) @rich_viewer = rich_viewer_class&.new(self) end |
#show_viewer_switcher? ⇒ Boolean
232 233 234 |
# File 'app/models/blob.rb', line 232 def show_viewer_switcher? rendered_as_text? && rich_viewer end |
#simple_viewer ⇒ Object
212 213 214 |
# File 'app/models/blob.rb', line 212 def simple_viewer @simple_viewer ||= simple_viewer_class.new(self) end |
#stored_externally? ⇒ Boolean
145 146 147 148 149 |
# File 'app/models/blob.rb', line 145 def stored_externally? return @stored_externally if defined?(@stored_externally) @stored_externally = external_storage && !external_storage_error? end |
#symlink? ⇒ Boolean
182 183 184 |
# File 'app/models/blob.rb', line 182 def symlink? mode == MODE_SYMLINK end |
#video? ⇒ Boolean
200 201 202 |
# File 'app/models/blob.rb', line 200 def video? UploaderHelper::SAFE_VIDEO_EXT.include?(extension) end |