Class: Ocak::LocalIssueFetcher

Inherits:
IssueFetcher show all
Defined in:
lib/ocak/local_issue_fetcher.rb

Constant Summary collapse

COMMENTS_SENTINEL =
'<!-- pipeline-comments -->'

Constants inherited from IssueFetcher

IssueFetcher::LABEL_COLORS

Instance Method Summary collapse

Methods inherited from IssueFetcher

#extract_issue_number_from_pr, #fetch_pr_comments, #fetch_reready_prs, #pr_comment, #pr_transition, #transition

Constructor Details

#initialize(config:, logger: nil) ⇒ LocalIssueFetcher

Returns a new instance of LocalIssueFetcher.



12
13
14
15
# File 'lib/ocak/local_issue_fetcher.rb', line 12

def initialize(config:, logger: nil)
  super
  @store_dir = File.join(config.project_dir, '.ocak', 'issues')
end

Instance Method Details

#add_label(issue_number, label) ⇒ Object



36
37
38
39
40
# File 'lib/ocak/local_issue_fetcher.rb', line 36

def add_label(issue_number, label)
  update_frontmatter(issue_number.to_i) do |fm|
    fm['labels'] = ((fm['labels'] || []) | [label])
  end
end

#all_issuesObject

— Queries —



87
88
89
90
91
92
# File 'lib/ocak/local_issue_fetcher.rb', line 87

def all_issues
  return [] unless Dir.exist?(@store_dir)

  Dir.glob(File.join(@store_dir, '*.md'))
     .filter_map { |f| parse_issue_file(f) }
end

#comment(issue_number, body) ⇒ Object



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/ocak/local_issue_fetcher.rb', line 48

def comment(issue_number, body)
  path = issue_path(issue_number.to_i)
  return unless path && File.exist?(path)

  content = File.read(path)
  timestamp = Time.now.utc.strftime('%Y-%m-%dT%H:%M:%SZ')

  unless content.include?(COMMENTS_SENTINEL)
    File.write(path, "#{content.chomp}\n\n#{COMMENTS_SENTINEL}\n#{timestamp}#{body}\n")
    return
  end

  File.open(path, 'a') { |f| f.write("#{timestamp}#{body}\n") }
rescue StandardError => e
  @logger&.warn("LocalIssueFetcher#comment failed for ##{issue_number}: #{e.message}")
  nil
end

#create(title:, body: '', labels: [], complexity: 'full') ⇒ Object

— Issue creation (CLI only) —



71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/ocak/local_issue_fetcher.rb', line 71

def create(title:, body: '', labels: [], complexity: 'full')
  FileUtils.mkdir_p(@store_dir)
  number = next_issue_number
  fm = {
    'number' => number,
    'title' => title,
    'labels' => labels,
    'complexity' => complexity,
    'created_at' => Time.now.utc.strftime('%Y-%m-%dT%H:%M:%SZ')
  }
  File.write(issue_path(number), build_file(fm, body))
  number
end

#ensure_label(_label) ⇒ Object



66
# File 'lib/ocak/local_issue_fetcher.rb', line 66

def ensure_label(_label) = nil

#ensure_labels(_labels) ⇒ Object



67
# File 'lib/ocak/local_issue_fetcher.rb', line 67

def ensure_labels(_labels) = nil

#fetch_readyObject

— Issue operations (overrides) —



19
20
21
22
23
24
25
26
27
# File 'lib/ocak/local_issue_fetcher.rb', line 19

def fetch_ready
  all_issues.select do |issue|
    labels = label_names(issue)
    labels.include?(@config.label_ready) && !labels.include?(@config.label_in_progress)
  end
rescue StandardError => e
  @logger&.warn("LocalIssueFetcher#fetch_ready failed: #{e.message}")
  []
end

#remove_label(issue_number, label) ⇒ Object



42
43
44
45
46
# File 'lib/ocak/local_issue_fetcher.rb', line 42

def remove_label(issue_number, label)
  update_frontmatter(issue_number.to_i) do |fm|
    fm['labels'] = (fm['labels'] || []) - [label]
  end
end

#view(issue_number, fields: 'number,title,body,labels') ⇒ Object

rubocop:disable Lint/UnusedMethodArgument



29
30
31
32
33
34
# File 'lib/ocak/local_issue_fetcher.rb', line 29

def view(issue_number, fields: 'number,title,body,labels') # rubocop:disable Lint/UnusedMethodArgument
  read_issue(issue_number.to_i)
rescue StandardError => e
  @logger&.warn("LocalIssueFetcher#view failed for ##{issue_number}: #{e.message}")
  nil
end