Skip to content

Instantly share code, notes, and snippets.

@gvergnaud
Created January 8, 2017 20:57
Show Gist options
  • Save gvergnaud/19085bf986ed2be004f547b73342ed9a to your computer and use it in GitHub Desktop.
Save gvergnaud/19085bf986ed2be004f547b73342ed9a to your computer and use it in GitHub Desktop.
/* --------------------------------------------------------------- *
Remove node modules recursively in a pure functionnal way
* ---------------------------------------------------------------- */
// applying functionnal techniques from @drboolean in his egghead course
// https://egghead.io/courses/professor-frisby-introduces-composable-functional-javascript
const fs = require('fs.extra')
const path = require('path')
const {last} = require('lodash/fp')
const Task = require('data.task')
const {List} = require('immutable-ext')
// getSubfolders :: Path -> Task _ (List Path)
const getSubfolders = folderPath => new Task((_, res) => res(
List(fs.readdirSync(folderPath))
.filter(file => fs.statSync(path.join(folderPath, file)).isDirectory())
.map(file => path.join(folderPath, file))
))
// isNodeModules :: Path -> Bool
const isNodeModules = folderPath => last(folderPath.split('/')) === 'node_modules'
// getNodeModules :: Path -> Task _ (List Path)
const getNodeModules = basePath =>
getSubfolders(basePath)
.chain(subfoldersPaths =>
subfoldersPaths
.traverse(Task.of, folderPath =>
isNodeModules(folderPath)
? Task.of([folderPath])
: getNodeModules(folderPath)
)
)
.map(xxs => xxs.reduce((acc, xs) => acc.concat(xs), List()))
// rmrf :: Path -> Task Error Path
const rmrf = filePath => new Task((rej, res) => {
fs.rmrf(filePath, err => {
if (err) rej(err)
else res(filePath)
})
})
// basePath :: Task Error Path
const basePath = new Task((rej, res) => {
const param = process.argv.slice(2)[0]
return param ? res(param) : rej(new Error(`
No base path given!
you have to specify one by typing \`npm start /path/to/base/folder\`
`))
})
// removeNodeModules :: Task Error (List ())
const removeNodeModules =
basePath
.chain(getNodeModules)
.chain(nodeModulePaths => nodeModulePaths.traverse(Task.of, rmrf))
module.exports = removeNodeModules
// index.js
const removeNodeModules = require('./removeNodeModules')
removeNodeModules.fork(
err => console.log(err.message),
removedPaths => console.log(
'Success!',
'here are the paths that have been removed : \n',
removedPaths.toJS()
)
)
// =>
// Success!
// here are the paths that have been removed :
// [ ... ]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment