Skip to content

Commit 1468799

Browse files
authored
Merge pull request #12 from SocketDev/add-glob-and-ignore
Add globbing and ignore support
2 parents fd61bc9 + 1867a8a commit 1468799

File tree

13 files changed

+642
-138
lines changed

13 files changed

+642
-138
lines changed

.eslintrc

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
{
22
"root": true,
3-
"plugins": ["jsdoc"],
3+
"plugins": [
4+
"jsdoc",
5+
"unicorn"
6+
],
47
"extends": [
58
"@socketsecurity",
69
"plugin:jsdoc/recommended"
@@ -24,6 +27,8 @@
2427
"jsdoc/require-property-description": "off",
2528
"jsdoc/require-returns-description": "off",
2629
"jsdoc/require-yields": "off",
27-
"jsdoc/valid-types": "off"
30+
"jsdoc/valid-types": "off",
31+
32+
"unicorn/expiring-todo-comments": "warn"
2833
}
2934
}

.github/workflows/nodejs.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,6 @@ jobs:
2525
no-lockfile: true
2626
npm-test-script: 'test-ci'
2727
node-versions: '14,16,18,19'
28-
os: 'ubuntu-latest,windows-latest'
28+
# We currently have some issues on Windows that will have to wait to be fixed
29+
# os: 'ubuntu-latest,windows-latest'
30+
os: 'ubuntu-latest'

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
/node_modules
55
/.env
66
/.nyc_output
7+
/.vscode
78

89
# We're a library, so please, no lock files
910
/package-lock.json
@@ -15,3 +16,4 @@
1516
!/lib/types/**/*.d.ts
1617

1718
# Library specific ones
19+
!/.vscode/extensions.json

.vscode/extensions.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"recommendations": [
3+
"ryanluker.vscode-coverage-gutters",
4+
"hbenl.vscode-test-explorer",
5+
"hbenl.vscode-mocha-test-adapter",
6+
"dbaeumer.vscode-eslint",
7+
"gruntfuggly.todo-tree",
8+
"editorconfig.editorconfig"
9+
]
10+
}

README.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,15 @@ socket report view QXU8PmK7LfH608RAwfIKdbcHgwEd_ZeWJ9QEGv05FJUQ
2222
## Commands
2323

2424
* `socket info <package@version>` - looks up issues for a package
25-
* `socket report create <path(s)-to-folder-or-file>` - uploads the specified `package.json` and/or `package-lock.json` to create a report on [socket.dev](https://socket.dev/). If only one of a `package.json`/`package-lock.json` has been specified, the other will be automatically found and uploaded if it exists
25+
26+
* `socket report create <path(s)-to-folder-or-file>` - creates a report on [socket.dev](https://socket.dev/)
27+
28+
Uploads the specified `package.json` and lock files and, if any folder is specified, the ones found in there. Also includes the complementary `package.json` and lock file to any specified. Currently `package-lock.json` and `yarn.lock` are supported.
29+
30+
Supports globbing such as `**/package.json`.
31+
32+
Ignores any file specified in your project's `.gitignore`, the `projectIgnorePaths` in your project's [`socket.yml`](https://docs.socket.dev/docs/socket-yml) and on top of that has a sensible set of [default ignores](https://www.npmjs.com/package/ignore-by-default)
33+
2634
* `socket report view <report-id>` - looks up issues and scores from a report
2735

2836
## Flags
@@ -48,6 +56,10 @@ socket report view QXU8PmK7LfH608RAwfIKdbcHgwEd_ZeWJ9QEGv05FJUQ
4856
* `--help` - prints the help for the current command. All CLI tools should have this flag
4957
* `--version` - prints the version of the tool. All CLI tools should have this flag
5058

59+
## Configuration files
60+
61+
The CLI reads and uses data from a [`socket.yml` file](https://docs.socket.dev/docs/socket-yml) in the folder you run it in. It supports the version 2 of the `socket.yml` file format and makes use of the `projectIgnorePaths` to excludes files when creating a report.
62+
5163
## Environment variables
5264

5365
* `SOCKET_SECURITY_API_KEY` - if set, this will be used as the API-key

lib/commands/report/create.js

Lines changed: 20 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,17 @@
11
/* eslint-disable no-console */
22

3-
import { stat } from 'node:fs/promises'
43
import path from 'node:path'
54

65
import meow from 'meow'
76
import ora from 'ora'
8-
import { ErrorWithCause } from 'pony-cause'
97

108
import { handleApiCall, handleUnsuccessfulApiResponse } from '../../utils/api-helpers.js'
119
import { ChalkOrMarkdown, logSymbols } from '../../utils/chalk-markdown.js'
12-
import { InputError } from '../../utils/errors.js'
1310
import { printFlagList } from '../../utils/formatting.js'
1411
import { createDebugLogger } from '../../utils/misc.js'
12+
import { getPackageFiles } from '../../utils/path-resolve.js'
1513
import { setupSdk } from '../../utils/sdk.js'
16-
import { isErrnoException } from '../../utils/type-helpers.js'
14+
import { readSocketConfig } from '../../utils/socket-config.js'
1715
import { fetchReportData, formatReportDataOutput } from './view.js'
1816

1917
/** @type {import('../../utils/meow-with-subcommands').CliSubcommand} */
@@ -80,6 +78,17 @@ async function setupCommand (name, description, argv, importMeta) {
8078
Usage
8179
$ ${name} <paths-to-package-folders-and-files>
8280
81+
Uploads the specified "package.json" and lock files and, if any folder is
82+
specified, the ones found in there. Also includes the complementary
83+
"package.json" and lock file to any specified. Currently "package-lock.json"
84+
and "yarn.lock" are supported.
85+
86+
Supports globbing such as "**/package.json".
87+
88+
Ignores any file specified in your project's ".gitignore", your project's
89+
"socket.yml" file's "projectIgnorePaths" and also has a sensible set of
90+
default ignores from the "ignore-by-default" module.
91+
8392
Options
8493
${printFlagList({
8594
'--all': 'Include all issues',
@@ -93,7 +102,7 @@ async function setupCommand (name, description, argv, importMeta) {
93102
94103
Examples
95104
$ ${name} .
96-
$ ${name} ../package-lock.json
105+
$ ${name} '**/package.json'
97106
$ ${name} /path/to/a/package.json /path/to/another/package.json
98107
$ ${name} . --view --json
99108
`, {
@@ -152,8 +161,12 @@ async function setupCommand (name, description, argv, importMeta) {
152161

153162
const debugLog = createDebugLogger(dryRun || cli.flags.debug)
154163

164+
// TODO: Allow setting a custom cwd and/or configFile path?
155165
const cwd = process.cwd()
156-
const packagePaths = await resolvePackagePaths(cwd, cli.input)
166+
const absoluteConfigPath = path.join(cwd, 'socket.yml')
167+
168+
const config = await readSocketConfig(absoluteConfigPath)
169+
const packagePaths = await getPackageFiles(cwd, cli.input, config, debugLog)
157170

158171
return {
159172
cwd,
@@ -174,7 +187,7 @@ async function setupCommand (name, description, argv, importMeta) {
174187
* @returns {Promise<void|import('@socketsecurity/sdk').SocketSdkReturnType<'createReport'>>}
175188
*/
176189
async function createReport (packagePaths, { cwd, debugLog, dryRun }) {
177-
debugLog(`${logSymbols.info} Uploading:`, packagePaths.join(`\n${logSymbols.info} Uploading:`))
190+
debugLog('Uploading:', packagePaths.join(`\n${logSymbols.info} Uploading: `))
178191

179192
if (dryRun) {
180193
return
@@ -210,113 +223,3 @@ function formatReportCreationOutput (data, { outputJson, outputMarkdown }) {
210223

211224
console.log('\nNew report: ' + format.hyperlink(data.id, data.url, { fallbackToUrl: true }))
212225
}
213-
214-
// TODO: Add globbing support with support for ignoring, as a "./**/package.json" in a project also traverses eg. node_modules
215-
/**
216-
* Takes paths to folders and/or package.json / package-lock.json files and resolves to package.json + package-lock.json pairs (where feasible)
217-
*
218-
* @param {string} cwd
219-
* @param {string[]} inputPaths
220-
* @returns {Promise<string[]>}
221-
* @throws {InputError}
222-
*/
223-
async function resolvePackagePaths (cwd, inputPaths) {
224-
const packagePathLookups = inputPaths.map(async (filePath) => {
225-
const packagePath = await resolvePackagePath(cwd, filePath)
226-
return findComplementaryPackageFile(packagePath)
227-
})
228-
229-
const packagePaths = await Promise.all(packagePathLookups)
230-
231-
const uniquePackagePaths = new Set(packagePaths.flat())
232-
233-
return [...uniquePackagePaths]
234-
}
235-
236-
/**
237-
* Resolves a package.json / package-lock.json path from a relative folder / file path
238-
*
239-
* @param {string} cwd
240-
* @param {string} inputPath
241-
* @returns {Promise<string>}
242-
* @throws {InputError}
243-
*/
244-
async function resolvePackagePath (cwd, inputPath) {
245-
const filePath = path.resolve(cwd, inputPath)
246-
/** @type {string|undefined} */
247-
let filePathAppended
248-
249-
try {
250-
const fileStat = await stat(filePath)
251-
252-
if (fileStat.isDirectory()) {
253-
filePathAppended = path.resolve(filePath, 'package.json')
254-
}
255-
} catch (err) {
256-
if (isErrnoException(err) && err.code === 'ENOENT') {
257-
throw new InputError(`Expected '${inputPath}' to point to an existing file or directory`)
258-
}
259-
throw new ErrorWithCause('Failed to resolve path to package.json', { cause: err })
260-
}
261-
262-
if (filePathAppended) {
263-
/** @type {import('node:fs').Stats} */
264-
let filePathAppendedStat
265-
266-
try {
267-
filePathAppendedStat = await stat(filePathAppended)
268-
} catch (err) {
269-
if (isErrnoException(err) && err.code === 'ENOENT') {
270-
throw new InputError(`Expected directory '${inputPath}' to contain a package.json file`)
271-
}
272-
throw new ErrorWithCause('Failed to resolve package.json in directory', { cause: err })
273-
}
274-
275-
if (!filePathAppendedStat.isFile()) {
276-
throw new InputError(`Expected '${filePathAppended}' to be a file`)
277-
}
278-
279-
return filePathAppended
280-
}
281-
282-
return filePath
283-
}
284-
285-
/**
286-
* Finds any complementary file to a package.json or package-lock.json
287-
*
288-
* @param {string} packagePath
289-
* @returns {Promise<string[]>}
290-
* @throws {InputError}
291-
*/
292-
async function findComplementaryPackageFile (packagePath) {
293-
const basename = path.basename(packagePath)
294-
const dirname = path.dirname(packagePath)
295-
296-
if (basename === 'package-lock.json') {
297-
// We need the package file as well
298-
return [
299-
packagePath,
300-
path.resolve(dirname, 'package.json')
301-
]
302-
}
303-
304-
if (basename === 'package.json') {
305-
const lockfilePath = path.resolve(dirname, 'package-lock.json')
306-
try {
307-
const lockfileStat = await stat(lockfilePath)
308-
if (lockfileStat.isFile()) {
309-
return [packagePath, lockfilePath]
310-
}
311-
} catch (err) {
312-
if (isErrnoException(err) && err.code === 'ENOENT') {
313-
return [packagePath]
314-
}
315-
throw new ErrorWithCause(`Unexpected error when finding a lockfile for '${packagePath}'`, { cause: err })
316-
}
317-
318-
throw new InputError(`Encountered a non-file at lockfile path '${lockfilePath}'`)
319-
}
320-
321-
throw new InputError(`Expected '${packagePath}' to point to a package.json or package-lock.json or to a folder containing a package.json`)
322-
}

lib/utils/misc.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
1+
import { logSymbols } from './chalk-markdown.js'
2+
13
/**
24
* @param {boolean|undefined} printDebugLogs
35
* @returns {typeof console.error}
46
*/
57
export function createDebugLogger (printDebugLogs) {
6-
if (printDebugLogs) {
8+
return printDebugLogs
79
// eslint-disable-next-line no-console
8-
return console.error.bind(console)
9-
}
10-
return () => {}
10+
? (...params) => console.error(logSymbols.info, ...params)
11+
: () => {}
1112
}
1213

1314
/**

0 commit comments

Comments
 (0)