Skip to content

Commit

Permalink
Move js dep walking into a module, add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ryanblock committed Dec 20, 2020
1 parent fe8f9b9 commit 59d7f4a
Show file tree
Hide file tree
Showing 12 changed files with 114 additions and 37 deletions.
2 changes: 1 addition & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
test/mocks/normal
test/mocks/
test/tmp
34 changes: 34 additions & 0 deletions src/actions/autoinstall/get-dir-deps.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
let { join } = require('path')
let { sync: rm } = require('rimraf')
let { sync: glob } = require('glob')
let { ignoreDeps } = require('../../lib')
let getRequires = require('./get-requires')

module.exports = function getDirDeps ({ dir, update }) {
// Clean everything out bebefore we get going jic
rm(join(dir, 'node_modules'))

// Collection of all dependencies from all files in this directory
let deps = []

// Userland files that could not be parsed
let failures = []

// Gather ye business logic while ye may
let files = glob('**/*.js', { cwd: dir }).filter(ignoreDeps)
files.forEach(f => {
try {
let requires = getRequires({ dir, file: join(dir, f), update })
if (requires) deps = deps.concat(requires)
}
catch (error) {
failures.push({ file: join(dir, f), error })
}
})

// Tidy up the dependencies
deps = [ ...new Set(deps.sort()) ] // Dedupe
deps = deps.filter(d => d !== 'aws-sdk') // Already present at runtime

return { deps, failures, files }
}
48 changes: 15 additions & 33 deletions src/actions/autoinstall/index.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
let { writeFileSync } = require('fs')
let { join } = require('path')
let { sync: glob } = require('glob')
let rm = require('rimraf').sync
let { ignoreDeps } = require('../../lib')
let getDeps = require('./get-root-deps')
let getRequires = require('./get-requires')
let getRootDeps = require('./get-root-deps')
let getDirDeps = require('./get-dir-deps')

module.exports = function autoinstaller (params) {
let { dirs, inventory, update, verbose } = params
if (!dirs.length) return []

let installing = [] // Generated manifests to be hydrated later (if there are no parsing failures)
let failures = [] // Userland files that could not be parsed
// Generated manifests to be hydrated later (if there are no parsing failures)
let installing = []

// Userland files that could not be parsed
let failures = []

// Get package[-lock] dependencies
let allDeps = getDeps(inventory)
let allDeps = getRootDeps(inventory)

update.start('Finding dependencies')
// Stats
Expand All @@ -31,36 +31,18 @@ module.exports = function autoinstaller (params) {
// Autoinstall is currently Node.js only - exit early if it's another runtime
if (!lambda.config.runtime.startsWith('nodejs')) return
try {
// Clean everything out bebefore we get going jic
rm(join(dir, 'node_modules'))

// Collection of all dependencies from all files in this directory
let dirDeps = []

// Gather ye business logic while ye may
let files = glob('**/*.js', { cwd: dir }).filter(ignoreDeps)
files.forEach(f => {
projectFiles++
try {
let deps = getRequires({ dir, file: join(dir, f), update })
if (deps) dirDeps = dirDeps.concat(deps)
}
catch (error) {
failures.push({ file: join(dir, f), error })
}
})

// Tidy up the dependencies
dirDeps = [ ...new Set(dirDeps.sort()) ] // Dedupe
dirDeps = dirDeps.filter(d => d !== 'aws-sdk') // Already present at runtime
let result = getDirDeps({ dir, update })
let { deps, files } = result
projectFiles += files.length
failures = failures.concat(result.failures)

// Exit now if there are no deps to write
if (!dirDeps.length) return
totalDeps += dirDeps.length
if (!deps.length) return
totalDeps += deps.length

// Build the manifest
let dependencies = {}
dirDeps.forEach(dep => dependencies[dep] = allDeps[dep] || 'latest')
deps.forEach(dep => dependencies[dep] = allDeps[dep] || 'latest')
let lambdaPackage = {
_arc: 'autoinstall',
_module: 'hydrate',
Expand Down
9 changes: 9 additions & 0 deletions test/mocks/deps/one.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Built-ins should be ignored
let path = require('path')

// AWS-SDK should also be ignored
let aws = require('aws-sdk')

// Real deps should not be ignored!
// Let's keep it in here with the ignored ones to prove this file was read
let a = require('a')
4 changes: 4 additions & 0 deletions test/mocks/deps/subfolder/subsubfolder/five.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
let options = { ok: true }
let d = require('d')(options)

let something = [ d, require('e') ]
1 change: 1 addition & 0 deletions test/mocks/deps/subfolder/subsubfolder/four.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// Goose egg
1 change: 1 addition & 0 deletions test/mocks/deps/subfolder/subsubfolder/ignored.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// Ignore me!
5 changes: 5 additions & 0 deletions test/mocks/deps/subfolder/subsubfolder/six.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
let something = process.env.SOMETHING
require(something)

// Also require 'c' to test de-duping
require('c')
3 changes: 3 additions & 0 deletions test/mocks/deps/subfolder/three.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
let something = {
c: require('c')
}
3 changes: 3 additions & 0 deletions test/mocks/deps/subfolder/two.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
function idk () {
let b = require('b')
}
35 changes: 35 additions & 0 deletions test/unit/src/actions/autoinstall/get-dir-deps-tests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
let { join } = require('path')
let test = require('tape')
let sut = join(process.cwd(), 'src', 'actions', 'autoinstall', 'get-dir-deps')
let getDirDeps = require(sut)
let mock = join(process.cwd(), 'test', 'mocks', 'deps')
let { updater } = require('@architect/utils')
let update = updater('Hydrate')

test('Set up env', t => {
t.plan(1)
t.ok(getDirDeps, 'Dependency getter module is present')
})

test(`Walk a folder's deps`, t => {
t.plan(4)
let stdout = process.stdout.write
let data = ''
process.stdout.write = write => {
data += write
}
let { deps, failures, files } = getDirDeps({ dir: mock, update })
process.stdout.write = stdout
let correct = [ 'a', 'b', 'c', 'd', 'e' ]

t.deepEqual(deps.sort(), correct, `Got correct deps`)
console.log(correct)

t.notOk(failures.length, 'Got no failures')

t.equal(files.length, 6, 'Scanned walked six js files')
console.log(files.sort())

t.ok(data.includes(`'something'`), 'Warned about dynamic require')
console.log(data)
})
6 changes: 3 additions & 3 deletions test/unit/src/actions/autoinstall/get-root-deps-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ let { join } = require('path')
let test = require('tape')
let mockFs = require('mock-fs')
let sut = join(process.cwd(), 'src', 'actions', 'autoinstall', 'get-root-deps')
let getDeps = require(sut)
let getRootDeps = require(sut)

function pkgify (deps, devDeps, lock) {
let tmpl = { name: 'app' }
Expand All @@ -14,14 +14,14 @@ function pkgify (deps, devDeps, lock) {
let inventory = { inv: { _project: { src: process.cwd() } } }
let run = fs => {
mockFs(fs)
let result = getDeps(inventory)
let result = getRootDeps(inventory)
mockFs.restore()
return result
}

test('Set up env', t => {
t.plan(1)
t.ok(getDeps, 'Dependency getter module is present')
t.ok(getRootDeps, 'Dependency getter module is present')
})

test('package.json', t => {
Expand Down

0 comments on commit 59d7f4a

Please sign in to comment.