Class: DiffNote
- Inherits:
-
Note
- Object
- ActiveRecord::Base
- ApplicationRecord
- Note
- DiffNote
- Includes:
- DiffPositionableNote, Gitlab::Utils::StrongMemoize, NoteOnDiff
- Defined in:
- app/models/diff_note.rb
Overview
A note on merge request or commit diffs
A note of this type can be resolvable.
Constant Summary collapse
- NoteDiffFileCreationError =
Class.new(StandardError)
- DIFF_LINE_NOT_FOUND_MESSAGE =
"Failed to find diff line for: %{file_path}, old_line: %{old_line}, new_line: %{new_line}"- DIFF_FILE_NOT_FOUND_MESSAGE =
"Failed to find diff file"
Constants inherited from Note
Note::NON_DIFF_NOTE_TYPES, Note::TYPES_RESTRICTED_BY_GROUP_ABILITY, Note::TYPES_RESTRICTED_BY_PROJECT_ABILITY
Constants included from ThrottledTouch
ThrottledTouch::TOUCH_INTERVAL
Constants included from Gitlab::SQL::Pattern
Gitlab::SQL::Pattern::MIN_CHARS_FOR_PARTIAL_MATCHING, Gitlab::SQL::Pattern::REGEX_QUOTED_TERM
Constants included from ResolvableNote
ResolvableNote::RESOLVABLE_TYPES
Constants included from CacheMarkdownField
CacheMarkdownField::INVALIDATED_BY
Constants included from Redactable
Redactable::UNSUBSCRIBE_PATTERN
Constants included from Import::HasImportSource
Import::HasImportSource::IMPORT_SOURCES
Constants inherited from ApplicationRecord
Constants included from HasCheckConstraints
HasCheckConstraints::NOT_NULL_CHECK_PATTERN
Constants included from ResetOnColumnErrors
ResetOnColumnErrors::MAX_RESET_PERIOD
Instance Attribute Summary
Attributes inherited from Note
#commands_changes, #quick_actions_status, #redacted_note_html, #skip_keep_around_commits, #skip_touch_noteable, #total_reference_count, #user_visible_reference_count
Attributes included from CacheMarkdownField
#skip_markdown_cache_validation
Attributes included from Importable
#importing, #user_contributions
Class Method Summary collapse
Instance Method Summary collapse
- #banzai_render_context(field) ⇒ Object
- #create_diff_file ⇒ Object
- #created_at_diff?(diff_refs) ⇒ Boolean
-
#diff_file(create_missing_diff_file: true) ⇒ Object
Returns the diff file from
original_position. - #diff_line ⇒ Object
- #discussion_class ⇒ Object
-
#latest_diff_file ⇒ Object
Returns the diff file from
position. - #latest_diff_file_path ⇒ Object
- #multiline? ⇒ Boolean
- #original_line_code ⇒ Object
- #raw_truncated_diff_lines ⇒ Object
- #requires_diff_file_validation_during_import? ⇒ Boolean
-
#supports_suggestion? ⇒ Boolean
Checks if the current
positionline in the diff exists and is suggestible (not a deletion). - #validate_diff_file_and_line ⇒ Object
Methods included from DiffPositionableNote
#active?, #diff_refs_match_commit, #keep_around_commits, #on_file?, #on_image?, #on_text?, #repository, #set_original_position, #shas, #should_update_position?, #update_position
Methods included from NoteOnDiff
#active?, #diff_attributes, #diff_note?
Methods inherited from Note
#active?, #award_emoji?, #broadcast_noteable_notes_changed, #bump_updated_at, #can_be_award_emoji?, #can_be_discussion_note?, #can_create_todo?, #check_for_spam?, cherry_picked_merge_requests, #commit, #confidential?, #contains_emoji_only?, #contributor?, count_for_collection, #diff_note?, #editable?, #edited?, #emoji_awardable?, #exportable_record?, #for_abuse_report?, #for_alert_mangement_alert?, #for_commit?, #for_compliance_violation?, #for_design?, #for_issuable?, #for_issue?, #for_merge_request?, #for_personal_snippet?, #for_project_noteable?, #for_project_snippet?, #for_snippet?, #for_vulnerability?, #for_wiki_page?, #for_work_item?, #group_level_issue?, grouped_diff_discussions, #hook_attrs, #human_max_access, #issuable_ability_name, #last_edited_at, #mentioned_filtered_user_ids_for, #mentioned_users, #merge_requests, model_name, #noteable, #noteable_ability_name, #noteable_author?, #noteable_type=, #notify_after_create, #notify_after_destroy, parent_object_field, #parent_user, positions, #post_processed_cache_key, #project_name, #references, #resource_parent, #retrieve_upload, search, #show_outdated_changes?, simple_sorts, #skip_notification?, #skip_project_check?, #system_note_visible_for?, #system_note_with_references?, #touch, #touch_noteable, #trigger_note_subscription_create, #trigger_note_subscription_destroy, #trigger_note_subscription_update, #trigger_work_item_updated_subscription, #user_mention_class, #user_mention_identifier, #user_mentions, with_web_entity_associations
Methods included from Gitlab::Utils::Override
#extended, extensions, #included, #method_added, #override, #prepended, #queue_verification, verify!
Methods included from Spammable
#allow_possible_spam?, #check_for_spam, #check_for_spam?, #clear_spam_flags!, #invalidate_if_spam, #needs_recaptcha!, #recaptcha_error!, #render_recaptcha?, #spam, #spam!, #spam_description, #spam_title, #spammable_attribute_changed?, #spammable_entity_type, #spammable_text, #submittable_as_spam?, #submittable_as_spam_by?, #supports_recaptcha?, #unrecoverable_spam_error!
Methods included from ThrottledTouch
Methods included from Gitlab::SQL::Pattern
Methods included from Editable
Methods included from ResolvableNote
#potentially_resolvable?, #resolvable?, #resolve!, #resolve_without_save, #resolved?, #to_be_resolved?, #unresolve!, #unresolve_without_save
Methods included from AfterCommitQueue
#run_after_commit, #run_after_commit_or_now
Methods included from CacheMarkdownField
#attribute_invalidated?, #cached_html_for, #cached_html_up_to_date?, #can_cache_field?, #invalidated_markdown_cache?, #latest_cached_markdown_version, #mentionable_attributes_changed?, #mentioned_filtered_user_ids_for, #parent_user, #refresh_markdown_cache, #refresh_markdown_cache!, #rendered_field_content, #skip_project_check?, #store_mentions!, #store_mentions?, #store_mentions_after_commit?, #updated_cached_html_for
Methods included from FasterCacheKeys
Methods included from Import::HasImportSource
Methods included from Awardable
#awarded_emoji?, #downvotes, #emoji_awardable?, #grouped_awards, #upvotes, #user_authored?, #user_can_award?
Methods included from Mentionable
#all_references, #create_cross_references!, #create_new_cross_references!, #directly_addressed_users, #extractors, #gfm_reference, #local_reference, #matches_cross_reference_regex?, #mentioned_users, #referenced_group_users, #referenced_groups, #referenced_mentionables, #referenced_projects, #referenced_users, #user_mention_class, #user_mention_identifier
Methods included from Participable
#participant?, #participants, #visible_participants
Methods included from Notes::Discussion
#derive_discussion_id, #discussion, #discussion=, #discussion_id, #ensure_discussion_id, #in_reply_to?, #part_of_discussion?, #start_of_discussion?, #to_discussion
Methods included from Notes::ActiveRecord
Methods inherited from ApplicationRecord
===, cached_column_list, #create_or_load_association, current_transaction, declarative_enum, default_select_columns, delete_all_returning, #deleted_from_database?, id_in, id_not_in, iid_in, nullable_column?, primary_key_in, #readable_by?, safe_ensure_unique, safe_find_or_create_by, safe_find_or_create_by!, #to_ability_name, underscore, where_exists, where_not_exists, with_fast_read_statement_timeout, without_order
Methods included from Organizations::Sharding
Methods included from ResetOnColumnErrors
#reset_on_union_error, #reset_on_unknown_attribute_error
Methods included from Gitlab::SensitiveSerializableHash
Class Method Details
.noteable_types ⇒ Object
13 14 15 |
# File 'app/models/diff_note.rb', line 13 def self.noteable_types %w[MergeRequest Commit DesignManagement::Design] end |
Instance Method Details
#banzai_render_context(field) ⇒ Object
138 139 140 |
# File 'app/models/diff_note.rb', line 138 def banzai_render_context(field) super.merge(suggestions_filter_enabled: true) end |
#create_diff_file ⇒ Object
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'app/models/diff_note.rb', line 65 def create_diff_file return unless should_create_diff_file? diff_file = diff_file(create_missing_diff_file: false) raise NoteDiffFileCreationError, DIFF_FILE_NOT_FOUND_MESSAGE unless diff_file diff_line = diff_file.line_for_position(self.original_position) unless diff_line raise NoteDiffFileCreationError, DIFF_LINE_NOT_FOUND_MESSAGE % { file_path: diff_file.file_path, old_line: original_position.old_line, new_line: original_position.new_line } end creation_params = diff_file.diff.to_hash .except(:too_large, :generated, :encoded_file_path, :binary) .merge(diff: diff_file.diff_hunk(diff_line)) create_note_diff_file(creation_params) clear_memoization(:diff_file) end |
#created_at_diff?(diff_refs) ⇒ Boolean
118 119 120 121 122 123 |
# File 'app/models/diff_note.rb', line 118 def created_at_diff?(diff_refs) return false unless supported? return true if for_commit? self.original_position.diff_refs == diff_refs end |
#diff_file(create_missing_diff_file: true) ⇒ Object
Returns the diff file from original_position
98 99 100 101 102 103 104 105 106 |
# File 'app/models/diff_note.rb', line 98 def diff_file(create_missing_diff_file: true) strong_memoize(:diff_file) do next if for_design? enqueue_diff_file_creation_job if create_missing_diff_file && should_create_diff_file? fetch_diff_file end end |
#diff_line ⇒ Object
108 109 110 |
# File 'app/models/diff_note.rb', line 108 def diff_line @diff_line ||= diff_file&.line_for_position(self.original_position) end |
#discussion_class ⇒ Object
38 39 40 |
# File 'app/models/diff_note.rb', line 38 def discussion_class(*) DiffDiscussion end |
#latest_diff_file ⇒ Object
Returns the diff file from position
89 90 91 92 93 94 95 |
# File 'app/models/diff_note.rb', line 89 def latest_diff_file strong_memoize(:latest_diff_file) do next if for_design? position.diff_file(repository) end end |
#latest_diff_file_path ⇒ Object
146 147 148 |
# File 'app/models/diff_note.rb', line 146 def latest_diff_file_path latest_diff_file.file_path end |
#multiline? ⇒ Boolean
142 143 144 |
# File 'app/models/diff_note.rb', line 142 def multiline? position&.multiline? end |
#original_line_code ⇒ Object
112 113 114 115 116 |
# File 'app/models/diff_note.rb', line 112 def original_line_code return unless on_text? self.diff_file.line_code(self.diff_line) end |
#raw_truncated_diff_lines ⇒ Object
150 151 152 153 154 155 |
# File 'app/models/diff_note.rb', line 150 def raw_truncated_diff_lines discussion .truncated_diff_lines(highlight: false) .map(&:text) .join("\n") end |
#requires_diff_file_validation_during_import? ⇒ Boolean
61 62 63 |
# File 'app/models/diff_note.rb', line 61 def requires_diff_file_validation_during_import? importing? && should_create_diff_file? end |
#supports_suggestion? ⇒ Boolean
Checks if the current position line in the diff exists and is suggestible (not a deletion).
Avoid using in iterations as it requests Gitaly.
129 130 131 132 133 134 135 136 |
# File 'app/models/diff_note.rb', line 129 def supports_suggestion? return false unless noteable&.supports_suggestion? && on_text? # We don't want to trigger side-effects of `diff_file` call. return false unless file = latest_diff_file return false unless line = file.line_for_position(self.position) line&.suggestible? end |
#validate_diff_file_and_line ⇒ Object
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'app/models/diff_note.rb', line 42 def validate_diff_file_and_line diff_file = diff_file(create_missing_diff_file: false) unless diff_file errors.add(:base, :missing_diff_file, message: DIFF_FILE_NOT_FOUND_MESSAGE) return end diff_line = diff_file.line_for_position(self.original_position) return if diff_line errors.add(:base, :missing_diff_line, message: DIFF_LINE_NOT_FOUND_MESSAGE % { file_path: diff_file.file_path, old_line: original_position.old_line, new_line: original_position.new_line }) end |