newsman 0.1.13 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +7 -1
- data/lib/newsman/assistant.rb +136 -0
- data/lib/newsman/github.rb +80 -0
- data/lib/newsman/html_output.rb +42 -17
- data/lib/newsman/issues.rb +94 -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 +67 -127
- data/test/test_assistant.rb +38 -0
- 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 +23 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c0ec4c08d224982a75fc3ae533368cdeff2c4d7cab0072441fcfbd604f194b42
|
4
|
+
data.tar.gz: 8633c4f4dc84b0f6a285e06b67b0cb9dd3f9e7a18d6dc032589237652181d36f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
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
|
@@ -0,0 +1,136 @@
|
|
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
|
+
|
23
|
+
require 'openai'
|
24
|
+
|
25
|
+
# This class mimics a robot that can analyse a developer activity.
|
26
|
+
# The assistant uses OpenAI API to analyze.
|
27
|
+
class Assistant
|
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.'
|
32
|
+
|
33
|
+
def initialize(token, model: 'gpt-3.5-turbo', temperature: 0.3)
|
34
|
+
@token = token
|
35
|
+
@model = model
|
36
|
+
@temperature = temperature
|
37
|
+
@client = OpenAI::Client.new(access_token: token)
|
38
|
+
end
|
39
|
+
|
40
|
+
def say_hello
|
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
|
46
|
+
end
|
47
|
+
|
48
|
+
# rubocop:disable Metrics/MethodLength
|
49
|
+
def next_plans(issues)
|
50
|
+
example = "repository-name:\n
|
51
|
+
- To publish ABC package draft [#27]\n
|
52
|
+
- To review first draft of the report [#56]\n
|
53
|
+
- To implement optimization for the class X [#125]"
|
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)
|
65
|
+
end
|
66
|
+
# rubocop:enable Metrics/MethodLength
|
67
|
+
|
68
|
+
# rubocop:disable Metrics/MethodLength
|
69
|
+
def prev_results(prs)
|
70
|
+
example = "repository-name:\n
|
71
|
+
- Added 100 new files to the Dataset [#168]\n
|
72
|
+
- Fixed the deployment of XYZ [#169]\n
|
73
|
+
- Refined the requirements [#177]\n"
|
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)
|
85
|
+
end
|
86
|
+
# rubocop:enable Metrics/MethodLength
|
87
|
+
|
88
|
+
# rubocop:disable Metrics/MethodLength
|
89
|
+
def risks(all)
|
90
|
+
example = "repository-name:\n
|
91
|
+
- The server is weak, we may fail the delivery\n
|
92
|
+
of the dataset, report milestone will be missed [#487].\n
|
93
|
+
- The code in repository is suboptimal, we might have some problems for the future maintainability [#44].\n"
|
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)
|
104
|
+
end
|
105
|
+
# rubocop:enable Metrics/MethodLength
|
106
|
+
|
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.
|
112
|
+
|
113
|
+
Here is the report:
|
114
|
+
|
115
|
+
#{report}
|
116
|
+
PROMPT
|
117
|
+
send(prompt)
|
118
|
+
end
|
119
|
+
|
120
|
+
def send(request)
|
121
|
+
@client.chat(
|
122
|
+
parameters: {
|
123
|
+
model: @model,
|
124
|
+
messages: [
|
125
|
+
{ role: 'system', content: CONTEXT },
|
126
|
+
{ role: 'user', content: request.to_s }
|
127
|
+
],
|
128
|
+
temperature: @temperature
|
129
|
+
}
|
130
|
+
).dig('choices', 0, 'message', 'content')
|
131
|
+
end
|
132
|
+
|
133
|
+
def deprecated(method)
|
134
|
+
warn "Warning! '#{method}' is deprecated and will be removed in future versions."
|
135
|
+
end
|
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
|
data/lib/newsman/html_output.rb
CHANGED
@@ -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
|
-
|
12
|
-
</head>
|
13
|
-
<body>
|
14
|
-
|
15
|
-
|
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
|
-
|
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
|
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
|
data/lib/newsman/issues.rb
CHANGED
@@ -1,37 +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
|
-
|
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,
|
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
|
-
@
|
36
|
+
@additional = defaults.merge(additional)
|
16
37
|
end
|
17
38
|
|
18
39
|
def to_s
|
19
|
-
|
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}"
|
20
51
|
end
|
21
52
|
|
22
|
-
def
|
23
|
-
|
53
|
+
def url
|
54
|
+
@additional[:url]
|
55
|
+
end
|
56
|
+
|
57
|
+
def labels
|
58
|
+
@additional[:labels]
|
59
|
+
end
|
60
|
+
|
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
|
79
|
+
|
80
|
+
def initialize(title, body, repo, number, **additional)
|
81
|
+
defaults = { url: 'undefined', labels: [] }
|
30
82
|
@title = title
|
31
83
|
@body = body
|
32
84
|
@repo = repo
|
33
85
|
@number = number
|
34
|
-
@
|
86
|
+
@additional = defaults.merge(additional)
|
35
87
|
end
|
36
88
|
|
37
89
|
def extract_real_body
|
@@ -42,17 +94,44 @@ class PddIssue
|
|
42
94
|
end
|
43
95
|
|
44
96
|
def issue_link
|
45
|
-
@body[%r{https://github\.com/[\w\-/]+/blob/[\w\d]+/[\w/.-]+#\w+-\w+}, 0]
|
46
|
-
'
|
47
|
-
|
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/', '')
|
48
100
|
end
|
49
101
|
|
50
102
|
def to_s
|
51
|
-
|
103
|
+
<<~MARKDOWN
|
104
|
+
title: ```#{@title}```,
|
105
|
+
description: ```#{extract_real_body}```,
|
106
|
+
repo: ```#{@repo}```,
|
107
|
+
issue number: \##{@number},
|
108
|
+
additional: #{@additional}
|
109
|
+
MARKDOWN
|
52
110
|
end
|
53
111
|
|
54
112
|
def detailed_title
|
55
|
-
"title: #{@title}, repo: #{@repo}, issue number: \##{@number}, url: #{
|
113
|
+
"title: #{@title}, repo: #{@repo}, issue number: \##{@number}, url: #{url}, labels: #{labels}"
|
56
114
|
end
|
57
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
|
58
137
|
end
|
data/lib/newsman/pull_request.rb
CHANGED
@@ -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
|
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
|