Skip to content

Commit 546446f

Browse files
authored
Merge pull request #71 from snyk/chore/osm-2746-improve-maintainability
feat: [OSM-2746] improve maintainability
2 parents cdbc13e + e1aae07 commit 546446f

13 files changed

+350
-244
lines changed

.circleci/config.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@ windows_defaults: &windows_defaults
2020
test_matrix_unix: &test_matrix_unix
2121
matrix:
2222
parameters:
23-
node_version: [ '16.18', '18.18', '20.9' ]
23+
node_version: [ '18.18', '20.9', '22.0' ]
2424

2525
test_matrix_win: &test_matrix_win
2626
matrix:
2727
parameters:
28-
node_version: [ '16', '18', '20' ]
28+
node_version: [ '18', '20', '22' ]
2929

3030
commands:
3131
install_deps:

.eslintrc.json

Lines changed: 0 additions & 23 deletions
This file was deleted.

.prettierrc.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"arrowParens": "always",
3+
"trailingComma": "all",
4+
"singleQuote": true,
5+
"htmlWhitespaceSensitivity": "ignore"
6+
}

eslint.config.mjs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import eslint from '@eslint/js';
2+
import stylisticTs from '@stylistic/eslint-plugin-ts'
3+
import tseslint from 'typescript-eslint';
4+
5+
export default tseslint.config({
6+
files: ['**/*.ts'],
7+
extends: [
8+
eslint.configs.recommended,
9+
tseslint.configs.recommended,
10+
],
11+
languageOptions: {
12+
parserOptions: {
13+
parser: '@typescript-eslint/parser',
14+
project: "./tsconfig.json"
15+
},
16+
},
17+
plugins: {
18+
'@stylistic/ts': stylisticTs,
19+
'@typescript-eslint': tseslint.plugin,
20+
},
21+
rules: {
22+
"indent": "off",
23+
"@stylistic/ts/indent": ["error", 2],
24+
"@typescript-eslint/await-thenable": 2,
25+
"@typescript-eslint/ban-ts-comment": 2,
26+
"@typescript-eslint/explicit-function-return-type": 0,
27+
"@typescript-eslint/no-explicit-any": 0,
28+
"@typescript-eslint/no-require-imports": 2,
29+
"@typescript-eslint/no-unnecessary-type-assertion": 2,
30+
"@typescript-eslint/promise-function-async": 2,
31+
"@typescript-eslint/unbound-method": 2
32+
},
33+
});

jest.config.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/** @type {import('ts-jest').JestConfigWithTsJest} **/
2+
module.exports = {
3+
testEnvironment: "node",
4+
transform: {
5+
"^.+\.tsx?$": ["ts-jest",{}],
6+
},
7+
};

lib/composer-cmds.ts

Lines changed: 47 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,65 @@
11
import * as path from 'path';
22
import * as childProcess from 'child_process';
33

4-
export const composerVersionCmd = {command: 'composer', args: ['--version']};
5-
export const composerShowCmd = {command: 'composer', args: ['show', '-p']};
6-
export const pharVersionCmd = {
7-
command: `php`,
8-
args: [`${path.resolve(path.resolve() + '/composer.phar')}`, '--version']
4+
type Command = {
5+
command: string;
6+
args: string[];
97
};
10-
export const pharShowCmd = {
11-
command: `php`,
12-
args: [`${path.resolve(path.resolve() + '/composer.phar')}`, 'show', '-p', '--format=json']
8+
9+
function versionCmd(this: Command): Command {
10+
return {
11+
command: this.command,
12+
args: [...this.args, '--version'],
13+
};
14+
}
15+
16+
function listPlatformDepsCmd(this: Command): Command {
17+
return {
18+
command: this.command,
19+
args: [...this.args, 'show', '-p', '--format=json'],
20+
};
21+
}
22+
23+
export const globalComposer = {
24+
command: 'composer',
25+
args: [],
26+
version: versionCmd,
27+
listPlatformDeps: listPlatformDepsCmd,
28+
};
29+
export const localComposer = {
30+
command: 'php',
31+
args: [`${path.resolve(path.resolve() + '/composer.phar')}`],
32+
version: versionCmd,
33+
listPlatformDeps: listPlatformDepsCmd,
1334
};
1435

1536
function cleanUpComposerWarnings(composerOutput: string): string {
16-
// Remove all lines preceding the JSON data; including Deprecation messages and blank lines.
37+
// Remove all lines preceding the JSON data; including "Deprecated" messages and blank lines.
1738
const lines = composerOutput.split('\n');
18-
const jsonStartIndex = lines.findIndex((line) => line.length > 0 && !line.startsWith('Deprecated:'));
39+
const jsonStartIndex = lines.findIndex((line) => line.startsWith('{'));
1940

2041
return lines.slice(jsonStartIndex).join('\n');
2142
}
2243

23-
export function cmdReturnsOk(cmd: string, args: string[] = []): boolean {
24-
const spawnOptions: childProcess.SpawnOptions = {shell: false};
25-
return !!cmd && childProcess.spawnSync(cmd, args, spawnOptions).status === 0;
44+
export function cmdReturnsOk(cmd: Command): boolean {
45+
const spawnOptions: childProcess.SpawnOptions = { shell: false };
46+
return (
47+
!!cmd &&
48+
childProcess.spawnSync(cmd.command, cmd.args, spawnOptions).status === 0
49+
);
2650
}
2751

2852
// run a cmd in a specific folder and it's result should be there
29-
export function execWithResult(cmd: string, basePath: string, args: string[] = []): string {
30-
const spawnOptions: childProcess.SpawnOptions = {cwd: basePath, shell: false}
31-
const execResult = childProcess.spawnSync(cmd, args, spawnOptions);
53+
export function execWithResult(cmd: Command, basePath: string): string {
54+
const spawnOptions: childProcess.SpawnOptions = {
55+
cwd: basePath,
56+
shell: false,
57+
};
58+
const execResult = childProcess.spawnSync(
59+
cmd.command,
60+
cmd.args,
61+
spawnOptions,
62+
);
3263

3364
// Throw the whole Result object in case of error, similarly to `execSync`.
3465
if (execResult.status !== 0) {

lib/index.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,18 @@ import { PhpPluginResult, PhpOptions } from './types';
55

66
const PLUGIN_NAME = 'snyk-php-plugin';
77

8-
export async function inspect(basePath: string, fileName: string, options: PhpOptions = {}): Promise<PhpPluginResult> {
8+
export async function inspect(
9+
basePath: string,
10+
fileName: string,
11+
options: PhpOptions = {},
12+
): Promise<PhpPluginResult> {
913
const systemVersions = systemDeps(basePath, options);
10-
const depsTree = composerLockFileParser.buildDepTreeFromFiles(basePath, fileName, systemVersions, options.dev);
14+
const depsTree = composerLockFileParser.buildDepTreeFromFiles(
15+
basePath,
16+
fileName,
17+
systemVersions,
18+
options.dev,
19+
);
1120

1221
return Promise.resolve({
1322
package: depsTree,

lib/system-deps.ts

Lines changed: 18 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,33 @@
1-
import * as os from 'os';
21
import { SystemPackages } from '@snyk/composer-lockfile-parser';
32

43
import * as cmds from './composer-cmds';
54
import { PhpOptions } from './types';
65

7-
function isSet(variable): boolean {
8-
return typeof variable !== 'undefined';
9-
}
10-
11-
export function systemDeps(basePath: string, options: PhpOptions): SystemPackages {
12-
const composerOk = isSet(options.composerIsFine) ?
13-
options.composerIsFine : cmds.cmdReturnsOk(cmds.composerVersionCmd.command, cmds.composerVersionCmd.args);
14-
const composerPharOk = isSet(options.composerPharIsFine) ?
15-
options.composerPharIsFine : cmds.cmdReturnsOk(cmds.pharVersionCmd.command, cmds.pharVersionCmd.args);
6+
export function systemDeps(
7+
basePath: string,
8+
options: PhpOptions,
9+
): SystemPackages {
10+
const composerOk =
11+
options.composerIsFine ?? cmds.cmdReturnsOk(cmds.globalComposer.version());
12+
const composerPharOk =
13+
options.composerPharIsFine ??
14+
cmds.cmdReturnsOk(cmds.localComposer.version());
1615

1716
let finalVersionsObj = {};
1817

19-
if (options.systemVersions && (Object.keys(options.systemVersions).length > 0)) {
18+
if (
19+
options.systemVersions &&
20+
Object.keys(options.systemVersions).length > 0
21+
) {
2022
// give first preference to a stub
2123
finalVersionsObj = options.systemVersions;
22-
} else if (composerOk) {
23-
const lines = cmds.execWithResult(cmds.composerShowCmd.command, basePath, cmds.composerShowCmd.args).split(os.EOL);
24-
lines.forEach((line) => {
25-
const [part1, part2] = line.split(/\s+/);
26-
if (part2) {
27-
finalVersionsObj[part1] = part2;
28-
}
29-
});
30-
} else if (composerPharOk) {
31-
const output = cmds.execWithResult(cmds.pharShowCmd.command, basePath, cmds.pharShowCmd.args);
24+
} else if (composerOk || composerPharOk) {
25+
const composer = composerOk ? cmds.globalComposer : cmds.localComposer;
26+
27+
const output = cmds.execWithResult(composer.listPlatformDeps(), basePath);
3228
const versionsObj = JSON.parse(output).platform;
3329

34-
versionsObj.forEach(({name, version}) => {
30+
versionsObj.forEach(({ name, version }) => {
3531
finalVersionsObj[name] = version;
3632
});
3733
} else {

package.json

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,14 @@
55
"scripts": {
66
"build": "tsc",
77
"build-watch": "tsc -w",
8-
"lint": "eslint {lib,test}/**/*.ts",
8+
"lint": "npm run lint:js && npm run lint:format",
9+
"lint:js": "eslint {lib,test}/**/*.ts",
10+
"lint:format": "prettier --check '{lib,test}/**/*.ts'",
11+
"format": "prettier --write '{lib,test}/**/*.ts'",
912
"prepare": "npm run build",
1013
"semantic-release": "semantic-release",
1114
"test": "npm run lint && npm run unit-test",
12-
"unit-test": "tap -Rspec test/*.test.ts --timeout=300"
15+
"unit-test": "jest --testTimeout=500"
1316
},
1417
"files": [
1518
"dist",
@@ -23,21 +26,23 @@
2326
"author": "Snyk <https://snyk.io>",
2427
"license": "Apache-2.0",
2528
"engines": {
26-
"node": ">=8"
29+
"node": ">=18"
2730
},
2831
"dependencies": {
2932
"@snyk/cli-interface": "^2.9.1",
3033
"@snyk/composer-lockfile-parser": "^1.4.1",
3134
"@snyk/dep-graph": "^1.22.0",
32-
"tslib": "1.14.1"
35+
"tslib": "^2.8.1"
3336
},
3437
"devDependencies": {
35-
"@types/node": "6.14.6",
36-
"@typescript-eslint/eslint-plugin": "1.10.2",
37-
"@typescript-eslint/parser": "1.10.2",
38-
"eslint": "5.16.0",
39-
"sync-request": "3.0.1",
40-
"tap": "12.7.0",
41-
"typescript": "3.8.3"
38+
"@stylistic/eslint-plugin-ts": "^4.2.0",
39+
"@types/node": "^22.15.2",
40+
"@typescript-eslint/parser": "^8.31.0",
41+
"eslint": "9.25.1",
42+
"eslint-config-prettier": "^10.1.2",
43+
"prettier": "^3.5.3",
44+
"ts-jest": "^29.3.2",
45+
"typescript": "5.8.3",
46+
"typescript-eslint": "^8.31.0"
4247
}
4348
}

0 commit comments

Comments
 (0)