bonethug 0.0.5 → 0.0.6
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.
- data/README.md +5 -3
- data/Rakefile +2 -1
- data/bin/bonethug +2 -7
- data/lib/bonethug/cli.rb +44 -0
- data/lib/bonethug/installer.rb +202 -0
- data/lib/bonethug/version.rb +1 -1
- data/lib/bonethug.rb +3 -13
- data/lib/tasks/setup.rake +1 -1
- data/skel/base/README.md +2 -2
- data/skel/base/config/{cnf.yml → example.cnf.yml} +47 -8
- data/skel/base/config/{deploy.rb → example.deploy.rb} +23 -3
- data/skel/base/lib/conf.rb +4 -4
- data/skel/base/log/.gitkeep +0 -0
- data/skel/project_types/drupal/.gitignore +10 -21
- data/skel/project_types/drupal/composer.json +2 -28
- data/skel/project_types/drupal/public/sites/default/development.settings.php +259 -0
- data/skel/project_types/drupal/public/sites/default/production.settings.php +259 -0
- data/skel/project_types/drupal/public/sites/default/settings.php +17 -0
- data/skel/project_types/drupal/public/sites/default/staging.settings.php +260 -0
- data/skel/project_types/php/composer.json +2 -28
- data/skel/project_types/silverstripe3/config/example.schedule.rb +58 -0
- data/skel/skel.yml +7 -0
- metadata +15 -8
- data/lib/bonethug/setup.rake +0 -19
- data/skel/base/composer.json +0 -31
- /data/skel/base/config/{backup.rb → example.backup.rb} +0 -0
- /data/skel/base/config/{schedule.rb → example.schedule.rb} +0 -0
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Bonethug
|
2
2
|
|
3
|
-
|
3
|
+
Project Skeleton Manager
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
@@ -18,7 +18,9 @@ Or install it yourself as:
|
|
18
18
|
|
19
19
|
## Usage
|
20
20
|
|
21
|
-
|
21
|
+
### Commands
|
22
|
+
|
23
|
+
$ bonethug install {rails3|silverstripe3|drupal|php|sinatra}
|
22
24
|
|
23
25
|
## Contributing
|
24
26
|
|
@@ -26,4 +28,4 @@ TODO: Write usage instructions here
|
|
26
28
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
29
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
30
|
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
-
5. Create new Pull Request
|
31
|
+
5. Create new Pull Request
|
data/Rakefile
CHANGED
data/bin/bonethug
CHANGED
@@ -1,13 +1,8 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
|
2
3
|
root_path = File.expand_path(File.dirname(__FILE__)) + '/..'
|
3
|
-
puts root_path
|
4
4
|
|
5
5
|
require 'rubygems' unless Object.const_defined?(:Gem)
|
6
6
|
require root_path +'/lib/bonethug'
|
7
|
-
require 'rake'
|
8
|
-
|
9
|
-
ARGV.each do|a|
|
10
|
-
puts "Argument: #{a}"
|
11
|
-
end
|
12
7
|
|
13
|
-
Bonethug::
|
8
|
+
Bonethug::CLI.handle
|
data/lib/bonethug/cli.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
module Bonethug
|
2
|
+
class CLI
|
3
|
+
|
4
|
+
def self.handle
|
5
|
+
|
6
|
+
# what are we doing?
|
7
|
+
task = ARGV[0] || 'help'
|
8
|
+
|
9
|
+
case task
|
10
|
+
|
11
|
+
when 'help'
|
12
|
+
|
13
|
+
display_help
|
14
|
+
|
15
|
+
when 'install'
|
16
|
+
|
17
|
+
# handle args
|
18
|
+
type = ARGV[1]
|
19
|
+
location = ARGV[2] || '.'
|
20
|
+
puts 'Usage: bonethug install [location]' if type.empty?
|
21
|
+
|
22
|
+
# run the installer
|
23
|
+
Installer.install type, location
|
24
|
+
|
25
|
+
when 'clean'
|
26
|
+
|
27
|
+
location = ARGV[1] || '.'
|
28
|
+
Installer.clean location
|
29
|
+
|
30
|
+
else
|
31
|
+
|
32
|
+
# We didn't find a task
|
33
|
+
puts 'Task not found'
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.display_help
|
40
|
+
puts 'Usage: bonethug task [argument]...'
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,202 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__)) + '/../../skel/base/lib/conf'
|
2
|
+
require 'fileutils'
|
3
|
+
require 'find'
|
4
|
+
require 'digest/md5'
|
5
|
+
require 'yaml'
|
6
|
+
|
7
|
+
module Bonethug
|
8
|
+
|
9
|
+
class Installer
|
10
|
+
|
11
|
+
include FileUtils
|
12
|
+
include Digest
|
13
|
+
|
14
|
+
@@skel_dir = File.expand_path(File.dirname(__FILE__)) + '/../../skel'
|
15
|
+
@@conf = Conf.new.add(@@skel_dir + '/skel.yml')
|
16
|
+
@@project_config_files = ['backup.rb','cnf.yml','deploy.rb','schedule.rb']
|
17
|
+
|
18
|
+
def self.install(type, target = '.')
|
19
|
+
|
20
|
+
# @@conf = Conf.new.add(@@skel_dir + '/skel.yml')
|
21
|
+
|
22
|
+
# create full path
|
23
|
+
target = File.expand_path target
|
24
|
+
|
25
|
+
# let the user know we are installing
|
26
|
+
puts 'Installing '+ type + ' to ' + target + '...'
|
27
|
+
|
28
|
+
# load the configuration
|
29
|
+
raise "Unsupported type: " + type.to_s unless @@conf.get('project_types').has_key? type.to_s
|
30
|
+
conf = @@conf.node_merge 'base', 'project_types.' + type
|
31
|
+
|
32
|
+
# set the tmp dir
|
33
|
+
tmp_dir = File.expand_path target + '/.bonethug-tmp'
|
34
|
+
|
35
|
+
# clean up any exisitng install tmp files
|
36
|
+
if File.directory? tmp_dir
|
37
|
+
puts 'Cleaning up old installer temporary files...'
|
38
|
+
FileUtils.rm_rf tmp_dir
|
39
|
+
end
|
40
|
+
|
41
|
+
# create tmp dir
|
42
|
+
puts 'Creating build directory at ' + tmp_dir
|
43
|
+
FileUtils.mkdir tmp_dir
|
44
|
+
FileUtils.mkdir tmp_dir + '/.bonethug'
|
45
|
+
|
46
|
+
# build the file set
|
47
|
+
puts 'Building ' + type + ' skeleton...'
|
48
|
+
FileUtils.cp_r @@skel_dir + '/project_types/' + type + '/.', tmp_dir
|
49
|
+
FileUtils.cp_r @@skel_dir + '/base/.', tmp_dir
|
50
|
+
|
51
|
+
# build the manifest
|
52
|
+
puts 'Creating manifest...'
|
53
|
+
self.build_manifest tmp_dir
|
54
|
+
|
55
|
+
# modify the manifest root
|
56
|
+
manifest_path = tmp_dir + '/.bonethug/manifest'
|
57
|
+
File.open(manifest_path,'w') do |file|
|
58
|
+
file.puts File.read(manifest_path).gsub(/\.bonethug-tmp/,'')
|
59
|
+
end
|
60
|
+
|
61
|
+
# clean up the target dir
|
62
|
+
puts 'Cleaning up install directory...'
|
63
|
+
self.clean target
|
64
|
+
|
65
|
+
# copy the files
|
66
|
+
puts 'Installing build to ' + target + '...'
|
67
|
+
FileUtils.cp_r tmp_dir + '/.', target
|
68
|
+
|
69
|
+
# try to update the configuration files
|
70
|
+
puts 'Updating configs...'
|
71
|
+
self.update_configuration_files(target)
|
72
|
+
|
73
|
+
# try to update the configuration files
|
74
|
+
puts 'Updating build informtation...'
|
75
|
+
self.save_project_meta_data(target)
|
76
|
+
|
77
|
+
# clean up any exisitng install tmp files
|
78
|
+
puts 'Cleaning up temporary files...'
|
79
|
+
FileUtils.rm_rf tmp_dir
|
80
|
+
|
81
|
+
puts "Installation Complete"
|
82
|
+
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.clean(target)
|
86
|
+
|
87
|
+
manifest_path = target + '/.bonethug/manifest'
|
88
|
+
|
89
|
+
if File.exists? manifest_path
|
90
|
+
|
91
|
+
puts 'Reading manifest...'
|
92
|
+
manifest = File.read(manifest_path).split("\n")
|
93
|
+
|
94
|
+
puts 'Cleaning up ' + manifest.count.to_s + ' files'
|
95
|
+
not_removed = []
|
96
|
+
manifest.each do |file|
|
97
|
+
not_removed.push file unless self.try_delete file
|
98
|
+
end
|
99
|
+
|
100
|
+
if not_removed.count > 0
|
101
|
+
|
102
|
+
puts 'Retrying removal of ' + not_removed.count.to_s + ' files'
|
103
|
+
failed = []
|
104
|
+
not_removed.each do |file|
|
105
|
+
failed.push file unless self.try_delete file
|
106
|
+
end
|
107
|
+
|
108
|
+
puts 'Removal of the following' + failed.count.to_s + ' files failed'
|
109
|
+
puts failed.join("\n")
|
110
|
+
|
111
|
+
end
|
112
|
+
|
113
|
+
else
|
114
|
+
puts 'Nothing to do'
|
115
|
+
end
|
116
|
+
self
|
117
|
+
end
|
118
|
+
|
119
|
+
protected
|
120
|
+
|
121
|
+
def self.try_delete(file)
|
122
|
+
if (File.directory?(file) and Find.find(file).empty?) or File.file?(file)
|
123
|
+
rm_rf file
|
124
|
+
return false if File.exists? file
|
125
|
+
return true
|
126
|
+
else
|
127
|
+
return false
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def self.build_manifest(dir)
|
132
|
+
dir_contents = Find.find(dir).map { |p| File.expand_path(p) }
|
133
|
+
manifest = dir_contents - ((@@conf.get('exlcuded_paths') || []).map { |p| File.expand_path(p) })
|
134
|
+
File.open(dir + '/.bonethug/manifest','w') { |file| file.puts manifest.join("\n") }
|
135
|
+
self
|
136
|
+
end
|
137
|
+
|
138
|
+
def self.update_configuration_files(target)
|
139
|
+
|
140
|
+
# load the existing project's datafile if present
|
141
|
+
meta_data = self.get_project_meta_data target
|
142
|
+
|
143
|
+
@@project_config_files.each do |config|
|
144
|
+
|
145
|
+
do_copy = true
|
146
|
+
example_file = target + '/config/example.' + config
|
147
|
+
target_file = target + '/config/' + config
|
148
|
+
|
149
|
+
# analyse the config file + build data file
|
150
|
+
file_exists = File.exist?(target_file)
|
151
|
+
contents_not_modified = false
|
152
|
+
contents_not_modified = true if file_exists and meta_data and meta_data['config_digests'] and meta_data['config_digests']['example.' + config] == self.contents_md5(target_file)
|
153
|
+
|
154
|
+
# meta_data_is_hash = meta_data_exists and meta_data.class.name == 'Hash' and meta_data['config_digests'].class.name == 'Hash'
|
155
|
+
# config_digests_found = meta_data_is_hash and meta_data['config_digests'].methods.include?('has_key?') and meta_data['config_digests'].has_key?('example.' + config)
|
156
|
+
# contents_not_modified = config_digests_found and meta_data['config_digests']['example.' + config] == self.contents_md5(target_file)
|
157
|
+
|
158
|
+
# don't copy if the file exists...
|
159
|
+
do_copy = false if file_exists
|
160
|
+
|
161
|
+
# unless it hasn't been modified, i.e. probably not conf.yml, but possibly some of the other ones
|
162
|
+
|
163
|
+
do_copy = true if contents_not_modified
|
164
|
+
|
165
|
+
# Copy if that's ok
|
166
|
+
FileUtils.cp example_file, target_file if do_copy
|
167
|
+
|
168
|
+
end
|
169
|
+
|
170
|
+
# return self for chaining
|
171
|
+
self
|
172
|
+
|
173
|
+
end
|
174
|
+
|
175
|
+
def self.contents_md5(file)
|
176
|
+
return false unless File.exist?(file)
|
177
|
+
MD5.digest File.read(file)
|
178
|
+
end
|
179
|
+
|
180
|
+
def self.save_project_meta_data(base_dir)
|
181
|
+
|
182
|
+
meta_data = {'config_digests' => {}}
|
183
|
+
@@project_config_files.each do |file|
|
184
|
+
meta_data['config_digests']['example.' + file] = self.contents_md5(base_dir + '/config/example.' + file)
|
185
|
+
end
|
186
|
+
File.open(base_dir + '/.bonethug/data','w') { |file| file.puts meta_data.to_yaml }
|
187
|
+
|
188
|
+
# return self for chaining
|
189
|
+
self
|
190
|
+
|
191
|
+
end
|
192
|
+
|
193
|
+
def self.get_project_meta_data(base_dir)
|
194
|
+
|
195
|
+
data_file = base_dir + '/.bonethug/data'
|
196
|
+
return YAML.load_file data_file if File.exists? data_file
|
197
|
+
return false
|
198
|
+
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
end
|
data/lib/bonethug/version.rb
CHANGED
data/lib/bonethug.rb
CHANGED
@@ -1,17 +1,7 @@
|
|
1
1
|
require "bonethug/version"
|
2
|
+
require "bonethug/installer"
|
3
|
+
require "bonethug/cli"
|
2
4
|
|
3
5
|
module Bonethug
|
4
6
|
|
5
|
-
|
6
|
-
def self.call_rake(arguments)
|
7
|
-
if RUBY_PLATFORM =~ /mswin/
|
8
|
-
rake_cmd = "rake.bat" #very important because windows will break with just "rake"
|
9
|
-
else
|
10
|
-
rake_cmd = "rake"
|
11
|
-
end
|
12
|
-
puts "calling #{rake_cmd} " + arguments
|
13
|
-
puts system("#{rake_cmd} " + arguments)
|
14
|
-
puts $?
|
15
|
-
end
|
16
|
-
|
17
|
-
end
|
7
|
+
end
|
data/lib/tasks/setup.rake
CHANGED
data/skel/base/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
deploy:
|
2
2
|
common:
|
3
|
-
project_type:
|
3
|
+
project_type: rails3 | silverstripe3 | drupal | php | sinatra
|
4
4
|
base_dir: /var/www
|
5
5
|
repository: git@gitlab.....
|
6
6
|
project_slug: tradespot
|
@@ -12,13 +12,27 @@ deploy:
|
|
12
12
|
development:
|
13
13
|
staging:
|
14
14
|
domain: staging.domain.com
|
15
|
+
default_branch: master
|
15
16
|
production:
|
16
|
-
domain: production.
|
17
|
+
domain: production.domain.com
|
18
|
+
default_branch: stable
|
17
19
|
dbs:
|
18
20
|
default:
|
19
21
|
development:
|
22
|
+
user: root
|
23
|
+
pass:
|
24
|
+
host: localhost
|
25
|
+
port: 3306
|
20
26
|
staging:
|
27
|
+
user: staging_db
|
28
|
+
pass: passw0rd
|
29
|
+
host: localhost
|
30
|
+
port: 3306
|
21
31
|
production:
|
32
|
+
user: production_db
|
33
|
+
pass: passw0rd
|
34
|
+
host: localhost
|
35
|
+
port: 3306
|
22
36
|
backup:
|
23
37
|
local:
|
24
38
|
keep:2
|
@@ -27,6 +41,16 @@ backup:
|
|
27
41
|
host: backup-host.com
|
28
42
|
user: remote_backup
|
29
43
|
pass: passw0rd
|
44
|
+
sftp:
|
45
|
+
keep: 10
|
46
|
+
host: backup-host.com
|
47
|
+
user: remote_backup
|
48
|
+
pass: passw0rd
|
49
|
+
s3:
|
50
|
+
keep: 10
|
51
|
+
key: key
|
52
|
+
secret: secret
|
53
|
+
bucket: bucket
|
30
54
|
apache:
|
31
55
|
development:
|
32
56
|
staging:
|
@@ -46,14 +70,29 @@ apache:
|
|
46
70
|
SS_ENVIRONMENT_TYPE: live
|
47
71
|
RAILS_ENV: production
|
48
72
|
APPLICATION_ENV: production
|
49
|
-
|
50
|
-
permissions:
|
73
|
+
chown:
|
51
74
|
development:
|
52
75
|
staging:
|
53
|
-
www_executable:
|
54
|
-
- vendor/bin
|
55
76
|
production:
|
56
|
-
|
57
|
-
|
77
|
+
-
|
78
|
+
path: public/uploads
|
79
|
+
user: www-data
|
80
|
+
chmod:
|
81
|
+
development:
|
82
|
+
staging:
|
83
|
+
production:
|
84
|
+
-
|
85
|
+
path: public/uploads
|
86
|
+
mode: 775
|
87
|
+
chgrp:
|
88
|
+
development:
|
89
|
+
staging:
|
90
|
+
production:
|
91
|
+
-
|
92
|
+
path: public/uploads
|
93
|
+
group: www-data
|
94
|
+
resources:
|
95
|
+
- public/assets
|
96
|
+
- public/uploads
|
58
97
|
log_dirs:
|
59
98
|
- log
|
@@ -197,9 +197,29 @@ task :deploy => :environment do
|
|
197
197
|
queue! %[cd #{deploy_to}/current/public && chown -R www-data:www-data . && chmod -R 775 .]
|
198
198
|
queue! %[cd #{deploy_to}/shared/tmp && chown -R www-data:www-data . && chmod -R 775 .]
|
199
199
|
queue! %[touch #{deploy_to}/current/tmp/restart.txt]
|
200
|
-
|
201
|
-
|
202
|
-
|
200
|
+
|
201
|
+
# apply defined permissions
|
202
|
+
chowns = conf.get('chown.'+env)
|
203
|
+
if chowns
|
204
|
+
chowns.each do |index, chown|
|
205
|
+
queue! %[cd #{deploy_to}/current/#{chown.get('path')} && chown -R chown.get('user') .]
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
# apply defined permissions
|
210
|
+
chgrps = conf.get('chgrp.'+env)
|
211
|
+
if chgrps
|
212
|
+
chgrps.each do |index, chgrp|
|
213
|
+
queue! %[cd #{deploy_to}/current/#{chgrp.get('path')} && chgrp -R chgrp.get('group') .]
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
# apply defined permissions
|
218
|
+
chmods = conf.get('chmod.'+env)
|
219
|
+
if chmods
|
220
|
+
chmods.each do |index, chmod|
|
221
|
+
queue! %[cd #{deploy_to}/current/#{chmod.get('path')} && chmod -R chmod.get('mode') .]
|
222
|
+
end
|
203
223
|
end
|
204
224
|
|
205
225
|
queue! %[a2ensite "#{vhost}"]
|
data/skel/base/lib/conf.rb
CHANGED
@@ -14,7 +14,7 @@ class Conf
|
|
14
14
|
|
15
15
|
def initialize(new_hash = nil, options = {})
|
16
16
|
raise "New hash must be of type Hash" if new_hash && new_hash.class.name != 'Hash'
|
17
|
-
@options = {use_fallbacks: true}.merge
|
17
|
+
@options = {use_fallbacks: true}.merge options
|
18
18
|
@loaded_paths = []
|
19
19
|
@paths = {}
|
20
20
|
@config_hashes = {}
|
@@ -29,7 +29,7 @@ class Conf
|
|
29
29
|
else
|
30
30
|
raise "add_path only accepts stings or hashes"
|
31
31
|
end
|
32
|
-
@paths.merge
|
32
|
+
@paths = @paths.merge path_hash
|
33
33
|
self
|
34
34
|
end
|
35
35
|
|
@@ -57,7 +57,7 @@ class Conf
|
|
57
57
|
# create the other nodes
|
58
58
|
if options and options.has_key? :root
|
59
59
|
fragment = fragment_base
|
60
|
-
nodes = options[:root].split
|
60
|
+
nodes = options[:root].split '.'
|
61
61
|
nodes.each_with_index do |node,i|
|
62
62
|
fragment[node] = i == nodes.length-1 ? @config_hashes[path] : {}
|
63
63
|
fragment = fragment[node]
|
@@ -67,7 +67,7 @@ class Conf
|
|
67
67
|
end
|
68
68
|
|
69
69
|
# output
|
70
|
-
out = out.merge
|
70
|
+
out = out.merge fragment_base
|
71
71
|
|
72
72
|
end
|
73
73
|
@compiled_hash = out
|
File without changes
|
@@ -1,22 +1,11 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
db_dumps
|
8
|
-
tmp/*
|
9
|
-
composer.phar
|
1
|
+
/.bundle
|
2
|
+
/vendor
|
3
|
+
/bin
|
4
|
+
/logs/*
|
5
|
+
/backups/*
|
6
|
+
/db_dumps
|
10
7
|
|
11
|
-
#
|
12
|
-
public/
|
13
|
-
public/
|
14
|
-
public/
|
15
|
-
public/assets/*
|
16
|
-
public/bootstrap_forms
|
17
|
-
public/cms
|
18
|
-
public/framework
|
19
|
-
public/html5
|
20
|
-
public/widgets
|
21
|
-
public/compass
|
22
|
-
composer.phar
|
8
|
+
# project ignores - might need review
|
9
|
+
/public/sites/*/files
|
10
|
+
/public/sites/*/private
|
11
|
+
/public/sites/all/modules/filemanager/files
|
@@ -1,31 +1,5 @@
|
|
1
1
|
{
|
2
|
-
|
3
|
-
|
4
|
-
"symfony/yaml" : "2.3.*@dev",
|
5
|
-
"silverstripe/framework" : "3.1.*@dev",
|
6
|
-
"silverstripe/cms" : "3.1.*@dev",
|
7
|
-
"silverstripe-themes/simple" : "dev-master",
|
8
|
-
"silverstripe/installer" : "3.1.*@dev",
|
9
|
-
"silverstripe/bootstrap-forms" : "dev-master",
|
10
|
-
"silverstripe/html5" : "dev-master",
|
11
|
-
"silverstripe/widgets" : "dev-master",
|
12
|
-
"silverstripe/compass" : "dev-master"
|
13
|
-
},
|
14
|
-
"extra": {
|
15
|
-
"installer-paths": {
|
16
|
-
"public/vendor/{$name}": [
|
17
|
-
],
|
18
|
-
"public/themes/{$name}": [
|
19
|
-
"silverstripe-themes/simple"
|
20
|
-
],
|
21
|
-
"public/{$name}": [
|
22
|
-
"silverstripe/framework",
|
23
|
-
"silverstripe/cms",
|
24
|
-
"silverstripe/bootstrap-forms",
|
25
|
-
"silverstripe/html5",
|
26
|
-
"silverstripe/widgets",
|
27
|
-
"silverstripe/compass"
|
28
|
-
]
|
2
|
+
"require": {
|
3
|
+
"symfony/yaml" : "2.3.*@dev"
|
29
4
|
}
|
30
|
-
}
|
31
5
|
}
|