Skip to content

Commit

Permalink
feat: support dependency check in esm modules
Browse files Browse the repository at this point in the history
Auto-detect `type: "module"` in a project's `package.json` and switch
`detective` implementation to `detective-es6` which understands `import`.
  • Loading branch information
achingbrain committed Jul 29, 2021
1 parent 58c710c commit 96199d3
Show file tree
Hide file tree
Showing 7 changed files with 89 additions and 61 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@
"release-major": "node cli.js release --type major"
},
"dependencies": {
"@achingbrain/dependency-check": "^4.1.0",
"@electron/get": "^1.12.3",
"@polka/send-type": "^0.5.2",
"@types/chai": "^4.2.16",
Expand All @@ -80,6 +79,8 @@
"conventional-github-releaser": "^3.1.5",
"copyfiles": "^2.4.1",
"cors": "^2.8.5",
"dependency-check": "^5.0.0-1",
"detective-es6": "^2.2.0",
"electron-mocha": "^10.0.0",
"env-paths": "^2.2.1",
"esbuild": "^0.12.15",
Expand Down
13 changes: 12 additions & 1 deletion src/dependency-check.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
const path = require('path')
const execa = require('execa')
const merge = require('merge-options')
const { pkg } = require('./utils')

/**
* @typedef {import("execa").Options} ExecaOptions
Expand Down Expand Up @@ -34,9 +35,19 @@ const check = (argv, execaOptions) => {
.concat(argv.fileConfig.dependencyCheck.ignore)
.reduce((acc, i) => acc.concat('-i', i), /** @type {string[]} */ ([]))

const args = [...input, '--missing', ...noDev, ...ignore]

if (pkg.type === 'module') {
// use detective-es6
args.push(
'--detective',
require.resolve('detective-es6')
)
}

return execa(
'dependency-check',
[...input, '--missing', ...noDev, ...ignore, ...forwardOptions],
[...args, ...forwardOptions],
merge(
{
localDir: path.join(__dirname, '..'),
Expand Down
102 changes: 43 additions & 59 deletions test/dependency-check.js
Original file line number Diff line number Diff line change
@@ -1,46 +1,47 @@
/* eslint-env mocha */
'use strict'

const { check } = require('../src/dependency-check')
const { expect } = require('../utils/chai')
const path = require('path')
const merge = require('merge-options')
const { userConfig } = require('../src/config/user')

// returns an object that looks like the yargs input
const yargsv = (overrides = {}) => {
const argv = {
_: ['dependency-check'],
input: userConfig.dependencyCheck.input,
productionOnly: false,
productionInput: userConfig.dependencyCheck.productionInput,
ignore: [],
fileConfig: userConfig
}

return merge(argv, overrides)
}
const bin = require.resolve('../')
const execa = require('execa')

describe('dependency check', () => {
it('should fail for missing deps', async () => {
await expect(
check(yargsv(), {
execa(bin, ['dependency-check'], {
cwd: path.join(__dirname, 'fixtures/dependency-check/fail')
})
).to.eventually.be.rejectedWith('execa')
})

it('should fail for missing deps in an esm project', async () => {
await expect(
execa(bin, ['dependency-check'], {
cwd: path.join(__dirname, 'fixtures/dependency-check/esm-fail')
})
).to.eventually.be.rejectedWith('execa')
})

it('should pass when there are no missing deps', async () => {
await expect(
check(yargsv(), {
execa(bin, ['dependency-check'], {
cwd: path.join(__dirname, 'fixtures/dependency-check/pass')
})
).to.eventually.be.fulfilled()
})

it('should pass when there are no missing deps in an esm project', async () => {
await expect(
execa(bin, ['dependency-check'], {
cwd: path.join(__dirname, 'fixtures/dependency-check/esm-pass')
})
).to.eventually.be.fulfilled()
})

it('should forward options', async () => {
await expect(
check(yargsv({ '--': ['--unused'] }), {
execa(bin, ['dependency-check', '--', '--unused'], {
cwd: path.join(__dirname, 'fixtures/dependency-check/pass')
})
).to.eventually.be.rejectedWith(
Expand All @@ -50,7 +51,7 @@ describe('dependency check', () => {

it('should fail for missing production deps', async () => {
await expect(
check(yargsv({ productionOnly: true }), {
execa(bin, ['dependency-check', '-p'], {
cwd: path.join(__dirname, 'fixtures/dependency-check/fail-prod')
})
).to.eventually.be.rejectedWith('execa')
Expand All @@ -60,16 +61,12 @@ describe('dependency check', () => {
const file = 'derp/foo.js'

await expect(
check(
yargsv({
input: [file]
}),
{
cwd: path.join(
__dirname,
'fixtures/dependency-check/pass-certain-files'
)
}
execa(bin, ['dependency-check', file], {
cwd: path.join(
__dirname,
'fixtures/dependency-check/pass-certain-files'
)
}
)
).to.eventually.be.fulfilled()
})
Expand All @@ -78,46 +75,33 @@ describe('dependency check', () => {
const file = 'derp/foo.js'

await expect(
check(
yargsv({
productionOnly: true,
input: [file]
}),
{
cwd: path.join(
__dirname,
'fixtures/dependency-check/pass-certain-files'
)
}
execa(bin, ['dependency-check', file, '-p'], {
cwd: path.join(
__dirname,
'fixtures/dependency-check/pass-certain-files'
)
}
)
).to.eventually.be.fulfilled()
})

it('should pass for ignored modules', async () => {
await expect(
check(
yargsv({
ignore: ['execa']
}),
{
cwd: path.join(__dirname, 'fixtures/dependency-check/fail')
}
execa(bin, ['dependency-check', '-i', 'execa'], {
cwd: path.join(__dirname, 'fixtures/dependency-check/fail')
}
)
).to.eventually.be.fulfilled()
})

it('should pass for modules used in .aegir.js', async () => {
await expect(
check(
yargsv({
'--': ['--unused']
}),
{
cwd: path.join(
__dirname,
'fixtures/dependency-check/with-aegir-config'
)
}
execa(bin, ['dependency-check', '--', '--unused'], {
cwd: path.join(
__dirname,
'fixtures/dependency-check/with-aegir-config'
)
}
)
).to.eventually.be.fulfilled()
})
Expand Down
3 changes: 3 additions & 0 deletions test/fixtures/dependency-check/esm-fail/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// @ts-nocheck
/* eslint-disable no-unused-vars */
import execa from 'execa'
11 changes: 11 additions & 0 deletions test/fixtures/dependency-check/esm-fail/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "esm-dep-check-fail",
"version": "1.0.0",
"main": "index.js",
"type": "module",
"eslintConfig": {
"parserOptions": {
"sourceType": "module"
}
}
}
3 changes: 3 additions & 0 deletions test/fixtures/dependency-check/esm-pass/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// @ts-nocheck
/* eslint-disable no-unused-vars */
import execa from 'execa'
15 changes: 15 additions & 0 deletions test/fixtures/dependency-check/esm-pass/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"name": "esm-dep-check-pass",
"version": "1.0.0",
"main": "index.js",
"type": "module",
"eslintConfig": {
"parserOptions": {
"sourceType": "module"
}
},
"dependencies": {
"execa": "1.0.0",
"pico": "1.0.0"
}
}

0 comments on commit 96199d3

Please sign in to comment.