diff --git a/deployment.coffee b/deployment.coffee
index 1c3f8a1..27ec8fa 100644
--- a/deployment.coffee
+++ b/deployment.coffee
@@ -2,25 +2,192 @@
# Deployment script
#
# Commands:
-# hubot deploy [from branch ] to [after [, , ...]]
+# hubot deploy [with ] [from branch ] to [after [, , ...]]
#
# URLS:
#
# Notes:
#
+fs = require 'fs'
+
+deploymentDirectory = null
module.exports = (robot) ->
- robot.hear /deploy ([^\s]+)( from branch ([^\s]+))? to ([^\s]+)( after (.*))?$/i, (res) ->
- project = res.match[1]
- environnement = res.match[4]
- branch = if res.match[3] then res.match[3] else null
- commands = if res.match[6] then cleanCommands res.match[6].split(',') else []
+ robot.hear /deploy set ([^\s]+) +(.+)$/i, (res) ->
+ if res.match[1] == "directory"
+ deploymentDirectory = res.match[2]
+
+ robot.hear /deploy +([^\s]+)( +with +([^\s]+))?( +from +branch +([^\s]+))? +to +([^\s]+)( +after (.*))?$/i, (res) ->
+
+ if ! process.env.hasOwnProperty('HUBO_DEPLOYMENT_PROJECTS_DIRECTORY')
+ if deploymentDirectory == null
+ res.reply "You must set the env var HUBO_DEPLOYMENT_PROJECTS_DIRECTORY with the directory of the projects."
+ res.reply "Temporaly, you can use the command: deploy set directory "
+ return
+
+ project = res.match[1]
+ target = res.match[6]
+ program = if res.match[3] then res.match[3] else null
+ branch = if res.match[5] then res.match[5] else null
+ commands = if res.match[8] then cleanCommands res.match[8].split "," else []
+
+ if deploymentDirectory != null
+ directory = deploymentDirectory
+ else
+ directory = process.env.HUBO_DEPLOYMENT_PROJECTS_DIRECTORY
+
+ directory += "/" + project
+
+ try
+ fs.stat directory, (err, stats) ->
+ if err != null or !stats.isDirectory
+ return res.reply "Project not found [" + directory + "]"
+
+ try
+ fs.statSync directory + '/.svn'
+ pv = new SvnProjectVersionning branch
+ catch e
+
+ try
+ fs.statSync directory + '/.git'
+ pv = new GitProjectVersionning branch
+ catch e
+
+ if pv
+ d = deploy directory, pv, commands, target, program
+ res.send d
+ else
+ res.reply "Not a SVN or GIT repository"
+ catch e
+ res.reply "Exception: " + e
+
+class ProjectVersionning
+ constructor: (@branch) ->
+ getUpdateCommands: () ->
+
+class SvnProjectVersionning extends ProjectVersionning
+ getUpdateCommands: () ->
+ ['svn up']
+
+class GitProjectVersionning extends ProjectVersionning
+ getUpdateCommands: () ->
+ commands = []
+
+ if @branch == null
+ commands.push 'git pull origin $(git rev-parse --abbrev-ref HEAD)'
+ else
+ br = @branch.split "/"
+
+ if br.length == 1
+ commands.push 'git checkout ' + br[0]
+ commands.push 'git pull origin ' + br[0]
+ else if br.length == 2
+ commands.push 'git checkout ' + br[1]
+ commands.push 'git pull ' + br.join(' ')
+
+ commands
+
+logExec = (command, options) ->
+ exec = require "sync-exec"
+ exec command, options
+
+
+deploy = (directory, projectVersionning, commands, target, program) ->
+ commands = projectVersionning.getUpdateCommands().concat(commands)
+ canDeploy = true
+ results = []
+
+ for command in commands
+ if !canDeploy
+ continue
+
+ stmt = logExec command , {cwd: directory}
+
+ results.push {
+ command: command,
+ status: stmt.status,
+ stdout: stmt.stdout,
+ stderr: stmt.stderr,
+ }
+
+ if stmt.status != 0
+ canDeploy = false
+
+ if canDeploy
+ command = buildDeployCommand(directory, program, target)
+ stmt = logExec command, {cwd: directory}
+
+ results.push {
+ command: command,
+ status: stmt.status,
+ stdout: stmt.stdout,
+ stderr: stmt.stderr,
+ }
+
+ output = ""
+
+ for stmt in results
+ output += generateOutput stmt
+
+ output
+
+generateOutput = (stmt) ->
+ prefix = "deploy-" + Date.now()
+ status =
+ if stmt.status == 0
+ "OK"
+ else
+ "Failed"
+ """
+#{stmt.command} #{status}
+
+ Outputs:
STDOUT STDERR
+
#{stmt.stdout}
+
#{stmt.stderr}
+
+
+ """
+
+buildDeployCommand = (directory, program, target) ->
+ if program == 'mage'
+ command = 'vendor/bin/mage deploy to:' + target
+ else
+ interpreter = null
+
+ try
+ fs.statSync directory + '/bin/console'
+ interpreter = 'php bin/console'
+ catch e
+
+ try
+ fs.statSync directory + '/app/console'
+ interpreter = 'php app/console'
+ catch e
+
+ if interpreter != null
+ command = interpreter + ' project:deploy ' + target + ' --go'
+
+ command
cleanCommands = (commands) ->
results = []
- commands = commands.map(Function.prototype.call, String.prototype.trim)
+ commands = commands.map Function.prototype.call, String.prototype.trim
+
+ interpreters = {
+ "sf" : "php symfony",
+ "sf2" : "php app/console",
+ "sf3" : "php bin/console",
+ "composer": "composer"
+ }
for command in commands
- results.push(command) if command != ''
-
+ if command != ""
+ if command.match /(sf[2-3]?|composer):.+/
+ elements = command.split ":"
+ interpreter = elements[0]
+ elements = elements.splice 1
+ args = elements.join(":")
+ results.push interpreters[interpreter] + " " + args
+ else
+ results.push command
results