๐Ÿ“ฆ kitten / multitars

๐Ÿ“„ changelog.js ยท 126 lines
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
126const { config } = require('dotenv');
const { getInfo } = require('@changesets/get-github-info');

config();

const REPO = 'kitten/multitars';
const SEE_LINE = /^See:\s*(.*)/i;
const TRAILING_CHAR = /[.;:]$/g;
const listFormatter = new Intl.ListFormat('en-US');

const getSummaryLines = cs => {
  let lines = cs.summary.trim().split(/\r?\n/);
  if (!lines.some(line => /```/.test(line))) {
    lines = lines.map(l => l.trim()).filter(Boolean);
    const size = lines.length;
    if (size > 0) {
      lines[size - 1] = lines[size - 1].replace(TRAILING_CHAR, '');
    }
  }
  return lines;
};

/** Creates a "(See X)" string from a template */
const templateSeeRef = links => {
  const humanReadableLinks = links.filter(Boolean).map(link => {
    if (typeof link === 'string') return link;
    return link.pull || link.commit;
  });

  const size = humanReadableLinks.length;
  if (size === 0) return '';

  const str = listFormatter.format(humanReadableLinks);
  return `(See ${str})`;
};

const changelogFunctions = {
  getDependencyReleaseLine: async (changesets, dependenciesUpdated) => {
    if (dependenciesUpdated.length === 0) return '';

    const dependenciesLinks = await Promise.all(
      changesets.map(async cs => {
        if (!cs.commit) return undefined;

        const lines = getSummaryLines(cs);
        const prLine = lines.find(line => SEE_LINE.test(line));
        if (prLine) {
          const match = prLine.match(SEE_LINE);
          return (match && match[1].trim()) || undefined;
        }

        const { links } = await getInfo({
          repo: REPO,
          commit: cs.commit,
        });

        return links;
      })
    );

    let changesetLink = '- Updated dependencies';

    const seeRef = templateSeeRef(dependenciesLinks);
    if (seeRef) changesetLink += ` ${seeRef}`;

    const detailsLinks = dependenciesUpdated.map(dep => {
      return `  - ${dep.name}@${dep.newVersion}`;
    });

    return [changesetLink, ...detailsLinks].join('\n');
  },
  getReleaseLine: async (changeset, type) => {
    let pull, commit, user;

    const lines = getSummaryLines(changeset);
    const prLineIndex = lines.findIndex(line => SEE_LINE.test(line));
    if (prLineIndex > -1) {
      const match = lines[prLineIndex].match(SEE_LINE);
      pull = (match && match[1].trim()) || undefined;
      lines.splice(prLineIndex, 1);
    }

    const [firstLine, ...futureLines] = lines;

    if (changeset.commit && !pull) {
      const { links } = await getInfo({
        repo: REPO,
        commit: changeset.commit,
      });

      pull = links.pull || undefined;
      commit = links.commit || undefined;
      user = links.user || undefined;
    }

    let annotation = '';
    if (type === 'patch' && /^\s*fix/i.test(firstLine)) {
      annotation = 'โš ๏ธ ';
    }

    let str = `- ${annotation}${firstLine}`;
    if (futureLines.length > 0) {
      str += `\n${futureLines.map(l => `  ${l}`).join('\n')}`;
    }

    const endsWithParagraph = /(?<=(?:[!;?.]|```) *)$/g;
    if (user && !endsWithParagraph) {
      str += `, by ${user}`;
    } else {
      str += `\nSubmitted by ${user}`;
    }

    if (pull || commit) {
      const seeRef = templateSeeRef([pull || commit]);
      if (seeRef) str += ` ${seeRef}`;
    }

    return str;
  },
};

module.exports = {
  ...changelogFunctions,
  default: changelogFunctions,
};