bonethug 0.0.67 → 0.0.68

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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