Skip to content

Commit

Permalink
feat: more logs & configurable log level (#1131)
Browse files Browse the repository at this point in the history
## Changed
  * Log output is less verbose, can be re-enabled via CLI switch `--verbose`  
    Warnings and errors are still displayed as before.  
    This is considered a non-breaking change, since only informational logs and debug information is affected.
## Added
  * CLI switch `-v, --verbose` to increase output verbosity
    May be used multiple times, like `-vvv`.
  * More logs on info-level 
  * More logs on debug-level

fixes #158

---------

Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com>
  • Loading branch information
jkowalleck committed Dec 8, 2023
1 parent 0d684b9 commit 436c85d
Show file tree
Hide file tree
Showing 8 changed files with 89 additions and 14 deletions.
6 changes: 6 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ module.exports = {
],
parserOptions: {
project: './tsconfig.json'
},
rules: {
/* @see https://typescript-eslint.io/rules/unbound-method/ */
'@typescript-eslint/unbound-method': ['error', {
ignoreStatic: true
}]
}
},
{
Expand Down
4 changes: 2 additions & 2 deletions .github/ISSUE_TEMPLATE/ValidationError-report.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ Steps to reproduce the behavior:
<!-- upload the complete output to this issue, or a pastebin of you choice and put the link here. -->
4. Expected result:
<!-- run the original call again
with parameters `--no-validate --output-reproducible --output-file=-`,
then upload the output this issue, or to a pastebin of you choice and put the link here. -->
with parameters `-vvv --no-validate --output-reproducible --output-file=-`,
then upload all output to this issue, or to a pastebin of you choice and put the link here. -->

## Environment

Expand Down
12 changes: 11 additions & 1 deletion HISTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,18 @@ All notable changes to this project will be documented in this file.
## unreleased

* Changed
* Hardened JSON imports (via [#1132])
* Log output is less verbose, can be re-enabled via CLI switch `--verbose` ([#158] via [#1131])
Warnings and errors are still displayed as before.
This is considered a non-breaking change, since only informational logs and debug information is affected.
* Hardened JSON imports (via [#1132])
* Added
* CLI switch `-v, --verbose` to increase output verbosity ([#158] via [#1131])
May be used multiple times, like `-vvv`.
* More logs on info-level (via [#1131])
* More logs on debug-level (via [#1131])

[#158]: https://github.com/CycloneDX/cyclonedx-node-npm/issues/158
[#1131]: https://github.com/CycloneDX/cyclonedx-node-npm/pull/1131
[#1132]: https://github.com/CycloneDX/cyclonedx-node-npm/pull/1132

## 1.14.3 - 2023-12-01
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ Options:
--no-validate Disable validation of resulting BOM.
--mc-type <type> Type of the main component.
(choices: "application", "firmware", "library", default: "application")
-v, --verbose Increase the verbosity of messages.
Use multiple times to increase the verbosity even more.
-V, --version output the version number
-h, --help display help for command
```
Expand Down
11 changes: 7 additions & 4 deletions src/builders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,6 @@ export class BomBuilder {
}
}

// TODO use instead ? : https://www.npmjs.com/package/debug ?
this.console.info('INFO | gather dependency tree ...')
this.console.debug('DEBUG | npm-ls: run npm with %j in %j', args, projectDir)
let npmLsReturns: Buffer
Expand Down Expand Up @@ -208,7 +207,6 @@ export class BomBuilder {
}

buildFromNpmLs (data: any, npmVersion?: string): Models.Bom {
// TODO use instead ? : https://www.npmjs.com/package/debug ?
this.console.info('INFO | build BOM ...')

// region all components & dependencies
Expand Down Expand Up @@ -310,11 +308,13 @@ export class BomBuilder {
for (const [depName, depData] of Object.entries(data.dependencies ?? {}) as any) {
if (depData === null || typeof depData !== 'object') {
// cannot build
this.console.debug('DEBUG | skip malformed component %j in %j', depName, depData)
continue // for-loop
}
if (typeof depData.path !== 'string') {
// might be an optional dependency that was not installed
// skip, as it was not installed anyway
this.console.debug('DEBUG | skip missing component %j in %j', depName, depData.path)
continue // for-loop
}

Expand All @@ -323,14 +323,17 @@ export class BomBuilder {
const _dep = this.makeComponent(depData)
if (_dep === false) {
// shall be skipped
this.console.debug('DEBUG | skip impossible component %j in %j', depName, depData.path)
continue // for-loop
}
dep = _dep ??
new DummyComponent(Enums.ComponentType.Library, `InterferedDependency.${depName as string}`)
if (dep instanceof DummyComponent) {
this.console.warn('WARN | InterferedDependency $j', dep.name)
this.console.warn('WARN | InterferedDependency %j in %j', depName, depData.path)
} else {
this.console.debug('DEBUG | built component %j in %j: %j', depName, depData.path, dep)
}

this.console.info('INFO | add component for %j in %j', depName, depData.path)
allComponents.set(depData.path, dep)
}
directDepRefs.add(dep.bomRef)
Expand Down
27 changes: 20 additions & 7 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { dirname, resolve } from 'path'

import { loadJsonFile } from './_helpers'
import { BomBuilder, TreeBuilder } from './builders'
import { makeConsoleLogger } from './logger'

enum OutputFormat {
JSON = 'JSON',
Expand All @@ -50,6 +51,7 @@ interface CommandOptions {
outputFile: string
validate: boolean
mcType: Enums.ComponentType
verbose: number
}

function makeCommand (process: NodeJS.Process): Command {
Expand Down Expand Up @@ -164,6 +166,15 @@ function makeCommand (process: NodeJS.Process): Command {
).default(
Enums.ComponentType.Application
)
).addOption(
new Option(
'-v, --verbose',
'Increase the verbosity of messages. Use multiple times to increase the verbosity even more.'
).argParser<number>(
function (_: any, previous: number): number {
return previous + 1
}
).default(0)
).addArgument(
new Argument(
'[<package-manifest>]',
Expand All @@ -189,13 +200,11 @@ const ExitCode: Readonly<Record<string, number>> = Object.freeze({
export async function run (process: NodeJS.Process): Promise<number> {
process.title = 'cyclonedx-node-npm'

// all output shall be bound to stdError - stdOut is for result output only
const myConsole = new console.Console(process.stderr, process.stderr)

const program = makeCommand(process)
program.parse(process.argv)

const options: CommandOptions = program.opts()
const myConsole = makeConsoleLogger(options.verbose)
myConsole.debug('DEBUG | options: %j', options)

const packageFile = resolve(process.cwd(), program.args[0] ?? 'package.json')
Expand Down Expand Up @@ -272,7 +281,9 @@ export async function run (process: NodeJS.Process): Promise<number> {
myConsole.log('LOG | try validate BOM result ...')
try {
const validationErrors = await validator.validate(serialized)
if (validationErrors !== null) {
if (validationErrors === null) {
myConsole.info('INFO | BOM result appears valid')
} else {
myConsole.debug('DEBUG | BOM result invalid. details: ', validationErrors)
myConsole.error('ERROR | Failed to generate valid BOM.')
myConsole.warn(
Expand All @@ -290,14 +301,16 @@ export async function run (process: NodeJS.Process): Promise<number> {
}
}

// TODO use instead ? : https://www.npmjs.com/package/debug ?
myConsole.log('LOG | writing BOM to', options.outputFile)
writeSync(
const written = writeSync(
options.outputFile === OutputStdOut
? process.stdout.fd
: openSync(resolve(process.cwd(), options.outputFile), 'w'),
serialized
)
myConsole.info('INFO | wrote %d bytes to %s', written, options.outputFile)

return ExitCode.SUCCESS
return written > 0
? ExitCode.SUCCESS
: ExitCode.FAILURE
}
39 changes: 39 additions & 0 deletions src/logger.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*!
This file is part of CycloneDX generator for NPM projects.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
SPDX-License-Identifier: Apache-2.0
Copyright (c) OWASP Foundation. All Rights Reserved.
*/

function noop (): void {
// do nothing
}

export function makeConsoleLogger (level: number): Console {
// all output shall be bound to stdError - stdOut is for result output only
const myConsole = new console.Console(process.stderr, process.stderr)

if (level < 3) {
myConsole.debug = noop
if (level < 2) {
myConsole.info = noop
if (level < 1) {
myConsole.log = noop
}
}
}

return myConsole
}
2 changes: 2 additions & 0 deletions tests/integration/synthetics/cli.run.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ describe('cli.run()', () => {
argv: [
process.argv[0],
'dummy_process',
'-vvv',
'--output-reproducible',
'--validate',
// no intention to test all the spec-versions nor all the output-formats - this would be not our scope.
Expand Down Expand Up @@ -311,6 +312,7 @@ describe('cli.run()', () => {
argv: [
process.argv[0],
'dummy_process',
'-vvv',
'--ignore-npm-errors',
'--output-reproducible',
'--validate',
Expand Down

0 comments on commit 436c85d

Please sign in to comment.