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::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::MetricsDashboardYml, 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.
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.
103 104 105 106 107 |
# File 'app/models/blob.rb', line 103 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 |
Class Method Details
.decorate(blob, container = nil) ⇒ Object
89 90 91 92 93 |
# File 'app/models/blob.rb', line 89 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
95 96 97 98 99 100 101 |
# File 'app/models/blob.rb', line 95 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) do |items, loader, args| args[:key].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
203 204 205 |
# File 'app/models/blob.rb', line 203 def audio? UploaderHelper::SAFE_AUDIO_EXT.include?(extension) end |
#auxiliary_viewer ⇒ Object
221 222 223 224 225 |
# File 'app/models/blob.rb', line 221 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.
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
# File 'app/models/blob.rb', line 165 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.
117 118 119 120 121 122 123 |
# File 'app/models/blob.rb', line 117 def data if binary_in_repo? super else @data ||= super.encode(Encoding::UTF_8, invalid: :replace, undef: :replace) end end |
#empty? ⇒ Boolean
132 133 134 |
# File 'app/models/blob.rb', line 132 def empty? raw_size == 0 end |
#executable? ⇒ Boolean
185 186 187 |
# File 'app/models/blob.rb', line 185 def executable? mode == MODE_EXECUTABLE end |
#expand! ⇒ Object
239 240 241 |
# File 'app/models/blob.rb', line 239 def @expanded = true end |
#expanded? ⇒ Boolean
235 236 237 |
# File 'app/models/blob.rb', line 235 def !!@expanded end |
#extension ⇒ Object
189 190 191 |
# File 'app/models/blob.rb', line 189 def extension @extension ||= extname.downcase.delete('.') end |
#external_storage_error? ⇒ Boolean
136 137 138 139 140 141 142 |
# File 'app/models/blob.rb', line 136 def external_storage_error? if external_storage == :lfs !repository.lfs_enabled? else false end end |
#file_type ⇒ Object
193 194 195 196 197 |
# File 'app/models/blob.rb', line 193 def file_type name = File.basename(path) Gitlab::FileDetector.type_of(path) || Gitlab::FileDetector.type_of(name) end |
#inspect ⇒ Object
109 110 111 |
# File 'app/models/blob.rb', line 109 def inspect "#<#{self.class.name} oid:#{id[0..8]} commit:#{commit_id[0..8]} path:#{path}>" end |
#load_all_data! ⇒ Object
125 126 127 128 129 130 |
# File 'app/models/blob.rb', line 125 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.
153 154 155 156 157 158 159 |
# File 'app/models/blob.rb', line 153 def raw_size if stored_externally? external_size else size end end |
#readable_text? ⇒ Boolean
207 208 209 |
# File 'app/models/blob.rb', line 207 def readable_text? text_in_repo? && !stored_externally? && !truncated? end |
#rendered_as_text?(ignore_errors: true) ⇒ Boolean
227 228 229 |
# File 'app/models/blob.rb', line 227 def rendered_as_text?(ignore_errors: true) simple_viewer.is_a?(BlobViewer::Text) && (ignore_errors || simple_viewer.render_error.nil?) end |
#rich_viewer ⇒ Object
215 216 217 218 219 |
# File 'app/models/blob.rb', line 215 def rich_viewer return @rich_viewer if defined?(@rich_viewer) @rich_viewer = rich_viewer_class&.new(self) end |
#show_viewer_switcher? ⇒ Boolean
231 232 233 |
# File 'app/models/blob.rb', line 231 def show_viewer_switcher? rendered_as_text? && rich_viewer end |
#simple_viewer ⇒ Object
211 212 213 |
# File 'app/models/blob.rb', line 211 def simple_viewer @simple_viewer ||= simple_viewer_class.new(self) end |
#stored_externally? ⇒ Boolean
144 145 146 147 148 |
# File 'app/models/blob.rb', line 144 def stored_externally? return @stored_externally if defined?(@stored_externally) @stored_externally = external_storage && !external_storage_error? end |
#symlink? ⇒ Boolean
181 182 183 |
# File 'app/models/blob.rb', line 181 def symlink? mode == MODE_SYMLINK end |
#video? ⇒ Boolean
199 200 201 |
# File 'app/models/blob.rb', line 199 def video? UploaderHelper::SAFE_VIDEO_EXT.include?(extension) end |