Skip to content

Commit 738ad61

Browse files
committed
Python report creation
1 parent f1339ac commit 738ad61

2 files changed

Lines changed: 56 additions & 40 deletions

File tree

lib/utils/path-resolve.js

Lines changed: 54 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -5,29 +5,35 @@ import { globby } from 'globby'
55
import ignore from 'ignore'
66
// @ts-ignore This package provides no types
77
import { directories } from 'ignore-by-default'
8+
import micromatch from 'micromatch'
89
import { ErrorWithCause } from 'pony-cause'
910

1011
import { InputError } from './errors.js'
12+
import { setupSdk } from './sdk.js'
1113
import { isErrnoException } from './type-helpers.js'
1214

13-
/** @type {readonly string[]} */
14-
const SUPPORTED_LOCKFILES = [
15-
'package-lock.json',
16-
'yarn.lock',
17-
]
18-
1915
/**
2016
* There are a lot of possible folders that we should not be looking in and "ignore-by-default" helps us with defining those
2117
*
2218
* @type {readonly string[]}
2319
*/
2420
const ignoreByDefault = directories()
2521

26-
/** @type {readonly string[]} */
22+
/** @type { string[]} */
2723
const GLOB_IGNORE = [
2824
...ignoreByDefault.map(item => '**/' + item)
2925
]
3026

27+
/** @type {import('globby').Options} */
28+
const BASE_GLOBBY_OPTS = {
29+
absolute: true,
30+
expandDirectories: false,
31+
gitignore: true,
32+
ignore: GLOB_IGNORE,
33+
markDirectories: true,
34+
unique: true,
35+
}
36+
3137
/**
3238
* Resolves package.json and lockfiles from (globbed) input paths, applying relevant ignores
3339
*
@@ -43,14 +49,9 @@ export async function getPackageFiles (cwd, inputPaths, config, debugLog) {
4349

4450
// TODO: Does not support `~/` paths
4551
const entries = await globby(inputPaths, {
46-
absolute: true,
52+
...BASE_GLOBBY_OPTS,
4753
cwd,
48-
expandDirectories: false,
49-
gitignore: true,
50-
ignore: [...GLOB_IGNORE],
51-
markDirectories: true,
52-
onlyFiles: false,
53-
unique: true,
54+
onlyFiles: false
5455
})
5556

5657
debugLog(`Globbed resolved ${inputPaths.length} paths to ${entries.length} paths:`, entries)
@@ -77,7 +78,12 @@ export async function getPackageFiles (cwd, inputPaths, config, debugLog) {
7778
* @throws {InputError}
7879
*/
7980
export async function mapGlobResultToFiles (entries) {
80-
const packageFiles = await Promise.all(entries.map(mapGlobEntryToFiles))
81+
// TODO: setupSdk(getDefaultKey() || FREE_API_KEY) after #46 merged
82+
const sdk = await setupSdk()
83+
const supportedFiles = await sdk.getReportSupportedFiles()
84+
const packageFiles = await Promise.all(
85+
entries.map(entry => mapGlobEntryToFiles(entry, supportedFiles))
86+
)
8187

8288
const uniquePackageFiles = [...new Set(packageFiles.flat())]
8389

@@ -88,46 +94,54 @@ export async function mapGlobResultToFiles (entries) {
8894
* Takes a single path to a folder, package.json or a recognized lock file and resolves to a package.json + lockfile pair (where possible)
8995
*
9096
* @param {string} entry
97+
* @param {import('@socketsecurity/sdk').SocketSdkReturnType<'getReportSupportedFiles'>['data']} supportedFiles
9198
* @returns {Promise<string[]>}
9299
* @throws {InputError}
93100
*/
94-
export async function mapGlobEntryToFiles (entry) {
101+
export async function mapGlobEntryToFiles (entry, supportedFiles) {
95102
/** @type {string|undefined} */
96-
let pkgFile
97-
/** @type {string|undefined} */
98-
let lockFile
99-
103+
let pkgJSFile
104+
/** @type {string[]} */
105+
let jsLockFiles = []
106+
/** @type {string[]} */
107+
let pyFiles = []
108+
109+
const jsSupported = supportedFiles['npm'] || {}
110+
const jsLockFilePatterns = Object.keys(jsSupported)
111+
.filter(key => key !== 'packagejson')
112+
.map(key => /** @type {{ pattern: string }} */ (jsSupported[key]).pattern)
113+
114+
const pyFilePatterns = Object.values(supportedFiles['pypi'] || {}).map(p => p.pattern)
100115
if (entry.endsWith('/')) {
101116
// If the match is a folder and that folder contains a package.json file, then include it
102117
const filePath = path.resolve(entry, 'package.json')
103-
pkgFile = await fileExists(filePath) ? filePath : undefined
118+
if (await fileExists(filePath)) pkgJSFile = filePath
119+
pyFiles = await globby(pyFilePatterns, {
120+
...BASE_GLOBBY_OPTS,
121+
cwd: entry
122+
})
104123
} else if (path.basename(entry) === 'package.json') {
105124
// If the match is a package.json file, then include it
106-
pkgFile = entry
107-
} else if (SUPPORTED_LOCKFILES.includes(path.basename(entry))) {
108-
// If the match is a lock file, include both it and the corresponding package.json file
109-
lockFile = entry
110-
pkgFile = path.resolve(path.dirname(entry), 'package.json')
125+
pkgJSFile = entry
126+
} else if (micromatch.isMatch(entry, jsLockFilePatterns)) {
127+
jsLockFiles = [entry]
128+
pkgJSFile = path.resolve(path.dirname(entry), 'package.json')
129+
if (!(await fileExists(pkgJSFile))) return []
130+
} else if (micromatch.isMatch(entry, pyFilePatterns)) {
131+
pyFiles = [entry]
111132
}
112133

113134
// If we will include a package.json file but don't already have a corresponding lockfile, then look for one
114-
if (!lockFile && pkgFile) {
115-
const pkgDir = path.dirname(pkgFile)
116-
117-
for (const name of SUPPORTED_LOCKFILES) {
118-
const lockFileAlternative = path.resolve(pkgDir, name)
119-
if (await fileExists(lockFileAlternative)) {
120-
lockFile = lockFileAlternative
121-
break
122-
}
123-
}
124-
}
135+
if (!jsLockFiles.length && pkgJSFile) {
136+
const pkgDir = path.dirname(pkgJSFile)
125137

126-
if (pkgFile && lockFile) {
127-
return [pkgFile, lockFile]
138+
jsLockFiles = await globby(jsLockFilePatterns, {
139+
...BASE_GLOBBY_OPTS,
140+
cwd: pkgDir
141+
})
128142
}
129143

130-
return pkgFile ? [pkgFile] : []
144+
return [...jsLockFiles, ...pyFiles].concat(pkgJSFile ? [pkgJSFile] : [])
131145
}
132146

133147
/**

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
"@tsconfig/node14": "^1.0.3",
4848
"@types/chai": "^4.3.3",
4949
"@types/chai-as-promised": "^7.1.5",
50+
"@types/micromatch": "^4.0.2",
5051
"@types/mocha": "^10.0.1",
5152
"@types/mock-fs": "^4.13.1",
5253
"@types/node": "^14.18.31",
@@ -93,6 +94,7 @@
9394
"is-interactive": "^2.0.0",
9495
"is-unicode-supported": "^1.3.0",
9596
"meow": "^11.0.0",
97+
"micromatch": "^4.0.5",
9698
"ora": "^6.1.2",
9799
"pony-cause": "^2.1.8",
98100
"prompts": "^2.4.2",

0 commit comments

Comments
 (0)