Skip to content

Commit

Permalink
feat: parse release notes
Browse files Browse the repository at this point in the history
  • Loading branch information
iowillhoit committed Nov 8, 2021
1 parent b351bb2 commit 83f0a47
Show file tree
Hide file tree
Showing 8 changed files with 146 additions and 12 deletions.
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
"@salesforce/ts-types": "^1.5.20",
"fs-extra": "^10.0.0",
"got": "^11.8.2",
"marked": "^4.0.0",
"marked-terminal": "^4.2.0",
"semver": "^7.3.5",
"sinon-chai": "^3.7.0",
"tslib": "^2"
Expand All @@ -26,6 +28,8 @@
"@salesforce/prettier-config": "^0.0.2",
"@salesforce/ts-sinon": "1.3.18",
"@types/fs-extra": "^9.0.13",
"@types/marked": "^4.0.0",
"@types/marked-terminal": "^3.1.3",
"@types/semver": "^7.3.8",
"@typescript-eslint/eslint-plugin": "^4.28.1",
"@typescript-eslint/parser": "^4.28.1",
Expand Down
20 changes: 16 additions & 4 deletions src/commands/info/releasenotes/display.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/

// Needed this to ensure the "helpers" were decalred before read in examples
// Needed this to ensure the "helpers" were declared before read in examples
/* eslint-disable @typescript-eslint/member-ordering */

import { marked } from 'marked';
import * as TerminalRenderer from 'marked-terminal';
import { Env } from '@salesforce/kit';
import { flags, SfdxCommand } from '@salesforce/command';
import { getString } from '@salesforce/ts-types';
Expand All @@ -16,12 +18,13 @@ import { Messages } from '@salesforce/core';
import { getInfoConfig, InfoConfig } from '../../../shared/get-info-config';
import { getReleaseNotes } from '../../../shared/get-release-notes';
import { getDistTagVersion } from '../../../shared/get-dist-tag-version';
import { parseReleaseNotes } from '../../../shared/parse-release-notes';

// Initialize Messages with the current plugin directory
Messages.importMessagesDirectory(__dirname);

// Load the specific messages for this file. Messages from @salesforce/command, @salesforce/core,
// or any library that is sfdxusing the messages framework can also be loaded this way.
// or any library that is sfdx using the messages framework can also be loaded this way.
const messages = Messages.loadMessages('@salesforce/plugin-info', 'display');

export default class Display extends SfdxCommand {
Expand Down Expand Up @@ -97,7 +100,16 @@ export default class Display extends SfdxCommand {
return;
}

// temp until markdown parser is added
this.ux.log(releaseNotes);
try {
const tokens = parseReleaseNotes(releaseNotes, version, releaseNotesPath);

marked.setOptions({
renderer: new TerminalRenderer(),
});

this.ux.log(marked.parser(tokens));
} catch (err) {
warn('parseReleaseNotes() failed with message', err);
}
}
}
2 changes: 1 addition & 1 deletion src/shared/get-info-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Add to oclif object
"info": {
"releasenotes": {
"distTagUrl": "https://registry.npmjs.org/-/package/sfdx-cli/dist-tags",
"releaseNotesPath": "https://raw.githubusercontent.com/forcedotcom/cli/main/releasenotes/sfdx",
"releaseNotesPath": "https://github.com/forcedotcom/cli/tree/main/releasenotes/sfdx",
"releaseNotesFilename": "README.md"
}
}
Expand Down
6 changes: 4 additions & 2 deletions src/shared/get-release-notes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,16 @@ import { PLUGIN_INFO_GET_TIMEOUT } from '../constants';
export async function getReleaseNotes(base: string, filename: string, version: string): Promise<string> {
const majorVersion = major(version);

const rawBase = base.replace('github.com', 'raw.githubusercontent.com').replace('/blob/', '/').replace('/tree/', '/');

const options = {
timeout: PLUGIN_INFO_GET_TIMEOUT,
throwHttpErrors: false,
};

const getPromises = [
got(`${base}/v${majorVersion}.md`, options),
got(`${base}/${filename}`, { ...options, throwHttpErrors: true }),
got(`${rawBase}/v${majorVersion}.md`, options),
got(`${rawBase}/${filename}`, { ...options, throwHttpErrors: true }),
];

const [versioned, readme] = await Promise.all(getPromises);
Expand Down
44 changes: 44 additions & 0 deletions src/shared/parse-release-notes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright (c) 2018, salesforce.com, inc.
* All rights reserved.
* Licensed under the BSD 3-Clause license.
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/

import { marked } from 'marked';

export function parseReleaseNotes(notes: string, version: string, baseUrl?: string): marked.Token[] {
let found = false;

const parsed = marked.lexer(notes);

const tokens = parsed.filter((token) => {
// TODO: Make header depth a setting in oclif.info?
if (token.type === 'heading' && token.depth === 2) {
if (token.text.includes(version)) {
found = true;

return token;
}

found = false;
} else if (found === true) {
return token;
}
});

if (!tokens.length) {
throw new Error(`Version '${version}' was not found. You can view release notes online at: ${baseUrl}`);
}

const fixRelativeLinks = (token: marked.Token): void => {
// If link is relative, add the baseurl. https://regex101.com/r/h802kJ/1
if (token.type === 'link' && !token.href.match(/(?:[a-z][a-z0-9+.-]*:|\/\/)/gi)) {
token.href = `${baseUrl}/${token.href}`;
}
};

marked.walkTokens(tokens, fixRelativeLinks);

return tokens;
}
2 changes: 1 addition & 1 deletion test/shared/get-info-config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ describe('getInfoConfig tests', () => {
info: {
releasenotes: {
distTagUrl: 'https://registry.npmjs.org/-/package/sfdx-cli/dist-tags',
releaseNotesPath: 'https://raw.githubusercontent.com/forcedotcom/cli/main/releasenotes/sfdx',
releaseNotesPath: 'https://github.com/forcedotcom/cli/tree/main/releasenotes/sfdx',
releaseNotesFilename: 'README.md',
},
},
Expand Down
14 changes: 11 additions & 3 deletions test/shared/get-release-notes.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,16 @@ describe('getReleaseNotes tests', () => {
let semverSpy: Sinon.SinonSpy;

let path: string;
let rawPath: string;
let version: string;
let filename: string;
let options;
let versionedResponse: gotResponse;
let readmeResponse: gotResponse;

beforeEach(() => {
path = 'https://example.com';
path = 'https://github.com/forcedotcom/cli/tree/main/releasenotes/sfdx';
rawPath = 'https://raw.githubusercontent.com/forcedotcom/cli/main/releasenotes/sfdx';
version = '1.2.3';
filename = 'readme.md';
options = {
Expand Down Expand Up @@ -71,18 +73,24 @@ describe('getReleaseNotes tests', () => {
expect(semverSpy.returnValues[0]).to.equal(1);
});

it('converts path from pjson.oclif.info to a raw github url', async () => {
await getReleaseNotes(path, filename, version);

expect(gotStub.args[0][0]).to.include(rawPath);
});

it('makes versioned GET request with correct args', async () => {
await getReleaseNotes(path, filename, version);

const expected = [`${path}/v1.md`, options];
const expected = [`${rawPath}/v1.md`, options];

expect(gotStub.args[0]).to.deep.equal(expected);
});

it('makes readme GET request with correct args', async () => {
await getReleaseNotes(path, filename, version);

const expected = [`${path}/${filename}`, { ...options, throwHttpErrors: true }];
const expected = [`${rawPath}/${filename}`, { ...options, throwHttpErrors: true }];

expect(gotStub.args[1]).to.deep.equal(expected);
});
Expand Down
66 changes: 65 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -880,6 +880,24 @@
resolved "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.159.tgz#61089719dc6fdd9c5cb46efc827f2571d1517065"
integrity sha512-gF7A72f7WQN33DpqOWw9geApQPh4M3PxluMtaHxWHXEGSN12/WbcEk/eNSqWNQcQhF66VSZ06vCF94CrHwXJDg==

"@types/marked-terminal@^3.1.3":
version "3.1.3"
resolved "https://registry.yarnpkg.com/@types/marked-terminal/-/marked-terminal-3.1.3.tgz#41fefdf23d6c8895c20ba57b4e21fa7e3c69efac"
integrity sha512-dKgOLKlI5zFb2jTbRcyQqbdrHxeU74DCOkVIZtsoB2sc1ctXZ1iB2uxG2jjAuzoLdvwHP065ijN6Q8HecWdWYg==
dependencies:
"@types/marked" "^3"
chalk "^2.4.1"

"@types/marked@^3":
version "3.0.3"
resolved "https://registry.yarnpkg.com/@types/marked/-/marked-3.0.3.tgz#37878f405d5f0cff0e6128cea330bd0aa8df8cb3"
integrity sha512-ZgAr847Wl68W+B0sWH7F4fDPxTzerLnRuUXjUpp1n4NjGSs8hgPAjAp7NQIXblG34MXTrf5wWkAK8PVJ2LIlVg==

"@types/marked@^4.0.0":
version "4.0.0"
resolved "https://registry.yarnpkg.com/@types/marked/-/marked-4.0.0.tgz#2e7036d348adc7f5916946349596194b99eb4673"
integrity sha512-Zuz0vlQDfPuop4aFFWFdFTTpVmFqkwAQJ4Onxmgc2ZMxhgaO0UxEwWpz23uHXd9QhwsFB1BJBmWNjheZmqdBuQ==

"@types/minimatch@*", "@types/minimatch@^3.0.3":
version "3.0.3"
resolved "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
Expand Down Expand Up @@ -1078,6 +1096,13 @@ ansi-escapes@^4.3.0:
dependencies:
type-fest "^0.11.0"

ansi-escapes@^4.3.1:
version "4.3.2"
resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e"
integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==
dependencies:
type-fest "^0.21.3"

ansi-regex@^3.0.0:
version "3.0.0"
resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998"
Expand Down Expand Up @@ -1663,6 +1688,16 @@ cli-progress@^3.4.0:
colors "^1.1.2"
string-width "^4.2.0"

cli-table3@^0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.6.0.tgz#b7b1bc65ca8e7b5cef9124e13dc2b21e2ce4faee"
integrity sha512-gnB85c3MGC7Nm9I/FkiasNBOKjOiO1RNuXXarQms37q4QMpWdlbBgD/VnOStA2faG1dpXMv31RFApjX1/QdgWQ==
dependencies:
object-assign "^4.1.0"
string-width "^4.2.0"
optionalDependencies:
colors "^1.1.2"

cli-truncate@^2.1.0:
version "2.1.0"
resolved "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz#c39e28bf05edcde5be3b98992a22deed5a2b93c7"
Expand Down Expand Up @@ -4532,11 +4567,28 @@ map-visit@^1.0.0:
dependencies:
object-visit "^1.0.0"

marked-terminal@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/marked-terminal/-/marked-terminal-4.2.0.tgz#593734a53cf9a4bb01ea961aa579bd21889ce502"
integrity sha512-DQfNRV9svZf0Dm9Cf5x5xaVJ1+XjxQW6XjFJ5HFkVyK52SDpj5PCBzS5X5r2w9nHr3mlB0T5201UMLue9fmhUw==
dependencies:
ansi-escapes "^4.3.1"
cardinal "^2.1.1"
chalk "^4.1.0"
cli-table3 "^0.6.0"
node-emoji "^1.10.0"
supports-hyperlinks "^2.1.0"

marked@^1.1.1:
version "1.2.8"
resolved "https://registry.npmjs.org/marked/-/marked-1.2.8.tgz#5008ece15cfa43e653e85845f3525af4beb6bdd4"
integrity sha512-lzmFjGnzWHkmbk85q/ILZjFoHHJIQGF+SxGEfIdGk/XhiTPhqGs37gbru6Kkd48diJnEyYwnG67nru0Z2gQtuQ==

marked@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/marked/-/marked-4.0.0.tgz#fd4ff16f6b99fbe6beb729f2077ea717d0ec4edb"
integrity sha512-K3C1JvtiXuXVLoxDQEJP4NMLBuThlTkthgUOCzqLghIpHfis1DIZZfPI3o4UgfFpQ0d+JvTql2h+szR9jQ1p1w==

meow@^3.3.0:
version "3.7.0"
resolved "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb"
Expand Down Expand Up @@ -4869,6 +4921,13 @@ nise@^5.1.0:
just-extend "^4.0.2"
path-to-regexp "^1.7.0"

node-emoji@^1.10.0:
version "1.11.0"
resolved "https://registry.yarnpkg.com/node-emoji/-/node-emoji-1.11.0.tgz#69a0150e6946e2f115e9d7ea4df7971e2628301c"
integrity sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==
dependencies:
lodash "^4.17.21"

node-preload@^0.2.1:
version "0.2.1"
resolved "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz#c03043bb327f417a18fee7ab7ee57b408a144301"
Expand Down Expand Up @@ -4958,7 +5017,7 @@ oauth-sign@~0.9.0:
resolved "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455"
integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==

object-assign@^4.0.1:
object-assign@^4.0.1, object-assign@^4.1.0:
version "4.1.1"
resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
Expand Down Expand Up @@ -6650,6 +6709,11 @@ type-fest@^0.20.2:
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4"
integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==

type-fest@^0.21.3:
version "0.21.3"
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37"
integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==

type-fest@^0.6.0:
version "0.6.0"
resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b"
Expand Down

0 comments on commit 83f0a47

Please sign in to comment.