<commit_before>fs           = require('fs')
path         = require('path')
uglify       = require('uglify-js')
stitch       = require('../assets/stitch')
Dependency   = require('./dependency')
Stitch       = require('./stitch')
{toArray}    = require('./utils')
mime         = require('connect').static.mime

class Package
  constructor: (name, config = {}) ->
    @name         = name
    @require      = config.require
    @libs         = toArray(config.libs || [])
    @paths        = toArray(config.paths || [])
    @modules      = toArray(config.modules || [])
    @target       = config.target
    @jsAfter      = config.jsAfter or ""
    @url          = config.url or ""
    # determine content type based on target
    @contentType  = mime.lookup(@target)
    # check required config values

  compileModules: ->
    @dependency or= new Dependency(@modules)
    @stitch       = new Stitch(@paths)
    @stuff        = @dependency.resolve().concat(@stitch.resolve())
    stitch(identifier: @require, modules: @stuff)

  compileLibs: ->
    (fs.readFileSync(lib, 'utf8') for lib in @libs).join("\n")

  compile: (minify = false) ->
    try
      if @isJavascript()
        result = [@compileLibs(), @compileModules(), @jsAfter].join("\n")
        result = uglify(result) if minify
        result
      else
        result = []
        for _path in @paths
          # TODO: currently this only works with index files, perhaps someday loop over the directory
          # contents and pickup the other files?? though with stylus can always get other content by mixins
          _path  = require.resolve(path.resolve(_path))
          delete require.cache[_path]
          result.push require(_path)
        result.join("\n")
    catch ex
      console.trace ex
      # only return when in server mode, otherwise exit
      # TODO: pass in mode as argument instead of checking process.argv??
      command = process.argv[2]
      switch command
        when "server" then return "console.log(\"#{ex}\");"
        when "watch"  then return ""
        when "build"  then process.exit(1)

  isJavascript: ->
    @contentType is "application/javascript"

  unlink: ->
    fs.unlinkSync(@target) if fs.existsSync(@target)

  build: (minify = false) ->
    console.log "Building #{@name} to target: #{@target}"
    source = @compile(minify)
    fs.writeFileSync(@target, source) if source

  watch: ->
    for dir in (path.dirname(lib) for lib in @libs).concat @paths
      continue unless fs.existsSync(dir)
      require('watch').watchTree dir, { persistent: true, interval: 1000 },  (file, curr, prev) =>
        @build() if curr and (curr.nlink is 0 or +curr.mtime isnt +prev?.mtime)

  # TODO: move this to a separate middleware class, pass in package to call compile and content type on..
  middleware: (req, res, next) =>
    str = @compile()
    res.charset = 'utf-8'
    res.setHeader('Content-Type', @contentType)
    res.setHeader('Content-Length', Buffer.byteLength(str))
    res.end((req.method is 'HEAD' and null) or str)<commit_msg>better variables names and using argv value passed in to perform optional steps<commit_after>fs           = require('fs')
path         = require('path')
uglify       = require('uglify-js')
stitchFile   = require('../assets/stitch')
Dependency   = require('./dependency')
Stitch       = require('./stitch')
{toArray}    = require('./utils')
mime         = require('connect').static.mime

class Package
  constructor: (name, config = {}, argv = {}) ->
    @name        = name
    @argv        = argv
    # set config values
    @require     = config.require
    @target      = config.target
    @libs        = toArray(config.libs || [])
    @paths       = toArray(config.paths || [])
    @modules     = toArray(config.modules || [])
    @jsAfter     = config.jsAfter or ""
    @url         = config.url or ""
    # TODO: sanity checkes on config values??
    # determine content type based on target file name
    @contentType = mime.lookup(@target)

  compileModules: ->
    @depend or= new Dependency(@modules)
    _stitch   = new Stitch(@paths)
    _modules  = @depend.resolve().concat(_stitch.resolve())
    stitchFile(identifier: @require, modules: _modules)

  compileLibs: ->
    # TODO: be able to handle being given a folder and loading each file...can this compile coffeescript??
    (fs.readFileSync(lib, 'utf8') for lib in @libs).join("\n")

  compile: (minify = false) ->
    try
      if @isJavascript()
        result = [@compileLibs(), @compileModules(), @jsAfter].join("\n")
        result = uglify(result) if minify
        result
      else
        result = []
        for _path in @paths
          # TODO: currently this only works with index files, perhaps someday loop over the directory
          # contents and pickup the other files?? though with stylus can always get other content by mixins
          _path  = require.resolve(path.resolve(_path))
          delete require.cache[_path]
          result.push require(_path)
        # TODO: do we want a minify option for css??
        result.join("\n")
    catch ex
      console.trace ex
      # only return when in server/watch mode, otherwise exit
      switch @argv.command
        when "server" then return "console.log(\"#{ex}\");"
        when "watch"  then return ""
        else process.exit(1)

  isJavascript: ->
    @contentType is "application/javascript"

  unlink: ->
    fs.unlinkSync(@target) if fs.existsSync(@target)

  build: (minify = false) ->
    console.log "Building '#{@name}' target: #{@target}"
    source = @compile(minify)
    fs.writeFileSync(@target, source) if source

  watch: ->
    for dir in (path.dirname(lib) for lib in @libs).concat @paths
      continue unless fs.existsSync(dir)
      require('watch').watchTree dir, { persistent: true, interval: 1000 },  (file, curr, prev) =>
        @build() if curr and (curr.nlink is 0 or +curr.mtime isnt +prev?.mtime)

  middleware: (req, res, next) =>
    str = @compile()
    res.charset = 'utf-8'
    res.setHeader('Content-Type', @contentType)
    res.setHeader('Content-Length', Buffer.byteLength(str))
    res.end((req.method is 'HEAD' and null) or str)
{'fraction_non_alphanumeric': 0.13125406107862247, 'fraction_numerical': 0.002761533463287849, 'mean_word_length': 2.6345926800472257, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7443023', 'n_tokens_mistral': 1843, 'n_tokens_neox': 1788, 'n_words': 537}