newsman 0.1.14 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +7 -1
- data/lib/newsman/assistant.rb +83 -96
- data/lib/newsman/github.rb +80 -0
- data/lib/newsman/html_output.rb +42 -17
- data/lib/newsman/issues.rb +92 -15
- data/lib/newsman/pull_request.rb +32 -1
- data/lib/newsman/report.rb +49 -13
- data/lib/newsman/stdout_output.rb +22 -0
- data/lib/newsman/txt_output.rb +21 -0
- data/lib/newsman.rb +64 -100
- data/test/test_assistant.rb +8 -3
- data/test/test_htmlout.rb +1 -1
- data/test/test_issue.rb +62 -0
- data/test/test_pdd_issue.rb +35 -5
- data/test/test_pull_request.rb +39 -0
- data/test/test_report.rb +32 -24
- data/test/test_week_before.rb +1 -1
- metadata +21 -4
data/lib/newsman/report.rb
CHANGED
@@ -1,8 +1,29 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
+
# Copyright (c) 2024 Volodya Lombrozo
|
5
|
+
#
|
6
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
7
|
+
# of this software and associated documentation files (the 'Software'), to deal
|
8
|
+
# in the Software without restriction, including without limitation the rights
|
9
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
10
|
+
# copies of the Software, and to permit persons to whom the Software is
|
11
|
+
# furnished to do so, subject to the following conditions:
|
12
|
+
#
|
13
|
+
# The above copyright notice and this permission notice shall be included in all
|
14
|
+
# copies or substantial portions of the Software.
|
15
|
+
#
|
16
|
+
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
17
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
18
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
|
19
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
20
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
21
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
22
|
+
# SOFTWARE.
|
23
|
+
|
24
|
+
# This class builds entire report based on issues and pull requests passed.
|
4
25
|
class Report
|
5
|
-
def initialize(user, position, title, additional: ReportItems.new([],[]))
|
26
|
+
def initialize(user, position, title, additional: ReportItems.new([], []))
|
6
27
|
@user = user
|
7
28
|
@position = position
|
8
29
|
@title = title
|
@@ -10,14 +31,30 @@ class Report
|
|
10
31
|
end
|
11
32
|
|
12
33
|
def build(achievements, plans, risks, date)
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
34
|
+
<<~TEMPLATE
|
35
|
+
From: #{@user}
|
36
|
+
Subject: #{week_of_a_year(@title, date)}
|
37
|
+
|
38
|
+
Hi all,
|
39
|
+
|
40
|
+
Last week achievements:
|
41
|
+
#{achievements}
|
42
|
+
|
43
|
+
Next week plans:
|
44
|
+
#{plans}
|
45
|
+
|
46
|
+
Risks:
|
47
|
+
#{risks}
|
48
|
+
|
49
|
+
Best regards,
|
50
|
+
#{@user}
|
51
|
+
#{@position}
|
52
|
+
#{date}
|
53
|
+
TEMPLATE
|
54
|
+
end
|
55
|
+
|
56
|
+
def append_additional(report)
|
57
|
+
"#{report}\n#{"------\n#{@additional}" unless @additional.empty?}"
|
21
58
|
end
|
22
59
|
end
|
23
60
|
|
@@ -26,9 +63,8 @@ def week_of_a_year(project, today)
|
|
26
63
|
"WEEK #{number} #{project}"
|
27
64
|
end
|
28
65
|
|
29
|
-
|
66
|
+
# Report items inner class.
|
30
67
|
class ReportItems
|
31
|
-
|
32
68
|
def initialize(prs, issues)
|
33
69
|
@prs = prs || []
|
34
70
|
@issues = issues || []
|
@@ -41,7 +77,7 @@ class ReportItems
|
|
41
77
|
|
42
78
|
def to_s
|
43
79
|
prs_list = @prs.map(&:detailed_title).map { |obj| " - #{obj}\n" }.join
|
44
|
-
issues_list = @issues.map(&:detailed_title).map { |obj| " - #{obj}\n" }.join
|
45
|
-
|
80
|
+
issues_list = @issues.map(&:detailed_title).map { |obj| " - #{obj}\n" }.join
|
81
|
+
"Closed Pull Requests:\n#{prs_list}\nOpen Issues:\n#{issues_list}"
|
46
82
|
end
|
47
83
|
end
|
@@ -1,5 +1,27 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
#
|
4
|
+
# Copyright (c) 2024 Volodya Lombrozo
|
5
|
+
#
|
6
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
7
|
+
# of this software and associated documentation files (the 'Software'), to deal
|
8
|
+
# in the Software without restriction, including without limitation the rights
|
9
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
10
|
+
# copies of the Software, and to permit persons to whom the Software is
|
11
|
+
# furnished to do so, subject to the following conditions:
|
12
|
+
#
|
13
|
+
# The above copyright notice and this permission notice shall be included in all
|
14
|
+
# copies or substantial portions of the Software.
|
15
|
+
#
|
16
|
+
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
17
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
18
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
|
19
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
20
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
21
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
22
|
+
# SOFTWARE.
|
23
|
+
|
24
|
+
# This class prints report to a console.
|
3
25
|
class Stdout
|
4
26
|
def print(report)
|
5
27
|
puts 'Print a report to stdout'
|
data/lib/newsman/txt_output.rb
CHANGED
@@ -1,5 +1,26 @@
|
|
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
|
+
|
23
|
+
# This class knows how to print a report to a separate file.
|
3
24
|
class Txtout
|
4
25
|
def initialize(root = '.')
|
5
26
|
@root = root
|
data/lib/newsman.rb
CHANGED
@@ -1,6 +1,27 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# frozen_string_literal: true
|
3
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
|
+
|
4
25
|
require 'octokit'
|
5
26
|
require 'openai'
|
6
27
|
require 'dotenv'
|
@@ -12,7 +33,9 @@ require_relative 'newsman/txt_output'
|
|
12
33
|
require_relative 'newsman/html_output'
|
13
34
|
require_relative 'newsman/report'
|
14
35
|
require_relative 'newsman/assistant'
|
36
|
+
require_relative 'newsman/github'
|
15
37
|
|
38
|
+
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
16
39
|
def generate
|
17
40
|
# Load all options required
|
18
41
|
# Pay attention that some of them have default values.
|
@@ -26,7 +49,9 @@ def generate
|
|
26
49
|
options[:username] = u
|
27
50
|
end
|
28
51
|
opts.on('-r', '--repository REPOSITORIES',
|
29
|
-
|
52
|
+
'Specify which repositories to include in a report.'\
|
53
|
+
'You can specify several repositories using a comma separator,'\
|
54
|
+
"for example: '-r objectionary/jeo-maven-plugin,objectionary/opeo-maven-plugin'") do |r|
|
30
55
|
options[:repositories] = r
|
31
56
|
end
|
32
57
|
opts.on('-p', '--position POSITION',
|
@@ -34,7 +59,8 @@ def generate
|
|
34
59
|
options[:position] = p
|
35
60
|
end
|
36
61
|
opts.on('-o', '--output OUTPUT',
|
37
|
-
|
62
|
+
'Output type. Newsman prints a report to a stdout by default.'\
|
63
|
+
"You can choose another options like '-o html', '-o txt' or even '-o html'") do |o|
|
38
64
|
options[:output] = o
|
39
65
|
end
|
40
66
|
opts.on('-t', '--title TITLE', 'Project Title. Empty by default') do |t|
|
@@ -45,118 +71,61 @@ def generate
|
|
45
71
|
def options.require_option(key, message)
|
46
72
|
raise OptionParser::MissingArgument, message if self[key].nil?
|
47
73
|
end
|
48
|
-
|
49
74
|
# Check for required options
|
50
75
|
options.require_option(:name, 'Reporter name is required. Please specify using -n or --name.')
|
51
76
|
options.require_option(:username, 'GitHub username is required. Please specify using -u or --username.')
|
52
77
|
options.require_option(:repositories,
|
53
|
-
'GitHub repository is required.
|
78
|
+
'GitHub repository is required.'\
|
79
|
+
' Please specify one or several repositories using -r or --repositories.')
|
54
80
|
options[:position] ||= 'Software Developer'
|
55
81
|
options[:output] ||= 'stdout'
|
56
82
|
options[:title] ||= ''
|
57
83
|
all_params = options.map { |key, value| "#{key}: #{value}" }.join(', ')
|
58
84
|
puts "Parsed parameters: #{all_params}"
|
59
|
-
|
60
|
-
#
|
61
|
-
Dotenv.load
|
62
|
-
Dotenv.require_keys('GITHUB_TOKEN', 'OPENAI_TOKEN')
|
63
|
-
|
64
|
-
# Init all required parameters
|
65
|
-
# Reporter Info
|
85
|
+
load_environment_variables
|
86
|
+
# Init all required parameters Reporter Info
|
66
87
|
reporter = options[:name]
|
67
88
|
reporter_position = options[:position]
|
68
89
|
# GitHub
|
69
90
|
github_username = options[:username]
|
70
91
|
github_repositories = options[:repositories].split(',').map { |repo| "repo:#{repo}" }.join(' ')
|
71
|
-
|
72
92
|
# Your GitHub personal access token
|
73
93
|
# Make sure it has the 'repo'
|
74
94
|
github_token = ENV['GITHUB_TOKEN']
|
75
95
|
# Your OpenAI personal access token
|
76
96
|
openai_token = ENV['OPENAI_TOKEN']
|
77
97
|
# Create a GitHub client instance with your access token
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
one_month_ago = Date.today.prev_month.strftime('%Y-%m-%d')
|
82
|
-
# Display pull request
|
83
|
-
query = "is:pr author:#{github_username} created:>=#{one_week_ago} #{github_repositories}"
|
84
|
-
issues_query = "is:issue is:open author:#{github_username} author:0pdd created:>=#{one_month_ago} #{github_repositories}"
|
85
|
-
puts "Searching pull requests for #{github_username}."
|
86
|
-
puts "Newsman uses the following request to GitHub to gather the required information about user activity: '#{query}'"
|
87
|
-
prs = []
|
88
|
-
pull_requests = client.search_issues(query)
|
89
|
-
pull_requests.items.each do |pr|
|
90
|
-
title = pr.title.to_s
|
91
|
-
description = pr.body.to_s
|
92
|
-
repository = pr.repository_url.split('/').last
|
93
|
-
puts "Found PR in #{repository}: #{title}"
|
94
|
-
# Create a new PullRequest object and add it to the list
|
95
|
-
pr = PullRequest.new(repository, title, description, url: pr.html_url)
|
96
|
-
prs << pr
|
97
|
-
end
|
98
|
-
raw_prs = prs
|
99
|
-
prs = prs.map(&:to_s).join("\n\n\n")
|
100
|
-
grouped_prs = raw_prs.group_by { |pr| pr.repository }
|
101
|
-
|
102
|
-
puts "Searching issues using the following query: '#{issues_query}'"
|
103
|
-
issues = []
|
104
|
-
client.search_issues(issues_query).items.each do |issue|
|
105
|
-
title = issue.title.to_s
|
106
|
-
body = issue.body.to_s
|
107
|
-
repository = issue.repository_url.split('/').last
|
108
|
-
number = issue.number.to_s
|
109
|
-
puts "Found issue in #{repository}:[##{number}] #{title}"
|
110
|
-
issues << if issue.user.login == '0pdd'
|
111
|
-
PddIssue.new(title, body, repository, number, url: issue.html_url)
|
112
|
-
else
|
113
|
-
Issue.new(title, body, repository, number, url: issue.html_url)
|
114
|
-
end
|
115
|
-
end
|
116
|
-
raw_issues = issues
|
117
|
-
issues = issues.map(&:to_s).join("\n\n\n")
|
118
|
-
grouped_issues = raw_issues.group_by { |iss| iss.repo }
|
119
|
-
|
98
|
+
github = Github.new(github_token)
|
99
|
+
prs = github.pull_requests(github_username, github_repositories)
|
100
|
+
issues = github.issues(github_username, github_repositories)
|
120
101
|
puts "\nNow lets test some aggregation using OpenAI\n\n"
|
121
|
-
openai_client = OpenAI::Client.new(access_token: openai_token)
|
122
|
-
|
123
102
|
assistant = Assistant.new(openai_token)
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
risks_full_answer = assistant.old_risks(prs)
|
130
|
-
else
|
131
|
-
puts "Assistant builds a report using a new approach, using groupping"
|
132
|
-
# Build previous results
|
133
|
-
answer = ""
|
134
|
-
grouped_prs.each do |repository, rprs|
|
135
|
-
puts "Building a results report for the repository: #{repository}"
|
136
|
-
answer = answer + assistant.prev_results(rprs.map(&:to_s).join("\n\n\n"))
|
137
|
-
end
|
138
|
-
# Build next plans
|
139
|
-
issues_full_answer = ""
|
140
|
-
grouped_issues.each do |repository, rissues|
|
141
|
-
puts "Building a future plans report for the repository: #{repository}"
|
142
|
-
issues_full_answer = issues_full_answer + assistant.next_plans(rissues.map(&:to_s).join("\n\n\n"))
|
143
|
-
end
|
144
|
-
# Find risks
|
145
|
-
risks_full_answer = assistant.risks(prs)
|
103
|
+
# Build previous results
|
104
|
+
answer = ''
|
105
|
+
prs.group_by(&:repository).each do |repository, rprs|
|
106
|
+
puts "Building a results report for the repository: #{repository}"
|
107
|
+
answer = "#{answer}\n#{assistant.prev_results(join(rprs))}"
|
146
108
|
end
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
109
|
+
# Build next plans
|
110
|
+
issues_full_answer = ''
|
111
|
+
issues.group_by(&:repo).each do |repository, rissues|
|
112
|
+
puts "Building a future plans report for the repository: #{repository}"
|
113
|
+
issues_full_answer = "#{issues_full_answer}\n#{assistant.next_plans(join(rissues))}"
|
114
|
+
end
|
115
|
+
# Build report
|
116
|
+
report = Report.new(
|
117
|
+
reporter,
|
118
|
+
reporter_position,
|
151
119
|
options[:title],
|
152
|
-
additional: ReportItems.new(
|
153
|
-
).build(
|
154
|
-
answer,
|
155
|
-
issues_full_answer,
|
156
|
-
risks_full_answer,
|
157
|
-
Date.today
|
120
|
+
additional: ReportItems.new(prs, issues)
|
158
121
|
)
|
159
|
-
|
122
|
+
full_answer = assistant.format(report.build(
|
123
|
+
answer,
|
124
|
+
issues_full_answer,
|
125
|
+
assistant.risks(join(prs)),
|
126
|
+
Date.today
|
127
|
+
))
|
128
|
+
full_answer = report.append_additional(full_answer)
|
160
129
|
output_mode = options[:output]
|
161
130
|
puts "Output mode is '#{output_mode}'"
|
162
131
|
if output_mode.eql? 'txt'
|
@@ -173,20 +142,15 @@ def generate
|
|
173
142
|
output.print(full_answer)
|
174
143
|
end
|
175
144
|
end
|
145
|
+
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
176
146
|
|
177
|
-
def
|
178
|
-
|
179
|
-
|
180
|
-
# Subtract 7 days to get the date one week ago
|
181
|
-
one_week_ago = today - 7
|
182
|
-
# Format the date as "YYYY-MM-DD"
|
183
|
-
one_week_ago.strftime('%Y-%m-%d')
|
184
|
-
# Return the formatted date
|
147
|
+
def load_environment_variables
|
148
|
+
Dotenv.load
|
149
|
+
Dotenv.require_keys('GITHUB_TOKEN', 'OPENAI_TOKEN')
|
185
150
|
end
|
186
151
|
|
187
|
-
def
|
188
|
-
|
189
|
-
"WEEK #{number} #{project}"
|
152
|
+
def join(items)
|
153
|
+
"[#{items.map(&:to_json).join(',')}]"
|
190
154
|
end
|
191
155
|
|
192
156
|
# Execute the function only if this script is run directly like `./newsman.rb`
|
data/test/test_assistant.rb
CHANGED
@@ -26,8 +26,13 @@ require_relative '../lib/newsman/assistant'
|
|
26
26
|
|
27
27
|
class TestAssistant < Minitest::Test
|
28
28
|
def test_creates_default_assistant
|
29
|
-
assistant = Assistant
|
30
|
-
|
29
|
+
assistant = Assistant.new('test-token')
|
30
|
+
expected = <<~EXPECTED
|
31
|
+
I'm an assistant that can work with OpenAI client.
|
32
|
+
Please, use me, if you need any help.
|
33
|
+
I'm using gpt-3.5-turbo, with 0.3 temperature.
|
34
|
+
EXPECTED
|
35
|
+
assert_equal expected,
|
36
|
+
assistant.say_hello
|
31
37
|
end
|
32
38
|
end
|
33
|
-
|
data/test/test_htmlout.rb
CHANGED
data/test/test_issue.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# Copyright (c) 2024 Volodya Lombrozo
|
5
|
+
#
|
6
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
7
|
+
# of this software and associated documentation files (the 'Software'), to deal
|
8
|
+
# in the Software without restriction, including without limitation the rights
|
9
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
10
|
+
# copies of the Software, and to permit persons to whom the Software is
|
11
|
+
# furnished to do so, subject to the following conditions:
|
12
|
+
#
|
13
|
+
# The above copyright notice and this permission notice shall be included in all
|
14
|
+
# copies or substantial portions of the Software.
|
15
|
+
#
|
16
|
+
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
17
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
18
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
|
19
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
20
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
21
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
22
|
+
# SOFTWARE.
|
23
|
+
|
24
|
+
require 'minitest/autorun'
|
25
|
+
require_relative '../lib/newsman/issues'
|
26
|
+
|
27
|
+
class TestIssue < Minitest::Test
|
28
|
+
def test_converts_issue_to_json
|
29
|
+
issue = Issue.new(
|
30
|
+
'AnnotationsApplication.java:32-35: Check default values...',
|
31
|
+
'TEST_BODY',
|
32
|
+
'jeo-maven-plugin',
|
33
|
+
531
|
34
|
+
)
|
35
|
+
expected = <<~JSON.chomp
|
36
|
+
{"number":531,"title":"AnnotationsApplication.java:32-35: Check default values...","description":"TEST_BODY","repository":"jeo-maven-plugin","url":"undefined"}
|
37
|
+
JSON
|
38
|
+
assert_equal expected, issue.to_json
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_important_issue
|
42
|
+
issue = Issue.new(
|
43
|
+
'Important Issue Title',
|
44
|
+
'Important Issue Body',
|
45
|
+
'jeo-maven-plugin',
|
46
|
+
531,
|
47
|
+
labels: ['soon']
|
48
|
+
)
|
49
|
+
assert issue.important?
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_unimportant_issue
|
53
|
+
issue = Issue.new(
|
54
|
+
'Unimportant Issue Title',
|
55
|
+
'Unimportant Issue Body',
|
56
|
+
'jeo-maven-plugin',
|
57
|
+
531,
|
58
|
+
labels: ['not-soon']
|
59
|
+
)
|
60
|
+
assert !issue.important?
|
61
|
+
end
|
62
|
+
end
|
data/test/test_pdd_issue.rb
CHANGED
@@ -25,7 +25,7 @@ require 'minitest/autorun'
|
|
25
25
|
require_relative '../lib/newsman/issues'
|
26
26
|
|
27
27
|
class TestPddIssue < Minitest::Test
|
28
|
-
TEST_BODY =
|
28
|
+
TEST_BODY = <<~BODY
|
29
29
|
The puzzle `531-462261de` from #531 has to be resolved:
|
30
30
|
|
31
31
|
https://github.com/objectionary/jeo-maven-plugin/blob/5a42b2c9f7e0ff01cbb2c4626e1dc5dc3f8aa7b8/src/it/annotations/src/main/java/org/eolang/jeo/annotations/AnnotationsApplication.java#L32-L35
|
@@ -34,11 +34,18 @@ class TestPddIssue < Minitest::Test
|
|
34
34
|
|
35
35
|
Estimate: 90 minutes, role: DEV.
|
36
36
|
|
37
|
-
If you have any technical questions, don't ask me, submit new tickets instead.
|
38
|
-
|
37
|
+
If you have any technical questions, don't ask me, submit new tickets instead.
|
38
|
+
The task will be "done" when the problem is fixed and the text of the puzzle is _removed_ from the source code.
|
39
|
+
Here is more about [PDD](http://www.yegor256.com/2009/03/04/pdd.html) and [about me](http://www.yegor256.com/2017/04/05/pdd-in-action.html).
|
40
|
+
BODY
|
39
41
|
|
40
|
-
EXPECTED_DESCRIPTION = [
|
41
|
-
|
42
|
+
EXPECTED_DESCRIPTION = [
|
43
|
+
" * @todo #531:90min Check default values for annotation properties.\n",
|
44
|
+
" * We still encounter some problems with annotation processing.\n",
|
45
|
+
" * Especially with Autowired annotation from Spring Framework.\n",
|
46
|
+
" * It's relatively simple annotation, but it's not processed correctly.\n",
|
47
|
+
" */\n"
|
48
|
+
].freeze
|
42
49
|
|
43
50
|
def test_parses_pdd_issue
|
44
51
|
issue = PddIssue.new('AnnotationsApplication.java:32-35: Check default values...',
|
@@ -46,4 +53,27 @@ class TestPddIssue < Minitest::Test
|
|
46
53
|
'jeo-maven-plugin', 531)
|
47
54
|
assert_equal(EXPECTED_DESCRIPTION, issue.extract_real_body)
|
48
55
|
end
|
56
|
+
|
57
|
+
def test_converts_to_json
|
58
|
+
issue = PddIssue.new('AnnotationsApplication.java:32-35: Check default values...',
|
59
|
+
'TEST_BODY',
|
60
|
+
'jeo-maven-plugin', 531)
|
61
|
+
expected = <<~JSON.chomp
|
62
|
+
{"number":531,"title":"AnnotationsApplication.java:32-35: Check default values...","description":"TEST_BODY","repository":"jeo-maven-plugin","url":"undefined"}
|
63
|
+
JSON
|
64
|
+
assert_equal(
|
65
|
+
expected,
|
66
|
+
issue.to_json
|
67
|
+
)
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_important_issue
|
71
|
+
issue = PddIssue.new('Title', 'Body', 'jeo-maven-plugin', 531, labels: ['soon'])
|
72
|
+
assert issue.important?
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_unimportant_issue
|
76
|
+
issue = PddIssue.new('Title', 'Body', 'jeo-maven-plugin', 531)
|
77
|
+
assert !issue.important?
|
78
|
+
end
|
49
79
|
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# Copyright (c) 2024 Volodya Lombrozo
|
5
|
+
#
|
6
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
7
|
+
# of this software and associated documentation files (the 'Software'), to deal
|
8
|
+
# in the Software without restriction, including without limitation the rights
|
9
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
10
|
+
# copies of the Software, and to permit persons to whom the Software is
|
11
|
+
# furnished to do so, subject to the following conditions:
|
12
|
+
#
|
13
|
+
# The above copyright notice and this permission notice shall be included in all
|
14
|
+
# copies or substantial portions of the Software.
|
15
|
+
#
|
16
|
+
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
17
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
18
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
|
19
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
20
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
21
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
22
|
+
# SOFTWARE.
|
23
|
+
|
24
|
+
require 'minitest/autorun'
|
25
|
+
require_relative '../lib/newsman/pull_request'
|
26
|
+
|
27
|
+
class TestPullRequest < Minitest::Test
|
28
|
+
def test_converts_pr_to_json
|
29
|
+
pr = PullRequest.new(
|
30
|
+
'jeo-maven-plugin',
|
31
|
+
'Interesting Title',
|
32
|
+
'Pr description'
|
33
|
+
)
|
34
|
+
assert_equal(
|
35
|
+
'{"title":"Interesting Title","description":"Pr description","repository":"jeo-maven-plugin","url":"undefined"}',
|
36
|
+
pr.to_json
|
37
|
+
)
|
38
|
+
end
|
39
|
+
end
|
data/test/test_report.rb
CHANGED
@@ -27,42 +27,50 @@ require_relative '../lib/newsman/issues'
|
|
27
27
|
require_relative '../lib/newsman/pull_request'
|
28
28
|
|
29
29
|
class TestReport < Minitest::Test
|
30
|
-
|
31
|
-
|
32
|
-
Subject: WEEK 11 Project
|
30
|
+
REPORT_EXAMPLE = <<~EXPECTED
|
31
|
+
From: User
|
32
|
+
Subject: WEEK 11 Project
|
33
|
+
|
34
|
+
Hi all,
|
33
35
|
|
34
|
-
|
36
|
+
Last week achievements:
|
37
|
+
repository-a:
|
38
|
+
- Did a lot of for (a) repository
|
35
39
|
|
36
|
-
|
37
|
-
repository-
|
38
|
-
|
40
|
+
Next week plans:
|
41
|
+
repository-b:
|
42
|
+
- I will do a lot for repository (b)
|
39
43
|
|
40
|
-
|
41
|
-
|
42
|
-
- I will do a lot for repository (b)
|
44
|
+
Risks:
|
45
|
+
- <todo>
|
43
46
|
|
44
|
-
|
45
|
-
|
47
|
+
Best regards,
|
48
|
+
User
|
49
|
+
Developer
|
50
|
+
2024-03-14
|
51
|
+
EXPECTED
|
46
52
|
|
47
|
-
|
48
|
-
|
49
|
-
Developer
|
50
|
-
2024-03-14"
|
53
|
+
def test_report
|
54
|
+
expected = REPORT_EXAMPLE
|
51
55
|
report = Report.new('User', 'Developer', 'Project')
|
52
56
|
out = report.build("repository-a:\n - Did a lot of for (a) repository",
|
53
|
-
"repository-b:\n - I will do a lot for repository (b)",
|
57
|
+
"repository-b:\n - I will do a lot for repository (b)",
|
58
|
+
'- <todo>',
|
59
|
+
Date.new(2024, 3, 14))
|
54
60
|
assert_equal expected, out
|
55
61
|
end
|
56
62
|
|
57
63
|
def test_report_items
|
58
|
-
expected =
|
59
|
-
|
60
|
-
|
61
|
-
actual = ReportItems.new(prs, issues).to_s
|
64
|
+
expected = <<~EXPECTED
|
65
|
+
Closed Pull Requests:
|
66
|
+
- title: title, repo: repo, url: http://some.url.com
|
62
67
|
|
63
|
-
|
68
|
+
Open Issues:
|
69
|
+
- title: title, repo: repo, number: #123, url: http://google.com, labels: []
|
70
|
+
EXPECTED
|
71
|
+
issues = [Issue.new('title', 'body', 'repo', '123', url: 'http://google.com')]
|
72
|
+
prs = [PullRequest.new('repo', 'title', 'body', url: 'http://some.url.com')]
|
73
|
+
actual = ReportItems.new(prs, issues).to_s
|
64
74
|
assert_equal expected, actual
|
65
75
|
end
|
66
|
-
|
67
|
-
|
68
76
|
end
|