1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-11-26 20:39:08 +01:00
metamask-extension/development/highlights/storybook.js
kumavis f472c2615a
CI - add metamaskbot comment "highlights" section for showing relevant storybook changes (#12095)
* ci/announce/highlight - add bot announcement section for "highlights" showing off important diffs + storybook highlights

* ci/announce/highlight - fix announcement message

* Update index.js

* xxx tmp xxx

* ci/announce/highlight - fix dirty file calculation

* ci/announce/highlight - try/catch wrap highlight generation for build stability

* ui - put fox emojis in the mascot component

* ci/announce/highlight - start storybook permalinks

* ci/announce/highlight - fix storybook permalink util

* ci/announce/highlight - fix storybook permalink util

* ci/announce/highlight - small styling fix

* storybook - use any easily predictable story id

* ci/announce/highlight - revert sample commit

* ci/announce/highlight - minimal documentation
2021-09-15 08:55:48 -10:00

87 lines
2.5 KiB
JavaScript

const path = require('path');
const { promisify } = require('util');
const exec = promisify(require('child_process').exec);
const dependencyTree = require('dependency-tree');
const cwd = process.cwd();
const resolutionCache = {};
// 1. load stories
// 2. load list per story
// 3. filter against files
module.exports = {
getHighlights,
getHighlightAnnouncement,
};
async function getHighlightAnnouncement({ changedFiles, artifactBase }) {
const highlights = await getHighlights({ changedFiles });
if (!highlights.length) return null;
const highlightsBody = highlights
.map((entry) => `\n- [${entry}](${urlForStoryFile(entry, artifactBase)})`)
.join('');
const announcement = `<details>
<summary>storybook</summary>
${highlightsBody}
</details>\n\n`;
return announcement;
}
async function getHighlights({ changedFiles }) {
const highlights = [];
const storyFiles = await getAllStories();
// check each story file for dep graph overlap with changed files
for (const storyFile of storyFiles) {
const list = await getLocalDependencyList(storyFile);
if (list.some((entry) => changedFiles.includes(entry))) {
highlights.push(storyFile);
}
}
return highlights;
}
async function getAllStories() {
const { stdout } = await exec('find ui -name "*.stories.js"');
const matches = stdout.split('\n').slice(0, -1);
return matches;
}
async function getLocalDependencyList(filename) {
const list = dependencyTree
.toList({
filename,
// not sure what this does but its mandatory
directory: cwd,
webpackConfig: `.storybook/main.js`,
// skip all dependencies
filter: (entry) => !entry.includes('node_modules'),
// for memoization across trees: 30s -> 5s
visited: resolutionCache,
})
.map((entry) => path.relative(cwd, entry));
return list;
}
function urlForStoryFile(filename, artifactBase) {
const storyId = sanitize(filename);
return `${artifactBase}/storybook/index.html?path=/story/${storyId}`;
}
/**
* Remove punctuation and illegal characters from a story ID.
* See:
* https://gist.github.com/davidjrice/9d2af51100e41c6c4b4a
* https://github.com/ComponentDriven/csf/blame/7ac941eee85816a4c567ca85460731acb5360f50/src/index.ts
*/
function sanitize(string) {
return (
string
.toLowerCase()
// eslint-disable-next-line no-useless-escape
.replace(/[ ’–—―′¿'`~!@#$%^&*()_|+\-=?;:'",.<>\{\}\[\]\\\/]/giu, '-')
.replace(/-+/gu, '-')
.replace(/^-+/u, '')
.replace(/-+$/u, '')
);
}