changelog-tool 0.7.1 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -18,7 +18,7 @@ jobs:
18
18
 
19
19
  strategy:
20
20
  matrix:
21
- node-version: [16.x, 18.x]
21
+ node-version: [16.x, 18.x, 20.x]
22
22
  # See supported Node.js release schedule at https://nodejs.org/en/about/releases/
23
23
 
24
24
  steps:
package/changelog.md CHANGED
@@ -1,6 +1,32 @@
1
1
  Changelog
2
2
  =========
3
3
 
4
+ 1.0.0 (2023-06-20)
5
+ ------------------
6
+
7
+ First stable release! Just kidding, it was already stable.
8
+
9
+ * Add support for [Markdown reference links][1]. References are a Markdown
10
+ feature that lets you write links in paragraphs, but put the actual target
11
+ near the end of the document similar to references in technical documents.
12
+ This can declutter the reading experience for those reading the Markdown
13
+ sources. The tool doesn't let you quickly add links via the CLI yet, but it
14
+ will no longer mangle them when they appear.
15
+ * Testing Node 20
16
+ * Bugfix: Always insert an empty line between the 'preface' and bulletpoints
17
+ sections of a version block.
18
+
19
+
20
+ 0.7.2 (2023-02-17)
21
+ ------------------
22
+
23
+ * Added a `--nowrap` option to `show`, which doesn't wrap long lines. This is
24
+ useful for copy-pasting changelog into places where linebreaks are
25
+ significant, such as the Github releases section.
26
+ * Support multiple digits for the alpha/beta release string.
27
+ * Also allows setting the changelog message as positional arguments.
28
+
29
+
4
30
  0.7.1 (2023-02-14)
5
31
  ------------------
6
32
 
@@ -60,4 +86,7 @@ Changelog
60
86
  0.1.0 (2023-02-08)
61
87
  ------------------
62
88
 
63
- * Implemented the 'help' and 'init' commands.
89
+ * Implemented the 'help' and 'init' commands
90
+
91
+ [1]: https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet#link "Markdown cheatsheet: Links"
92
+
package/changelog.mjs CHANGED
@@ -10,13 +10,21 @@ export class Changelog {
10
10
  */
11
11
  versions = [];
12
12
 
13
+ /**
14
+ * @type {Link[]}
15
+ */
16
+ links = [];
17
+
13
18
  toString() {
14
19
 
15
20
  return (
16
21
  this.title + '\n' +
17
22
  ('='.repeat(this.title.length)) + '\n' +
18
23
  '\n' +
19
- this.versions.map(version => version.toString()).join('\n\n')
24
+ this.versions.map(version => version.toString()).join('\n\n') +
25
+
26
+ // Sorry about this line future me (or someone else)
27
+ (this.links.length > 0 ? ('\n' + this.links.map( link => wrap(`[${link.name}]: ${link.href}${link.title?` "${link.title}"`:''}`, link.name.length+4)).join('\n') + '\n') : '')
20
28
  );
21
29
 
22
30
  }
@@ -116,15 +124,28 @@ export class VersionLog {
116
124
 
117
125
  toString() {
118
126
 
127
+ return this.output();
128
+
129
+ }
130
+
131
+ /**
132
+ * Renders the changelog as a string.
133
+ *
134
+ * @param {boolean} lineWrap
135
+ * @returns {string}
136
+ */
137
+ output(lineWrap = true) {
138
+
139
+ const lineLength = lineWrap ? 79 : Infinity;
119
140
  const title = this.version + ' (' + (this.date ?? '????-??-??') + ')';
120
141
  return (
121
142
  title + '\n' +
122
143
  ('-'.repeat(title.length)) + '\n' +
123
- (this.preface ? '\n' + wrap(this.preface) : '') +
144
+ (this.preface ? '\n' + wrap(this.preface, 0, lineLength) + '\n' : '') +
124
145
  '\n' +
125
- this.items.map(version => version.toString()).join('\n') +
146
+ this.items.map(version => version.output(lineWrap)).join('\n') +
126
147
  '\n' +
127
- (this.postface ? '\n' + wrap(this.postface) + '\n' : '')
148
+ (this.postface ? '\n' + wrap(this.postface, 0, lineLength) + '\n' : '')
128
149
  );
129
150
 
130
151
  }
@@ -134,7 +155,7 @@ export class VersionLog {
134
155
  export class LogItem {
135
156
 
136
157
  /**
137
- * @type string
158
+ * @type {string}
138
159
  */
139
160
  message;
140
161
 
@@ -145,6 +166,17 @@ export class LogItem {
145
166
  this.message = message;
146
167
  }
147
168
 
169
+ /**
170
+ * Renders the changelog as a string.
171
+ *
172
+ * @param {boolean} lineWrap
173
+ * @returns {string}
174
+ */
175
+ output(lineWrap = true) {
176
+ const lineLength = lineWrap ? 79 : Infinity;
177
+ return wrap('* ' + this.message, 2, lineLength);
178
+ }
179
+
148
180
  toString() {
149
181
 
150
182
  return wrap('* ' + this.message, 2);
@@ -153,4 +185,9 @@ export class LogItem {
153
185
 
154
186
  }
155
187
 
156
-
188
+ /**
189
+ * @typedef Link {Object}
190
+ * @property Link.href {string}
191
+ * @property Link.name {string}
192
+ * @property Link.title {string|null}
193
+ */
package/cli.mjs CHANGED
@@ -49,6 +49,10 @@ async function main() {
49
49
  type: 'boolean',
50
50
  description: 'Indicates that the current change is a major change.',
51
51
  },
52
+ nowrap: {
53
+ type: 'boolean',
54
+ description: 'Don\'t wrap "show" output'
55
+ }
52
56
  },
53
57
  allowPositionals: true,
54
58
  });
@@ -79,7 +83,12 @@ async function main() {
79
83
  changeType = 'major';
80
84
  }
81
85
  if (!values.message) {
82
- throw new Error('The "-m" or "--message" argument is required');
86
+ if (positionals.length>1) {
87
+ // We also support setting a message after the command instead of -m
88
+ values.message = positionals.slice(1).join(' ');
89
+ } else {
90
+ throw new Error('The "-m" or "--message" argument is required');
91
+ }
83
92
  }
84
93
  await add({
85
94
  message: values.message,
@@ -93,7 +102,11 @@ async function main() {
93
102
  await format();
94
103
  break;
95
104
  case 'show' :
96
- await show({ all: !!values.all, version: positionals[1]});
105
+ await show({
106
+ all: !!values.all,
107
+ version: positionals[1],
108
+ noWrap: !!values.nowrap
109
+ });
97
110
  break;
98
111
  case 'list' :
99
112
  await list();
@@ -170,8 +183,9 @@ async function list() {
170
183
  * @param {Object} showOptions
171
184
  * @param {boolean} showOptions.all Show all versions
172
185
  * @param {string?} showOptions.version show a specific version
186
+ * @param {boolean?} showOptions.noWrap don't line-wrap output
173
187
  */
174
- async function show({all, version}) {
188
+ async function show({all, version, noWrap}) {
175
189
 
176
190
  const changelog = await parseChangelog();
177
191
 
@@ -186,7 +200,7 @@ async function show({all, version}) {
186
200
 
187
201
  console.log(
188
202
  toRender
189
- .map( log => log.toString())
203
+ .map( log => log.output(!noWrap))
190
204
  .join('\n\n')
191
205
  );
192
206
 
package/package.json CHANGED
@@ -1,13 +1,20 @@
1
1
  {
2
2
  "name": "changelog-tool",
3
- "version": "0.7.1",
3
+ "version": "1.0.0",
4
4
  "description": "A CLI tool for manipulating changelogs",
5
5
  "type": "module",
6
6
  "main": "index.mjs",
7
+ "homepage": "https://github.com/evert/changelog-tool",
8
+ "author": "Evert Pot (https://evertpot.com/)",
9
+ "license": "MIT",
7
10
  "scripts": {
8
11
  "test": "node --test",
9
12
  "watch": "tsc --watch"
10
13
  },
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "git@github.com:evert/changelog-tool.git"
17
+ },
11
18
  "keywords": [
12
19
  "changelog",
13
20
  "markdown"
package/parse.mjs CHANGED
@@ -14,6 +14,10 @@ export async function parseFile(filename) {
14
14
 
15
15
  }
16
16
 
17
+ const linkReferenceRe = /^\[([a-zA-Z0-9])+\]:/;
18
+ const versionRe = /^([0-9\.]{3,}(?:-(?:alpha|beta)\.[0-9]+)?) \(([0-9]{4}-[0-9]{2}-[0-9]{2}|\?\?\?\?-\?\?-\?\?)\)$/;
19
+
20
+
17
21
  /**
18
22
  * @param {string} changelogInput
19
23
  * @returns {Changelog}
@@ -51,10 +55,31 @@ export function parse(changelogInput) {
51
55
  continue;
52
56
  }
53
57
 
58
+ // Look for link references
59
+ if (linkReferenceRe.test(line)) {
60
+
61
+ let linkRefLine = line;
62
+ while(lines[idx+1]?.match(/^\W\W/)) {
63
+ // If the line was folded over multiple lines, read those too.
64
+ linkRefLine += ' ' + lines[idx+1].trim();
65
+ idx++;
66
+ }
67
+ const name = linkRefLine.match(linkReferenceRe)?.[1];
68
+ const href = linkRefLine.split(' ')[1];
69
+ const title = linkRefLine.includes('"') ? linkRefLine.substring(linkRefLine.indexOf('"')+1,linkRefLine.lastIndexOf('"')) : null;
70
+ changelog.links.push({
71
+ name: /** @type {string} */(name),
72
+ href,
73
+ title
74
+ });
75
+ continue;
76
+
77
+ }
78
+
54
79
  // Look to the next line for ----
55
80
  if (lines[idx+1]?.match(/^-{1,}$/)) {
56
81
  // Found a new Version
57
- const matches = line.match(/^([0-9\.]{3,}(?:-(?:alpha|beta)\.[0-9])?) \(([0-9]{4}-[0-9]{2}-[0-9]{2}|\?\?\?\?-\?\?-\?\?)\)$/);
82
+ const matches = line.match(versionRe);
58
83
 
59
84
  if (!matches) {
60
85
  throw new Error(`A version title must have the format "1.0.0 (YYYY-MM-DD)" or "1.0.0 (????-??-??)" for unreleased versions. We found: "${line}"`);
package/readme.md CHANGED
@@ -8,6 +8,9 @@ This tool currently expects to work with a file named 'changelog.md' in the
8
8
  current working directory. This is a markdown file that looks like this:
9
9
 
10
10
  ```
11
+ Changelog
12
+ =========
13
+
11
14
  0.4.0 (????-??-??)
12
15
  ------------------
13
16
 
package/test/parse.mjs CHANGED
@@ -83,7 +83,6 @@ Well, that's all folks.
83
83
  *
84
84
  `;
85
85
 
86
- debugger;
87
86
  const result = await parse(input);
88
87
 
89
88
  const latest = result.get('0.2.0');
@@ -93,3 +92,44 @@ Well, that's all folks.
93
92
 
94
93
 
95
94
  });
95
+
96
+ test('Link references', async() => {
97
+
98
+
99
+ const input = `Changesss
100
+ =========
101
+
102
+ 0.2.0 (????-??-??)
103
+ ------------------
104
+
105
+ WOW another release. How good is that?
106
+ Here's another line.
107
+
108
+ * Implemented the 'list' command.
109
+ * Added testing framework. See [the blog post][1] for more information.
110
+
111
+ 0.1.0 (2023-02-08)
112
+ ------------------
113
+
114
+ * Implemented the ['help'][2] and 'init' commands.
115
+
116
+ [1]: https://evertpot.com/ "My Blog"
117
+ [2]: https://indieweb.social/@evert "My Mastodon account, but it's split
118
+ over two lines"
119
+ `;
120
+
121
+ debugger;
122
+ const result = await parse(input);
123
+
124
+ assert.deepEqual({
125
+ name: '1',
126
+ href: 'https://evertpot.com/',
127
+ title: 'My Blog',
128
+ }, result.links[0]);
129
+ assert.deepEqual({
130
+ name: '2',
131
+ href: 'https://indieweb.social/@evert',
132
+ title: 'My Mastodon account, but it\'s split over two lines',
133
+ }, result.links[1]);
134
+
135
+ });