newsman 0.1.13 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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'
@@ -11,7 +32,10 @@ require_relative 'newsman/stdout_output'
11
32
  require_relative 'newsman/txt_output'
12
33
  require_relative 'newsman/html_output'
13
34
  require_relative 'newsman/report'
35
+ require_relative 'newsman/assistant'
36
+ require_relative 'newsman/github'
14
37
 
38
+ # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
15
39
  def generate
16
40
  # Load all options required
17
41
  # Pay attention that some of them have default values.
@@ -25,7 +49,9 @@ def generate
25
49
  options[:username] = u
26
50
  end
27
51
  opts.on('-r', '--repository REPOSITORIES',
28
- "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'") do |r|
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|
29
55
  options[:repositories] = r
30
56
  end
31
57
  opts.on('-p', '--position POSITION',
@@ -33,7 +59,8 @@ def generate
33
59
  options[:position] = p
34
60
  end
35
61
  opts.on('-o', '--output OUTPUT',
36
- "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'") do |o|
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|
37
64
  options[:output] = o
38
65
  end
39
66
  opts.on('-t', '--title TITLE', 'Project Title. Empty by default') do |t|
@@ -44,145 +71,63 @@ def generate
44
71
  def options.require_option(key, message)
45
72
  raise OptionParser::MissingArgument, message if self[key].nil?
46
73
  end
47
-
48
74
  # Check for required options
49
75
  options.require_option(:name, 'Reporter name is required. Please specify using -n or --name.')
50
76
  options.require_option(:username, 'GitHub username is required. Please specify using -u or --username.')
51
77
  options.require_option(:repositories,
52
- 'GitHub repository is required. Please specify one or several repositories using -r or --repositories.')
78
+ 'GitHub repository is required.'\
79
+ ' Please specify one or several repositories using -r or --repositories.')
53
80
  options[:position] ||= 'Software Developer'
54
81
  options[:output] ||= 'stdout'
55
82
  options[:title] ||= ''
56
83
  all_params = options.map { |key, value| "#{key}: #{value}" }.join(', ')
57
84
  puts "Parsed parameters: #{all_params}"
58
-
59
- # Load all required environment variables
60
- Dotenv.load
61
- Dotenv.require_keys('GITHUB_TOKEN', 'OPENAI_TOKEN')
62
-
63
- # Init all required parameters
64
- # Reporter Info
85
+ load_environment_variables
86
+ # Init all required parameters Reporter Info
65
87
  reporter = options[:name]
66
88
  reporter_position = options[:position]
67
89
  # GitHub
68
90
  github_username = options[:username]
69
91
  github_repositories = options[:repositories].split(',').map { |repo| "repo:#{repo}" }.join(' ')
70
-
71
92
  # Your GitHub personal access token
72
93
  # Make sure it has the 'repo'
73
94
  github_token = ENV['GITHUB_TOKEN']
74
95
  # Your OpenAI personal access token
75
96
  openai_token = ENV['OPENAI_TOKEN']
76
97
  # Create a GitHub client instance with your access token
77
- client = Octokit::Client.new(github_token: github_token)
78
- # Calculate the date one week ago
79
- one_week_ago = date_one_week_ago(Date.today)
80
- one_month_ago = Date.today.prev_month.strftime('%Y-%m-%d')
81
- # Display pull request
82
- query = "is:pr author:#{github_username} created:>=#{one_week_ago} #{github_repositories}"
83
- issues_query = "is:issue is:open author:#{github_username} author:0pdd created:>=#{one_month_ago} #{github_repositories}"
84
- puts "Searching pull requests for #{github_username}."
85
- puts "Newsman uses the following request to GitHub to gather the required information about user activity: '#{query}'"
86
- prs = []
87
- pull_requests = client.search_issues(query)
88
- pull_requests.items.each do |pr|
89
- title = pr.title.to_s
90
- description = pr.body.to_s
91
- repository = pr.repository_url.split('/').last
92
- puts "Found PR in #{repository}: #{title}"
93
- # Create a new PullRequest object and add it to the list
94
- pr = PullRequest.new(repository, title, description, url: pr.html_url)
95
- prs << pr
98
+ github = Github.new(github_token)
99
+ prs = github.pull_requests(github_username, github_repositories)
100
+ issues = github.issues(github_username, github_repositories)
101
+ puts "\nNow lets test some aggregation using OpenAI\n\n"
102
+ assistant = Assistant.new(openai_token)
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))}"
96
108
  end
97
- raw_prs = prs
98
- prs = prs.map(&:to_s).join("\n\n\n")
99
-
100
- puts "Searching issues using the following query: '#{issues_query}'"
101
- issues = []
102
- client.search_issues(issues_query).items.each do |issue|
103
- title = issue.title.to_s
104
- body = issue.body.to_s
105
- repository = issue.repository_url.split('/').last
106
- number = issue.number.to_s
107
- puts "Found issue in #{repository}:[##{number}] #{title}"
108
- issues << if issue.user.login == '0pdd'
109
- PddIssue.new(title, body, repository, number, url: issue.html_url)
110
- else
111
- Issue.new(title, body, repository, number, url: issue.html_url)
112
- end
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))}"
113
114
  end
114
- raw_issues = issues
115
- issues = issues.map(&:to_s).join("\n\n\n")
116
- # puts "Found issues:\n #{issues}"
117
-
118
- puts "\nNow lets test some aggregation using OpenAI\n\n"
119
- openai_client = OpenAI::Client.new(access_token: openai_token)
120
-
121
- example = "some-repository-name-x:
122
- - Added 100 new files to the Dataset [#168]
123
- - Fixed the deployment of XYZ [#169]
124
- - Refined the requirements [#177]
125
- some-repository-name-y:
126
- - Removed XYZ class [#57]
127
- - Refactored http module [#69]"
128
-
129
- example_plans = "some-repository-name-x:
130
- - To publish ABC package draft [#27]
131
- - To review first draft of the report [#56]
132
- some-repository-name-y:
133
- - To implement optimization for the class X [#125]"
134
-
135
- example_risks = "some-repository-name-x:
136
- - The server is weak, we may fail the delivery
137
- of the dataset, report milestone will be missed [#487].
138
- some-repository-name-y:
139
- - The code in repository is suboptimal, we might have some problems for the future maintainability [#44].
140
- "
141
-
142
- response = openai_client.chat(
143
- parameters: {
144
- model: 'gpt-3.5-turbo',
145
- messages: [
146
- { role: 'system',
147
- 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.' },
148
- { role: 'user',
149
- 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}]" }
150
- ],
151
- temperature: 0.3
152
- }
115
+ # Build report
116
+ report = Report.new(
117
+ reporter,
118
+ reporter_position,
119
+ options[:title],
120
+ additional: ReportItems.new(prs, issues)
153
121
  )
154
- answer = response.dig('choices', 0, 'message', 'content')
155
- issues_response = openai_client.chat(
156
- parameters: {
157
- model: 'gpt-3.5-turbo',
158
- messages: [
159
- { role: 'system',
160
- 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.' },
161
- { role: 'user',
162
- 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}]. Use the same formatting as here \n```#{answer}```\n" }
163
- ],
164
- temperature: 0.3
165
- }
166
- )
167
- issues_full_answer = issues_response.dig('choices', 0, 'message', 'content')
168
-
169
- risks_full_answer = openai_client.chat(
170
- parameters: {
171
- model: 'gpt-3.5-turbo',
172
- messages: [
173
- { role: 'system',
174
- 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.' },
175
- { role: 'user',
176
- 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: ```#{prs}```.]" }
177
- ],
178
- temperature: 0.3
179
- }
180
- ).dig('choices', 0, 'message', 'content')
181
-
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)
182
129
  output_mode = options[:output]
183
130
  puts "Output mode is '#{output_mode}'"
184
- full_answer = Report.new(reporter, reporter_position, options[:title], additional: ReportItems.new(raw_prs, raw_issues)).build(answer, issues_full_answer,
185
- risks_full_answer, Date.today)
186
131
  if output_mode.eql? 'txt'
187
132
  puts 'Print result to txy file'
188
133
  output = Txtout.new('.')
@@ -197,20 +142,15 @@ some-repository-name-y:
197
142
  output.print(full_answer)
198
143
  end
199
144
  end
145
+ # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
200
146
 
201
- def date_one_week_ago(today)
202
- # Convert today to a Date object if it's not already
203
- today = Date.parse(today) unless today.is_a?(Date)
204
- # Subtract 7 days to get the date one week ago
205
- one_week_ago = today - 7
206
- # Format the date as "YYYY-MM-DD"
207
- one_week_ago.strftime('%Y-%m-%d')
208
- # Return the formatted date
147
+ def load_environment_variables
148
+ Dotenv.load
149
+ Dotenv.require_keys('GITHUB_TOKEN', 'OPENAI_TOKEN')
209
150
  end
210
151
 
211
- def week_of_a_year(project, today)
212
- number = today.strftime('%U').to_i + 1
213
- "WEEK #{number} #{project}"
152
+ def join(items)
153
+ "[#{items.map(&:to_json).join(',')}]"
214
154
  end
215
155
 
216
156
  # Execute the function only if this script is run directly like `./newsman.rb`
@@ -0,0 +1,38 @@
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/assistant'
26
+
27
+ class TestAssistant < Minitest::Test
28
+ def test_creates_default_assistant
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
37
+ end
38
+ end
data/test/test_htmlout.rb CHANGED
@@ -42,7 +42,7 @@ List is here:<br/>
42
42
 
43
43
  </body>
44
44
  </html>
45
- "
45
+ ".freeze
46
46
 
47
47
  def test_writes_to_a_html_file
48
48
  Dir.mktmpdir do |temp_dir|
@@ -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
@@ -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. The task will be \"done\" when the problem is fixed and the text of the puzzle is _removed_ from the source code. 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).
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 = [" * @todo #531:90min Check default values for annotation properties.\n",
41
- " * We still encounter some problems with annotation processing.\n", " * Especially with Autowired annotation from Spring Framework.\n", " * It's relatively simple annotation, but it's not processed correctly.\n", " */\n"].freeze
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
- def test_report
31
- expected = "From: User
32
- Subject: WEEK 11 Project
30
+ REPORT_EXAMPLE = <<~EXPECTED
31
+ From: User
32
+ Subject: WEEK 11 Project
33
+
34
+ Hi all,
33
35
 
34
- Hi all,
36
+ Last week achievements:
37
+ repository-a:
38
+ - Did a lot of for (a) repository
35
39
 
36
- Last week achievements:
37
- repository-a:
38
- - Did a lot of for (a) repository
40
+ Next week plans:
41
+ repository-b:
42
+ - I will do a lot for repository (b)
39
43
 
40
- Next week plans:
41
- repository-b:
42
- - I will do a lot for repository (b)
44
+ Risks:
45
+ - <todo>
43
46
 
44
- Risks:
45
- - <todo>
47
+ Best regards,
48
+ User
49
+ Developer
50
+ 2024-03-14
51
+ EXPECTED
46
52
 
47
- Best regards,
48
- User
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)", '- <todo>', Date.new(2024, 3, 14))
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 = "Closed Pull Requests:\n - title: title, repo: repo, url: http://some.url.com\n\nOpen Issues:\n - title: title, repo: repo, number: #123, url: http://google.com\n"
59
- issues = [ Issue::new('title', 'body', 'repo', '123', url: 'http://google.com')]
60
- prs = [ PullRequest::new('repo', 'title', 'body', url: 'http://some.url.com') ]
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
- puts actual
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
@@ -22,7 +22,7 @@
22
22
  # SOFTWARE.
23
23
 
24
24
  require 'minitest/autorun'
25
- require_relative '../lib/newsman'
25
+ require_relative '../lib/newsman/github'
26
26
 
27
27
  class TestDateOneWeekAgo < Minitest::Test
28
28
  def test_date_one_week_ago
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: newsman
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.13
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Volodya Lombrozo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-04-22 00:00:00.000000000 Z
11
+ date: 2024-06-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '3.2'
41
+ - !ruby/object:Gem::Dependency
42
+ name: json
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '2.6'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '2.6'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: dotenv
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -163,14 +177,19 @@ files:
163
177
  - README.md
164
178
  - bin/newsman
165
179
  - lib/newsman.rb
180
+ - lib/newsman/assistant.rb
181
+ - lib/newsman/github.rb
166
182
  - lib/newsman/html_output.rb
167
183
  - lib/newsman/issues.rb
168
184
  - lib/newsman/pull_request.rb
169
185
  - lib/newsman/report.rb
170
186
  - lib/newsman/stdout_output.rb
171
187
  - lib/newsman/txt_output.rb
188
+ - test/test_assistant.rb
172
189
  - test/test_htmlout.rb
190
+ - test/test_issue.rb
173
191
  - test/test_pdd_issue.rb
192
+ - test/test_pull_request.rb
174
193
  - test/test_report.rb
175
194
  - test/test_txtout.rb
176
195
  - test/test_week_before.rb
@@ -188,14 +207,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
188
207
  requirements:
189
208
  - - ">="
190
209
  - !ruby/object:Gem::Version
191
- version: '0'
210
+ version: '3.0'
192
211
  required_rubygems_version: !ruby/object:Gem::Requirement
193
212
  requirements:
194
213
  - - ">="
195
214
  - !ruby/object:Gem::Version
196
215
  version: '0'
197
216
  requirements: []
198
- rubygems_version: 3.5.7
217
+ rubygems_version: 3.5.9
199
218
  signing_key:
200
219
  specification_version: 4
201
220
  summary: GitHub user weekly news