bonethug 0.0.67 → 0.0.68

Sign up to get free protection for your applications and to get access to all the features.
Files changed (151) hide show
  1. data/.gitignore +1 -0
  2. data/Gemfile +0 -0
  3. data/ISSUES.txt +0 -0
  4. data/LICENSE.txt +0 -0
  5. data/README.md +0 -0
  6. data/Rakefile +0 -0
  7. data/TODO.txt +5 -4
  8. data/bin/bonethug +0 -0
  9. data/bin/thug +0 -0
  10. data/bonethug.gemspec +0 -0
  11. data/config/backup.rb +0 -0
  12. data/config/cnf.yml +184 -177
  13. data/config/deploy.rb +68 -26
  14. data/config/schedule.rb +0 -0
  15. data/config/syncer.rb +0 -0
  16. data/lib/bonethug/cli.rb +242 -242
  17. data/lib/bonethug/conf.rb +0 -0
  18. data/lib/bonethug/installer.rb +378 -378
  19. data/lib/bonethug/utils.rb +0 -0
  20. data/lib/bonethug/version.rb +2 -2
  21. data/lib/bonethug/watcher.rb +0 -0
  22. data/lib/bonethug.rb +0 -0
  23. data/lib/tasks/bonethug.rake +0 -0
  24. data/scripts/ubuntu_setup.sh +0 -0
  25. data/scripts/ubuntu_setup_2.4.sh +106 -0
  26. data/skel/base/.gitignore +0 -0
  27. data/skel/base/Gemfile +0 -0
  28. data/skel/base/README.md +0 -0
  29. data/skel/base/config/example/.gitkeep +0 -0
  30. data/skel/base/lib/.gitkeep +0 -0
  31. data/skel/base/log/.gitkeep +0 -0
  32. data/skel/base/public/favicon.ico +0 -0
  33. data/skel/base/public/robots.txt +0 -0
  34. data/skel/project_types/drupal/.gitignore +0 -0
  35. data/skel/project_types/drupal/composer.json +0 -0
  36. data/skel/project_types/drupal/lib/flush_drupal_cache.php +0 -0
  37. data/skel/project_types/drupal/public/sites/all/themes/project/.keep +0 -0
  38. data/skel/project_types/drupal/public/sites/default/development.settings.php +0 -0
  39. data/skel/project_types/drupal/public/sites/default/production.settings.php +0 -0
  40. data/skel/project_types/drupal/public/sites/default/settings.php +0 -0
  41. data/skel/project_types/drupal/public/sites/default/staging.settings.php +0 -0
  42. data/skel/project_types/drupal6/.gitignore +0 -0
  43. data/skel/project_types/drupal6/composer.json +0 -0
  44. data/skel/project_types/drupal6/lib/flush_drupal_cache.php +0 -0
  45. data/skel/project_types/drupal6/public/sites/all/themes/project/.keep +0 -0
  46. data/skel/project_types/drupal6/public/sites/default/development.settings.php +0 -0
  47. data/skel/project_types/drupal6/public/sites/default/production.settings.php +0 -0
  48. data/skel/project_types/drupal6/public/sites/default/settings.php +0 -0
  49. data/skel/project_types/drupal6/public/sites/default/staging.settings.php +0 -0
  50. data/skel/project_types/drupal7/.gitignore +0 -0
  51. data/skel/project_types/drupal7/composer.json +0 -0
  52. data/skel/project_types/drupal7/lib/flush_drupal_cache.php +0 -0
  53. data/skel/project_types/drupal7/public/sites/all/themes/project/.keep +0 -0
  54. data/skel/project_types/drupal7/public/sites/default/development.settings.php +0 -0
  55. data/skel/project_types/drupal7/public/sites/default/production.settings.php +0 -0
  56. data/skel/project_types/drupal7/public/sites/default/settings.php +0 -0
  57. data/skel/project_types/drupal7/public/sites/default/staging.settings.php +0 -0
  58. data/skel/project_types/drupal8/.gitignore +0 -0
  59. data/skel/project_types/drupal8/composer.json +0 -0
  60. data/skel/project_types/drupal8/lib/flush_drupal_cache.php +0 -0
  61. data/skel/project_types/drupal8/public/sites/all/themes/project/.keep +0 -0
  62. data/skel/project_types/drupal8/public/sites/default/development.settings.php +0 -0
  63. data/skel/project_types/drupal8/public/sites/default/production.settings.php +0 -0
  64. data/skel/project_types/drupal8/public/sites/default/settings.php +0 -0
  65. data/skel/project_types/drupal8/public/sites/default/staging.settings.php +0 -0
  66. data/skel/project_types/php/.gitignore +0 -0
  67. data/skel/project_types/php/composer.json +0 -0
  68. data/skel/project_types/rails3/Gemfile +0 -0
  69. data/skel/project_types/rails3/README.md +0 -0
  70. data/skel/project_types/rails4/Gemfile +0 -0
  71. data/skel/project_types/rails4/README.md +0 -0
  72. data/skel/project_types/rails4/app/assets/fonts/.keep +0 -0
  73. data/skel/project_types/rails4/app/assets/images/.keep +0 -0
  74. data/skel/project_types/rails4/app/assets/images/favicons/apple-touch-icon-114x114.png +0 -0
  75. data/skel/project_types/rails4/app/assets/images/favicons/apple-touch-icon-120x120.png +0 -0
  76. data/skel/project_types/rails4/app/assets/images/favicons/apple-touch-icon-144x144.png +0 -0
  77. data/skel/project_types/rails4/app/assets/images/favicons/apple-touch-icon-152x152.png +0 -0
  78. data/skel/project_types/rails4/app/assets/images/favicons/apple-touch-icon-57x57.png +0 -0
  79. data/skel/project_types/rails4/app/assets/images/favicons/apple-touch-icon-60x60.png +0 -0
  80. data/skel/project_types/rails4/app/assets/images/favicons/apple-touch-icon-72x72.png +0 -0
  81. data/skel/project_types/rails4/app/assets/images/favicons/apple-touch-icon-76x76.png +0 -0
  82. data/skel/project_types/rails4/app/assets/images/favicons/apple-touch-icon.png +0 -0
  83. data/skel/project_types/rails4/app/assets/images/favicons/favicon.ico +0 -0
  84. data/skel/project_types/rails4/app/assets/images/favicons/iconifier-readme.txt +0 -0
  85. data/skel/project_types/rails4/app/assets/javascripts/application.js +0 -0
  86. data/skel/project_types/rails4/app/assets/javascripts/lte-ie8-shims.js +0 -0
  87. data/skel/project_types/rails4/app/assets/javascripts/main.js.coffee +0 -0
  88. data/skel/project_types/rails4/app/assets/stylesheets/application.css.scss +0 -0
  89. data/skel/project_types/rails4/app/assets/stylesheets/main.scss +0 -0
  90. data/skel/project_types/rails4/app/controllers/errors_controller.rb +0 -0
  91. data/skel/project_types/rails4/app/helpers/application_helper.rb +0 -0
  92. data/skel/project_types/rails4/app/views/application/index.html.erb +0 -0
  93. data/skel/project_types/rails4/app/views/errors/not_found.html.erb +0 -0
  94. data/skel/project_types/rails4/app/views/errors/server_error.html.erb +0 -0
  95. data/skel/project_types/rails4/app/views/layouts/application.html.erb +0 -0
  96. data/skel/project_types/rails4/config/application.rb +0 -0
  97. data/skel/project_types/rails4/config/environments/development.rb +0 -0
  98. data/skel/project_types/rails4/config/environments/production.rb +0 -0
  99. data/skel/project_types/rails4/config/environments/staging.rb +0 -0
  100. data/skel/project_types/rails4/config/environments/test.rb +0 -0
  101. data/skel/project_types/rails4/config/routes.rb +0 -0
  102. data/skel/project_types/silverstripe3/.bowerrc +0 -0
  103. data/skel/project_types/silverstripe3/.gitignore +0 -0
  104. data/skel/project_types/silverstripe3/README.md +0 -0
  105. data/skel/project_types/silverstripe3/bower.json +0 -0
  106. data/skel/project_types/silverstripe3/composer.json +26 -26
  107. data/skel/project_types/silverstripe3/lib/ss_loadconf.php +0 -0
  108. data/skel/project_types/silverstripe3/public/.htaccess +0 -0
  109. data/skel/project_types/silverstripe3/public/_ss_environment.php +0 -0
  110. data/skel/project_types/silverstripe3/public/assets/error-404.html +0 -0
  111. data/skel/project_types/silverstripe3/public/assets/error-500.html +0 -0
  112. data/skel/project_types/silverstripe3/public/index.php.bak +0 -0
  113. data/skel/project_types/silverstripe3/public/project/.htaccess +0 -0
  114. data/skel/project_types/silverstripe3/public/project/_config/config.yml +0 -0
  115. data/skel/project_types/silverstripe3/public/project/_config.php +0 -0
  116. data/skel/project_types/silverstripe3/public/project/code/Controllers/.gitkeep +0 -0
  117. data/skel/project_types/silverstripe3/public/project/code/Extensions/.gitkeep +0 -0
  118. data/skel/project_types/silverstripe3/public/project/code/Forms/.gitkeep +0 -0
  119. data/skel/project_types/silverstripe3/public/project/code/Objects/.gitkeep +0 -0
  120. data/skel/project_types/silverstripe3/public/project/code/Pages/HomePage.php +0 -0
  121. data/skel/project_types/silverstripe3/public/project/code/Pages/Page.php +0 -0
  122. data/skel/project_types/silverstripe3/public/project/code/Pages/RootPage.php +0 -0
  123. data/skel/project_types/silverstripe3/public/project/code/Tasks/.gitkeep +0 -0
  124. data/skel/project_types/silverstripe3/public/project/coffee/application.js.coffee +0 -0
  125. data/skel/project_types/silverstripe3/public/project/javascript/.gitkeep +0 -0
  126. data/skel/project_types/silverstripe3/public/silverstripe-cache/.gitkeep +0 -0
  127. data/skel/project_types/silverstripe3/public/themes/project/css/.gitkeep +0 -0
  128. data/skel/project_types/silverstripe3/public/themes/project/css/editor.css +0 -0
  129. data/skel/project_types/silverstripe3/public/themes/project/css/typography.css +0 -0
  130. data/skel/project_types/silverstripe3/public/themes/project/images/favicons/apple-touch-icon-114x114.png +0 -0
  131. data/skel/project_types/silverstripe3/public/themes/project/images/favicons/apple-touch-icon-120x120.png +0 -0
  132. data/skel/project_types/silverstripe3/public/themes/project/images/favicons/apple-touch-icon-144x144.png +0 -0
  133. data/skel/project_types/silverstripe3/public/themes/project/images/favicons/apple-touch-icon-152x152.png +0 -0
  134. data/skel/project_types/silverstripe3/public/themes/project/images/favicons/apple-touch-icon-57x57.png +0 -0
  135. data/skel/project_types/silverstripe3/public/themes/project/images/favicons/apple-touch-icon-60x60.png +0 -0
  136. data/skel/project_types/silverstripe3/public/themes/project/images/favicons/apple-touch-icon-72x72.png +0 -0
  137. data/skel/project_types/silverstripe3/public/themes/project/images/favicons/apple-touch-icon-76x76.png +0 -0
  138. data/skel/project_types/silverstripe3/public/themes/project/images/favicons/apple-touch-icon.png +0 -0
  139. data/skel/project_types/silverstripe3/public/themes/project/images/favicons/favicon.ico +0 -0
  140. data/skel/project_types/silverstripe3/public/themes/project/images/favicons/iconifier-readme.txt +0 -0
  141. data/skel/project_types/silverstripe3/public/themes/project/scss/_functions.scss +0 -0
  142. data/skel/project_types/silverstripe3/public/themes/project/scss/_mixins.scss +0 -0
  143. data/skel/project_types/silverstripe3/public/themes/project/scss/_vars.scss +0 -0
  144. data/skel/project_types/silverstripe3/public/themes/project/scss/main.scss +0 -0
  145. data/skel/project_types/silverstripe3/public/themes/project/scss/typography.scss +0 -0
  146. data/skel/project_types/silverstripe3/public/themes/project/templates/Includes/.gitkeep +0 -0
  147. data/skel/project_types/silverstripe3/public/themes/project/templates/Layout/Page.ss +0 -0
  148. data/skel/project_types/silverstripe3/public/themes/project/templates/Layout/Security.ss +0 -0
  149. data/skel/project_types/silverstripe3/public/themes/project/templates/Page.ss +0 -0
  150. data/skel/skel.yml +0 -0
  151. metadata +3 -2
@@ -1,379 +1,379 @@
1
- # Todo
2
- # ----------------
3
- # - Have some sort of safe vs forced install - tie in with exlcuded paths
4
- # - Check that excluded paths is working in manifest
5
- # - bonethug init seems doesn't seem to update gemfile if there is one
6
- # - Gemfile, .gitignore, composer.json need to be no go zones
7
- # - for rails it should copy the gem file call bundle install, do a cleanup then call bundle exec rails new application_name
8
- # ----------------
9
-
10
- require 'rubygems'
11
- require 'bonethug/conf'
12
- require 'fileutils'
13
- require 'find'
14
- require 'digest/md5'
15
- require 'yaml'
16
-
17
- module Bonethug
18
-
19
- class Installer
20
-
21
- include FileUtils
22
- include Digest
23
-
24
- @@bonthug_gem_dir = File.expand_path(File.dirname(__FILE__) + '/../..')
25
- @@skel_dir = @@bonthug_gem_dir + '/skel'
26
- @@conf = Conf.new.add(@@skel_dir + '/skel.yml')
27
- @@project_config_files = {editable: ['cnf.yml','schedule.rb'], generated: ['backup.rb','deploy.rb']}
28
-
29
- def self.install(type, target = '.')
30
-
31
- # @@conf = Conf.new.add(@@skel_dir + '/skel.yml')
32
-
33
- # create full path
34
- target = File.expand_path target
35
-
36
- # let the user know we are installing
37
- puts 'Installing '+ type + ' to ' + target + '...'
38
-
39
- # load the configuration
40
- unless @@conf.get('project_types').has_key? type.to_s
41
- puts "Unsupported type: " + type.to_s
42
- exit
43
- end
44
- conf = @@conf.node_merge 'base', 'project_types.' + type
45
-
46
- # set the tmp dir
47
- tmp_dir = File.expand_path target + '/.bonethug-tmp'
48
-
49
- # clean up any exisitng install tmp files
50
- if File.directory? tmp_dir
51
- puts 'Cleaning up old installer temporary files...'
52
- FileUtils.rm_rf tmp_dir
53
- end
54
-
55
- # create tmp dir
56
- puts 'Creating build directory at ' + tmp_dir
57
- FileUtils.mkdir tmp_dir
58
- FileUtils.mkdir tmp_dir + '/.bonethug'
59
-
60
- # build the file set
61
- puts 'Building ' + type + ' skeleton...'
62
- FileUtils.cp_r @@skel_dir + '/base/.', tmp_dir
63
- FileUtils.cp_r @@skel_dir + '/project_types/' + type + '/.', tmp_dir
64
-
65
- # build the manifest
66
- puts 'Creating manifest...'
67
- self.build_manifest tmp_dir
68
-
69
- # modify the manifest root
70
- manifest_path = tmp_dir + '/.bonethug/manifest'
71
- File.open(manifest_path,'w') do |file|
72
- file.puts File.read(manifest_path).gsub(/\.bonethug-tmp/,'')
73
- end
74
-
75
- # clean up the target dir
76
- puts 'Cleaning up install directory...'
77
- self.clean target
78
-
79
- # copy the files
80
- puts 'Installing build to ' + target + '...'
81
- FileUtils.cp_r tmp_dir + '/.', target
82
-
83
- # try to update the configuration files
84
- puts 'Updating build informtation...'
85
- self.save_project_meta_data(target)
86
-
87
- # clean up any exisitng install tmp files
88
- puts 'Cleaning up temporary files...'
89
- FileUtils.rm_rf tmp_dir
90
-
91
- puts "Installation Complete"
92
-
93
- # try to update the configuration files
94
- puts 'Updating configs...'
95
- self.bonethugise(target, :init)
96
-
97
- end
98
-
99
- def self.clean(target)
100
-
101
- manifest_path = target + '/.bonethug/manifest'
102
-
103
- if File.exists? manifest_path
104
-
105
- puts 'Reading manifest...'
106
- manifest = File.read(manifest_path).split("\n")
107
-
108
- puts 'Cleaning up ' + manifest.count.to_s + ' files'
109
- not_removed = []
110
- manifest.each do |file|
111
- not_removed.push file unless self.try_delete file
112
- end
113
-
114
- if not_removed.count > 0
115
-
116
- puts 'Retrying removal of ' + not_removed.count.to_s + ' files'
117
- failed = []
118
- not_removed.each do |file|
119
- failed.push file unless self.try_delete file
120
- end
121
-
122
- puts 'Removal of the following' + failed.count.to_s + ' files failed'
123
- puts failed.join("\n")
124
-
125
- end
126
-
127
- else
128
- puts 'Nothing to do'
129
- end
130
- self
131
- end
132
-
133
- # Prepares init db scripts
134
- # --------------------------
135
-
136
- def self.init_mysql_db_script(db, path, admin_user = 'root')
137
-
138
- script_content = "
139
- CREATE DATABASE IF NOT EXISTS " + db.get('name') + ";
140
- GRANT ALL ON " + db.get('name') + ".* TO " + db.get('user') + "@" + db.get('host') + (db.get('pass') ? " IDENTIFIED BY " + db.get('pass') : "") + ";
141
- FLUSH PRIVILEGES;
142
- "
143
- cmd = 'cd ' + path + ' && ' +
144
- 'echo "' + script_content + '" > .bonethug/sql.txt && ' +
145
- 'mysql -h ' + db.get('host') + ' -u ' + admin_user + ' -p < .bonethug/sql.txt'
146
-
147
- end
148
-
149
- def self.execute_init_mysql_db_script(env, admin_user = 'root', path = '.')
150
-
151
- exec_path = File.expand_path(path)
152
- conf = Bonethug::Conf.new.add(exec_path + '/config/cnf.yml')
153
- conf.add(exec_path + '/config/database.yml' => { root: 'dbs.default' }) if File.exist? exec_path + '/config/database.yml'
154
-
155
- conf.get('dbs').each do |name,envs|
156
-
157
- db = envs.get env
158
- puts "creating: " + db.get('name')
159
- system Bonethug::Installer.init_mysql_db_script(db, path, admin_user)
160
-
161
- end
162
-
163
- end
164
-
165
-
166
- # Reads system setup scripts
167
- # --------------------------
168
-
169
- def self.get_setup_script
170
- @@bonthug_gem_dir + '/scripts/ubuntu_setup.sh'
171
- end
172
-
173
- def self.get_setup_script_content
174
- File.read self.get_setup_script
175
- end
176
-
177
- def self.get_setup_env_cmds
178
- self.parse_sh self.get_setup_script_content
179
- end
180
-
181
- def self.parse_sh(content)
182
- content.split("\n").select { |line| !(line =~ /^[\s\t]+$/ || line =~ /^[\s\t]*#/ || line.strip.length == 0) }
183
- end
184
-
185
- # ---------
186
- # Protected
187
- # ---------
188
-
189
- protected
190
-
191
- def self.try_delete(file)
192
- if (File.directory?(file) and Find.find(file).empty?) or File.file?(file)
193
- rm_rf file
194
- return false if File.exists? file
195
- return true
196
- else
197
- return false
198
- end
199
- end
200
-
201
- def self.build_manifest(dir)
202
- dir_contents = Find.find(dir).map { |p| File.expand_path(p) }
203
- manifest = dir_contents - ((@@conf.get('exlcuded_paths','Array') || []).map { |p| File.expand_path(p) })
204
- File.open(dir + '/.bonethug/manifest','w') { |file| file.puts manifest.join("\n") }
205
- self
206
- end
207
-
208
- def self.contents_md5(file)
209
- return false unless File.exist?(file)
210
- MD5.digest File.read(file)
211
- end
212
-
213
- def self.save_project_meta_data(base_dir)
214
-
215
- meta_data = {'config_digests' => {}}
216
- @@project_config_files[:editable].each do |file|
217
- meta_data['config_digests']['example/' + file] = self.contents_md5(base_dir + '/config/example/' + file)
218
- end
219
- File.open(base_dir + '/.bonethug/data','w') { |file| file.puts meta_data.to_yaml }
220
-
221
- # return self for chaining
222
- self
223
-
224
- end
225
-
226
- def self.get_project_meta_data(base_dir)
227
-
228
- data_file = base_dir + '/.bonethug/data'
229
- return YAML.load_file data_file if File.exists? data_file
230
- return false
231
-
232
- end
233
-
234
- # mode == :init
235
- # copy cnf.yml + schedule.rb to config if possible
236
- # copy cnf.yml + schedule.rb to config/example if possible
237
- # copy backup.rb and deploy.rb to .bonethug if possible
238
- # add bonethug to gemfile if required
239
- # run bundle install
240
-
241
- # mode == :update
242
- # copy cnf.yml + schedule.rb to config if possible
243
- # force copy cnf.yml + schedule.rb to config/example
244
- # force copy backup.rb and deploy.rb to .bonethug
245
- # add bonethug to gemfile if required
246
- # run bundle install
247
-
248
- def self.bonethugise(dir='.', mode=:init)
249
-
250
- target = File.expand_path(dir)
251
-
252
- # run bundle update first
253
- system('bundle update bonethug') if mode == :update
254
-
255
- # check for the existence of required dirs and create if required
256
- [target + '/.bonethug', target + '/config', target + '/config/example'].each do |path|
257
- FileUtils.mkdir path unless File.directory? path
258
- end
259
-
260
- # Handle config files
261
- @@project_config_files.each do |type, dirs|
262
- dirs.each do |config|
263
-
264
- # vars
265
- src_file = @@bonthug_gem_dir + '/config/' + config
266
- example_file = target + '/config/example/' + config if type == :editable
267
- target_file = type == :editable ? target + '/config/' + config : target + '/.bonethug/' + config
268
-
269
- # output
270
- puts 'Handling ' + target_file
271
-
272
- # what mode are we in?
273
- if mode == :init
274
- FileUtils.cp src_file, example_file if type == :editable and !File.exist?(example_file)
275
- FileUtils.cp src_file, target_file unless File.exist?(target_file)
276
- elsif mode == :update
277
- FileUtils.cp src_file, example_file if type == :editable
278
- FileUtils.cp src_file, target_file if type == :generated or !File.exist?(target_file)
279
- else
280
- puts "Invalid bonethugise mode"
281
- exit
282
- end
283
-
284
- end
285
- end
286
-
287
- # Handle project type specific files
288
- if mode == :update
289
- target_cnf = target + '/config/cnf.yml'
290
- project_conf = Conf.new.add target_cnf
291
- project_type = project_conf.get('deploy.common.project_type')
292
- if project_type
293
- bonethug_files = @@conf.get 'project_types.' + project_type + '.bonethug_files'
294
- if bonethug_files
295
- bonethug_files.each do |index, file|
296
-
297
- # push some output
298
- puts 'Handling ' + index.to_s + ':' + file.to_s
299
-
300
- # do the copy
301
- src_file = @@bonthug_gem_dir + '/skel/project_types/' + project_type + '/' + file
302
- dst_file = target + '/' + file
303
- FileUtils.cp src_file, dst_file
304
-
305
- end
306
- end
307
- else
308
- puts "Couldn't find project type in " + target_cnf
309
- end
310
- end
311
-
312
- # handle gemfile
313
- gemfile_path = target + '/Gemfile'
314
- if File.exist? gemfile_path
315
-
316
- # extract the contents
317
- gemfile_contents = File.read(gemfile_path)
318
-
319
- # identify what we are looking for
320
- required_gems = {
321
- 'mina' => 'nadarei/mina',
322
- 'astrails-safe' => 'astrails/safe',
323
- 'whenever' => 'javan/whenever',
324
- 'guard-erb' => 'azt3k/guard-erb',
325
- 'bonethug' => nil
326
- }
327
-
328
- # look at each requirement and identify if we need things
329
- required_gems.each do |gem_name, github|
330
-
331
- add_gem = false;
332
- gem_reg = Regexp.new('gem[^"\']+["\']'+gem_name+'["\']')
333
- git_reg = Regexp.new('gem[^"\']+["\']'+gem_name+'["\'],[^,]+github: ["\']'+github+'["\']') if github
334
-
335
- if gem_reg =~ gemfile_contents
336
- puts 'Found '+gem_name+' in gem file.'
337
- if github
338
- puts 'Requires github version, checking...'
339
- unless git_reg =~ gemfile_contents
340
- puts 'Couldn\'t find '+gem_name+' (github) in gem file adding...'
341
- gemfile_contents.gsub(gem_reg,'')
342
- add_gem = true;
343
- end
344
- end
345
- else
346
- puts "Couldn't find "+gem_name+" in gem file adding..."
347
- add_gem = true;
348
- end
349
-
350
- if add_gem
351
- gemfile_contents += "\n" + 'gem "'+gem_name+'"'+(github ? ', github: "'+github+'"' : '')
352
- File.open(gemfile_path,'w') { |file| file.puts gemfile_contents }
353
- end
354
-
355
- end
356
-
357
- else
358
- puts 'No Gemfile found, creating one...'
359
- FileUtils.cp @@skel_dir + '/base/Gemfile', gemfile_path
360
- end
361
-
362
- # run bundler
363
- exec 'bundle install --path vendor'
364
-
365
- # self
366
-
367
- end
368
-
369
- def self.update(dir = '.')
370
- self.bonethugise(dir,:update)
371
- end
372
-
373
- def self.init(dir = '.')
374
- self.bonethugise(dir,:init)
375
- end
376
-
377
- end
378
-
1
+ # Todo
2
+ # ----------------
3
+ # - Have some sort of safe vs forced install - tie in with exlcuded paths
4
+ # - Check that excluded paths is working in manifest
5
+ # - bonethug init seems doesn't seem to update gemfile if there is one
6
+ # - Gemfile, .gitignore, composer.json need to be no go zones
7
+ # - for rails it should copy the gem file call bundle install, do a cleanup then call bundle exec rails new application_name
8
+ # ----------------
9
+
10
+ require 'rubygems'
11
+ require 'bonethug/conf'
12
+ require 'fileutils'
13
+ require 'find'
14
+ require 'digest/md5'
15
+ require 'yaml'
16
+
17
+ module Bonethug
18
+
19
+ class Installer
20
+
21
+ include FileUtils
22
+ include Digest
23
+
24
+ @@bonthug_gem_dir = File.expand_path(File.dirname(__FILE__) + '/../..')
25
+ @@skel_dir = @@bonthug_gem_dir + '/skel'
26
+ @@conf = Conf.new.add(@@skel_dir + '/skel.yml')
27
+ @@project_config_files = {editable: ['cnf.yml','schedule.rb'], generated: ['backup.rb','deploy.rb']}
28
+
29
+ def self.install(type, target = '.')
30
+
31
+ # @@conf = Conf.new.add(@@skel_dir + '/skel.yml')
32
+
33
+ # create full path
34
+ target = File.expand_path target
35
+
36
+ # let the user know we are installing
37
+ puts 'Installing '+ type + ' to ' + target + '...'
38
+
39
+ # load the configuration
40
+ unless @@conf.get('project_types').has_key? type.to_s
41
+ puts "Unsupported type: " + type.to_s
42
+ exit
43
+ end
44
+ conf = @@conf.node_merge 'base', 'project_types.' + type
45
+
46
+ # set the tmp dir
47
+ tmp_dir = File.expand_path target + '/.bonethug-tmp'
48
+
49
+ # clean up any exisitng install tmp files
50
+ if File.directory? tmp_dir
51
+ puts 'Cleaning up old installer temporary files...'
52
+ FileUtils.rm_rf tmp_dir
53
+ end
54
+
55
+ # create tmp dir
56
+ puts 'Creating build directory at ' + tmp_dir
57
+ FileUtils.mkdir tmp_dir
58
+ FileUtils.mkdir tmp_dir + '/.bonethug'
59
+
60
+ # build the file set
61
+ puts 'Building ' + type + ' skeleton...'
62
+ FileUtils.cp_r @@skel_dir + '/base/.', tmp_dir
63
+ FileUtils.cp_r @@skel_dir + '/project_types/' + type + '/.', tmp_dir
64
+
65
+ # build the manifest
66
+ puts 'Creating manifest...'
67
+ self.build_manifest tmp_dir
68
+
69
+ # modify the manifest root
70
+ manifest_path = tmp_dir + '/.bonethug/manifest'
71
+ File.open(manifest_path,'w') do |file|
72
+ file.puts File.read(manifest_path).gsub(/\.bonethug-tmp/,'')
73
+ end
74
+
75
+ # clean up the target dir
76
+ puts 'Cleaning up install directory...'
77
+ self.clean target
78
+
79
+ # copy the files
80
+ puts 'Installing build to ' + target + '...'
81
+ FileUtils.cp_r tmp_dir + '/.', target
82
+
83
+ # try to update the configuration files
84
+ puts 'Updating build informtation...'
85
+ self.save_project_meta_data(target)
86
+
87
+ # clean up any exisitng install tmp files
88
+ puts 'Cleaning up temporary files...'
89
+ FileUtils.rm_rf tmp_dir
90
+
91
+ puts "Installation Complete"
92
+
93
+ # try to update the configuration files
94
+ puts 'Updating configs...'
95
+ self.bonethugise(target, :init)
96
+
97
+ end
98
+
99
+ def self.clean(target)
100
+
101
+ manifest_path = target + '/.bonethug/manifest'
102
+
103
+ if File.exists? manifest_path
104
+
105
+ puts 'Reading manifest...'
106
+ manifest = File.read(manifest_path).split("\n")
107
+
108
+ puts 'Cleaning up ' + manifest.count.to_s + ' files'
109
+ not_removed = []
110
+ manifest.each do |file|
111
+ not_removed.push file unless self.try_delete file
112
+ end
113
+
114
+ if not_removed.count > 0
115
+
116
+ puts 'Retrying removal of ' + not_removed.count.to_s + ' files'
117
+ failed = []
118
+ not_removed.each do |file|
119
+ failed.push file unless self.try_delete file
120
+ end
121
+
122
+ puts 'Removal of the following' + failed.count.to_s + ' files failed'
123
+ puts failed.join("\n")
124
+
125
+ end
126
+
127
+ else
128
+ puts 'Nothing to do'
129
+ end
130
+ self
131
+ end
132
+
133
+ # Prepares init db scripts
134
+ # --------------------------
135
+
136
+ def self.init_mysql_db_script(db, path, admin_user = 'root')
137
+
138
+ script_content = "
139
+ CREATE DATABASE IF NOT EXISTS " + db.get('name') + ";
140
+ GRANT ALL ON " + db.get('name') + ".* TO " + db.get('user') + "@" + db.get('host') + (db.get('pass') ? " IDENTIFIED BY " + db.get('pass') : "") + ";
141
+ FLUSH PRIVILEGES;
142
+ "
143
+ cmd = 'cd ' + path + ' && ' +
144
+ 'echo "' + script_content + '" > .bonethug/sql.txt && ' +
145
+ 'mysql -h ' + db.get('host') + ' -u ' + admin_user + ' -p < .bonethug/sql.txt'
146
+
147
+ end
148
+
149
+ def self.execute_init_mysql_db_script(env, admin_user = 'root', path = '.')
150
+
151
+ exec_path = File.expand_path(path)
152
+ conf = Bonethug::Conf.new.add(exec_path + '/config/cnf.yml')
153
+ conf.add(exec_path + '/config/database.yml' => { root: 'dbs.default' }) if File.exist? exec_path + '/config/database.yml'
154
+
155
+ conf.get('dbs').each do |name,envs|
156
+
157
+ db = envs.get env
158
+ puts "creating: " + db.get('name')
159
+ system Bonethug::Installer.init_mysql_db_script(db, path, admin_user)
160
+
161
+ end
162
+
163
+ end
164
+
165
+
166
+ # Reads system setup scripts
167
+ # --------------------------
168
+
169
+ def self.get_setup_script
170
+ @@bonthug_gem_dir + '/scripts/ubuntu_setup.sh'
171
+ end
172
+
173
+ def self.get_setup_script_content
174
+ File.read self.get_setup_script
175
+ end
176
+
177
+ def self.get_setup_env_cmds
178
+ self.parse_sh self.get_setup_script_content
179
+ end
180
+
181
+ def self.parse_sh(content)
182
+ content.split("\n").select { |line| !(line =~ /^[\s\t]+$/ || line =~ /^[\s\t]*#/ || line.strip.length == 0) }
183
+ end
184
+
185
+ # ---------
186
+ # Protected
187
+ # ---------
188
+
189
+ protected
190
+
191
+ def self.try_delete(file)
192
+ if (File.directory?(file) and Find.find(file).empty?) or File.file?(file)
193
+ rm_rf file
194
+ return false if File.exists? file
195
+ return true
196
+ else
197
+ return false
198
+ end
199
+ end
200
+
201
+ def self.build_manifest(dir)
202
+ dir_contents = Find.find(dir).map { |p| File.expand_path(p) }
203
+ manifest = dir_contents - ((@@conf.get('exlcuded_paths','Array') || []).map { |p| File.expand_path(p) })
204
+ File.open(dir + '/.bonethug/manifest','w') { |file| file.puts manifest.join("\n") }
205
+ self
206
+ end
207
+
208
+ def self.contents_md5(file)
209
+ return false unless File.exist?(file)
210
+ MD5.digest File.read(file)
211
+ end
212
+
213
+ def self.save_project_meta_data(base_dir)
214
+
215
+ meta_data = {'config_digests' => {}}
216
+ @@project_config_files[:editable].each do |file|
217
+ meta_data['config_digests']['example/' + file] = self.contents_md5(base_dir + '/config/example/' + file)
218
+ end
219
+ File.open(base_dir + '/.bonethug/data','w') { |file| file.puts meta_data.to_yaml }
220
+
221
+ # return self for chaining
222
+ self
223
+
224
+ end
225
+
226
+ def self.get_project_meta_data(base_dir)
227
+
228
+ data_file = base_dir + '/.bonethug/data'
229
+ return YAML.load_file data_file if File.exists? data_file
230
+ return false
231
+
232
+ end
233
+
234
+ # mode == :init
235
+ # copy cnf.yml + schedule.rb to config if possible
236
+ # copy cnf.yml + schedule.rb to config/example if possible
237
+ # copy backup.rb and deploy.rb to .bonethug if possible
238
+ # add bonethug to gemfile if required
239
+ # run bundle install
240
+
241
+ # mode == :update
242
+ # copy cnf.yml + schedule.rb to config if possible
243
+ # force copy cnf.yml + schedule.rb to config/example
244
+ # force copy backup.rb and deploy.rb to .bonethug
245
+ # add bonethug to gemfile if required
246
+ # run bundle install
247
+
248
+ def self.bonethugise(dir='.', mode=:init)
249
+
250
+ target = File.expand_path(dir)
251
+
252
+ # run bundle update first
253
+ system('bundle update bonethug') if mode == :update
254
+
255
+ # check for the existence of required dirs and create if required
256
+ [target + '/.bonethug', target + '/config', target + '/config/example'].each do |path|
257
+ FileUtils.mkdir path unless File.directory? path
258
+ end
259
+
260
+ # Handle config files
261
+ @@project_config_files.each do |type, dirs|
262
+ dirs.each do |config|
263
+
264
+ # vars
265
+ src_file = @@bonthug_gem_dir + '/config/' + config
266
+ example_file = target + '/config/example/' + config if type == :editable
267
+ target_file = type == :editable ? target + '/config/' + config : target + '/.bonethug/' + config
268
+
269
+ # output
270
+ puts 'Handling ' + target_file
271
+
272
+ # what mode are we in?
273
+ if mode == :init
274
+ FileUtils.cp src_file, example_file if type == :editable and !File.exist?(example_file)
275
+ FileUtils.cp src_file, target_file unless File.exist?(target_file)
276
+ elsif mode == :update
277
+ FileUtils.cp src_file, example_file if type == :editable
278
+ FileUtils.cp src_file, target_file if type == :generated or !File.exist?(target_file)
279
+ else
280
+ puts "Invalid bonethugise mode"
281
+ exit
282
+ end
283
+
284
+ end
285
+ end
286
+
287
+ # Handle project type specific files
288
+ if mode == :update
289
+ target_cnf = target + '/config/cnf.yml'
290
+ project_conf = Conf.new.add target_cnf
291
+ project_type = project_conf.get('deploy.common.project_type')
292
+ if project_type
293
+ bonethug_files = @@conf.get 'project_types.' + project_type + '.bonethug_files'
294
+ if bonethug_files
295
+ bonethug_files.each do |index, file|
296
+
297
+ # push some output
298
+ puts 'Handling ' + index.to_s + ':' + file.to_s
299
+
300
+ # do the copy
301
+ src_file = @@bonthug_gem_dir + '/skel/project_types/' + project_type + '/' + file
302
+ dst_file = target + '/' + file
303
+ FileUtils.cp src_file, dst_file
304
+
305
+ end
306
+ end
307
+ else
308
+ puts "Couldn't find project type in " + target_cnf
309
+ end
310
+ end
311
+
312
+ # handle gemfile
313
+ gemfile_path = target + '/Gemfile'
314
+ if File.exist? gemfile_path
315
+
316
+ # extract the contents
317
+ gemfile_contents = File.read(gemfile_path)
318
+
319
+ # identify what we are looking for
320
+ required_gems = {
321
+ 'mina' => 'nadarei/mina',
322
+ 'astrails-safe' => 'astrails/safe',
323
+ 'whenever' => 'javan/whenever',
324
+ 'guard-erb' => 'azt3k/guard-erb',
325
+ 'bonethug' => nil
326
+ }
327
+
328
+ # look at each requirement and identify if we need things
329
+ required_gems.each do |gem_name, github|
330
+
331
+ add_gem = false;
332
+ gem_reg = Regexp.new('gem[^"\']+["\']'+gem_name+'["\']')
333
+ git_reg = Regexp.new('gem[^"\']+["\']'+gem_name+'["\'],[^,]+github: ["\']'+github+'["\']') if github
334
+
335
+ if gem_reg =~ gemfile_contents
336
+ puts 'Found '+gem_name+' in gem file.'
337
+ if github
338
+ puts 'Requires github version, checking...'
339
+ unless git_reg =~ gemfile_contents
340
+ puts 'Couldn\'t find '+gem_name+' (github) in gem file adding...'
341
+ gemfile_contents.gsub(gem_reg,'')
342
+ add_gem = true;
343
+ end
344
+ end
345
+ else
346
+ puts "Couldn't find "+gem_name+" in gem file adding..."
347
+ add_gem = true;
348
+ end
349
+
350
+ if add_gem
351
+ gemfile_contents += "\n" + 'gem "'+gem_name+'"'+(github ? ', github: "'+github+'"' : '')
352
+ File.open(gemfile_path,'w') { |file| file.puts gemfile_contents }
353
+ end
354
+
355
+ end
356
+
357
+ else
358
+ puts 'No Gemfile found, creating one...'
359
+ FileUtils.cp @@skel_dir + '/base/Gemfile', gemfile_path
360
+ end
361
+
362
+ # run bundler
363
+ exec 'bundle install --path vendor'
364
+
365
+ # self
366
+
367
+ end
368
+
369
+ def self.update(dir = '.')
370
+ self.bonethugise(dir,:update)
371
+ end
372
+
373
+ def self.init(dir = '.')
374
+ self.bonethugise(dir,:init)
375
+ end
376
+
377
+ end
378
+
379
379
  end