Class: PlanMyStuff::Link

Inherits:
Object
  • Object
show all
Includes:
ActiveModel::Attributes, ActiveModel::Model, ActiveModel::Serializers::JSON
Defined in:
lib/plan_my_stuff/link.rb

Overview

Value object representing a typed relationship between two issues. Built by Issue#add_related!, #add_blocker!, #add_sub_issue!, #set_parent!, and #mark_duplicate!; also returned from their remove_* counterparts so callers can render activity-log lines like “Added parent issue: owner/repo#42”.

Metadata-backed types live in IssueMetadata#links; native types are routed through GitHub APIs and never persisted in our metadata.

Constant Summary collapse

METADATA_TYPES =
%w[related].freeze
NATIVE_TYPES =
%w[blocking blocked_by parent sub_ticket duplicate_of].freeze
ALL_TYPES =
(METADATA_TYPES + NATIVE_TYPES).freeze

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.build(input, type: nil, source_repo: nil) ⇒ PlanMyStuff::Link

Builds and validates a Link from an Issue-like object, another Link, or a hash. type: fills in when the input does not carry one; source_repo fills in when the hash input does not carry one. Raises ActiveModel::ValidationError on missing/invalid fields, ArgumentError when input is an unsupported shape.

Parameters:

Returns:



47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/plan_my_stuff/link.rb', line 47

def build(input, type: nil, source_repo: nil)
  return input if input.is_a?(PlanMyStuff::Link)

  link =
    if input.is_a?(Hash)
      build_from_hash(input, type: type, source_repo: source_repo)
    else
      build_from_issue_like(input, type: type)
    end

  link.validate!
  link
end

Instance Method Details

#==(other) ⇒ Boolean Also known as: eql?

Parameters:

  • other (Object)

Returns:

  • (Boolean)


131
132
133
134
135
# File 'lib/plan_my_stuff/link.rb', line 131

def ==(other)
  return false unless other.is_a?(PlanMyStuff::Link)

  type == other.type && issue_number == other.issue_number && repo == other.repo
end

#hashInteger

Returns:

  • (Integer)


140
141
142
# File 'lib/plan_my_stuff/link.rb', line 140

def hash
  [type, issue_number, repo].hash
end

#issuePlanMyStuff::Issue

Lazy-fetches and memoizes the target Issue.

Returns:



123
124
125
# File 'lib/plan_my_stuff/link.rb', line 123

def issue
  @issue ||= PlanMyStuff::Issue.find(issue_number, repo: repo)
end

#issue_numberInteger

Returns target issue’s GitHub issue number.

Returns:

  • (Integer)

    target issue’s GitHub issue number



26
# File 'lib/plan_my_stuff/link.rb', line 26

attribute :issue_number, :integer

#repoString

Returns full “owner/name” path of the target issue’s repo.

Returns:

  • (String)

    full “owner/name” path of the target issue’s repo



28
# File 'lib/plan_my_stuff/link.rb', line 28

attribute :repo, :string

#same_repo?(other_repo) ⇒ Boolean

Parameters:

Returns:

  • (Boolean)


113
114
115
116
117
# File 'lib/plan_my_stuff/link.rb', line 113

def same_repo?(other_repo)
  return false if other_repo.nil?

  repo == self.class.__send__(:repo_string, other_repo)
end

#to_hHash

Returns:

  • (Hash)


101
102
103
104
105
106
107
# File 'lib/plan_my_stuff/link.rb', line 101

def to_h
  {
    type: type,
    issue_number: issue_number,
    repo: repo,
  }
end

#to_sString

Returns e.g. “owner/repo#42”.

Returns:

  • (String)

    e.g. “owner/repo#42”



96
97
98
# File 'lib/plan_my_stuff/link.rb', line 96

def to_s
  "#{repo}##{issue_number}"
end

#typeString

Returns one of ALL_TYPES.

Returns:

  • (String)

    one of ALL_TYPES



24
# File 'lib/plan_my_stuff/link.rb', line 24

attribute :type, :string