Skip to content

Commit

Permalink
Skip traversal (#56)
Browse files Browse the repository at this point in the history
  • Loading branch information
aviaviavi authored Aug 2, 2023
1 parent c71d11d commit a6deeff
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 3 deletions.
31 changes: 30 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ collect stats on install, no additional code is required!

Head to your package's dashboard on Scarf to see your reports when available.

#### Configuration
### Configuring

Users of your package will be opted in by default and can opt out by setting the
`SCARF_ANALYTICS=false` environment variable. If you'd like Scarf analytics to
Expand Down Expand Up @@ -75,6 +75,35 @@ By default, scarf-js will only trigger analytics when your package is installed
}
```


#### Full Configuration Example

```json5
// your-package/package.json

{
// ...
"scarfSettings": {
// Toggles whether Scarf is enabled for this package
"enabled": true,
// Enables Scarf when users run npm install directly in your repository
"allowTopLevel": true,
// Users will be opted into analytics by default
"defaultOptIn": true,
// By default, Scarf searches for its own location in your build's dependency
// graph to ensure reporting can be done for all packages using Scarf.
// For large projects with lots of dependencies, generating that dependency
// graph takes more time than Scarf allots for its entire process, so Scarf
// will always time out. `skipTraversal` is an optional flag for large
// applications to skip that traversal entirely. Use this flag with caution and
// care, as it will break Scarf analytics for all other packages you depend
// on in your build.
"skipTraversal": false
}
// ...
}
```

### FAQ

#### What information does scarf-js provide me as a package author?
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
],
"scripts": {
"postinstall": "node ./report.js",
"test": "jest"
"test": "jest --verbose"
},
"author": "Scarf Systems",
"license": "Apache-2.0",
Expand All @@ -30,6 +30,7 @@
"jest",
"beforeAll",
"afterAll",
"fail",
"describe"
]
}
Expand Down
29 changes: 28 additions & 1 deletion report.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const localDevPort = process.env.SCARF_LOCAL_PORT
const https = localDevPort ? require('http') : require('https')
const fs = require('fs')
const fsAsync = fs.promises
const util = require('util')

const scarfHost = localDevPort ? 'localhost' : 'scarf.sh'
const scarfLibName = '@scarf/scarf'
Expand Down Expand Up @@ -67,6 +68,10 @@ function allowTopLevel (rootPackage) {
return rootPackage && rootPackage.scarfSettings && rootPackage.scarfSettings.allowTopLevel
}

function skipTraversal (rootPackage) {
return rootPackage && rootPackage.scarfSettings && rootPackage.scarfSettings.skipTraversal
}

function parentIsRoot (dependencyToReport) {
return dependencyToReport.parent.name === dependencyToReport.rootPackage.name &&
dependencyToReport.parent.version === dependencyToReport.rootPackage.version
Expand Down Expand Up @@ -187,7 +192,29 @@ function processDependencyTreeOutput (resolve, reject) {
}
}

async function getDependencyInfo () {
// packageJSONOverride: a test convenience to set a packageJSON explicitly.
// Leave empty to use the actual root package.json.
async function getDependencyInfo (packageJSONOverride) {
try {
const rootPackageJSON = require(packageJSONOverride || path.join(rootPath, 'package.json'))
const scarfPackageJSON = require(path.join(dirName(), 'package.json'))

if (skipTraversal(rootPackageJSON)) {
logIfVerbose('skipping dependency tree traversal')
const shallowDepInfo = {
scarf: { name: '@scarf/scarf', version: scarfPackageJSON.version },
parent: { name: rootPackageJSON.name, version: rootPackageJSON.version },
rootPackage: { name: rootPackageJSON.name, version: rootPackageJSON.version },
anyInChainDisabled: false,
skippedTraversal: true
}
logIfVerbose(util.inspect(shallowDepInfo))
return shallowDepInfo
}
} catch (err) {
logIfVerbose(err, console.error)
}

return new Promise((resolve, reject) => {
exec(`cd ${rootPath} && npm ls @scarf/scarf --json --long`, { timeout: execTimeout, maxBuffer: 1024 * 1024 * 1024 }, processDependencyTreeOutput(resolve, reject))
})
Expand Down
10 changes: 10 additions & 0 deletions test/skip-traversal-package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"name": "test-package",
"version": "1.0",
"dependencies": {
"@scarf/scarf": "*"
},
"scarfSettings": {
"skipTraversal": true
}
}
12 changes: 12 additions & 0 deletions test/skip-traversal.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const report = require('../report')

describe('Skip Traversal Flag', () => {
test('Can skip npm ls when skipTraversal is enabled', async () => {
const depInfo = await report.getDependencyInfo('./test/skip-traversal-package.json')
expect(depInfo.skippedTraversal).toBe(true)
try {
await report.getDependencyInfo()
fail('Should fail after parsing the real dependency tree and not seeing a parent')
} catch {}
})
})

0 comments on commit a6deeff

Please sign in to comment.