Skip to content

Commit

Permalink
Copy changes from evmar/webtreemap PR
Browse files Browse the repository at this point in the history
  • Loading branch information
danvk committed Aug 22, 2021
1 parent ad8b138 commit 0260189
Show file tree
Hide file tree
Showing 6 changed files with 113 additions and 48 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/build
/build-node
/node_modules
/demo/demo.js
/docs
Expand Down
14 changes: 8 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,27 @@
"description": "treemap visualization",
"main": "dist/webtreemap.js",
"bin": {
"webtreemap": "build/cli.js"
"webtreemap": "build-node/cli.js"
},
"dependencies": {
"commander": "^2.11.0"
"commander": "^2.11.0",
"open": "^8.2.1"
},
"devDependencies": {
"@types/commander": "^2.11.0",
"@types/node": "^8.0.34",
"@types/node": "12.20.20",
"prettier": "1.14.3",
"rollup": "^1.19.4",
"rollup-plugin-banner": "^0.2.1",
"typescript": "^3.1.3"
"typescript": "^4.3.5"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"fmt": "prettier --write src/*.ts demo/*.ts *.md",
"build": "tsc && rollup -c",
"demo": "mkdir -p public; du -a node_modules/ | node build/cli.js --title 'node_modules for webtreemap' > public/index.html",
"build:demo": "yarn build && yarn tsc --module commonjs && yarn demo",
"build:cli": "tsc -p tsconfig.node.json",
"build:demo": "yarn build:cli && yarn demo",
"demo": "mkdir -p public; du -a node_modules/ | node build-node/cli.js --title 'node_modules for webtreemap' > public/index.html",
"watch": "find src | entr yarn build:demo",
"clean": "rm -rf build dist public",
"roll": "yarn build; gcp -f dist/webtreemap.js ~/chromium/src/third_party/third_party/devtools-frontend/src/front_end/third_party/webtreemap/webtreemap.js"
Expand Down
90 changes: 57 additions & 33 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,12 @@
*/

import {Command} from 'commander';
import * as fs from 'fs';
import * as readline from 'readline';
import {promises as fs} from 'fs';
import crypto from 'crypto';
import open from 'open';
import os from 'os';
import path from 'path';
import readline from 'readline';

import * as tree from './tree';

Expand All @@ -34,28 +38,40 @@ async function readLines() {
});
}

/** Reads a file to a string. */
async function readFile(path: string) {
return new Promise<string>((resolve, reject) => {
fs.readFile(path, {encoding: 'utf-8'}, (err, data) => {
if (err) {
reject(err);
return;
}
resolve(data);
});
});
/** Read an array of lines from a list of files */
async function readLinesFromFiles(files: string[]) {
let lines: string[] = [];
for (const file of files) {
const contents = await fs.readFile(file, 'utf-8');
lines = lines.concat(contents.split('\n'));
}
return lines;
}

/** Constructs a tree from an array of lines. */
function treeFromLines(lines: string[]): tree.Node {
const data: Array<[string, number]> = [];
for (const line of lines) {
const [, sizeStr, path] = line.match(/(\S+)\s+(.*)/) || ['', '', ''];
function parseLine(line: string): [string, number] {
if (line.match(/^\s*$/)) {
// Skip blank / whitespace-only lines
return ['', 0];
}

// Match (number)(whitespace)(path)
let m = line.match(/(\S+)\s+(.*)/);
if (m) {
const [, sizeStr, path] = m;
const size = Number(sizeStr);
data.push([path, size]);
if (isNaN(size)) {
throw new Error(`Unable to parse ${size} as a number in line: "${line}"`);
}
return [path, size];
}
let node = tree.treeify(data);

// Assume it's (path)
return [line, 1];
}

/** Constructs a tree from an array of lines. */
function treeFromLines(lines: string[]): tree.Node {
let node = tree.treeify(lines.map(parseLine));

// If there's a common empty parent, skip it.
if (node.id === undefined && node.children && node.children.length === 1) {
Expand All @@ -76,14 +92,6 @@ function treeFromLines(lines: string[]): tree.Node {
return node;
}

function plainCaption(n: tree.Node): string {
return n.id || '';
}

function sizeCaption(n: tree.Node): string {
return `${n.id || ''} (${n.size})`;
}

// TODO: update to use either SI units or Kibibytes
function humanSizeCaption(n: tree.Node): string {
let units = ['', 'k', 'm', 'g'];
Expand All @@ -96,6 +104,15 @@ function humanSizeCaption(n: tree.Node): string {
return `${n.id || ''} (${size.toFixed(1)}${units[unit]})`;
}


/** Write contents (utf-8 encoded) to a temp file, returning the path to the file. */
async function writeToTempFile(contents: string): Promise<string> {
const randHex = crypto.randomBytes(4).readUInt32LE(0).toString(16);
const filename = path.join(os.tmpdir(), `webtreemap-${randHex}.html`);
await fs.writeFile(filename, contents, {encoding: 'utf-8'});
return filename;
}

async function main() {
const args = new Command()
.description(`Generate web-based treemaps.
Expand All @@ -107,9 +124,14 @@ async function main() {
.option('-o, --output [path]', 'output to file, not stdout')
.option('--title [string]', 'title of output HTML')
.parse(process.argv);
const node = treeFromLines(await readLines());
const treemapJS = await readFile(__dirname + '/../dist/webtreemap.js');
const treemapCSS = await readFile(__dirname + '/../src/styles-to-add.css');

const lines =
args.args.length > 0 ? readLinesFromFiles(args.args) : readLines();

const node = treeFromLines(await lines);

const treemapJS = await fs.readFile(__dirname + '/../dist/webtreemap.js', 'utf-8');
const treemapCSS = await fs.readFile(__dirname + '/../src/styles-to-add.css', 'utf-8');
const title = args.title || 'webtreemap';

let inlineScript = `
Expand Down Expand Up @@ -142,9 +164,11 @@ ${treemapCSS}
</script>
`;
if (args.output) {
fs.writeFileSync(args.output, output, {encoding: 'utf-8'});
} else {
await fs.writeFile(args.output, output, {encoding: 'utf-8'});
} else if (!process.stdout.isTTY) {
console.log(output);
} else {
open(await writeToTempFile(output));
}
}

Expand Down
5 changes: 3 additions & 2 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
// "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
"useDefineForClassFields": false,

/* Strict Type-Checking Options */
"strict": true, /* Enable all strict type-checking options. */
Expand All @@ -36,13 +37,13 @@
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */

/* Module Resolution Options */
// "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
"moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
// "typeRoots": [], /* List of folders to include type definitions from. */
// "types": [], /* Type declaration files to be included in compilation. */
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
"allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */

Expand Down
9 changes: 9 additions & 0 deletions tsconfig.node.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
/* Basic Options */
"target": "es2015",
"module": "commonjs",
"outDir": "./build-node",
}
}
42 changes: 35 additions & 7 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,16 @@
version "8.0.40"
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.40.tgz#260f0440db0643f034c9103bba0be777ce25317c"

"@types/[email protected]":
version "12.20.20"
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.20.tgz#ce3d6c13c15c5e622a85efcd3a1cb2d9c7fa43a6"
integrity sha512-kqmxiJg4AT7rsSPIhO6eoBIx9mNwwpeH42yjtgQh6X2ANSpLpvToMXv+LMFdfxpwG1FZXZ41OGZMiUAtbBLEvg==

"@types/node@^12.6.9":
version "12.7.2"
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.2.tgz#c4e63af5e8823ce9cc3f0b34f7b998c2171f0c44"
integrity sha512-dyYO+f6ihZEtNPDcWNR1fkoTDf3zAK3lAABDze3mz6POyIercH0lEUawUFXlG8xaQZmm1yEBON/4TsYv/laDYg==

"@types/node@^8.0.34":
version "8.0.34"
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.34.tgz#55f801fa2ddb2a40dd6dfc15ecfe1dde9c129fe9"

acorn@^6.2.1:
version "6.3.0"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.3.0.tgz#0087509119ffa4fc0a0041d1e93a417e68cb856e"
Expand All @@ -35,6 +36,23 @@ commander@^2.11.0:
version "2.11.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.11.0.tgz#157152fd1e7a6c8d98a5b715cf376df928004563"

define-lazy-prop@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f"
integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==

is-docker@^2.0.0, is-docker@^2.1.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa"
integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==

is-wsl@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271"
integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==
dependencies:
is-docker "^2.0.0"

lodash._reinterpolate@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d"
Expand All @@ -55,6 +73,15 @@ lodash.templatesettings@^4.0.0:
dependencies:
lodash._reinterpolate "^3.0.0"

open@^8.2.1:
version "8.2.1"
resolved "https://registry.yarnpkg.com/open/-/open-8.2.1.tgz#82de42da0ccbf429bc12d099dad2e0975e14e8af"
integrity sha512-rXILpcQlkF/QuFez2BJDf3GsqpjGKbkUUToAIGo9A0Q6ZkoSGogZJulrUdwRkrAsoQvoZsrjCYt8+zblOk7JQQ==
dependencies:
define-lazy-prop "^2.0.0"
is-docker "^2.1.1"
is-wsl "^2.2.0"

[email protected]:
version "1.14.3"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.14.3.tgz#90238dd4c0684b7edce5f83b0fb7328e48bd0895"
Expand All @@ -75,6 +102,7 @@ rollup@^1.19.4:
"@types/node" "^12.6.9"
acorn "^6.2.1"

typescript@^3.1.3:
version "3.1.3"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.1.3.tgz#01b70247a6d3c2467f70c45795ef5ea18ce191d5"
typescript@^4.3.5:
version "4.3.5"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.5.tgz#4d1c37cc16e893973c45a06886b7113234f119f4"
integrity sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==

0 comments on commit 0260189

Please sign in to comment.