Skip to content

Commit

Permalink
Fix json output with ansi and line breaks (#406)
Browse files Browse the repository at this point in the history
* Add option to not generate ansi code

* Swap ts-node for swc-node for faster development

* Add option to hide legend

* Add swc/core dependency
  • Loading branch information
academo authored Jan 29, 2024
1 parent 1402850 commit fa3c331
Show file tree
Hide file tree
Showing 5 changed files with 873 additions and 822 deletions.
8 changes: 4 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,11 @@ Levitate consists of two commands _compare_ and _list-imports_. Developing again
- Use `DEBUG=*` to display debugging messages
- Use `LEVITATE_CACHE=1` to re-use downloaded npm packages.

### Run with ts-node for faster iteration
### Run with swc-node for faster iteration

You can run directly from the source with `ts-node`. e.g:
You can run directly from the source with `swc-node`. e.g:

` node --loader ts-node/esm --inspect ./src/bin.ts compare --prev @grafana/schema@9.0.7 --current @grafana/schema@latest`
`node -r @swc-node/register src/bin.ts --inspect ./src/bin.ts compare --prev @grafana/schema@9.0.7 --current @grafana/schema@latest`

### Fixtures for common development cases and test

Expand All @@ -109,6 +109,7 @@ The `./fixtures/` directory contains several fixtures examples of common and edg
List of available fixtures:

#### compare

Files to test the compare command. e.g.: `node ./dist/bin.js compare --prev ./fixtures/compare/bundle-old.ts --current ./fixtures/compare/bundle-new.ts`

#### exports
Expand All @@ -125,7 +126,6 @@ Files to test the `getUsageInfo` API. These files are used inside the unit tests

You can run, for example, `is-compatible` in the `grafana-plugin` fixture and modify it at will to test more use cases.


## Contribute Documentation

Documentation is a super important, critical part of this project. Docs are how we keep track of what we're doing, how, and why. It's how we stay on the same page about our policies. And it's how we tell others everything they need in order to be able to use this project -- or contribute to it. So thank you in advance.
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@
},
"devDependencies": {
"@grafana/eslint-config": "^7.0.0",
"@swc-node/register": "^1.6.8",
"@swc/core": "^1.3.107",
"@types/debug": "^4.1.7",
"@types/diff": "^5.0.2",
"@types/jest": "^29.5.11",
Expand All @@ -66,7 +68,6 @@
"npm-run-all": "^4.1.5",
"prettier": "^3.1.1",
"ts-jest": "^29.1.1",
"ts-node": "^10.9.1",
"tsc-watch": "^6.0.4"
},
"nodemonConfig": {
Expand All @@ -92,4 +93,4 @@
"url": "https://github.com/grafana/levitate/issues"
},
"homepage": "https://github.com/grafana/levitate#readme"
}
}
1 change: 1 addition & 0 deletions src/print/comparison-json.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ function printJsonChanges(changes: Comparison['changes']) {
symbol: changes[name].current,
program: changes[name].currentProgram,
},
options: { useAnsi: false, showLegend: false },
}),
}));
}
75 changes: 48 additions & 27 deletions src/utils/diff.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,64 +3,85 @@ import * as diff from 'diff';
import { getFunctionParametersDiff, isFunction, isMethod } from '../commands/compare/compare';
import { ChangeType, SymbolMeta } from '../types';

function getDiffLegend() {
return '\n' + chalk.green('+ Added') + ' ' + chalk.red('- Removed') + '\n' + '\n';
type DiffOptions = {
useAnsi?: boolean;
showLegend?: boolean;
};

const defaultOptions: DiffOptions = {
useAnsi: true,
showLegend: true,
};

function getDiffLegend(options: DiffOptions = defaultOptions) {
const added = options.useAnsi ? chalk.green('+ Added') : '+ Added' + '\n';
const removed = options.useAnsi ? chalk.red('- Removed') : '- Removed' + '\n';
return `\n${added}${removed}\n\n`;
}

export function getDiff(prev: string, current: string) {
export function getDiff(prev: string, current: string, options: DiffOptions = defaultOptions) {
const patch = diff.createPatch('string', prev, current);

// @TODO type this and add tests
const lines = patch
.split('\n')
.slice(4)
.map(getDiffForLine)
.map((line) => {
switch (line[0]) {
// Added lines
case '+':
return options.useAnsi ? chalk.green(line) : line;
// Removed lines
case '-':
return options.useAnsi ? chalk.red(line) : line;
case ' ':
return line;
case '@':
return null;
case '\\':
return null;
}
})
.filter((line) => line !== null);

if (lines.length === 0 || !lines[0]) {
return '';
}

return getDiffLegend() + lines.join('\n') + '\n';
if (!options.showLegend) {
return lines.join('\n');
}
return getDiffLegend(options) + lines.join('\n') + '\n';
}

export function getSymbolDiff({ prev, current }: { prev: SymbolMeta; current: SymbolMeta }) {
export function getSymbolDiff({
prev,
current,
options = defaultOptions,
}: {
prev: SymbolMeta;
current: SymbolMeta;
options?: DiffOptions;
}) {
const prevDeclaration = prev.symbol.declarations[0].getText();
const currentDeclaration = current.symbol.declarations[0].getText();

if ((isFunction(prev.symbol) && isFunction(current.symbol)) || (isMethod(prev.symbol) && isMethod(current.symbol))) {
const functionDiffText = getDiff(prevDeclaration, currentDeclaration);
const functionDiffText = getDiff(prevDeclaration, currentDeclaration, options);
let paramsDiffText = '';
const parametersDiff = getFunctionParametersDiff({ prev, current });
if (parametersDiff && parametersDiff.type === ChangeType.PARAMETER_TYPE) {
paramsDiffText += chalk.yellow('Parameter type changed:\n');
try {
paramsDiffText += getDiff(
parametersDiff.prev.declarations[0].getText(),
parametersDiff.current.declarations[0].getText()
parametersDiff.current.declarations[0].getText(),
options
);
} catch (e) {
paramsDiffText = 'parameters -+-+-+-';
}
}
return functionDiffText + paramsDiffText;
}
return getDiff(prevDeclaration, currentDeclaration);
}

function getDiffForLine(line: any) {
switch (line[0]) {
// Added lines
case '+':
return chalk.green(line);
// Removed lines
case '-':
return chalk.red(line);
case ' ':
return line;
case '@':
return null;
case '\\':
return null;
}
return getDiff(prevDeclaration, currentDeclaration, options);
}
Loading

0 comments on commit fa3c331

Please sign in to comment.