newsman 0.1.14 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5a68ba87116b71adc25a5983ee3b91cc94414b27edee46781fdec6141988a278
4
- data.tar.gz: 02f0cb536bbe01e60578755227a0b0a03eed4c6086bceebcee399f6ae2a53aba
3
+ metadata.gz: c0ec4c08d224982a75fc3ae533368cdeff2c4d7cab0072441fcfbd604f194b42
4
+ data.tar.gz: 8633c4f4dc84b0f6a285e06b67b0cb9dd3f9e7a18d6dc032589237652181d36f
5
5
  SHA512:
6
- metadata.gz: 6e247fd019a04cc39c3d9bb3e2bc0db202947941cad27e968501f9d355308ee4704b6f8c76267e1b2953f00996e15a2c5c6c5dd03e7712f93e400ab3fd3633e7
7
- data.tar.gz: 2d416b5a3476432636e78fe08d18bc3480539ecaea6f896c757a99a85d11b0be47aa7459448c9b3a536f942828d6e2cf512a5cc5c6f1296248b03f33bae8f249
6
+ metadata.gz: 85df6a743456154cdfcd2999a2f3a1977347cf9b101c8f2e35bd0b13024e6e1d66e8cf699bc7a11feac586f5b7bb6a2bdc08b75936bf967b011afdc2f1963716
7
+ data.tar.gz: e4aa02defb4c4a02dee05fe334fb799f0f10b825110e194e0f3d7e5da79ce54144e5a77d1543c57acbdc56ca444fa4be625f4e16a9c83487abc917711d0e771c
data/README.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Newsman
2
2
 
3
+
4
+ [![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE.txt)
5
+ [![Gem Version](https://img.shields.io/gem/v/newsman.svg)](https://rubygems.org/gems/newsman)
6
+
3
7
  Newsman is a simple script that collects information about a developer's weekly activity on GitHub and creates a human-readable summary of the work done. To create the summary, Newsman asks ChatGPT to handle all the information about a developer's activity, including their pull requests and created issues.
4
8
 
5
9
  ## Install
@@ -31,7 +35,9 @@ Usage: newsman [options]
31
35
  -n, --name NAME Reporter name. Human readable name that will be used in a report
32
36
  -u, --username USERNAME GitHub username. For example, 'volodya-lombrozo'
33
37
  -r, --repository REPOSITORIES Specify which repositories to include in a report. You can specify several repositories using a comma separator, for example: '-r objectionary/jeo-maven-plugin,objectionary/opeo-maven-plugin'
34
- -p, --position Reporter position in a company. Default value is a 'Software Developer'.
38
+ -p, --position POSITION Reporter position in a company. Default value is a 'Software Developer'.
39
+ -o, --output OUTPUT Output type. Newsman prints a report to a stdout by default. You can choose another options like '-o html', '-o txt' or even '-o html'
40
+ -t, --title TITLE Project Title. Empty by default
35
41
  ```
36
42
 
37
43
  ### Example
@@ -1,8 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) 2024 Volodya Lombrozo
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the 'Software'), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in all
13
+ # copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ # SOFTWARE.
22
+
1
23
  require 'openai'
2
24
 
25
+ # This class mimics a robot that can analyse a developer activity.
26
+ # The assistant uses OpenAI API to analyze.
3
27
  class Assistant
4
-
5
- CONTEXT = 'You are a developer tasked with composing a concise report detailing your activities and progress for the previous week, intended for submission to your supervisor.'
28
+ CONTEXT = 'You are a developer tasked'\
29
+ ' with composing a concise report detailing your activities'\
30
+ ' and progress for the previous week,'\
31
+ ' intended for submission to your supervisor.'
6
32
 
7
33
  def initialize(token, model: 'gpt-3.5-turbo', temperature: 0.3)
8
34
  @token = token
@@ -12,111 +38,92 @@ class Assistant
12
38
  end
13
39
 
14
40
  def say_hello
15
- "I'm an assistant that can work with OpenAI client. Please, use me, if you need any help. I'm using #{@model}, with #{@temperature} temperature."
41
+ <<~HELLO
42
+ I'm an assistant that can work with OpenAI client.
43
+ Please, use me, if you need any help.
44
+ I'm using #{@model}, with #{@temperature} temperature.
45
+ HELLO
16
46
  end
17
47
 
48
+ # rubocop:disable Metrics/MethodLength
18
49
  def next_plans(issues)
19
50
  example = "repository-name:\n
20
51
  - To publish ABC package draft [#27]\n
21
52
  - To review first draft of the report [#56]\n
22
53
  - To implement optimization for the class X [#125]"
23
- return send("Please compile a summary of the plans for the next week using the following GitHub Issues descriptions. Each issue should be summarized in a single sentence, focusing more on the issue title and less on implementation details. Pay attention, that you didn't loose any issue. Ensure that each sentence includes the corresponding issue number as an integer value. If an issue doesn't mention an issue number, just print [#chore]. Combine all the information from each Issue into a concise and fluent sentences, as if you were a developer reporting on your work. Please strictly adhere to the example template provided: ```#{example}```. List of GitHub issues to aggregate: [#{issues}].")
54
+ prompt = <<~PROMPT
55
+ Please compile a summary of the plans for the next week using the GitHub Issues.
56
+ Each issue should be summarized in a single sentence.
57
+ Combine all the information from each Issue into a concise and fluent sentence.
58
+ Pay attention, that you didn't loose any issue.
59
+ Ensure that each sentence includes the corresponding issue number as an integer value. If an issue doesn't mention an issue number, just print [#chore].
60
+ If several issues have the same number, combine them into a single sentence.
61
+ Please strictly adhere to the example template provided: "#{example}".
62
+ List of GitHub Issues in JSON format: ```json #{issues}```.
63
+ PROMPT
64
+ send(prompt)
24
65
  end
66
+ # rubocop:enable Metrics/MethodLength
25
67
 
68
+ # rubocop:disable Metrics/MethodLength
26
69
  def prev_results(prs)
27
70
  example = "repository-name:\n
28
71
  - Added 100 new files to the Dataset [#168]\n
29
72
  - Fixed the deployment of XYZ [#169]\n
30
73
  - Refined the requirements [#177]\n"
31
- return send("Please compile a summary of the work completed in the following Pull Requests (PRs). Each PR should be summarized in a single sentence, focusing more on the PR title and less on implementation details. Pay attention, that you don't lose any PR. Ensure that each sentence includes the corresponding issue number as an integer value. If a PR doesn't mention an issue number, just print [#chore]. Combine all the information from each PR into a concise and fluent sentence, as if you were a developer reporting on your work. Please strictly adhere to the example template provided: ```#{example}```. List of Pull Requests: [#{prs}]")
74
+ prompt = <<~PROMPT
75
+ Please compile a summary of the work completed in the following Pull Requests (PRs).
76
+ Each PR should be summarized in a single sentence, focusing on the PR title rather than the implementation details.
77
+ Ensure no PR is omitted.
78
+ Each sentence must include the corresponding issue number as an integer value. If a PR does not mention an issue number, use [#chore].
79
+ If several PRs have the same number, combine them into a single sentence.
80
+ Combine the information from each PR into a concise and fluent sentence.
81
+ Follow the provided example template strictly: "#{example}".
82
+ List of Pull Requests in JSON format: ```json #{prs}```.
83
+ PROMPT
84
+ send(prompt)
32
85
  end
86
+ # rubocop:enable Metrics/MethodLength
33
87
 
88
+ # rubocop:disable Metrics/MethodLength
34
89
  def risks(all)
35
90
  example = "repository-name:\n
36
91
  - The server is weak, we may fail the delivery\n
37
92
  of the dataset, report milestone will be missed [#487].\n
38
93
  - The code in repository is suboptimal, we might have some problems for the future maintainability [#44].\n"
39
- return send("Please compile a summary of the risks identified in the repository. If you can't find anything, just answer 'No risks identified'. Developers usually mention some risks in pull request descriptions. They either mention 'risk' or 'issue'. I will give you a list of pull requests. Each risk should be summarized in a single sentence. Ensure that each sentence includes the corresponding PR number as an integer value. If a PR doesn't mention an issue number, just print [#chore]. Combine all the information from each PR into a concise and fluent sentence, as if you were a developer reporting on your work. Please strictly adhere to the example template provided: ```#{example}```. List of Pull Requests: [#{all}]")
94
+ prompt = <<~PROMPT
95
+ Please compile a summary of the risks identified in the repository from the list of pull requests provided.
96
+ If no risks are identified in a pull request, just answer 'No risks identified' for that PR.
97
+ Each risk should be summarized in a concise and fluent single sentence.
98
+ Developers usually mention some risks in pull request descriptions, either as 'risk' or 'issue'.#{' '}
99
+ Ensure that each sentence includes the corresponding PR number as an integer value. If a PR doesn't mention an issue number, just print [#chore].
100
+ Please strictly adhere to the example template provided: "#{example}".
101
+ List of Pull Requests: ```json #{all}```.
102
+ PROMPT
103
+ send(prompt)
40
104
  end
105
+ # rubocop:enable Metrics/MethodLength
41
106
 
42
- def old_prev_results(prs)
43
- deprecated(__method__)
44
- example = "some-repository-name-x:
45
- - Added 100 new files to the Dataset [#168]
46
- - Fixed the deployment of XYZ [#169]
47
- - Refined the requirements [#177]
48
- some-repository-name-y:
49
- - Removed XYZ class [#57]
50
- - Refactored http module [#69]"
51
- response = @client.chat(
52
- parameters: {
53
- model: 'gpt-3.5-turbo',
54
- messages: [
55
- { role: 'system',
56
- content: 'You are a developer tasked with composing a concise report detailing your activities and progress for the previous week, intended for submission to your supervisor.' },
57
- { role: 'user',
58
- content: "Please compile a summary of the work completed in the following Pull Requests (PRs). Each PR should be summarized in a single sentence, focusing more on the PR title and less on implementation details. Group the sentences by repositories, each identified by its name mentioned in the 'repository:[name]' attribute of the PR. Pay attention, that you don't lose any PR. The grouping is important an should be precise. Ensure that each sentence includes the corresponding issue number as an integer value. If a PR doesn't mention an issue number, just print [#chore]. Combine all the information from each PR into a concise and fluent sentence, as if you were a developer reporting on your work. Please strictly adhere to the example template provided. Example of a report: #{example}. List of Pull Requests: [#{prs}]" }
59
- ],
60
- temperature: 0.3
61
- }
62
- )
63
- answer = response.dig('choices', 0, 'message', 'content')
64
- return answer
65
- end
107
+ def format(report)
108
+ prompt = <<~PROMPT
109
+ I have a weekly report with different parts that use various formatting styles.
110
+ Please format the entire report into a single cohesive format while preserving the original text without any changes.
111
+ Ensure that the formatting is consistent throughout the document.
66
112
 
67
- def old_next_plans(issues)
68
- deprecated(__method__)
69
- example_plans = "some-repository-name-x:
70
- - To publish ABC package draft [#27]
71
- - To review first draft of the report [#56]
72
- some-repository-name-y:
73
- - To implement optimization for the class X [#125]"
74
- issues_response = @client.chat(
75
- parameters: {
76
- model: 'gpt-3.5-turbo',
77
- messages: [
78
- { role: 'system',
79
- content: 'You are a developer tasked with composing a concise report detailing your activities and progress for the previous week, intended for submission to your supervisor.' },
80
- { role: 'user',
81
- content: "Please compile a summary of the plans for the next week using the following GitHub Issues descriptions. Each issue should be summarized in a single sentence, focusing more on the issue title and less on implementation details. Group the sentences by repositories, each identified by its name mentioned in the 'repository:[name]' attribute of the issue. Pat attention, that you din't loose any issue. The grouping is important an should be precise. Ensure that each sentence includes the corresponding issue number as an integer value. If an issue doesn't mention an issue number, just print [#chore]. Combine all the information from each Issue into a concise and fluent sentences, as if you were a developer reporting on your work. Please strictly adhere to the example template provided: #{example_plans}. List of GitHub issues to aggregate: [#{issues}]." }
82
- ],
83
- temperature: 0.3
84
- }
85
- )
86
- issues_full_answer = issues_response.dig('choices', 0, 'message', 'content')
87
- return issues_full_answer
88
- end
113
+ Here is the report:
89
114
 
90
- def old_risks(all)
91
- deprecated(__method__)
92
- example_risks = "some-repository-name-x:
93
- - The server is weak, we may fail the delivery
94
- of the dataset, report milestone will be missed [#487].
95
- some-repository-name-y:
96
- - The code in repository is suboptimal, we might have some problems for the future maintainability [#44]."
97
- return @client.chat(
98
- parameters: {
99
- model: 'gpt-3.5-turbo',
100
- messages: [
101
- { role: 'system',
102
- content: 'You are a developer tasked with composing a concise report detailing your activities and progress for the previous week, intended for submission to your supervisor.' },
103
- { role: 'user',
104
- content: "Please compile a summary of the risks identified in some repositories. If you can't find anything, just leave answer empty. Add some entries to a report only if you are sure it's a risk. Developers usually mention some risks in pull request descriptions. They either mention 'risk' or 'issue'. I will give you a list of pull requests. Each risk should be summarized in a single sentence. Ensure that each sentence includes the corresponding issue number or PR number as an integer value. If a PR or an issue doesn't mention an issue number, just print [#chore]. Combine all the information from each PR into a concise and fluent sentence, as if you were a developer reporting on your work. Please strictly adhere to the example template provided. Example of a report: #{example_risks}. List of Pull Requests: ```#{all}```.]" }
105
- ],
106
- temperature: 0.3
107
- }
108
- ).dig('choices', 0, 'message', 'content')
115
+ #{report}
116
+ PROMPT
117
+ send(prompt)
109
118
  end
110
119
 
111
120
  def send(request)
112
- return @client.chat(
121
+ @client.chat(
113
122
  parameters: {
114
123
  model: @model,
115
124
  messages: [
116
- { role: 'system',
117
- content: CONTEXT },
118
- { role: 'user',
119
- content: "#{request}" }
125
+ { role: 'system', content: CONTEXT },
126
+ { role: 'user', content: request.to_s }
120
127
  ],
121
128
  temperature: @temperature
122
129
  }
@@ -126,24 +133,4 @@ some-repository-name-y:
126
133
  def deprecated(method)
127
134
  warn "Warning! '#{method}' is deprecated and will be removed in future versions."
128
135
  end
129
-
130
- def send(request)
131
- return @client.chat(
132
- parameters: {
133
- model: @model,
134
- messages: [
135
- { role: 'system',
136
- content: CONTEXT },
137
- { role: 'user',
138
- content: "#{request}" }
139
- ],
140
- temperature: @temperature
141
- }
142
- ).dig('choices', 0, 'message', 'content')
143
- end
144
-
145
- def deprecated(method)
146
- warn "Warning! '#{method}' is deprecated and will be removed in future versions."
147
- end
148
-
149
136
  end
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # Copyright (c) 2024 Volodya Lombrozo
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ # of this software and associated documentation files (the 'Software'), to deal
9
+ # in the Software without restriction, including without limitation the rights
10
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ # copies of the Software, and to permit persons to whom the Software is
12
+ # furnished to do so, subject to the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be included in all
15
+ # copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
20
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
+ # SOFTWARE.
24
+
25
+ # This class represents a useful abstraction over Github API.
26
+ class Github
27
+ def initialize(token)
28
+ @client = Octokit::Client.new(github_token: token)
29
+ end
30
+
31
+ def pull_requests(username, repositories)
32
+ query = "is:pr author:#{username} created:>=#{date_one_week_ago(Date.today)} #{repositories}"
33
+ puts "Searching pull requests for #{username}."
34
+ puts 'Newsman uses the following request to GitHub to gather the'\
35
+ " required information about user activity: '#{query}'"
36
+ @client.search_issues(query).items.map do |pull_request|
37
+ parse_pr(pull_request)
38
+ end
39
+ end
40
+
41
+ def issues(username, repositories)
42
+ one_month_ago = Date.today.prev_month.strftime('%Y-%m-%d')
43
+ query = "is:issue is:open author:#{username}"\
44
+ " author:0pdd created:>=#{one_month_ago} #{repositories}"
45
+ puts "Searching issues using the following query: '#{query}'"
46
+ @client.search_issues(query).items.map do |issue|
47
+ parse_issue(issue)
48
+ end.select(&:important?)
49
+ end
50
+
51
+ def parse_pr(pull_request)
52
+ title = pull_request.title.to_s
53
+ repository = pull_request.repository_url.split('/').last
54
+ puts "Found PR in #{repository}: #{title}"
55
+ PullRequest.new(repository, title, pull_request.body.to_s, url: pull_request.html_url)
56
+ end
57
+
58
+ def parse_issue(issue)
59
+ title, repository, number = issue_details(issue)
60
+ if issue.user.login == '0pdd'
61
+ PddIssue.new(title, issue.body.to_s, repository, number, url: issue.html_url, labels: issue.labels.map(&:name))
62
+ else
63
+ Issue.new(title, issue.body.to_s, repository, number, url: issue.html_url, labels: issue.labels.map(&:name))
64
+ end
65
+ end
66
+
67
+ def issue_details(issue)
68
+ title = issue.title.to_s
69
+ repository = issue.repository_url.split('/').last
70
+ number = issue.number.to_s
71
+ puts "Found issue in #{repository}:[##{number}] #{title}"
72
+ [title, repository, number]
73
+ end
74
+ end
75
+
76
+ def date_one_week_ago(today)
77
+ today = Date.parse(today) unless today.is_a?(Date)
78
+ one_week_ago = today - 7
79
+ one_week_ago.strftime('%Y-%m-%d')
80
+ end
@@ -1,40 +1,57 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # Copyright (c) 2024 Volodya Lombrozo
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the 'Software'), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in all
13
+ # copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ # SOFTWARE.
22
+
3
23
  require 'erb'
4
24
  require 'redcarpet'
5
25
  require 'nokogiri'
6
- # frozen_string_literal: true
7
26
 
27
+ # This class represents a report output in HTML format.
8
28
  class Htmlout
9
- TEMPLATE = "
10
- <head>
11
- <title><%= title %></title>
12
- </head>
13
- <body>
14
- <h1><%= title %></h1>
15
- <%= body %>
16
- </body>
17
- "
29
+ TEMPLATE = <<~HTML
30
+ <head>
31
+ <title><%= title %></title>
32
+ </head>
33
+ <body>
34
+ <h1><%= title %></h1>
35
+ <%= body %>
36
+ </body>
37
+ HTML
18
38
 
19
39
  def initialize(root = '.')
20
40
  @root = root
21
41
  end
22
42
 
43
+ # rubocop:disable Metrics/AbcSize
23
44
  def print(report, reporter)
24
45
  title = title(reporter)
25
- renderer = Redcarpet::Render::HTML.new(no_links: true, hard_wrap: true, prettify: true)
26
- markdown = Redcarpet::Markdown.new(renderer, autolink: true, tables: true)
27
- body = markdown.render(report)
28
- renderer = ERB.new(TEMPLATE)
29
- html_content = renderer.result(binding)
30
- html_content = Nokogiri::HTML(html_content, &:noblanks).to_xhtml(indent: 2)
46
+ body = to_html(report)
31
47
  puts "Create a html file in a directory #{@root}"
32
48
  file = File.new(File.join(@root, filename(reporter)), 'w')
33
49
  puts "File #{file.path} was successfully created"
34
- file.puts html_content
50
+ file.puts Nokogiri::HTML(ERB.new(TEMPLATE).result(binding), &:noblanks).to_xhtml(indent: 2)
35
51
  puts "Report was successfully printed to a #{file.path}"
36
52
  file.close
37
53
  end
54
+ # rubocop:enable Metrics/AbcSize
38
55
 
39
56
  def title(reporter)
40
57
  date = Time.new.strftime('%d.%m.%Y')
@@ -45,4 +62,12 @@ class Htmlout
45
62
  date = Time.new.strftime('%d.%m.%Y')
46
63
  "#{date}.#{reporter}.html"
47
64
  end
65
+
66
+ def to_html(report)
67
+ Redcarpet::Markdown.new(
68
+ Redcarpet::Render::HTML.new(no_links: true, hard_wrap: true, prettify: true),
69
+ autolink: true,
70
+ tables: true
71
+ ).render(report)
72
+ end
48
73
  end
@@ -1,39 +1,89 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # Copyright (c) 2024 Volodya Lombrozo
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the 'Software'), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in all
13
+ # copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ # SOFTWARE.
22
+
3
23
  require 'net/http'
4
- # frozen_string_literal: true
24
+ require 'json'
5
25
 
26
+ # This class represents a GitHub Issue abstraction created by a user.
6
27
  class Issue
7
28
  attr_accessor :title, :body, :repo, :number
8
- attr_reader :url
9
29
 
10
- def initialize(title, body, repo, number, url: 'undefined')
30
+ def initialize(title, body, repo, number, **additional)
31
+ defaults = { url: 'undefined', labels: [] }
11
32
  @title = title
12
33
  @body = body
13
34
  @repo = repo
14
35
  @number = number
15
- @url = url
36
+ @additional = defaults.merge(additional)
16
37
  end
17
38
 
18
39
  def to_s
19
- "title: ```#{@title}```,\ndescription: ```#{@body}```,\nrepo: ```#{@repo}```,\nissue number: \##{@number}\n"
40
+ <<~MARKDOWN
41
+ title: ```#{@title}```,
42
+ description: ```#{@body}```,
43
+ repo: ```#{@repo}```,
44
+ issue number: \##{@number},
45
+ additional: #{@additional}
46
+ MARKDOWN
47
+ end
48
+
49
+ def detailed_title
50
+ "title: #{@title}, repo: #{@repo}, number: \##{@number}, url: #{url}, labels: #{labels}"
51
+ end
52
+
53
+ def url
54
+ @additional[:url]
55
+ end
56
+
57
+ def labels
58
+ @additional[:labels]
20
59
  end
21
60
 
22
- def detailed_title
23
- "title: #{@title}, repo: #{@repo}, number: \##{@number}, url: #{@url}"
61
+ def to_json(*_args)
62
+ {
63
+ number: @number,
64
+ title: @title,
65
+ description: @body,
66
+ repository: @repo,
67
+ url: url.to_s
68
+ }.to_json
69
+ end
70
+
71
+ def important?
72
+ labels.include? 'soon'
24
73
  end
25
-
26
74
  end
27
75
 
76
+ # This class represents a GitHub issue abstraction created by a 0pdd robot.
28
77
  class PddIssue
29
78
  attr_accessor :repo
30
79
 
31
- def initialize(title, body, repo, number, url: 'undefined')
80
+ def initialize(title, body, repo, number, **additional)
81
+ defaults = { url: 'undefined', labels: [] }
32
82
  @title = title
33
83
  @body = body
34
84
  @repo = repo
35
85
  @number = number
36
- @url = url
86
+ @additional = defaults.merge(additional)
37
87
  end
38
88
 
39
89
  def extract_real_body
@@ -44,17 +94,44 @@ class PddIssue
44
94
  end
45
95
 
46
96
  def issue_link
47
- @body[%r{https://github\.com/[\w\-/]+/blob/[\w\d]+/[\w/.-]+#\w+-\w+}, 0].gsub('https://github.com', 'https://raw.githubusercontent.com').gsub(
48
- 'blob/', ''
49
- )
97
+ @body[%r{https://github\.com/[\w\-/]+/blob/[\w\d]+/[\w/.-]+#\w+-\w+}, 0]
98
+ .gsub('https://github.com', 'https://raw.githubusercontent.com')
99
+ .gsub('blob/', '')
50
100
  end
51
101
 
52
102
  def to_s
53
- "title: ```#{@title}```,\ndescription: ```#{extract_real_body}```,\nrepo: ```#{@repo}```,\nissue number: \##{@number}\n"
103
+ <<~MARKDOWN
104
+ title: ```#{@title}```,
105
+ description: ```#{extract_real_body}```,
106
+ repo: ```#{@repo}```,
107
+ issue number: \##{@number},
108
+ additional: #{@additional}
109
+ MARKDOWN
54
110
  end
55
111
 
56
112
  def detailed_title
57
- "title: #{@title}, repo: #{@repo}, issue number: \##{@number}, url: #{@url}"
113
+ "title: #{@title}, repo: #{@repo}, issue number: \##{@number}, url: #{url}, labels: #{labels}"
58
114
  end
59
115
 
116
+ def to_json(*_args)
117
+ {
118
+ number: @number,
119
+ title: @title,
120
+ description: @body,
121
+ repository: @repo,
122
+ url: url.to_s
123
+ }.to_json
124
+ end
125
+
126
+ def important?
127
+ labels.include? 'soon'
128
+ end
129
+
130
+ def url
131
+ @additional[:url]
132
+ end
133
+
134
+ def labels
135
+ @additional[:labels]
136
+ end
60
137
  end
@@ -1,5 +1,28 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # Copyright (c) 2024 Volodya Lombrozo
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the 'Software'), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in all
13
+ # copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ # SOFTWARE.
22
+ require 'json'
23
+
24
+ # This class represents GitHub Pull Request abstraction.
25
+ # In the future, it might be any Pull or Merge request.
3
26
  class PullRequest
4
27
  attr_accessor :repository, :title, :description
5
28
  attr_reader :url
@@ -11,6 +34,15 @@ class PullRequest
11
34
  @url = url
12
35
  end
13
36
 
37
+ def to_json(*_args)
38
+ {
39
+ title: @title,
40
+ description: @description,
41
+ repository: @repository,
42
+ url: @url
43
+ }.to_json
44
+ end
45
+
14
46
  def to_s
15
47
  "title: ```#{@title}```,\ndescription: ```#{@description}```,\nrepo: ```#{@repository}```\n"
16
48
  end
@@ -18,5 +50,4 @@ class PullRequest
18
50
  def detailed_title
19
51
  "title: #{@title}, repo: #{@repository}, url: #{@url}"
20
52
  end
21
-
22
53
  end