Skip to content

Commit

Permalink
Merge pull request #38 from Himenon/feat/add-native-dot-engine
Browse files Browse the repository at this point in the history
feat: add `--engine` which use native graphviz engine
  • Loading branch information
Himenon authored Feb 7, 2020
2 parents 6098c29 + b75167f commit 40245db
Show file tree
Hide file tree
Showing 36 changed files with 390 additions and 190 deletions.
17 changes: 17 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,20 @@ private_npm_cache
buildcache/
bin/*.js
.npmrc

### packages/cli

packages/cli/lib
packages/cli/coverage
packages/cli/node_modules
packages/cli/package-lock.json
packages/cli/.env*
packages/cli/*.log
packages/cli/private_npm_cache
packages/cli/data/
packages/cli/dist/
packages/cli/output

### packages/view

packages/view/dist
17 changes: 17 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,23 @@

docs

### packages/cli

packages/cli/lib
packages/cli/coverage
packages/cli/node_modules
packages/cli/package-lock.json
packages/cli/.env*
packages/cli/*.log
packages/cli/private_npm_cache
packages/cli/data/
packages/cli/dist/
packages/cli/output

### packages/view

packages/view/dist

### Node ###
# Logs
logs
Expand Down
11 changes: 0 additions & 11 deletions packages/cli/.gitignore

This file was deleted.

1 change: 0 additions & 1 deletion packages/cli/.prettierignore

This file was deleted.

26 changes: 18 additions & 8 deletions packages/cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ code-dependency --source ./src

## Option

**-s --source** (required)
### -s --source\*\* (required)

Source directory path

Expand All @@ -17,7 +17,7 @@ code-dependency --source ./src
code-dependency --source /home/app/src
```

**-p --port**
### -p --port

Server port number (default 3000).

Expand All @@ -26,15 +26,15 @@ code-dependency --source ./src --p 4000
code-dependency --source ./src --port 4000
```

**--ts-config**
### --ts-config

`tsconfig.json` path. [see](https://github.com/sverweij/dependency-cruiser/blob/develop/doc/cli.md#--ts-config-use-a-typescript-configuration-file-project)

```bash
code-dependency --source ./src --ts-config ./tsconfig.json
```

**--webpack-config**
### --webpack-config

`webpack.config.js` path. (JavaScript only) [see](https://github.com/sverweij/dependency-cruiser/blob/develop/doc/cli.md#--webpack-config-use-the-resolution-options-of-a-webpack-configuration)

Expand All @@ -43,23 +43,23 @@ code-dependency --source ./src --webpack-config webpack.config.js
code-dependency --source ./src --webpack-config your.config.js
```

**--exclude**
### --exclude

cruise ignore pattern (default: "node_modules"). [see](https://github.com/sverweij/dependency-cruiser/blob/develop/doc/cli.md#--exclude-exclude-dependencies-from-being-cruised)

```bash
code-dependency --source ./src --exclude node_modules
```

**--export-static**
### --export-static

generate static site.

```bash
code-dependency --source ./src --exclude node_modules --export-static ./docs
```

**--public-path**
### --public-path

```bash
code-dependency --source ./src --exclude node_modules --export-static ./docs --public-path /docs
Expand All @@ -79,7 +79,17 @@ Directory Structure
└── src // `--source` target : Browser entrypoint -> /project/src/index.html
```

**--dry-run** (experimental)
### --engine

Use native graphviz engine. (https://www.graphviz.org/)

Option: `dot` (recommended)

```bash
code-dependency --source ./src --exclude node_modules --export-static ./docs --public-path /docs --engine dot
```

### --dry-run (experimental)

if failed generate static file and retry generate static file only unfinished path.

Expand Down
5 changes: 4 additions & 1 deletion packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"export:static": "node ./bin/code-dependency.js --source ./src --exclude node_modules --export-static ./output --public-path http://localhost:5000/output",
"generate:docs": "node ./bin/code-dependency.js --source ./src --exclude node_modules --export-static ../../docs --public-path https://himenon.github.io/code-dependency/",
"server": "nodemon ./bin/code-dependency.js --source ./src --exclude node_modules",
"server2": "nodemon ./bin/code-dependency.js --source ./src --engine dot --exclude node_modules",
"start": "run-p develop server",
"test": "jest -c jest.config.json && yarn export:static",
"test:ci": "jest -c jest.config.json --no-cache --ci && yarn export:static",
Expand All @@ -60,6 +61,7 @@
"recursive-readdir": "^2.2.2",
"resolve-pkg": "^2.0.0",
"rimraf": "^3.0.1",
"tempfile": "^3.0.0",
"tsconfig": "^7.0.0",
"urljoin": "^0.1.5"
},
Expand All @@ -71,7 +73,8 @@
"@types/pretty": "^2.0.0",
"@types/react": "^16.9.19",
"@types/react-dom": "^16.9.5",
"@types/rimraf": "^2.0.3"
"@types/rimraf": "^2.0.3",
"@types/tempfile": "^3.0.0"
},
"publishConfig": {
"access": "public"
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/cli/PathFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export const create = ({ context = process.cwd(), source }: Params) => {
original: source,
binRelativePath: path.relative(__dirname, source),
rootDir: path.dirname(absolutePath),
rootAbsolutePath: absolutePath,
absoluteRootPath: absolutePath,
};
};

Expand Down
11 changes: 10 additions & 1 deletion packages/cli/src/cli/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import commander from "commander";
import { SourcePathInvalidError } from "../exceptions";
import { SourcePathInvalidError, CliArgumentError } from "../exceptions";
import * as PathFactory from "./PathFactory";

const isInvalidPath = require("is-invalid-path");
Expand All @@ -13,6 +13,7 @@ interface CLIArguments {
exportStatic?: PathFactory.Type;
publicPath?: string;
dryRun: boolean;
engine?: "dot";
}

export const validateCliArguments = (args: commander.Command): CLIArguments => {
Expand All @@ -22,6 +23,12 @@ export const validateCliArguments = (args: commander.Command): CLIArguments => {
if (args["tsConfig"] && isInvalidPath(args["source"])) {
throw new SourcePathInvalidError("`--source` arguments does not selected.");
}
if ("exportStatic" in args && typeof args["exportStatic"] !== "string") {
throw new CliArgumentError("`--export-static` require 1 string argument.");
}
if ("publicPath" in args && typeof args["publicPath"] !== "string") {
throw new CliArgumentError("`--public-path` require 1 string argument.");
}
return {
source: PathFactory.create({ source: args["source"] }),
port: args["port"],
Expand All @@ -31,6 +38,7 @@ export const validateCliArguments = (args: commander.Command): CLIArguments => {
exportStatic: args["exportStatic"] && PathFactory.create({ source: args["exportStatic"] }),
publicPath: args["publicPath"],
dryRun: !!args["dryRun"],
engine: args["engine"] === "dot" ? "dot" : undefined,
};
};

Expand All @@ -45,6 +53,7 @@ export const executeCommandLine = (): CLIArguments => {
.option("--export-static [static directory]", "static file hosting directory")
.option("--public-path [host public path]", "the base path for all the assets")
.option("--dry-run", "only use --export-static option")
.option("--engine <dot>", "already local installed graphviz. <https://www.graphviz.org/>")
.parse(process.argv);
return validateCliArguments(commander);
};
11 changes: 10 additions & 1 deletion packages/cli/src/config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as path from "path";
import { FilePathObject } from "@code-dependency/view";

export interface Type {
rendererType: "client" | "server";
server: {
port: number;
};
Expand All @@ -11,8 +12,16 @@ export interface Type {
filePathList: FilePathObject[];
}

export const create = (port: number, absoluteRootPath: string, filePathList: FilePathObject[]): Type => {
export interface Params {
rendererType: "client" | "server";
port: number;
absoluteRootPath: string;
filePathList: FilePathObject[];
}

export const create = ({ rendererType, port, absoluteRootPath, filePathList }: Params): Type => {
return {
rendererType,
server: {
port,
},
Expand Down
3 changes: 3 additions & 0 deletions packages/cli/src/constants/router.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
export const routes = {
index: {
path: "/",
},
project: {
path: "/project",
},
Expand Down
22 changes: 19 additions & 3 deletions packages/cli/src/controller/ApiController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,28 @@ export const createApiResponse = <T>(data: T): Api.ApiResponse<T> => {
export const create = (service: Service.Type, config: Config.Type) => {
const router = express.Router();

router.post("/graph", async (req, res) => {
router.post("/dot-source", async (req, res) => {
const filename = path.join(config.absoluteRootDirPath, req.body.path);
try {
const dot = service.dependencyCruiser.getDependenciesDot(filename);
const dotSource = service.dependencyCruiser.getDependenciesDot(filename);
const data = createApiResponse<Api.GraphResponseData>({
element: dot,
dotSource,
});
res.json(data);
} catch (error) {
res.status(500).send(error.message);
logger.error(error);
res.end();
}
});

router.post("/svg-element", async (req, res) => {
const filename = path.join(config.absoluteRootDirPath, req.body.path);
try {
const dotSource = service.dependencyCruiser.getDependenciesDot(filename);
const svgElement = await service.renderer.renderToString(dotSource);
const data = createApiResponse<Api.SvgResponseData>({
svgElement,
});
res.json(data);
} catch (error) {
Expand Down
11 changes: 11 additions & 0 deletions packages/cli/src/controller/ProjectController.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,30 @@
import express from "express";
import * as path from "path";
import ReactDOMServer from "react-dom/server";
import { ProjectView } from "../view";
import * as Service from "../service";
import * as Config from "../config";

export const create = (service: Service.Type, config: Config.Type) => {
const router = express.Router();

const createSvgElement = async (pathname: string): Promise<string | undefined> => {
const dotSource = service.dependencyCruiser.getDependenciesDot(path.join(config.absoluteRootDirPath, pathname));
return await service.renderer.renderToString(dotSource);
};

router.get("/", async (req, res) => {
const serverUrl = `${req.protocol}://${req.hostname}:${config.server.port}`;
const pathname: string | undefined = req.query.pathname;
const svgElement = config.rendererType === "client" ? undefined : pathname && (await createSvgElement(req.query.pathname));
try {
const props: ProjectView.Props = {
rendererType: config.rendererType,
serverUrl,
publicPath: serverUrl,
url: req.url,
pathname: req.query.pathname,
svgElement,
context: {},
service,
filePathList: config.filePathList,
Expand Down
3 changes: 3 additions & 0 deletions packages/cli/src/controller/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ import * as ApiController from "./ApiController";
import { routes } from "../constants/router";

export const create = (app: express.Application, service: Service.Type, config: Config.Type) => {
app.get(routes.index.path, (req, res) => {
res.redirect(routes.project.path);
});
app.use(routes.project.path, ProjectController.create(service, config));
app.use(routes.assets.path, AssetController.create());
app.use(routes.api.path, ApiController.create(service, config));
Expand Down
2 changes: 2 additions & 0 deletions packages/cli/src/exceptions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@ abstract class BaseCustomError extends Error {
}

export class SourcePathInvalidError extends BaseCustomError {}

export class CliArgumentError extends BaseCustomError {}
11 changes: 10 additions & 1 deletion packages/cli/src/exporter/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,16 @@ export const create = (service: Service.Type, config: Config.Type, isDryRun: boo
const generateStaticHtml = async (pathname: string, publicPath: string, assets: View.Assets): Promise<string> => {
const url = path.join("/", pathname.replace(path.extname(pathname), ""));
const dotSource = service.dependencyCruiser.getDependenciesDot(path.join(config.absoluteRootDirPath, pathname));
const view = await View.create(url, publicPath, pathname, dotSource, config.filePathList, assets);
const view = await View.create(
url,
publicPath,
pathname,
dotSource,
service.renderer.renderToString,
config.filePathList,
assets,
config.rendererType,
);
return "<!DOCTYPE html>" + ReactDOM.renderToStaticMarkup(view);
};

Expand Down
Loading

0 comments on commit 40245db

Please sign in to comment.