<commit_before>path     = require 'path'
fs       = require 'fs'
W        = require 'when'
nodefn   = require 'when/node'
nodecb   = require 'when/callbacks'
readdirp = require 'readdirp'
ncp      = require('ncp').ncp
exec     = require('child_process').exec
ejs      = require 'ejs'
inquirer = require 'inquirer'
Base     = require '../base'
S        = require 'string'
_        = require 'lodash'
dns      = require 'dns'

class Init extends Base

  constructor: -> super

  execute: (opts) ->
    configure_options.call(@, opts).with(@)
      .then(get_user_init_file)
      .then(run_user_before_function)
      .then(remove_overrides_from_prompt)
      .then(add_defaults_to_questions)
      .then(prompt_user_for_answers)
      .then(merge_config_values_with_overrides)
      .then(check_internet_connection)
      .then(ensure_template_is_updated)
      .then(checkout_version)
      .then(copy_template)
      .then(run_user_before_render_function)
      .then(replace_ejs)
      .then(run_user_after_function)
      .then(-> "project created at '#{@target}'!")

  # intended for use in the after function, quick way to remove
  # files/folders that users wanted to nix after the prompts.
  # TODO: this should be refactored out into a separate utils module
  remove: (f) ->
    fs.unlinkSync(path.resolve(@target, f))

  ###*
   * @private
  ###

  configure_options = (opts) ->
    if not opts or not opts.name
      return W.reject('your template needs a name!')

    # perhaps name should be template?
    @name        = opts.name
    @target      = opts.path
    @overrides   = opts.overrides || []
    @defaults    = opts.defaults
    @answers     = {}
    @version     = parse_version(@name) or ''

    # if we have a version, remove it and the @ from the name
    if @version.length then @name = @name.replace(@version, '').slice(0,-1)

    @sprout_path = @path(@name)

    # transform overrides paired array to object
    if Array.isArray(@overrides)
      @overrides = @overrides.reduce (m, v, i) =>
        (if i % 2 == 0 then m[v] = @overrides[i+1]); m
      , {}

    if not fs.existsSync(@sprout_path)
      return W.reject("template '#{@name}' does not exist")

    if not @target then @target = path.join(process.cwd(), @name)

    W.resolve()

  parse_version = (name) ->
    match = name.match(/@+([^@]*)$/)
    if match then match[1] else false

  get_user_init_file = ->
    init_file = path.join(@sprout_path, 'init.coffee')<commit_msg>ensure template's deps are installed<commit_after>path     = require 'path'
fs       = require 'fs'
W        = require 'when'
nodefn   = require 'when/node'
nodecb   = require 'when/callbacks'
readdirp = require 'readdirp'
ncp      = require('ncp').ncp
exec     = require('child_process').exec
ejs      = require 'ejs'
inquirer = require 'inquirer'
Base     = require '../base'
S        = require 'string'
_        = require 'lodash'
dns      = require 'dns'

class Init extends Base

  constructor: -> super

  execute: (opts) ->
    configure_options.call(@, opts).with(@)
      .then(install_template_dependencies)
      .then(get_user_init_file)
      .then(run_user_before_function)
      .then(remove_overrides_from_prompt)
      .then(add_defaults_to_questions)
      .then(prompt_user_for_answers)
      .then(merge_config_values_with_overrides)
      .then(check_internet_connection)
      .then(ensure_template_is_updated)
      .then(checkout_version)
      .then(copy_template)
      .then(run_user_before_render_function)
      .then(replace_ejs)
      .then(run_user_after_function)
      .then(-> "project created at '#{@target}'!")

  # intended for use in the after function, quick way to remove
  # files/folders that users wanted to nix after the prompts.
  # TODO: this should be refactored out into a separate utils module
  remove: (f) ->
    fs.unlinkSync(path.resolve(@target, f))

  ###*
   * @private
  ###

  configure_options = (opts) ->
    if not opts or not opts.name
      return W.reject('your template needs a name!')

    # perhaps name should be template?
    @name        = opts.name
    @target      = opts.path
    @overrides   = opts.overrides || []
    @defaults    = opts.defaults
    @answers     = {}
    @version     = parse_version(@name) or ''

    # if we have a version, remove it and the @ from the name
    if @version.length then @name = @name.replace(@version, '').slice(0,-1)

    @sprout_path = @path(@name)

    # transform overrides paired array to object
    if Array.isArray(@overrides)
      @overrides = @overrides.reduce (m, v, i) =>
        (if i % 2 == 0 then m[v] = @overrides[i+1]); m
      , {}

    if not fs.existsSync(@sprout_path)
      return W.reject("template '#{@name}' does not exist")

    if not @target then @target = path.join(process.cwd(), @name)

    W.resolve()

  parse_version = (name) ->
    match = name.match(/@+([^@]*)$/)
    if match then match[1] else false

  install_template_dependencies = ->
    pkg = path.join(@sprout_path, 'package.json')
    if fs.existsSync(pkg) then nodefn.call(exec, "npm install", cwd: @sprout_path)

  get_user_init_file = ->
    init_file = path.join(@sprout_path, 'init.coffee')
{'fraction_non_alphanumeric': 0.1281207664021676, 'fraction_numerical': 0.002322430810915425, 'mean_word_length': 2.903323262839879, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 20, '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': '4359152', 'n_tokens_mistral': 1734, 'n_tokens_neox': 1698, 'n_words': 428}