Skip to content

Commit

Permalink
chore(info): changes base
Browse files Browse the repository at this point in the history
  • Loading branch information
pranshuchittora committed Jul 24, 2019
1 parent 44df902 commit a58c286
Show file tree
Hide file tree
Showing 9 changed files with 861 additions and 54 deletions.
63 changes: 60 additions & 3 deletions packages/info/README.md
Expand Up @@ -9,22 +9,79 @@ This package returns a set of information related to the local environment.
## Installation

```bash
#npm
npm i -D @webpack-cli/info

#yarn
yarn add @webpack-cli/info -D

#npx
npx webpack info [options]

```

## Usage

### Args / Flags

#### Output format

| Flag | Description | Type |
| ------------------- | ----------------------------- | ----------- |
| `--output-json` | To get the output as JSON | [ boolean ] |
| `--output-markdown` | To get the output as markdown | [ boolean ] |

#### Options

| Flag | Description | Type |
| ------------------- | --------------------------------------------------------------- | ----------- |
| `--help` | Show help | [ boolean ] |
| `--version` | Show version number of `webpack-cli` | [ boolean ] |
| `--system` , `-s` | System information ( OS, CPU ) | [ boolean ] |
| `--binaries` , `-b` | Installed binaries (Node, yarn, npm) | [ boolean ] |
| `--browsers` | Installed web browsers | [ boolean ] |
| `--npmg` | Globally installed NPM packages ( webpack & webpack-cli only ) | [ boolean ] |
| `--npmPackages` | Info about packages related to webpack installed in the project | [ boolean ] |

### Node

```js
const envinfo = require("@webpack-cli/info").default;
envinfo();
const info = require('@webpack-cli/info').default;

async function wrapperFunc() {
await info({
/* Custom Config */
});
}
wrapperFunc();
```

#### Custom config

> Config has higher precedence than system flags
```json
// Config's relative path
{

"config": [string]
}
// System info
{
"binaries": [boolean],
"system": [boolean],
"browsers": [boolean],
"npmg": [boolean],
"npmPackages": [boolean],
}
```

The function returns `string` for `system` info, and returns an array of strings (`string[]`) for `config`

### CLI (via `webpack-cli`)

```bash
npx webpack-cli info
webpack-cli info --FLAGS #Flags are optional for custom output
```

[downloads]: https://img.shields.io/npm/dm/@webpack-cli/info.svg
Expand Down
54 changes: 42 additions & 12 deletions packages/info/__tests__/index.test.ts
@@ -1,15 +1,45 @@
import { information } from "../index";

describe("info", () => {
it("should return the information of the enviroment", async () => {
const returnedInformation = information();
const expectedInformation = {
Binaries: ["Node", "Yarn", "npm"],
Browsers: ["Chrome", "Firefox", "Safari"],
System: ["OS", "CPU"],
npmGlobalPackages: ["webpack", "webpack-cli"],
npmPackages: "*webpack*"
};
import { informationType } from "../index";

describe("infoSystem", () => {
it("should return the information of the system", async () => {
const returnedInformation = informationType("system");
const expectedInformation = { System: ["OS", "CPU", "Memory"] };

expect(returnedInformation).toEqual(expectedInformation);
});
});

describe("infoBinaries", () => {
it("should return the information of the binaries", async () => {
const returnedInformation = informationType("binaries");
const expectedInformation = { Binaries: ["Node", "Yarn", "npm"] };

expect(returnedInformation).toEqual(expectedInformation);
});
});

describe("infoBrowsers", () => {
it("should return the information of the browsers installed", async () => {
const returnedInformation = informationType("browsers");
const expectedInformation = { Browsers: ["Chrome", "Firefox", "Safari"] };

expect(returnedInformation).toEqual(expectedInformation);
});
});

describe("infoNpmGlobal", () => {
it("should return the information of the NPM global packages", async () => {
const returnedInformation = informationType("npmg");
const expectedInformation = { npmGlobalPackages: ["webpack", "webpack-cli"] };

expect(returnedInformation).toEqual(expectedInformation);
});
});

describe("infoNpm", () => {
it("should return the information of the NPM packages (webpack)", async () => {
const returnedInformation = informationType("npmPackages");
const expectedInformation = { npmPackages: "*webpack*" };

expect(returnedInformation).toEqual(expectedInformation);
});
Expand Down
13 changes: 13 additions & 0 deletions packages/info/commands.ts
@@ -0,0 +1,13 @@
export const AVAILABLE_COMMANDS: string[] = [
"binaries",
"system",
"browsers",
"npmGlobalPackages",
"npmPackages",
"npmg",
"npm",
"b",
"s"
];
export const AVAILABLE_FORMATS: string[] = ["output-json", "output-markdown"];
export const IGNORE_FLAGS: string[] = ["_", "$0", "outputMarkdown", "outputJson", "npm-packages"];
57 changes: 57 additions & 0 deletions packages/info/configParser.ts
@@ -0,0 +1,57 @@
import * as path from 'path';
import chalk from 'chalk';
import * as prettyjson from 'prettyjson';

export function getNameFromPath(fullPath: string): string {
const filename = fullPath.replace(/^.*[\\\/]/, '');
return filename;
}

export function resolveFilePath(relativeFilePath: string): string {
const configPath = path.resolve(process.cwd() + '/' + relativeFilePath);
return configPath;
}

export function fetchConfig(configPath: string): object {
let config = null;
try {
config = require(configPath);
} catch (e) {
process.stdout.write(chalk.red(`Error:`, e.code) + `\n` + e);
}
return config;
}

const CONFIG_SCHEMA = {
plugins: 'Array',
};

function modifyConfig(config, key) {
switch (CONFIG_SCHEMA[key]) {
case 'Array':
config[key].forEach((element, idx) => {
config[key][idx] = {
name: chalk.greenBright(element.constructor.name),
...element,
};
});
}
}

export function configReader(config): string[] {
let filteredArray = [];

let options = {
noColor: true,
};
Object.keys(config).map((key): void => {
if (CONFIG_SCHEMA[key]) {
modifyConfig(config, key);
}
let rowArray = [key];
rowArray.push(prettyjson.render(config[key], options));
filteredArray = [...filteredArray, rowArray];
});

return filteredArray;
}
99 changes: 80 additions & 19 deletions packages/info/index.ts
@@ -1,29 +1,90 @@
import chalk from "chalk";
import * as envinfo from "envinfo";
import * as process from "process";
import { argv } from "./options";

/**
* Prints debugging information for webpack issue reporting
*/
import { AVAILABLE_COMMANDS, AVAILABLE_FORMATS, IGNORE_FLAGS } from "./commands";
import { configReader, fetchConfig, resolveFilePath, getNameFromPath } from "./configParser";
import { renderTable } from "./renderTable";

interface Information {
Binaries: string[];
Browsers: string[];
System: string[];
npmGlobalPackages: string[];
npmPackages: string | string[];
Binaries?: string[];
Browsers?: string[];
System?: string[];
npmGlobalPackages?: string[];
npmPackages?: string | string[];
}
interface ArgvI {
_?: string[];
bin?: boolean;
binaries?: boolean;
config?: string;
}

const CONFIG = {};
const DEFAULT_DETAILS: Information = {
Binaries: ["Node", "Yarn", "npm"],
Browsers: ["Chrome", "Firefox", "Safari"],
System: ["OS", "CPU", "Memory"],
npmGlobalPackages: ["webpack", "webpack-cli"],
npmPackages: "*webpack*"
};

// eslint-disable-next-line
export function information(): Information {
return {
Binaries: ["Node", "Yarn", "npm"],
Browsers: ["Chrome", "Firefox", "Safari"],
System: ["OS", "CPU"],
npmGlobalPackages: ["webpack", "webpack-cli"],
npmPackages: "*webpack*"
};
let DETAILS_OBJ = {};

export function informationType(type: string): Information {
switch (type) {
case "system":
return { System: ["OS", "CPU", "Memory"] };
case "binaries":
return { Binaries: ["Node", "Yarn", "npm"] };
case "browsers":
return { Browsers: ["Chrome", "Firefox", "Safari"] };
case "npmg":
return { npmGlobalPackages: ["webpack", "webpack-cli"] };
case "npmPackages":
return { npmPackages: "*webpack*" };
}
}
export default async function info(CustomArgv: object): Promise<string[]> {
const CUSTOM_AGRUMENTS: boolean = typeof CustomArgv === "object";
const args: ArgvI = CUSTOM_AGRUMENTS ? CustomArgv : argv;
const configRelativePath = argv._[1] ? argv._[1] : args.config;
if (configRelativePath) {
const fullConfigPath = resolveFilePath(configRelativePath);
const fileName = getNameFromPath(fullConfigPath);
const config = fetchConfig(fullConfigPath);
const parsedConfig = configReader(config);

const stringifiedTable = renderTable(parsedConfig, fileName);
if (args.config) return parsedConfig;
else process.stdout.write(stringifiedTable + "\n");
} else {
Object.keys(args).forEach((flag: string) => {
if (IGNORE_FLAGS.includes(flag)) {
return;
} else if (AVAILABLE_COMMANDS.includes(flag)) {
const flagVal = informationType(flag);
DETAILS_OBJ = { ...DETAILS_OBJ, ...flagVal };
} else if (AVAILABLE_FORMATS.includes(flag)) {
switch (flag) {
case "output-json":
CONFIG["json"] = true;
break;
case "output-markdown":
CONFIG["markdown"] = true;
break;
}
} else {
// Invalid option
process.stdout.write("\n" + chalk.bgRed(flag) + chalk.red(" is an invalid option" + "\n"));
return;
}
});

export default async function info(): Promise<void> {
process.stdout.write(await envinfo.run(information()));
const OUTPUT = await envinfo.run(Object.keys(DETAILS_OBJ).length ? DETAILS_OBJ : DEFAULT_DETAILS, CONFIG);
!CUSTOM_AGRUMENTS ? process.stdout.write(OUTPUT + "\n") : null;
return OUTPUT;
}
process.exit(0);
}
42 changes: 42 additions & 0 deletions packages/info/options.ts
@@ -0,0 +1,42 @@
import * as yargs from "yargs";
export const argv = yargs
.option("system", {
alias: "s",
demandOption: false,
describe: "System information (OS, CPU)",
type: "boolean"
})
.option("binaries", {
alias: "b",
demandOption: false,
describe: "Installed binaries (Node, yarn, npm)",
type: "boolean"
})

.option("browsers", {
demandOption: false,
describe: "Installed web browsers",
type: "boolean"
})

.option("npmg", {
demandOption: false,
describe: "Globally installed NPM packages (webpack & webpack-cli only)",
type: "boolean"
})
.option("npmPackages", {
demandOption: false,
describe: "Info about packages related to webpack installed in the project",
type: "boolean"
})
.option("output-json", {
demandOption: false,
describe: "To get the output as JSON",
type: "boolean"
})
.option("output-markdown", {
demandOption: false,
describe: "To get the output as markdown",
type: "boolean"
})
.group(["output-json", "output-markdown"], `Output format`).argv;

0 comments on commit a58c286

Please sign in to comment.