     else
       msg.reply cmds.join "\n"
 
+
   robot.respond /tf create key$/i, (msg) ->
     return unless isAuthorized robot, msg
     return if fileExistsSendAndReturnTrue msg, publickey, "Key exists!  Erase it first."

    fs.unlinkSync("#{publickey}")
    return msg.send {room: msg.message.user.name}, "Key erased!"

  robot.respond /tf clone ([^\s]+) ([^\s]+)$/i, (msg) ->
    return unless isAuthorized robot, msg

    url = msg.match[1]
    projname = msg.match[2].replace /\//, "_"
    projpath = basepath + "/" + projname

    #fn = msg.message.user.name
    #fn.replace /\//, "_"

    cmd = "GIT_SSH_COMMAND='ssh -i #{privatekey} -F /dev/null -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no' git clone #{url} #{projpath}"
    execAndSendOutput msg, cmd


  robot.respond /tf list$/i, (msg) ->
    return unless isAuthorized robot, msg

    dirs = getDirectories()

    if dirs.length > 0
      return msg.send {room: msg.message.user.name}, "Projects: `#{dirs.join '`, `'}`"

    return msg.send {room: msg.message.user.name}, "No projects.  Clone something with `tf git clone <repourl> <proj>`."


  robot.respond /tf git (remote|pull) ([^\s]+)$/i, (msg) ->
    action = msg.match[1]
    proj = msg.match[2].replace /\//, "_"
    return unless isAuthorized robot, msg
    return if fileMissingSendAndReturnTrue msg, proj, "Invalid project name: `#{proj}`"

    gitcmd = "git remote -v" if action == 'remote'
    gitcmd = "git pull" if action == 'pull'
    cmd = "cd #{basepath}/#{proj} ; #{gitcmd}"
    execAndSendOutput msg, cmd


  robot.respond /tf tf (get) ([^\s]+)( update)?$/i, (msg) ->
    action = msg.match[1]
    proj = msg.match[2].replace /\//, "_"
    update = if msg.match[3] then true else false
    return unless isAuthorized robot, msg
    return if fileMissingSendAndReturnTrue msg, proj, "Invalid project name: `#{proj}`"

    params = [ "-no-color" ]
    params.push "-update=true" if update
    paramline = params.join " "

    cmd = "cd #{basepath}/#{proj}; terraform #{action} #{paramline}"
    execAndSendOutput msg, cmd


  robot.respond /tf delete ([^\s]+)$/i, (msg) ->
    proj = msg.match[1].replace /\//, "_"
    return unless isAuthorized robot, msg
    return if fileMissingSendAndReturnTrue msg, proj, "Invalid project name: `#{proj}`"

    return exec "cd #{basepath}; rm -rf #{proj}", (error, stdout, stderr) ->
      msg.send {room: msg.message.user.name}, "Project deleted: #{proj}"


  robot.respond /tf tf (plan|refresh|apply|destroy) ([^\s]+)( verbose)?$/i, (msg) ->
    action = msg.match[1]
    proj = msg.match[2].replace /\//, "_"
    verbose = true if msg.match[3]
    return unless isAuthorized robot, msg
    return if fileMissingSendAndReturnTrue msg, proj, "Invalid project name: `#{proj}`"

    env = []
    for domain in ['all','me',proj]
      domain = msg.message.user.name if domain is 'me'
      env.push getProjEnv robot, domain
    envline = env.join " "

    params = []
    params.push "-input=false"
    params.push "-no-color"
    paramline = params.join " "

    cmdline = "cd #{basepath}/#{proj}; #{envline} terraform #{action} #{paramline}"
    cmdline = "#{cmdline} -force" if action == 'destroy'
    msg.send {room: msg.message.user.name}, "```\n#{cmdline}\n```"
    exec cmdline, (error, stdout, stderr) ->
