UNPKG

6.99 kBtext/coffeescriptView Raw
1_ = require 'underscore'
2fs = require 'fs-extra'
3os = require 'os'
4path = require 'path'
5shell = require "shelljs"
6helpers = require '../modules/common/helpers'
7Processes = require '../lib/processes'
8EventEmitter = require("events").EventEmitter
9{spawn} = require 'child_process'
10{findFile, guard} = require '../modules/common/helpers'
11urlp = require 'url'
12
13
14url =
15 isAbsolutePath: (s)->
16 s.indexOf '/' > 0
17
18 isRelativePath: (s)->
19 s.indexOf('./') > 0 or s.indexOf('../') > 0
20
21 isGitRepo: (s)->
22 s.indexOf('git@') >=0 and s.indexOf('.git') > 0
23
24 isZipUrl: (s)->
25 s.indexOf('http://') >=0 or s.indexOf('https://')>0
26
27class Installer
28 constructor:(@from, @basedir)->
29
30 getKite:(callback)=>
31 if fs.existsSync @to and fs.existsSync path.join(@to, 'manifest.json')
32 callback new KDKite(@to)
33 else
34 @install(callback)
35
36class ZipInstaller extends Installer
37 install: (callback)->
38 pass
39
40 @test: (src)->
41 url.isZipUrl(src)
42
43class GitInstaller extends Installer
44
45 constructor:(@from, @basedir)->
46 @kiteDir = @getRepoNameFromUrl(@from)
47 @to = path.normalize(path.join(@basedir, 'kites', @kiteDir))
48
49 getRepoNameFromUrl: (s) ->
50 /\/(.*)\.git$/.exec(s)[1].split('.kite')[0]
51
52 install:(callback)->
53 guard (not shell.which "git"), "You need git to install dependencies."
54 repoUrl = urlp.parse @from
55 unless repoUrl.hostname
56 console.log "Installing: ", @to
57 shell.mkdir "-p", @to
58 shell.exec "git clone --recursive -q #{@from} #{@to}", (err, res)->
59 console.log "#{@to} installed."
60 callback()
61
62 @test: (src)->
63 url.isGitRepo(src)
64
65
66class FileSystemInstaller extends Installer
67
68 constructor:(@from, @basedir)->
69 @to = path.normalize(path.join(@basedir, 'kites', path.basename(@from)))
70
71 install:(callback)=>
72 # installs kite from the given path, by copying all the files..
73 fs.mkdirs @to, (err)=>
74 guard err, "directory create failure", err
75 fs.copy @from, @to, (err)=>
76 if err
77 console.log "Error:", err
78 callback(err)
79 kite = new KDKite(@to)
80 callback(false, kite)
81
82 @test: (src)->
83 url.isAbsolutePath(src)
84
85getInstallerClass = (url)->
86 installers = [ZipInstaller, GitInstaller, FileSystemInstaller]
87 for i in installers
88 try
89 if i.test(url)
90 return i
91 catch E
92 console.log E
93
94
95module.exports = class KDKite extends EventEmitter
96
97 constructor: (dir)->
98 @dir = dir
99 @dependencies = []
100
101 cloneFrom: (skel, callback)->
102 env =
103 name: @name,
104 username: @username
105 mail: @mail
106 version: @version
107
108 helpers.createSkeleton
109 skel: skel
110 toPath: @dir
111 env: env
112 callback: (err)=>
113 console.log "err: ", err
114 callback(err)
115
116 prepare: (callback)=>
117 @manifest = @getManifest =>
118 @findDependencies (err, deps)=>
119 guard err, "Error when installing dependency"
120 @emit "ready"
121 if callback
122 callback(false, @)
123
124 removeDependency: (depPath, callback)->
125 getManifest =>
126 @manifest.dependencies = _.reject @manifest.dependencies, (el)-> el == depPath
127 @saveManifest callback
128
129 addDependency: (p, callback)->
130 @getManifest =>
131 if p not in @manifest.dependencies
132 @manifest.dependencies.push p
133 @saveManifest callback
134 else
135 callback()
136
137 saveManifest: (callback)->
138 data = JSON.stringify @manifest, null, "\t"
139 fs.writeFile @manifestPath.fullpath, data, (err)=>
140 guard err, "Couldn't save manifest file", err
141 callback(err)
142
143 getManifest: (callback)->
144 @manifestPath = findFile @dir, ['.manifest', 'manifest.json']
145 guard not @manifestPath, "Couldn't find your manifest file - #{@dir}"
146
147 fs.readFile @manifestPath.fullpath, 'utf-8', (err, content)=>
148 guard err, "Couldnt read your manifest file, io error", err
149 try
150 @manifest = JSON.parse content
151 catch E
152 console.log "Error in your manifest file"
153 throw E
154 @name = @manifest.name
155 @version = @manifest.version
156 @username = @manifest.username
157 @mail = @manifest.mail
158 callback()
159
160 findDependencies: (callback) ->
161 # dependencies are some other kites in a tree based structure
162 # mykite
163 # \_> someotherkite
164 # \_> another kite
165 # this finds the dependencies, and installs them as needed
166 if @manifest.dependencies?.length > 0
167 cb = 0
168 for source in @manifest.dependencies
169 klass = getInstallerClass(source)
170 installer = new klass(source, @dir)
171 try
172 cb++
173 installer.getKite (err, kite)=>
174 kite.prepare (err, kite)=>
175 @dependencies.push kite
176 cb--
177 catch e
178 console.log "error", e
179 interval = setInterval =>
180 if cb is 0
181 callback(false, @dependencies)
182 clearInterval interval
183 , 0
184 else
185 callback(false,[])
186
187 listDependencies:(depth=0)->
188 @getManifest =>
189
190 pad = ""
191 for i in [0..(depth*2)]
192 pad += " "
193
194 if @manifest.dependencies?.length > 0
195 for dep in @manifest.dependencies
196 console.log "#{pad}", dep
197 toPath = @getRealPathFromDependency(dep)
198 depKite = new KDKite(toPath)
199 depKite.listDependencies(depth+1)
200
201
202 npm: (callback)->
203 curDir = process.cwd()
204 process.chdir(@dir)
205 install = spawn "npm", ["install"]
206 install.stdout.on "data", (data)-> process.stdout.write data
207 install.stderr.on "data", (data)-> process.stdout.write data
208 install.on "close", ->
209 process.stdout.write os.EOL
210 process.chdir(curDir)
211 callback()
212
213 spawn: (executable, entryPoint, args)=>
214 args = [entryPoint].concat args
215 @processes.spawn {cmd:executable, args, verbose:true, name:path.basename(@dir)}, (err, child)->
216 guard err, "Couldn't run kite #{err}"
217 console.log "now running the kite", entryPoint
218
219 run:(options)=>
220
221 tryFiles = (paths)->
222 for p in paths
223 if fs.existsSync p
224 return p
225
226 # TODO: which didnt work in vagrant/lxc, thats why this is here.
227 coffeePath = tryFiles ["/usr/bin/coffee","/usr/local/bin/coffee"]
228 console.log "coffeePath", coffeePath
229 nodeJsPath = tryFiles ["/usr/bin/nodejs", "/usr/local/bin/nodejs"]
230
231 @npm =>
232 # do we have a coffee file or js file for index.
233 executablesMap = {'index.coffee': coffeePath, 'index.js': nodeJsPath}
234 entryPoint = findFile(@dir, executablesMap)
235 guard not entryPoint, "Can't find your index.coffee or index.js file"
236 executable = executablesMap[entryPoint.key]
237 guard not executable, "cant find executable for " + JSON.stringify(executablesMap)
238
239 for dep in @dependencies
240 dep.processes = @processes
241 dep.prepare (err, obj)->
242 console.log "!!!!! prepared", obj.dir
243 obj.run()
244 @spawn executable, entryPoint.fullpath, ['--messagebusport', options.messageBusPort]