Skip to content

Commit

Permalink
Autoinstall self-cleanup, add additional diagnostic data to generated…
Browse files Browse the repository at this point in the history
… package.json
  • Loading branch information
ryanblock committed Dec 20, 2020
1 parent 84eb74a commit bbc03d4
Show file tree
Hide file tree
Showing 8 changed files with 55 additions and 23 deletions.
2 changes: 1 addition & 1 deletion changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

### Added

- TBA
- Added support for automated dependency management (`autoinstall`)

---

Expand Down
4 changes: 3 additions & 1 deletion cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@ let isShared = opt => opt === 'shared' || opt === '--shared' || opt === '-s'
let isUpdate = opt => opt === 'update' || opt === '--update' || opt === '-u' ||
opt === 'upgrade' || opt === '--upgrade' // jic
let isVerbose = opt => opt === 'verbose' || opt === '--verbose' || opt === '-v'
let isAutoinstall = opt => opt === 'autoinstall' || opt === '--autoinstall'

// eslint-disable-next-line
async function cmd (opts = []) {

let args = {
verbose: opts.some(isVerbose)
verbose: opts.some(isVerbose),
autoinstall: opts.some(isAutoinstall),
}

if (opts.some(isShared)) {
Expand Down
23 changes: 23 additions & 0 deletions src/_cleanup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
let { mkdirSync, renameSync } = require('fs')
let { join } = require('path')

// Best effort local artifact cleanup
module.exports = function cleanup (installed) {
if (installed) {
try {
installed.forEach(i => {
let { dir, file, remove } = i
if (file === 'package.json') {
let dest = join(dir, 'node_modules', '_arc-autoinstall')
mkdirSync(dest, { recursive: true })
remove.forEach(f => {
let before = join(dir, f)
let after = join(dest, f)
renameSync(before, after)
})
}
})
}
catch (err) { null } // Swallow errors, we may have to bubble something else
}
}
21 changes: 10 additions & 11 deletions src/actions/autoinstall/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,15 @@ let { existsSync, readFileSync, writeFileSync } = require('fs')
let { join } = require('path')
let { sync: glob } = require('glob')
let rm = require('rimraf').sync
let { ignoreDeps, stripCwd } = require('../../lib')
let { ignoreDeps } = require('../../lib')
let getRequires = require('./get-requires')

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

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

// Get package.json contents and map out root dependencies
let packageJson = join(process.cwd(), 'package.json')
Expand Down Expand Up @@ -64,14 +63,17 @@ module.exports = function autoinstaller (params) {
let dependencies = {}
dirDeps.forEach(dep => dependencies[dep] = packageJsonDeps[dep] || 'latest')
let lambdaPackage = {
_arc: 'hydrate-autoinstall',
description: `This file, .arc-autoinstall, and package-lock.json should have been deleted by Architect after deployment; all can be safely be removed`,
_arc: 'autoinstall',
_module: 'hydrate',
_date: new Date().toISOString(),
_parsed: files,
description: `This file was generated by Architect, and placed in node_modules to aid in debugging; if you found file in your function directory, you can safely remove it (and package-lock.json)`,
dependencies,
}
writes.push({
installing.push({
dir,
file: 'package.json',
del: 'package.json\npackage-lock.json', // Identify files for later deletion
remove: [ 'package.json', 'package-lock.json' ], // Identify files for later removal
data: JSON.stringify(lambdaPackage, null, 2)
})
}
Expand All @@ -92,12 +94,9 @@ module.exports = function autoinstaller (params) {
}

// Write everything at the end in case there were any parsing errors
writes.forEach(({ dir, file, data, del }) => {
let marker = join(dir, '.arc-autoinstall')
installing.forEach(({ dir, file, data }) => {
let manifest = join(dir, file)
writeFileSync(marker, del)
writeFileSync(manifest, data)
installing.push(stripCwd(manifest))
})

if (verbose) {
Expand Down
18 changes: 13 additions & 5 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
let { sync: glob } = require('glob')
let series = require('run-series')
let { dirname } = require('path')
let { dirname, join } = require('path')
let stripAnsi = require('strip-ansi')
let { pathToUnix, updater } = require('@architect/utils')
let inventory = require('@architect/inventory')
let { isDep, ignoreDeps, stripCwd } = require('./lib')
let shared = require('./shared')
let actions = require('./actions')
let cleanup = require('./_cleanup')

/**
* Installs deps into or updates current deps in:
Expand Down Expand Up @@ -41,7 +42,7 @@ function hydrator (inventory, installing, params, callback) {
copyShared = true,
hydrateShared = true
} = params

let autoinstalled // Assigned later
let action = installing ? 'Hydrat' : 'Updat' // Used in logging below

// From here on out normalize all file comparisons to Unix paths
Expand Down Expand Up @@ -117,13 +118,17 @@ function hydrator (inventory, installing, params, callback) {
let ops = []

// Run the autoinstaller first in case we need to add any new manifests to the ops
if (autoinstall) {
if (autoinstall && installing) {
// Ignore directories already known to have a manifest
let dirs = inv.lambdaSrcDirs.filter(d => !files.some(file => dirname(file) === pathToUnix(stripCwd(d))))
// Allow scoping to a single directory
if (basepath) dirs = dirs.filter(d => pathToUnix(stripCwd(d)) === pathToUnix(stripCwd(basepath)))
let installing = actions.autoinstall({ dirs, update, inventory, ...params })
files = files.concat(installing)
let result = actions.autoinstall({ dirs, update, inventory, ...params })
if (result.length) {
autoinstalled = result
let install = autoinstalled.map(({ dir, file }) => stripCwd(join(dir, file)))
files = files.concat(install)
}
}

// Install + update
Expand All @@ -143,6 +148,9 @@ function hydrator (inventory, installing, params, callback) {
}

series(ops, function done (err, result) {
// Tidy up before exiting
cleanup(autoinstalled)

result = [].concat.apply([], result) // Flatten the nested shared array
if (init) result.unshift(init) // Bump init logging to the top
if (err) callback(err, result)
Expand Down
2 changes: 1 addition & 1 deletion src/shared/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ module.exports = function shared (params = {}, callback) {
if (shared || views) {
start = update.status('Hydrating app with shared files')
}
paths = getPaths(inventory, 'shared')
paths = getPaths(inventory)
callback()
},
function (callback) {
Expand Down
4 changes: 2 additions & 2 deletions test/integration/default/install-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ test(`[Default (file copying)] install() hydrates all Functions', shared and vie
t.ok(existsSync(p), `node views dependency exists at ${p}`)
})
// Autoinstall-specific tests
let marker = join(arcAutoinstall[0], '.arc-autoinstall')
t.ok(existsSync(marker), 'Found autoinstall marker file')
let package = join(arcAutoinstall[0], 'node_modules', '_arc-autoinstall', 'package.json')
t.ok(existsSync(package), 'Found autoinstall package.json')
// Yarn-specific tests
let yarnFunction = join(mockTmp, 'src', 'http', 'put-on_your_boots')
let yarnIntFile = join(yarnFunction, 'node_modules', '.yarn-integrity')
Expand Down
4 changes: 2 additions & 2 deletions test/integration/symlink/install-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ test(`[Symlinking] install() with symlink hydrates all Functions', shared and vi
t.ok(existsSync(p), `node views dependency exists at ${p}`)
})
// Autoinstall-specific tests
let marker = join(arcAutoinstall[0], '.arc-autoinstall')
t.ok(existsSync(marker), 'Found autoinstall marker file')
let package = join(arcAutoinstall[0], 'node_modules', '_arc-autoinstall', 'package.json')
t.ok(existsSync(package), 'Found autoinstall package.json')
// Yarn-specific tests
let yarnFunction = join(mockTmp, 'src', 'http', 'put-on_your_boots')
let yarnIntFile = join(yarnFunction, 'node_modules', '.yarn-integrity')
Expand Down

0 comments on commit bbc03d4

Please sign in to comment.