aboutsummaryrefslogtreecommitdiffstats
path: root/packages/monorepo-scripts/src/convert_changelogs.ts
blob: c75abfc44011993e6c67c77adc06044f3e224e81 (plain) (blame)
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
#!/usr/bin/env node
/**
 * TEMPORARY SCRIPT
 * This script exists to migrate the legacy CHANGELOG.md to the canonical CHANGELOG.md
 * TODO: Remove after migration is successful and committed.
 */

import * as fs from 'fs';
import lernaGetPackages = require('lerna-get-packages');
import * as _ from 'lodash';
import * as moment from 'moment';
import * as path from 'path';
import { exec as execAsync } from 'promisify-child-process';

import { constants } from './constants';
import { Changelog, Changes, UpdatedPackage } from './types';
import { utils } from './utils';

const HEADER_PRAGMA = '##';

(async () => {
    const allLernaPackages = lernaGetPackages(constants.monorepoRootPath);
    const publicLernaPackages = _.filter(allLernaPackages, pkg => !pkg.package.private);
    for (const lernaPackage of publicLernaPackages) {
        const changelogMdIfExists = getChangelogMdIfExists(lernaPackage.package.name, lernaPackage.location);
        if (_.isUndefined(changelogMdIfExists)) {
            throw new Error(`${lernaPackage.package.name} should have CHANGELOG.md b/c it's public. Add one.`);
        }

        const lines = changelogMdIfExists.split('\n');
        const changelogs: Changelog[] = [];
        let changelog: Changelog = {
            version: '',
            changes: [],
        };
        /**
         * Example MD entry:
         * ## v0.3.1 - _March 18, 2018_
         *
         *    * Add TS types for `yargs` (#400)
         */
        for (const line of lines) {
            if (_.startsWith(line, `${HEADER_PRAGMA} `)) {
                let version = line.substr(4).split(' - ')[0];
                if (version === '0.x.x') {
                    version = utils.getNextPatchVersion(lernaPackage.package.version);
                }
                const dateStr = line.split('_')[1];
                let date;
                if (!_.includes(dateStr, 'TBD')) {
                    date = moment(dateStr, 'MMMM D, YYYY');
                }
                changelog = {
                    version,
                    changes: [],
                };
                if (!_.isUndefined(date)) {
                    changelog.timestamp = date.unix();
                }
                if (!_.includes(dateStr, 'TBD')) {
                    changelog.isPublished = true;
                }
                changelogs.push(changelog);
            } else if (_.includes(line, '* ')) {
                const note = line.split('* ')[1].split(' (#')[0];
                const prChunk = line.split(' (#')[1];
                let pr;
                if (!_.isUndefined(prChunk)) {
                    pr = prChunk.split(')')[0];
                }
                const changes: Changes = {
                    note,
                };
                if (!_.isUndefined(pr)) {
                    changes.pr = _.parseInt(pr);
                }
                changelog.changes.push(changes);
            }
        }
        const changelogJSONPath = JSON.stringify(changelogs, null, 4);
        const changelogJSONPathPath = `${lernaPackage.location}/CHANGELOG.json`;
        fs.writeFileSync(changelogJSONPathPath, changelogJSONPath);
        await utils.prettifyAsync(changelogJSONPath, constants.monorepoRootPath);
    }
})().catch(err => {
    utils.log(err.stdout);
    process.exit(1);
});

function getChangelogMdIfExists(packageName: string, location: string): string | undefined {
    const changelogPath = path.join(location, 'CHANGELOG.md');
    let changelogMd: string;
    try {
        changelogMd = fs.readFileSync(changelogPath, 'utf-8');
        return changelogMd;
    } catch (err) {
        return undefined;
    }
}