1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 | CONFIG = "ggg"
|
12 |
|
13 | LOGS_LINES = 40
|
14 | COMMIT_HISTORY = 5
|
15 | VERSION = "0.4.4"
|
16 |
|
17 | {exec} = require "child_process"
|
18 | fs = require 'fs'
|
19 | path = require 'path'
|
20 |
|
21 | program = require 'commander'
|
22 |
|
23 | MainConfig = require "./lib/MainConfig"
|
24 | Layer = require "./lib/Layer"
|
25 |
|
26 | program
|
27 | .version(VERSION)
|
28 | .option("-l, --local", "deploy locally for bootstrapping")
|
29 |
|
30 | program
|
31 | .command("init")
|
32 | .description("creates a ggg.js config file for you")
|
33 | .action ->
|
34 | init finish
|
35 |
|
36 |
|
37 | program
|
38 | .command("deploy <name> [branch]")
|
39 | .description("deploys a branch (defaults to origin/master) to named server")
|
40 | .action (name, branch) ->
|
41 | getLayer name, (err, layer) ->
|
42 | return finish err if err?
|
43 |
|
44 | branch = branch || "origin/master"
|
45 |
|
46 | layer.deploy branch, finish
|
47 |
|
48 |
|
49 | program
|
50 | .command("restart <name>")
|
51 | .description("restarts named server")
|
52 | .action (name) ->
|
53 | getLayer name, (err, layer) ->
|
54 | return finish err if err?
|
55 | layer.restart finish
|
56 |
|
57 |
|
58 | program
|
59 | .command("start <name>")
|
60 | .description("starts named server")
|
61 | .action (name) ->
|
62 | getLayer name, (err, layer) ->
|
63 | return finish err if err?
|
64 | layer.start finish
|
65 |
|
66 | program
|
67 | .command("stop <name>")
|
68 | .description("stops named server")
|
69 | .action (name) ->
|
70 | getLayer name, (err, layer) ->
|
71 | return finish err if err?
|
72 | layer.stop finish
|
73 |
|
74 | program
|
75 | .command("logs <name>")
|
76 | .description("Logs #{LOGS_LINES} lines of named servers log files")
|
77 | .option("-l, --lines <num>", "the number of lines to log")
|
78 | .action (name) ->
|
79 | getLayer name, (err, layer) ->
|
80 | return finish err if err?
|
81 | lines = program.lines || LOGS_LINES
|
82 | layer.serverLogs lines, finish
|
83 |
|
84 | program
|
85 | .command("history <name>")
|
86 | .description("Shows a history of #{COMMIT_HISTORY} last commits deployed")
|
87 | .option("-r, --revisions <num>", "the number of commits to show")
|
88 | .action (name) ->
|
89 | getLayer name, (err, layer) ->
|
90 | return finish err if err?
|
91 | revisions = program.args.revisions || COMMIT_HISTORY
|
92 | layer.commitHistory revisions, finish
|
93 |
|
94 | program
|
95 | .command("list")
|
96 | .description("lists all the servers")
|
97 | .action ->
|
98 | getConfigRepo (err, repoName, mainConfig) ->
|
99 | return finish err if err?
|
100 |
|
101 | list mainConfig, finish
|
102 |
|
103 | program
|
104 | .command("help")
|
105 | .description("display this help")
|
106 | .action ->
|
107 | console.log program.helpInformation()
|
108 | finish()
|
109 |
|
110 | program
|
111 | .command("*")
|
112 | .action ->
|
113 | finish new Error "bad command!"
|
114 |
|
115 |
|
116 |
|
117 |
|
118 | init = (cb) ->
|
119 | initConfigContent = """
|
120 | // example ggg.js. Delete what you don't need
|
121 | module.exports = {
|
122 |
|
123 | // services
|
124 | start: "node app.js",
|
125 |
|
126 | // install
|
127 | install: "npm install",
|
128 |
|
129 | // cron jobs (from your app folder)
|
130 | cron: {
|
131 | someTask: { time: "0 3 * * *", command: "node sometask.js"},
|
132 | }
|
133 |
|
134 | // servers to deploy to
|
135 | servers: {
|
136 | dev: "deploy@dev.mycompany.com",
|
137 | staging: ["deploy@staging.mycompany.com", "deploy@staging2.mycompany.com"]
|
138 | prod: {
|
139 | hosts: ["deploy@mycompany.com", "deploy@backup.mycompany.com"],
|
140 | cron: {
|
141 | someTask: {time: "0 3 * * *", command: "node sometask.js"},
|
142 | anotherTask: {time: "0 3 * * *", command: "node secondTask.js"}
|
143 | },
|
144 | start: "prodstart app.js"
|
145 | }
|
146 | }
|
147 | }
|
148 | """
|
149 |
|
150 | console.log "GOGOGO INITIALIZING!"
|
151 | console.log "*** Written to ggg.js ***"
|
152 | console.log initConfigContent
|
153 |
|
154 | fs.writeFile mainConfigPath() + ".js", initConfigContent, 0o0755, cb
|
155 |
|
156 | list = (mainConfig, cb) ->
|
157 | console.log "GOGOGO servers (see ggg.js)"
|
158 | console.log " - " + mainConfig.getLayerNames().join("\n - ")
|
159 |
|
160 |
|
161 |
|
162 |
|
163 | reponame = (dir, cb) ->
|
164 | exec "git config --get remote.origin.url", {cwd:dir}, (err, stdout, stderr) ->
|
165 | if err?
|
166 | cb null, path.basename(dir)
|
167 | else
|
168 | url = stdout.replace("\n","")
|
169 | cb null, path.basename(url).replace(".git","")
|
170 |
|
171 |
|
172 |
|
173 | mainConfigPath = -> path.join process.cwd(), CONFIG
|
174 |
|
175 |
|
176 | getConfigRepo = (cb) ->
|
177 | reponame process.cwd(), (err, repoName) ->
|
178 | return cb err if err?
|
179 | MainConfig.loadFromFile mainConfigPath(), (err, mainConfig) ->
|
180 | if err then return cb new Error "Bad gogogo config file, ggg.js. Run 'gogogo init' to create one. Err=#{err.message}"
|
181 |
|
182 | cb null, repoName, mainConfig
|
183 |
|
184 |
|
185 | getLayer = (name, cb) ->
|
186 | getConfigRepo (err, repoName, mainConfig) ->
|
187 | return cb err if err?
|
188 |
|
189 | layerConfig = mainConfig.getLayerByName name
|
190 | if !layerConfig then return cb new Error("Invalid Layer Name: #{name}")
|
191 |
|
192 | layer = new Layer name, layerConfig, repoName, mainConfig, program.local
|
193 | layer.on "error", (err) -> return cb err
|
194 | layer.on "ready", ->
|
195 | cb null, layer
|
196 |
|
197 |
|
198 | finish = (err) ->
|
199 | if err?
|
200 | console.log "!!! " + err.message
|
201 | console.log "stack follows:\n\n #{err.stack}"
|
202 | process.exit 1
|
203 | console.log "OK"
|
204 |
|
205 |
|
206 | module.exports = program
|