newsman 0.1.9 → 0.1.11

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: 2394e606a441d219f1b63d81957596975476de4da4a8cf2a8565638d9e5fd31e
4
- data.tar.gz: 10c89c9e91a89fde8c67822d72ada6de3cf731b1c3a7fc9aa9d0e7ad90c1f43a
3
+ metadata.gz: 47097e4e1db8dbfaa84c2aa58d8d9a13294cab2ab471a5927f1d083327a713db
4
+ data.tar.gz: 48ea4b8237d6daff81c15bbfc7786850c820a2a3bcceb931332594c5f5e2a02e
5
5
  SHA512:
6
- metadata.gz: d649675bf107b488ce5c8644414589419518e9f8f8ea497d80da5a3810de6fecc1a1f346fbd4c06a84f41e979df890af50ec89bbc89ed34056af5b7467f40dce
7
- data.tar.gz: 7de3191d99baee21f3346434d6aeb6550e9bb07e8f9a944215958206cd94a1176f367f699b84778a063227a165bf4e065bccbe48def5e8d9b1ae33eb6a59d2fc
6
+ metadata.gz: 662c512d37c279e44957de12a6d2825a266f048edf350ea5e272d23b88f7b35df0461c9eef3478e8e75e1623d6a8f5240d9000bd865d99498285dfec69ffd5bd
7
+ data.tar.gz: 764561fef8f5de1aea6cfa05983b767bc6d40707d82c9e8b5aaa96faffac4815bc934078852d03ec89be6b8f5445e45c9611666fef5b2a3bff26cb3b8bcd19d3
@@ -1,34 +1,37 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'erb'
4
+ require 'redcarpet'
5
+ require 'nokogiri'
2
6
  # frozen_string_literal: true
3
7
 
4
8
  class Htmlout
5
-
6
- TEMPLATE = "<!DOCTYPE html>
7
- <html lang=\"en\">
9
+ TEMPLATE = "
8
10
  <head>
9
- <meta charset=\"UTF-8\">
10
11
  <title><%= title %></title>
11
12
  </head>
12
13
  <body>
13
14
  <h1><%= title %></h1>
14
- <p><%= body %></p>
15
+ <%= body %>
15
16
  </body>
16
- </html>
17
17
  "
18
18
 
19
19
  def initialize(root = '.')
20
20
  @root = root
21
21
  end
22
-
22
+
23
23
  def print(report, reporter)
24
- title = title(reporter)
25
- body = report
24
+ 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)
26
28
  renderer = ERB.new(TEMPLATE)
27
29
  html_content = renderer.result(binding)
30
+ html_content = Nokogiri::HTML(html_content, &:noblanks).to_xhtml(indent: 2)
28
31
  puts "Create a html file in a directory #{@root}"
29
32
  file = File.new(File.join(@root, filename(reporter)), 'w')
30
33
  puts "File #{file.path} was successfully created"
31
- file.puts html_content
34
+ file.puts html_content
32
35
  puts "Report was successfully printed to a #{file.path}"
33
36
  file.close
34
37
  end
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'net/http'
2
4
  # frozen_string_literal: true
3
5
 
4
- class Issue
6
+ class Issue
5
7
  attr_accessor :title, :body, :repo, :number
6
8
 
7
9
  def initialize(title, body, repo, number)
@@ -17,7 +19,6 @@ class Issue
17
19
  end
18
20
 
19
21
  class PddIssue
20
-
21
22
  def initialize(title, body, repo, number)
22
23
  @title = title
23
24
  @body = body
@@ -26,18 +27,19 @@ class PddIssue
26
27
  end
27
28
 
28
29
  def extract_real_body
29
- address = issue_link()
30
+ address = issue_link
30
31
  line_numbers = address.scan(/#L(\d+)-L(\d+)/).flatten.map(&:to_i)
31
32
  uri = URI(address)
32
- return Net::HTTP.get(uri).lines[line_numbers[0]-1..line_numbers[1]]
33
+ Net::HTTP.get(uri).lines[line_numbers[0] - 1..line_numbers[1]]
33
34
  end
34
35
 
35
- def issue_link
36
- return @body[/https:\/\/github\.com\/[\w\-\/]+\/blob\/[\w\d]+\/[\w\/\.\-]+#\w+-\w+/, 0].gsub('https://github.com','https://raw.githubusercontent.com').gsub('blob/', '')
36
+ def issue_link
37
+ @body[%r{https://github\.com/[\w\-/]+/blob/[\w\d]+/[\w/.-]+#\w+-\w+}, 0].gsub('https://github.com', 'https://raw.githubusercontent.com').gsub(
38
+ 'blob/', ''
39
+ )
37
40
  end
38
41
 
39
42
  def to_s
40
43
  "title: ```#{@title}```,\ndescription: ```#{extract_real_body}```,\nrepo: ```#{@repo}```,\nissue number: \##{@number}\n"
41
44
  end
42
45
  end
43
-
@@ -13,4 +13,3 @@ class PullRequest
13
13
  "title: ```#{@title}```,\ndescription: ```#{@description}```,\nrepo: ```#{@repository}```\n"
14
14
  end
15
15
  end
16
-
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  class Report
4
5
  def initialize(user, position, title)
@@ -6,8 +7,10 @@ class Report
6
7
  @position = position
7
8
  @title = title
8
9
  end
9
- def build(achievements, plans, date)
10
- return "From: #{@user}\nSubject: #{week_of_a_year(@title, date)}\n\nHi all,\n\nLast week achievements:\n#{achievements}\n\nNext week plans:\n#{plans}\n\nRisks:\n- <todo>\n\nBest regards,\n#{@user}\n#{@position}\n#{date}"
10
+
11
+ def build(achievements, plans, risks, date)
12
+ "From: #{@user}\nSubject: #{week_of_a_year(@title,
13
+ date)}\n\nHi all,\n\nLast week achievements:\n#{achievements}\n\nNext week plans:\n#{plans}\n\nRisks:\n#{risks}\n\nBest regards,\n#{@user}\n#{@position}\n#{date}"
11
14
  end
12
15
  end
13
16
 
@@ -15,4 +18,3 @@ def week_of_a_year(project, today)
15
18
  number = today.strftime('%U').to_i + 1
16
19
  "WEEK #{number} #{project}"
17
20
  end
18
-
data/lib/newsman.rb CHANGED
@@ -76,7 +76,6 @@ def generate
76
76
  # Create a GitHub client instance with your access token
77
77
  client = Octokit::Client.new(github_token: github_token)
78
78
  # Calculate the date one week ago
79
- report_date = Date.today
80
79
  one_week_ago = date_one_week_ago(Date.today)
81
80
  one_month_ago = Date.today.prev_month.strftime('%Y-%m-%d')
82
81
  # Display pull request
@@ -96,7 +95,7 @@ def generate
96
95
  prs << pr
97
96
  end
98
97
  prs = prs.map(&:to_s).join("\n\n\n")
99
-
98
+
100
99
  puts "Searching issues using the following query: '#{issues_query}'"
101
100
  issues = []
102
101
  client.search_issues(issues_query).items.each do |issue|
@@ -105,32 +104,39 @@ def generate
105
104
  repository = issue.repository_url.split('/').last
106
105
  number = issue.number.to_s
107
106
  puts "Found issue in #{repository}:[##{number}] #{title}"
108
- if issue.user.login == "0pdd"
109
- issues << PddIssue.new(title, body, repository, number)
110
- else
111
- issues << Issue.new(title, body, repository, number)
112
- end
107
+ issues << if issue.user.login == '0pdd'
108
+ PddIssue.new(title, body, repository, number)
109
+ else
110
+ Issue.new(title, body, repository, number)
111
+ end
113
112
  end
114
113
  issues = issues.map(&:to_s).join("\n\n\n")
115
- #puts "Found issues:\n #{issues}"
116
-
114
+ # puts "Found issues:\n #{issues}"
115
+
117
116
  puts "\nNow lets test some aggregation using OpenAI\n\n"
118
117
  openai_client = OpenAI::Client.new(access_token: openai_token)
119
118
 
120
- example = "jeo-meven-plugin:
119
+ example = "some-repository-name-x:
121
120
  - Added 100 new files to the Dataset [#168]
122
121
  - Fixed the deployment of XYZ [#169]
123
122
  - Refined the requirements [#177]
124
- opeo-maven-plugin:
123
+ some-repository-name-y:
125
124
  - Removed XYZ class [#57]
126
125
  - Refactored http module [#69]"
127
126
 
128
- example_plans = "jeo-maven-plugin:
127
+ example_plans = "some-repository-name-x:
129
128
  - To publish ABC package draft [#27]
130
129
  - To review first draft of the report [#56]
131
- opeo-maven-plugin:
130
+ some-repository-name-y:
132
131
  - To implement optimization for the class X [#125]"
133
132
 
133
+ example_risks = "some-repository-name-x:
134
+ - The server is weak, we may fail the delivery
135
+ of the dataset, report milestone will be missed [#487].
136
+ some-repository-name-y:
137
+ - The code in repository is suboptimal, we might have some problems for the future maintainability [#44].
138
+ "
139
+
134
140
  response = openai_client.chat(
135
141
  parameters: {
136
142
  model: 'gpt-3.5-turbo',
@@ -138,7 +144,7 @@ def generate
138
144
  { role: 'system',
139
145
  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.' },
140
146
  { role: 'user',
141
- 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. 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}]" }
147
+ 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}]" }
142
148
  ],
143
149
  temperature: 0.3
144
150
  }
@@ -151,25 +157,40 @@ def generate
151
157
  { role: 'system',
152
158
  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.' },
153
159
  { role: 'user',
154
- 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. 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" }
160
+ 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" }
155
161
  ],
156
162
  temperature: 0.3
157
163
  }
158
- )
164
+ )
159
165
  issues_full_answer = issues_response.dig('choices', 0, 'message', 'content')
166
+
167
+ risks_full_answer = openai_client.chat(
168
+ parameters: {
169
+ model: 'gpt-3.5-turbo',
170
+ messages: [
171
+ { role: 'system',
172
+ 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.' },
173
+ { role: 'user',
174
+ 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}```.]" }
175
+ ],
176
+ temperature: 0.3
177
+ }
178
+ ).dig('choices', 0, 'message', 'content')
179
+
160
180
  output_mode = options[:output]
161
181
  puts "Output mode is '#{output_mode}'"
162
- full_answer = Report.new(reporter, reporter_position, options[:title]).build(answer, issues_full_answer, Date.today)
182
+ full_answer = Report.new(reporter, reporter_position, options[:title]).build(answer, issues_full_answer,
183
+ risks_full_answer, Date.today)
163
184
  if output_mode.eql? 'txt'
164
- puts "Print result to txy file"
185
+ puts 'Print result to txy file'
165
186
  output = Txtout.new('.')
166
187
  output.print(full_answer, github_username)
167
188
  elsif output_mode.eql? 'html'
168
- puts "Print result to html file"
189
+ puts 'Print result to html file'
169
190
  output = Htmlout.new('.')
170
191
  output.print(full_answer, github_username)
171
192
  else
172
- puts "Print result to stdout"
193
+ puts 'Print result to stdout'
173
194
  output = Stdout.new
174
195
  output.print(full_answer)
175
196
  end
data/test/test_htmlout.rb CHANGED
@@ -25,16 +25,21 @@ require 'minitest/autorun'
25
25
  require_relative '../lib/newsman/html_output'
26
26
 
27
27
  class TestHtmlout < Minitest::Test
28
-
29
- EXPECTED = "<!DOCTYPE html>
30
- <html lang=\"en\">
31
- <head>
32
- <meta charset=\"UTF-8\">
33
- <title>volodya-lombrozo #{Time.new.strftime('%d.%m.%Y')}</title>
34
- </head>
35
- <body>
28
+ EXPECTED = "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/REC-html40/loose.dtd\">
29
+ <html>
30
+ <head>
31
+ <title>volodya-lombrozo #{Time.new.strftime('%d.%m.%Y')}</title>
32
+ </head>
33
+ <body>
36
34
  <h1>volodya-lombrozo #{Time.new.strftime('%d.%m.%Y')}</h1>
37
35
  <p>Issue description</p>
36
+
37
+ <p>Here is a new paragraph<br/>
38
+ List is here:<br/>
39
+ - one<br/>
40
+ - two<br/>
41
+ - three</p>
42
+
38
43
  </body>
39
44
  </html>
40
45
  "
@@ -44,7 +49,8 @@ class TestHtmlout < Minitest::Test
44
49
  output = Htmlout.new(temp_dir)
45
50
  today = Date.today.strftime('%d.%m.%Y')
46
51
  expected = "#{today}.volodya-lombrozo.html"
47
- output.print("Issue description", 'volodya-lombrozo')
52
+ output.print("Issue description\n\nHere is a new paragraph\nList is here:\n - one\n - two\n - three",
53
+ 'volodya-lombrozo')
48
54
  assert(File.exist?(File.join(temp_dir, expected)))
49
55
  assert_equal(EXPECTED, File.read(File.join(temp_dir, expected)))
50
56
  end
@@ -26,22 +26,23 @@ require_relative '../lib/newsman/issues'
26
26
 
27
27
  class TestPddIssue < Minitest::Test
28
28
  TEST_BODY = "
29
- The puzzle `531-462261de` from #531 has to be resolved:
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
32
32
 
33
- The puzzle was created by @volodya-lombrozo on 29-Mar-24.
33
+ The puzzle was created by @volodya-lombrozo on 29-Mar-24.
34
34
 
35
- Estimate: 90 minutes, role: DEV.
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).
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
38
  "
39
39
 
40
- EXPECTED_DESCRIPTION = " * @todo #531:90min Check default values for annotation properties.\n", " * 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"
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
41
42
 
42
43
  def test_parses_pdd_issue
43
44
  issue = PddIssue.new('AnnotationsApplication.java:32-35: Check default values...',
44
- TEST_BODY,
45
+ TEST_BODY,
45
46
  'jeo-maven-plugin', 531)
46
47
  assert_equal(EXPECTED_DESCRIPTION, issue.extract_real_body)
47
48
  end
data/test/test_report.rb CHANGED
@@ -22,7 +22,7 @@
22
22
  # SOFTWARE.
23
23
 
24
24
  require 'minitest/autorun'
25
- require_relative '../lib/newsman/report.rb'
25
+ require_relative '../lib/newsman/report'
26
26
 
27
27
  class TestReport < Minitest::Test
28
28
  def test_report
@@ -47,8 +47,8 @@ User
47
47
  Developer
48
48
  2024-03-14"
49
49
  report = Report.new('User', 'Developer', 'Project')
50
- out = report.build("repository-a:\n - Did a lot of for (a) repository", "repository-b:\n - I will do a lot for repository (b)", Date.new(2024, 3, 14))
50
+ out = report.build("repository-a:\n - Did a lot of for (a) repository",
51
+ "repository-b:\n - I will do a lot for repository (b)", '- <todo>', Date.new(2024, 3, 14))
51
52
  assert_equal expected, out
52
53
  end
53
54
  end
54
-
@@ -30,4 +30,3 @@ class TestWeekOfYear < Minitest::Test
30
30
  assert_equal 'WEEK 9 OPEO', week_of_a_year('OPEO', Date.new(2024, 2, 29))
31
31
  end
32
32
  end
33
-
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.9
4
+ version: 0.1.11
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-04 00:00:00.000000000 Z
11
+ date: 2024-04-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest
@@ -66,6 +66,34 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '2.2'
69
+ - !ruby/object:Gem::Dependency
70
+ name: net-http
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '0.4'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '0.4'
83
+ - !ruby/object:Gem::Dependency
84
+ name: nokogiri
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '1.16'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '1.16'
69
97
  - !ruby/object:Gem::Dependency
70
98
  name: octokit
71
99
  requirement: !ruby/object:Gem::Requirement
@@ -95,33 +123,33 @@ dependencies:
95
123
  - !ruby/object:Gem::Version
96
124
  version: 0.4.0
97
125
  - !ruby/object:Gem::Dependency
98
- name: ruby-openai
126
+ name: redcarpet
99
127
  requirement: !ruby/object:Gem::Requirement
100
128
  requirements:
101
129
  - - "~>"
102
130
  - !ruby/object:Gem::Version
103
- version: '6.3'
131
+ version: '3.6'
104
132
  type: :runtime
105
133
  prerelease: false
106
134
  version_requirements: !ruby/object:Gem::Requirement
107
135
  requirements:
108
136
  - - "~>"
109
137
  - !ruby/object:Gem::Version
110
- version: '6.3'
138
+ version: '3.6'
111
139
  - !ruby/object:Gem::Dependency
112
- name: net-http
140
+ name: ruby-openai
113
141
  requirement: !ruby/object:Gem::Requirement
114
142
  requirements:
115
143
  - - "~>"
116
144
  - !ruby/object:Gem::Version
117
- version: '0.4'
145
+ version: '6.3'
118
146
  type: :runtime
119
147
  prerelease: false
120
148
  version_requirements: !ruby/object:Gem::Requirement
121
149
  requirements:
122
150
  - - "~>"
123
151
  - !ruby/object:Gem::Version
124
- version: '0.4'
152
+ version: '6.3'
125
153
  description: A simple gem that gathers GitHub statistics and creates human-readable
126
154
  report
127
155
  email: