Skip to content

Commit

Permalink
Feat(analytics): Introduce scanner type option
Browse files Browse the repository at this point in the history
  * you can easily switch to use `react` or `twig` scanner, or both

refs #DS-874
  • Loading branch information
literat committed Nov 29, 2023
1 parent b48b386 commit b292f8c
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 21 deletions.
48 changes: 45 additions & 3 deletions packages/analytics/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ yarn add -D @lmc-eu/spirit-analytics

## Usage

Running the command without arguments will use working directory as a root and parse entire directory structure from this point
Running the command without arguments will use the working directory as a root and parse the entire directory structure from this point.

```shell
spirit-analytics
Expand All @@ -29,19 +29,61 @@ You can parse only specific directories from the project with `--source` argumen
spirit-analytics --source ./frontend
```

By default the output will be saved into `.scanner` directory, but you can specify the path with `--output` argument:
By default, the output will be saved into the `.scanner` directory, but you can specify the path with the `--output` argument:

```shell
spirit-analytics --output path/to/folder
```

The [react-scanner] requires a [config file][react-scanner-config] to make it work, spirit-analytics has a default config inside, but if you will need, you can use your own config:
The [react-scanner] requires a [config file][react-scanner-config] to make it work, `spirit-analytics` has a default config inside, but if you need to, you can use your own config:

```shell
spirit-analytics --config path/to/config
```

You can easily switch from React scanner to Twig scanner using `type` argument. By default, both scanners will be used.

```shell
spirit-analytics --type react
```

You can run `spirit-analytics --help` to get a list of available options and examples.

## Configuration

You can provide your own configuration file in the following format:

```js
export default {
react: {
// react-scanner config; @see https://www.npmjs.com/package/react-scanner#config-file
},
twig: {
crawlFrom: './',
exclude: ['node_modules', 'dist', 'build', 'coverage', 'public', 'vendor', 'storybook-static'],
configFile: './config/spirit-web-twig.yml',
outputFile: './.scanner/adoption-data-twig.json',
coreComponentsPath: './vendor/lmc/spirit-web-twig-bundle/src/Resources/twig-components',
},
};
```

### Configuration Options

#### React

👉 [`react-scanner` Configuration Options][react-scanner-config-options]

#### Twig

| Option | Type | Description |
| ------------------ | --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| crawlFrom | `string` | The path of the directory to start crawling from. |
| exclude | `array` or `function` | Each array item should be a string or a regex. When crawling, if directory name matches exactly the string item or matches the regex item, it will be excluded from crawling. For more complex scenarios, exclude can be a a function that accepts a directory name and should return true if the directory should be excluded from crawling. |
| configFile | `string` | Path to the local `spirit-web-twig.yml` configuration file. |
| outputFile | `string` | Path to the file where the result of the analysis will be stored. |
| coreComponentsPath | `string` | Path to the directory where are core Spirit components installed. |

[react-scanner]: https://github.com/moroshko/react-scanner
[react-scanner-config]: https://github.com/moroshko/react-scanner#config-file
[react-scanner-config-options]: https://www.npmjs.com/package/react-scanner#config-options
2 changes: 1 addition & 1 deletion packages/analytics/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"access": "public",
"directory": "dist"
},
"main": "./index.js",
"main": "./index.cjs",
"module": "./index.js",
"types": "./index.d.ts",
"bin": "./bin/spirit-analytics.js",
Expand Down
3 changes: 2 additions & 1 deletion packages/analytics/src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { fs, path } from 'zx';
import { ROOT_PATH } from './constants';
import { _dirname, errorMessage, infoMessage } from './helpers';
import scanner from './scanner';
import { ScannerType } from './types';

const packageJson = fs.readJsonSync(path.resolve(_dirname, './package.json'));

Expand Down Expand Up @@ -46,7 +47,7 @@ export default async function cli(args: string[]) {
}

if (source) {
scanner({ source, outputPath: output, config: loadedConfig });
scanner({ source, outputPath: output, config: loadedConfig, type: selectedType });
infoMessage(`Start scanning: ${source}`);
} else {
scanner({
Expand Down
6 changes: 3 additions & 3 deletions packages/analytics/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ export const OUTPUT_FILENAME_PREFIX = 'spirit-analytics';
export const OUTPUT_DIR = '.scanner';
export const ROOT_PATH = '.';
export const REACT_OUTPUT_FILE = 'adoption-data-react.json';
export const TWIG_OUTPUT_FILE = '../.scanner/adoption-data-twig.json';
export const TWIG_CORE_COMPONENTS_PATH = '../vendor/lmc/spirit-web-twig-bundle/src/Resources/twig-components';
export const TWIG_CONFIG_FILE = '../config/spirit-web-twig.yml';
export const TWIG_OUTPUT_FILE = './.scanner/adoption-data-twig.json';
export const TWIG_CORE_COMPONENTS_PATH = './vendor/lmc/spirit-web-twig-bundle/src/Resources/twig-components';
export const TWIG_CONFIG_FILE = './config/spirit-web-twig.yml';
20 changes: 13 additions & 7 deletions packages/analytics/src/runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ import { _dirname } from './helpers';
import { getVersions } from './helpers/versions';
import reactScanner from './scanners/reactScanner';
import twigScanner from './scanners/twigScanner';
import { RunnerConfig, TrackedData } from './types';
import { RunnerConfig, ScannerType, TrackedData } from './types';

interface ProjectOutput {
spiritVersion: string;
trackedData: TrackedData;
}

type Runner = (config: RunnerConfig, source: string) => Promise<ProjectOutput>;
type Runner = (config: RunnerConfig, source: string, type: ScannerType) => Promise<ProjectOutput>;

const getTrackedData = async ({
config,
Expand All @@ -25,20 +25,26 @@ const getTrackedData = async ({
}): Promise<ProjectOutput> => {
const crawlFrom = path.resolve(source) || path.resolve(_dirname, ROOT_PATH);
const spiritVersion = await getVersions(crawlFrom);
let reactOutput = {};
let twigOutput = {};

const reactOutput = await reactScanner({ ...config, crawlFrom });
if (type === 'react' || type === null) {
reactOutput = await reactScanner({ ...config, crawlFrom });
}

const twigResult = await twigScanner({ ...config, crawlFrom });
if (type === 'twig' || type === null) {
twigOutput = await twigScanner({ ...config, crawlFrom });
}

return {
spiritVersion,
trackedData: {
...reactOutput,
...twigResult,
...twigOutput,
},
};
};

export const runner: Runner = (config, source) => {
return getTrackedData({ config, source });
export const runner: Runner = (config, source, type) => {
return getTrackedData({ config, source, type });
};
11 changes: 6 additions & 5 deletions packages/analytics/src/scanner.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { fs } from 'zx';
import { errorMessage, getOutputPath, infoMessage, timestamp } from './helpers';
import { runner } from './runner';
import { RunnerConfig } from './types';
import { RunnerConfig, ScannerType } from './types';

interface BaseArgs {
outputPath: string;
Expand All @@ -11,10 +11,11 @@ interface BaseArgs {

interface Args extends BaseArgs {
source: string;
type: ScannerType;
}

export const getRunnerCall = async ({ outputPath, config, source }: Args) => {
const result = await runner(config, source);
export const getRunnerCall = async ({ outputPath, config, source, type }: Args) => {
const result = await runner(config, source, type);

if (outputPath) {
fs.writeFile(getOutputPath(outputPath, timestamp()), JSON.stringify(result, null, 2), 'utf8').then(() => {
Expand All @@ -26,9 +27,9 @@ export const getRunnerCall = async ({ outputPath, config, source }: Args) => {
}
};

async function scanner({ source, outputPath, config }: Args) {
async function scanner({ source, outputPath, config, type }: Args) {
try {
await getRunnerCall({ outputPath, config, source });
await getRunnerCall({ outputPath, config, source, type });
} catch (err) {
errorMessage(`\n ${err}`);
}
Expand Down
4 changes: 3 additions & 1 deletion packages/analytics/src/scanners/twigScanner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ export async function getLocalComponentsFromPaths(paths: Array<string>): Promise
(file: string) => path.basename(file).charAt(0).toUpperCase() + path.basename(file).slice(1, -5),
);
}

return [];
});
}

Expand Down Expand Up @@ -123,7 +125,7 @@ function searchDirectoryForComponents(
localComponents: Array<string>,
baseComponents: Array<string>,
exclude: Array<string>,
): void | Result {
): Result {
let result: Result = {};

if (!exclude.includes(path.basename(dir))) {
Expand Down
2 changes: 2 additions & 0 deletions packages/analytics/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,5 @@ export interface RunnerConfig {
startTime?: string;
method?: string;
}

export type ScannerType = 'react' | 'twig' | null;

0 comments on commit b292f8c

Please sign in to comment.