forked from nushell/nu_scripts
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtools.nu
More file actions
201 lines (174 loc) · 6.19 KB
/
tools.nu
File metadata and controls
201 lines (174 loc) · 6.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
# Tools for creating the release notes.
use std/assert
use std-rfc/iter only
use util.nu *
use completions.nu *
use notice.nu *
use generate.nu *
# List all merged PRs since the last release
@example $"List all merged for ($example_version)" $"list-prs --milestone ($example_version)"
export def list-prs [
repo: string = 'nushell/nushell' # the name of the repo, e.g. 'nushell/nushell'
--since: datetime@"nu-complete date current" # list PRs on or after this date (defaults to 4 weeks ago if `--milestone` is not provided)
--milestone: string@"nu-complete version" # only list PRs in a certain milestone
--label: string # the PR label to filter by, e.g. 'good-first-issue'
]: nothing -> table {
query-prs $repo --since=$since --milestone=$milestone --label=$label
| select author title number mergedAt url
| sort-by mergedAt --reverse
| update author { get login }
}
# Construct a GitHub query for merged PRs on a repo.
def query-prs [
repo: string = 'nushell/nushell' # the name of the repo, e.g. 'nushell/nushell'
--since: datetime@"nu-complete date current" # list PRs on or after this date (defaults to 4 weeks ago if `--milestone` is not provided)
--milestone: string@"nu-complete version" # only list PRs in a certain milestone
--label: string # the PR label to filter by, e.g. 'good-first-issue'
]: nothing -> table {
mut query_parts = []
if $since != null or $milestone == null {
let date = $since | default ((date now) - 4wk) | format date '%Y-%m-%d'
$query_parts ++= [ $'merged:>($date)' ]
}
if $milestone != null {
$query_parts ++= [ $'milestone:"($milestone)"' ]
}
if $label != null {
$query_parts ++= [ $'label:($label)' ]
}
let query = $query_parts | str join ' '
let results = (
gh --repo $repo pr list --state merged
--limit (inf | into int)
--json author,title,number,mergedAt,url,body,labels
--search $query
| from json
)
assert ($results | is-not-empty) "Query returned no results"
$results
}
# Generate the release notes for the specified version.
export def release-notes [
version: string@"nu-complete version" # the version to generate release notes for
]: nothing -> string {
query-prs --milestone=$version
| where not author.is_bot
| sort-by mergedAt
| each { get-release-notes }
| tee { display-notices }
| where {|pr| "error" not-in ($pr.notices?.type? | default []) }
| generate-notes $version
}
# Check the release note summaries for the specified version.
export def check-prs [
version: string@"nu-complete version" # the version to generate release notes for
--as-table (-t) # output PR checks as a table
]: [
nothing -> nothing,
nothing -> table
] {
query-prs --milestone=$version
| where not author.is_bot
| sort-by mergedAt
| each { get-release-notes }
| if $as_table { group-notices } else { display-notices }
}
# Format the output of `list-prs` as a markdown table
export def pr-table [] {
sort-by author number
| update author { md-link $'@($in)' $'https://github.com/($in)' }
| insert link { pr-link }
| select author title link
| to md
| escape-tag
}
const toc = '[[toc](#table-of-contents)]'
# Generate and write the table of contents to a release notes file
export def write-toc [file: path] {
let known_h1s = [
"# Highlights and themes of this release",
"# Changes",
"# Notes for plugin developers",
"# Hall of fame",
"# Full changelog",
]
let lines = open $file | lines | each { str trim -r }
let content_start = 2 + (
$lines
| enumerate
| where item == '# Table of contents'
| first
| get index
)
let data = (
$lines
| slice $content_start..
| wrap line
| insert level {
get line | split chars | take while { $in == '#' } | length
}
| insert nocomment {
# We assume that comments only have one `#`
if ($in.level != 1) {
return true
}
let line = $in.line
# Try to use the whitelist first
if ($known_h1s | any {|| $line =~ $in}) {
return true
}
# We don't know so let's ask
let user = ([Ignore Accept] |
input list $"Is this a code comment or a markdown h1 heading:(char nl)(ansi blue)($line)(ansi reset)(char nl)Choose if we include it in the TOC!")
match $user {
"Accept" => {true}
"Ignore" => {false}
}
}
)
let table_of_contents = (
$data
| where level in 1..=3 and nocomment == true
| each {|header|
let indent = '- ' | fill -w ($header.level * 2) -a right
mut text = $header.line | str trim -l -c '#' | str trim -l
if $text ends-with $toc {
$text = $text | str substring ..<(-1 * ($toc | str length)) | str trim -r
}
let link = (
$text
| str downcase
| str kebab-case
)
# remove PR link from header, if applicable
let regex = r#'(?x) # verbose mode
(?<text>.+?) # the actual header text
\s+
\( # start PR link
\[\#\d+\] # PR number component
(?: # optional non-capturing group
\(.+?\) # link to PR
)? # end group
\)
'#
let prlink = $text | parse -r $regex
if ($prlink | is-not-empty) {
$text = $prlink.0.text
}
$"($indent)[_($text)_]\(#($link)-toc\)"
}
)
let content = $data | each {
if $in.level in 1..=3 and not ($in.line ends-with $toc) and $in.nocomment {
$'($in.line) ($toc)'
} else {
$in.line
}
}
[
...($lines | slice ..<$content_start)
...$table_of_contents
...$content
]
| save -r -f $file
}