Skip to content

Instantly share code, notes, and snippets.

@lawrencejones
Last active August 29, 2015 14:04
Show Gist options
  • Save lawrencejones/3348714b60f0f62d7aaf to your computer and use it in GitHub Desktop.
Save lawrencejones/3348714b60f0f62d7aaf to your computer and use it in GitHub Desktop.
A small coffeescript that generates a template dependencies manifest by searching through globbed coffee files

NPM Dependency Generator

Simple detection of used npm packages by searching files for require mentions. Will output JSON dependencies for a quick copy-paste.

Helpers

fs = require 'fs'
glob = require 'glob'
Q = require 'q'

Generates a promise that is resolved with a line of input from stdin.

readline = (msg) ->
  process.stdout.write msg if msg?
  process.stdin.resume()
  process.stdin.setEncoding 'utf8'
  process.stdin.once 'data', (data) ->
    def.resolve data.trim()
  (def = Q.defer()).promise

Wraps around a readline promise to verify a user has given an affirmative response. Will reject the promise if an affirmative response is not detected.

yn = ->
  readline.apply arguments
  .then (res) ->
    ys = /^(?:1|t(?:rue)?|y(?:es)?|ok(?:ay)?)$/i
    if not ys.test res
      throw Error 'User declined'
    else res

Script Body

Expand file globs

Q.all process.argv[2..].map (target) ->
  Q.nfcall glob.bind(glob), target

Read file contents

.then (ts) ->
  fileTap = {}
  Q.all ([].concat ts...).map (t) ->
    if not fileTap[t]?
      Q.nfcall fs.readFile, t, 'utf8'

Concat src and match requires

.then (files) ->
  src = files.reduce (a,c) -> a+c
  reqRexStr = "require\\s*['\"]([^'\"\/]+)[\"']"
  src.match new RegExp(reqRexStr, 'g')
  ?.map (match) -> match.match(new RegExp(reqRexStr))[1]

Print first try detection

.then (deps) ->
  console.log """
  From examining all targets, the following dependencies have
  been discovered...

    #{deps.join '\n  '}\n"""
  yn readline 'Does this look correct? '

Output printed json

  .then ->
    json = dependencies: {}
    json.dependencies[dep] = '*' for dep in deps
    console.log '\n'+JSON.stringify json, undefined, 2

Catch any failed steps

.catch (err) ->
  console.log """
    ERR! usage: npm-deps <target>...
        Supply script with filepaths or globs."""
  process.exit -1

Cleanup and exit

.finally ->
  process.stdout.write '\n'
  process.exit 0
$ npm-deps **/*.coffee
From examining all targets, the following dependencies have
been discovered...
express
fs
path
express-jwt
nodetime
morgan
compression
body-parser
memwatch
mongoose
q
fs
path
Does this look correct?
{
"dependencies": {
"express": "*",
"fs": "*",
"path": "*",
"express-jwt": "*",
"nodetime": "*",
"morgan": "*",
"compression": "*",
"body-parser": "*",
"memwatch": "*",
"mongoose": "*",
"q": "*"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment