forked from pockethost/pockethost
-
Notifications
You must be signed in to change notification settings - Fork 0
/
plopfile.mjs
186 lines (159 loc) · 6.76 KB
/
plopfile.mjs
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
import chalk from 'chalk'
import { execSync } from 'child_process'
import { readFileSync } from 'fs'
import inquirer from 'inquirer'
import yaml from 'js-yaml'
import ora from 'ora'
import { join } from 'path'
import { cwd } from 'process'
import factory from 'rizzdown'
/** @typedef {import('plop').NodePlopAPI} Plop */
const mkAIGenerator = (/** @type {string} */ subjectMatter) => {
const profilePath = join(cwd(), `.rizzdown/blog`)
const { generate } = factory({ profilePath, subjectMatter })
return async (/** @type {string} */ title, /** @type {string} */ prompt) => {
const spinner = ora().start(title)
const res = await generate(prompt, {})
spinner.stopAndPersist({ symbol: chalk.green(`✔︎`) })
return res
}
}
export default function (/** @type {Plop} */ plop) {
plop.setHelper('isoTimestamp', function () {
return new Date().toISOString()
})
plop.setHelper('yamlEncode', function (text) {
return yaml.dump(text).trim()
})
plop.setGenerator('blog-article', {
description: 'Generate a new blog article',
prompts: [
{
type: 'input',
name: 'synopsis',
message: '30-50 word synopsis of the news you wish to announce',
},
],
actions: [
async function (data) {
const profilePath = join(cwd(), `.rizzdown/blog`)
const subjectMatter = data.synopsis
const { factory } = await import('rizzdown')
const { generate } = factory({ profilePath, subjectMatter })
const spin = async (title, prompt) => {
const spinner = ora().start(title)
const res = await generate(prompt, {})
spinner.stopAndPersist({ symbol: chalk.green(`✔︎`) })
return res
}
data.title = await spin(
`Generating title...`,
`A title for this blog post, no more than 10 words. No exaggerations or puffery. Factual. ASCII characters only. Do not enclose in quotations.`,
)
data.description = await spin(
`Generating description...`,
`An OpenGraph summary/description for this blog post, no more than 50 words. A call to action. Factual. ASCII characters only.`,
)
data.summary = await spin(
`Generating summary...`,
`A one-paragraph introductory summary. ASCII characters only.`,
)
data.detail = await spin(
`Generating detail...`,
`A detailed analysis of the importance and use of this news. ASCII characters only.`,
)
console.log({ data })
},
{
type: 'add',
path: 'packages/lander/content/blog/{{dashCase title}}.md',
templateFile: 'plop-templates/blog.hbs',
},
],
})
plop.setGenerator('release', {
description: 'Generate a new release',
prompts: [],
actions: (data) => {
if (!data) throw new Error(`data expected`)
return [
async () => {
const commitsSinceLast = execSync(
`git log $(git describe --tags --abbrev=0)..HEAD --oneline | grep -E "fix:|enh:|feat:|docs:|chore:" | sed 's/^[^ ]*/\*/' | sort`,
)
.toString()
.replace(/^\S+?\s/gm, '')
.split(/\n/)
.filter((v) => !!v)
console.log(`Commits since last release:`)
commitsSinceLast.forEach((line) => console.log(` * ${line}`))
const { releaseType } = await inquirer.prompt({
type: 'list',
name: 'releaseType',
choices: ['major', 'minor', 'patch'],
message: `What type of release is this?`,
default: 2,
})
execSync(`npm version --no-git-tag-version ${releaseType}`)
const { version } = JSON.parse(
readFileSync(join(cwd(), './package.json')).toString(),
)
console.log(
`Great, a ${releaseType} release. The new version will be ${version}.`,
)
const summaries = commitsSinceLast
.map((commit) => `* ${commit}`)
.join(`\n`)
// const summaries = []
// // for (let i = 0; i < commitsSinceLast.length; i++) {
// // const commit = commitsSinceLast[i]
// // const { summary } = await inquirer.prompt({
// // type: 'input',
// // name: 'summary',
// // message: `Please summarize this commit log (enter to leave as is):`,
// // default: commit,
// // })
// // summaries.push(summary)
// // }
// summaries.push(...commitsSinceLast)
// const summary = await (async () => {
// const _summary = await mkAIGenerator(summaries)(
// `Generating commit summary...`,
// `Using semver parlance, this is a ${releaseType} release of PocketHost. What follows are the git commit messages for this ${releaseType} release. Please provide a one-paragraph summary under 50 words based on git commit messages. Factual. ASCII characters only. Use reflective and dry technical language, no calls to action or 'consumer' sounding language.`,
// )
// const { summary } = await inquirer.prompt({
// type: 'input',
// name: 'summary',
// message: `What is this release about, generally?`,
// default: _summary,
// })
// return summary
// })()
const generate = mkAIGenerator(
`# PocketHost v${version} release\n\n###Detailed updates\n\n${summaries}`,
)
data.version = version
data.title = `PocketHost v${version}`
data.opengraph = await generate(
`Generating OpenGraph description...`,
`An OpenGraph summary for this release, no more than 50 words. Factual. ASCII characters only. Use reflective and dry technical language, no calls to action or 'consumer' sounding language.`,
)
data.summary = await generate(
`Generating key updates summary...`,
`A bullet point summary of items tagged as 'feat' or 'fix'. Features come first. No more than 50 words TOTAL for the whole list. Factual. ASCII characters only. Use reflective and dry technical language, no calls to action or 'consumer' sounding language.`,
)
data.overview = await generate(
`Generating overview...`,
`1-3 short paragraphs organizing the major changes and discussing their importance. ASCII characters only. Use reflective and dry technical language, no calls to action or 'consumer' sounding language`,
)
data.change_log = summaries
},
{
type: 'add',
path: 'packages/lander/content/blog/{{dashCase title}}.md',
templateFile: 'plop-templates/blog.hbs',
},
]
},
})
}