mang_keeper 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +5 -0
- data/Gemfile +4 -0
- data/README.md +4 -0
- data/Rakefile +1 -0
- data/bin/mangkeeper +10 -0
- data/lib/mang_keeper.rb +21 -0
- data/lib/mang_keeper/application.rb +157 -0
- data/lib/mang_keeper/config.rb +63 -0
- data/lib/mang_keeper/helpers/confighelpers.rb +13 -0
- data/lib/mang_keeper/helpers/dbhelpers.rb +51 -0
- data/lib/mang_keeper/helpers/helpers.rb +9 -0
- data/lib/mang_keeper/helpers/initcheckhelpers.rb +11 -0
- data/lib/mang_keeper/init_generators/configs.rb +22 -0
- data/lib/mang_keeper/initializer.rb +53 -0
- data/lib/mang_keeper/scenario.rb +26 -0
- data/lib/mang_keeper/scenarios/info_scenario.rb +8 -0
- data/lib/mang_keeper/scenarios/init_scenario.rb +13 -0
- data/lib/mang_keeper/storage.rb +35 -0
- data/lib/mang_keeper/updates.rb +119 -0
- data/lib/mang_keeper/updates/core.rb +27 -0
- data/lib/mang_keeper/updates/core_mr.rb +26 -0
- data/lib/mang_keeper/updates/sd2.rb +26 -0
- data/lib/mang_keeper/updates/sd2_mr.rb +26 -0
- data/lib/mang_keeper/updates/ytdb.rb +27 -0
- data/lib/mang_keeper/version.rb +3 -0
- data/mang_keeper.gemspec +21 -0
- metadata +72 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/mangkeeper
ADDED
data/lib/mang_keeper.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require "optparse"
|
2
|
+
require "ostruct"
|
3
|
+
require "active_support/inflector"
|
4
|
+
require "json"
|
5
|
+
|
6
|
+
require "mang_keeper/version"
|
7
|
+
require "mang_keeper/helpers/dbhelpers"
|
8
|
+
require "mang_keeper/helpers/helpers"
|
9
|
+
require "mang_keeper/helpers/initcheckhelpers"
|
10
|
+
require "mang_keeper/helpers/confighelpers"
|
11
|
+
require "mang_keeper/updates"
|
12
|
+
require "mang_keeper/updates/core"
|
13
|
+
require "mang_keeper/updates/ytdb"
|
14
|
+
require "mang_keeper/updates/core_mr"
|
15
|
+
require "mang_keeper/updates/sd2"
|
16
|
+
require "mang_keeper/updates/sd2_mr"
|
17
|
+
require "mang_keeper/scenario"
|
18
|
+
require "mang_keeper/storage"
|
19
|
+
require "mang_keeper/config"
|
20
|
+
require "mang_keeper/application"
|
21
|
+
require "mang_keeper/initializer"
|
@@ -0,0 +1,157 @@
|
|
1
|
+
module MangKeeper
|
2
|
+
class << self
|
3
|
+
def application
|
4
|
+
@application ||= Application.new
|
5
|
+
end
|
6
|
+
|
7
|
+
def scenario
|
8
|
+
application.scenario
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class Application
|
13
|
+
|
14
|
+
DEFAULT_STORAGE_DIR = ".mangkeeper"
|
15
|
+
DEFAULT_SCENARIO = "info"
|
16
|
+
|
17
|
+
attr_accessor :skip_init_check
|
18
|
+
attr_reader :scenario
|
19
|
+
|
20
|
+
def initialize
|
21
|
+
@skip_init_check = false
|
22
|
+
end
|
23
|
+
|
24
|
+
def run
|
25
|
+
init
|
26
|
+
start_scenario
|
27
|
+
end
|
28
|
+
|
29
|
+
def init
|
30
|
+
handle_options
|
31
|
+
load_storage
|
32
|
+
config
|
33
|
+
get_scenario_name
|
34
|
+
load_scenario
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
def options
|
39
|
+
@options ||= OpenStruct.new
|
40
|
+
end
|
41
|
+
|
42
|
+
def storage
|
43
|
+
@storage
|
44
|
+
end
|
45
|
+
|
46
|
+
def config
|
47
|
+
@config ||= ConfigManager.new
|
48
|
+
end
|
49
|
+
|
50
|
+
def initializer
|
51
|
+
@initializer = Initializer.new
|
52
|
+
end
|
53
|
+
|
54
|
+
def dry_run?
|
55
|
+
!!options.dryrun
|
56
|
+
end
|
57
|
+
|
58
|
+
# A list of all the standard options, suitable for
|
59
|
+
# passing to OptionParser.
|
60
|
+
def standard_options
|
61
|
+
[
|
62
|
+
['--dry-run', '-n', "Do a dry run without executing actions.",
|
63
|
+
lambda { |value| options.dryrun = true }
|
64
|
+
],
|
65
|
+
['--storedir', '-d', "Specify mangkeeper internal storage directory",
|
66
|
+
lambda { |value| options.storagedir = value }
|
67
|
+
],
|
68
|
+
['--version', '-v', "Display the program version.",
|
69
|
+
lambda { |value|
|
70
|
+
puts "mangkeeper, version #{VERSION}"
|
71
|
+
exit
|
72
|
+
}
|
73
|
+
],
|
74
|
+
]
|
75
|
+
end
|
76
|
+
|
77
|
+
# Read and handle the command line options.
|
78
|
+
def handle_options
|
79
|
+
OptionParser.new do |opts|
|
80
|
+
opts.banner = "mangkeeper scenario {options}"
|
81
|
+
opts.separator ""
|
82
|
+
opts.separator "Options are ..."
|
83
|
+
|
84
|
+
opts.on_tail("-h", "--help", "-H", "Display this help message.") do
|
85
|
+
puts opts
|
86
|
+
exit
|
87
|
+
end
|
88
|
+
|
89
|
+
standard_options.each { |args| opts.on(*args) }
|
90
|
+
end.parse!
|
91
|
+
end
|
92
|
+
|
93
|
+
private
|
94
|
+
|
95
|
+
def load_storage
|
96
|
+
storage_dir = options.storagedir || DEFAULT_STORAGE_DIR
|
97
|
+
@storage = Storage.new(storage_dir)
|
98
|
+
end
|
99
|
+
|
100
|
+
def get_scenario_name
|
101
|
+
@scenario_name = ARGV[0] || DEFAULT_SCENARIO
|
102
|
+
end
|
103
|
+
|
104
|
+
def load_scenario
|
105
|
+
# Locate scenario
|
106
|
+
scenario_classname = "#{@scenario_name}_scenario".classify
|
107
|
+
|
108
|
+
checklist = [
|
109
|
+
# Search scenario in the storage...
|
110
|
+
File.expand_path(File.join(storage.directory, 'scenarios')),
|
111
|
+
|
112
|
+
# Search scenario in gem
|
113
|
+
'mang_keeper/scenarios',
|
114
|
+
|
115
|
+
# In the current directory
|
116
|
+
'.',
|
117
|
+
'./scenarios'
|
118
|
+
]
|
119
|
+
|
120
|
+
# Search
|
121
|
+
@scenario_path = nil
|
122
|
+
checklist.each do |path|
|
123
|
+
file = build_scenario_path(path, scenario_classname.underscore)
|
124
|
+
|
125
|
+
load_error = false
|
126
|
+
begin
|
127
|
+
require file
|
128
|
+
rescue LoadError
|
129
|
+
load_error = true
|
130
|
+
end
|
131
|
+
unless load_error
|
132
|
+
@scenario_path = file
|
133
|
+
break
|
134
|
+
end
|
135
|
+
end
|
136
|
+
raise "Scenario #{@scenario_name} not found!" unless @scenario_path
|
137
|
+
|
138
|
+
@scenario = scenario_classname.constantize.new
|
139
|
+
end
|
140
|
+
|
141
|
+
def build_scenario_path(path, scenario_name, ext = 'rb')
|
142
|
+
ext = ".#{ext}" unless ext =~ /^\./
|
143
|
+
File.join(path, "#{scenario_name}#{ext}")
|
144
|
+
end
|
145
|
+
|
146
|
+
def start_scenario
|
147
|
+
unless @skip_init_check || MangKeeper.application.storage.init?
|
148
|
+
puts("You have to run \"mangkeeper init\" before you can use this command!")
|
149
|
+
exit
|
150
|
+
end
|
151
|
+
config.load_required
|
152
|
+
@scenario.work
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
end
|
157
|
+
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module MangKeeper
|
2
|
+
|
3
|
+
class ConfigManager
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@configs = {}
|
7
|
+
@required_configs_loaded = false
|
8
|
+
end
|
9
|
+
|
10
|
+
def [](key)
|
11
|
+
@configs[key][:data]
|
12
|
+
end
|
13
|
+
|
14
|
+
def require(config)
|
15
|
+
return false if @configs[config]
|
16
|
+
@configs[config] = { :loaded => false }
|
17
|
+
load_required if @required_configs_loaded
|
18
|
+
end
|
19
|
+
|
20
|
+
def load_required
|
21
|
+
@configs.each do |config, info|
|
22
|
+
next if info[:loaded]
|
23
|
+
config_data = load(config, nil)
|
24
|
+
if config_data
|
25
|
+
info[:data] = config_data
|
26
|
+
info[:loaded] = true
|
27
|
+
else
|
28
|
+
raise "Required config was not found: #{config}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
@required_configs_loaded = true
|
32
|
+
end
|
33
|
+
|
34
|
+
def dump(config)
|
35
|
+
save(config, self[config])
|
36
|
+
end
|
37
|
+
|
38
|
+
def load(file, default = nil)
|
39
|
+
file = filename_check(file)
|
40
|
+
data = MangKeeper.application.storage.load(file, nil)
|
41
|
+
if data
|
42
|
+
JSON.parse(data)
|
43
|
+
else
|
44
|
+
default
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def save(file, data)
|
49
|
+
file = filename_check(file)
|
50
|
+
MangKeeper.application.storage.save(file, JSON.pretty_generate(data))
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def filename_check(filename)
|
56
|
+
filename = filename.to_s
|
57
|
+
filename = filename + ".json" if File.extname(filename) == ""
|
58
|
+
filename
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module MangKeeper
|
2
|
+
|
3
|
+
module DBHelpers
|
4
|
+
|
5
|
+
def set_default_db database
|
6
|
+
@default_db = database
|
7
|
+
end
|
8
|
+
|
9
|
+
def set_mysql_auth user, pass
|
10
|
+
@mysql_user, @mysql_pass = user, pass
|
11
|
+
end
|
12
|
+
|
13
|
+
def upload_file_to_db filename, database = @default_db, options = {}
|
14
|
+
do_log = options[:log].nil? ? true : options[:log]
|
15
|
+
full_path_in_log = options[:full_path_in_log].nil? ? true : options[:full_path_in_log]
|
16
|
+
read_only_mode = options[:read_only_mode].nil? ? false : options[:read_only_mode]
|
17
|
+
|
18
|
+
if do_log
|
19
|
+
log_filename = full_path_in_log ? filename : File.basename(filename)
|
20
|
+
puts "Uploading file: #{log_filename} to #{database}"
|
21
|
+
end
|
22
|
+
`mysql -B -u#{@mysql_user} -p#{@mysql_pass} -D#{database} < "#{filename}"` unless read_only_mode
|
23
|
+
# puts "Done" if do_log
|
24
|
+
end
|
25
|
+
|
26
|
+
def recreate_db database
|
27
|
+
puts "Recreating DB: #{database}"
|
28
|
+
if os_windows?
|
29
|
+
`echo DROP DATABASE IF EXISTS #{database}; | mysql -B -u#{@mysql_user} -p#{@mysql_pass}`
|
30
|
+
`echo CREATE DATABASE IF NOT EXISTS #{database}; | mysql -B -u#{@mysql_user} -p#{@mysql_pass}`
|
31
|
+
else
|
32
|
+
`echo "DROP DATABASE IF EXISTS #{database};" | mysql -B -u#{@mysql_user} -p#{@mysql_pass}`
|
33
|
+
`echo "CREATE DATABASE IF NOT EXISTS #{database};" | mysql -B -u#{@mysql_user} -p#{@mysql_pass}`
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
def upload_by_glob glob, options = {}
|
39
|
+
db = options[:db] || 'mangos'
|
40
|
+
exclude = options[:exclude] || []
|
41
|
+
filters = options[:filters] || []
|
42
|
+
Dir.glob(glob).each do |file|
|
43
|
+
next if exclude.member? File.basename(file)
|
44
|
+
next if filters.any? { |filter_proc| filter_proc && !filter_proc.call(file) }
|
45
|
+
upload_file_to_db file, db, { :read_only_mode => options[:read_only] }
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
config.save :mysql, {
|
2
|
+
user: "root",
|
3
|
+
pass: "",
|
4
|
+
default_db: "mangos",
|
5
|
+
}
|
6
|
+
|
7
|
+
config.save :sources_paths, {
|
8
|
+
mangos: "mangos",
|
9
|
+
scriptdev2: "mangos/src/bindings/ScriptDev2",
|
10
|
+
ytdb: "YTDB",
|
11
|
+
}
|
12
|
+
|
13
|
+
config.save :git_repos, {
|
14
|
+
mangos: "git://github.com/<user>/mangos.git",
|
15
|
+
scriptdev2: "git://github.com/<user>/scriptdev2.git",
|
16
|
+
ytdb: "git://github.com/<user>/YTDB.git",
|
17
|
+
}
|
18
|
+
|
19
|
+
config.save :load_sources, {
|
20
|
+
patch_scriptdev: true,
|
21
|
+
unpack_ytdb: true,
|
22
|
+
}
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module MangKeeper
|
2
|
+
|
3
|
+
class Initializer
|
4
|
+
INIT_GENERATORS_DIR = File.join(File.dirname(__FILE__), "init_generators")
|
5
|
+
|
6
|
+
class InitContext
|
7
|
+
def initialize(filename)
|
8
|
+
@filename = filename
|
9
|
+
end
|
10
|
+
|
11
|
+
def application
|
12
|
+
MangKeeper.application
|
13
|
+
end
|
14
|
+
|
15
|
+
def config
|
16
|
+
application.config
|
17
|
+
end
|
18
|
+
|
19
|
+
def storage
|
20
|
+
application.storage
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# This is an internal ruby constructor!!
|
25
|
+
def initialize
|
26
|
+
collect_init_scripts
|
27
|
+
end
|
28
|
+
|
29
|
+
def run
|
30
|
+
prepare_storage_dir
|
31
|
+
run_init_scripts
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def collect_init_scripts
|
37
|
+
@init_scripts = Dir[File.join(INIT_GENERATORS_DIR, "*.rb")]
|
38
|
+
end
|
39
|
+
|
40
|
+
def run_init_scripts
|
41
|
+
@init_scripts.each do |init_script|
|
42
|
+
InitContext.new(init_script).instance_eval(File.read(init_script))
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def prepare_storage_dir
|
47
|
+
Dir.mkdir(MangKeeper.application.storage.directory) unless File.directory?(MangKeeper.application.storage.directory)
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module MangKeeper
|
2
|
+
|
3
|
+
module Scenario
|
4
|
+
|
5
|
+
class Base
|
6
|
+
include DBHelpers
|
7
|
+
extend InitCheckHelpers
|
8
|
+
extend ConfigHelpers::ClassMethods
|
9
|
+
|
10
|
+
def storage
|
11
|
+
MangKeeper.application.storage
|
12
|
+
end
|
13
|
+
|
14
|
+
def config
|
15
|
+
MangKeeper.application.config
|
16
|
+
end
|
17
|
+
|
18
|
+
def work
|
19
|
+
raise "Work must be defined for scenario!"
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class InitScenario < MangKeeper::Scenario::Base
|
2
|
+
skip_init_check!
|
3
|
+
|
4
|
+
def work
|
5
|
+
MangKeeper.application.initializer.run
|
6
|
+
puts <<-MSG.gsub(/^ */, "")
|
7
|
+
Initialized MangKeeper in #{storage.directory}
|
8
|
+
|
9
|
+
Now you should visit #{storage.directory} and do some configuration...
|
10
|
+
MSG
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module MangKeeper
|
2
|
+
|
3
|
+
class Storage
|
4
|
+
attr_reader :directory
|
5
|
+
|
6
|
+
def initialize(dir)
|
7
|
+
@directory = dir
|
8
|
+
# warn "Storage directory #{directory} does not exist!" unless File.directory?(directory)
|
9
|
+
end
|
10
|
+
|
11
|
+
def save(file, data)
|
12
|
+
File.open(File.join(directory, file.to_s), "w") do |f|
|
13
|
+
f.write(data)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# Load file with default value on error
|
18
|
+
def load(file, default = nil)
|
19
|
+
load!(file)
|
20
|
+
rescue Errno::ENOENT
|
21
|
+
default
|
22
|
+
end
|
23
|
+
|
24
|
+
# Load JSON file with exception
|
25
|
+
def load!(file)
|
26
|
+
File.read(File.join(directory, file.to_s))
|
27
|
+
end
|
28
|
+
|
29
|
+
# Is current storage directory initialized with mangkeeper?
|
30
|
+
def init?
|
31
|
+
File.directory?(directory)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
module MangKeeper
|
2
|
+
|
3
|
+
class UpdatesList
|
4
|
+
|
5
|
+
def self.run &block
|
6
|
+
self.new.tap{ |list| list.instance_eval(&block) }
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@list = []
|
11
|
+
@filters = {}
|
12
|
+
end
|
13
|
+
|
14
|
+
# Allows tobind filter for specific update class
|
15
|
+
# Update will only be added if filter value is true
|
16
|
+
def filter(class_names, filter_code = nil, &block)
|
17
|
+
filter_code = block unless filter_code
|
18
|
+
raise ArgumentError, "You must pass a block or a proc as a second argument!" unless filter_code
|
19
|
+
class_names = [class_names] unless class_names.kind_of?(Array)
|
20
|
+
class_names.each do |class_name|
|
21
|
+
@filters[class_name] ||= []
|
22
|
+
@filters[class_name] << filter_code
|
23
|
+
end
|
24
|
+
self
|
25
|
+
end
|
26
|
+
|
27
|
+
def add(update)
|
28
|
+
return false if @filters[update.class].any? { |filter_proc| filter_proc && !filter_proc.call(update) }
|
29
|
+
add!(update)
|
30
|
+
end
|
31
|
+
|
32
|
+
def add!(update)
|
33
|
+
@list << update
|
34
|
+
end
|
35
|
+
|
36
|
+
def scan_by_glob(glob, updates_type)
|
37
|
+
Dir.glob(glob).each do |filename|
|
38
|
+
update = updates_type.build filename
|
39
|
+
add update if update
|
40
|
+
end
|
41
|
+
self
|
42
|
+
end
|
43
|
+
alias_method :[], :scan_by_glob
|
44
|
+
|
45
|
+
def apply_all(read_only = false)
|
46
|
+
sorted_list.each do |update|
|
47
|
+
filename, database = update.upload_info
|
48
|
+
if read_only
|
49
|
+
puts "Will upload #{filename} to #{database} [#{update.class.name}]"
|
50
|
+
else
|
51
|
+
MangKeeper.scenario.upload_file_to_db(filename, database)
|
52
|
+
end
|
53
|
+
update.applied!
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def latest_update
|
58
|
+
sorted_list.last
|
59
|
+
end
|
60
|
+
|
61
|
+
def to_s
|
62
|
+
sorted_list.map(&:to_s).join("\n")
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def sorted_list
|
68
|
+
@list.sort! do |a,b|
|
69
|
+
a, b = a.sort_data, b.sort_data
|
70
|
+
i = 0
|
71
|
+
i+=1 while a[i] == b[i] && (a[i+1] || b[i+1])
|
72
|
+
if a[i] && b[i]
|
73
|
+
a[i] <=> b[i]
|
74
|
+
else
|
75
|
+
a[i] ? 1 : -1
|
76
|
+
end
|
77
|
+
end
|
78
|
+
@list
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
class AbstractUpdateFile
|
83
|
+
attr_reader :filename, :database
|
84
|
+
|
85
|
+
def self.build(filename)
|
86
|
+
self.new :filename => filename
|
87
|
+
end
|
88
|
+
|
89
|
+
def initialize(options = {})
|
90
|
+
@filename = options[:filename]
|
91
|
+
@database = options[:database] # silently ignore if its nil and upload to default db
|
92
|
+
raise "Full filename must be supplied as :filename!" unless @filename
|
93
|
+
end
|
94
|
+
|
95
|
+
def upload_info
|
96
|
+
[self.filename, self.database]
|
97
|
+
end
|
98
|
+
|
99
|
+
def sort_data
|
100
|
+
[]
|
101
|
+
end
|
102
|
+
|
103
|
+
def applied?
|
104
|
+
@applied
|
105
|
+
end
|
106
|
+
|
107
|
+
def applied!
|
108
|
+
@applied = true
|
109
|
+
end
|
110
|
+
|
111
|
+
def to_s
|
112
|
+
info
|
113
|
+
end
|
114
|
+
|
115
|
+
def info
|
116
|
+
"[#{self.class.name}:#{filename}]"
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module MangKeeper
|
2
|
+
class CoreUpdateFile < AbstractUpdateFile
|
3
|
+
APPLY_PRIORITY = 1
|
4
|
+
|
5
|
+
def self.build filename
|
6
|
+
update = File.basename(filename, '.sql').split('_')
|
7
|
+
self.new :filename => filename, :database => update[2], :core_revision => update[0].to_i, :num => update[1].to_i
|
8
|
+
end
|
9
|
+
|
10
|
+
attr_reader :core_revision, :num
|
11
|
+
def initialize options = {}
|
12
|
+
super
|
13
|
+
@core_revision = options[:core_revision]
|
14
|
+
@num = options[:num]
|
15
|
+
raise "Core revision must be supplied as :core_revision!" unless @core_revision
|
16
|
+
end
|
17
|
+
|
18
|
+
def sort_data
|
19
|
+
[core_revision, APPLY_PRIORITY, num]
|
20
|
+
end
|
21
|
+
|
22
|
+
def info
|
23
|
+
"Rev#{core_revision} #{super}"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module MangKeeper
|
2
|
+
class CoreMrUpdateFile < AbstractUpdateFile
|
3
|
+
APPLY_PRIORITY = 1
|
4
|
+
|
5
|
+
def self.build filename
|
6
|
+
update = File.basename(filename, '.sql').split('_')
|
7
|
+
self.new :filename => filename, :database => update[1], :mr_revision => update[0].to_i!
|
8
|
+
end
|
9
|
+
|
10
|
+
attr_reader :mr_revision
|
11
|
+
def initialize options = {}
|
12
|
+
super
|
13
|
+
@mr_revision = options[:mr_revision]
|
14
|
+
raise "MR revision must be supplied as :mr_revision!" unless @mr_revision
|
15
|
+
end
|
16
|
+
|
17
|
+
def sort_data
|
18
|
+
[mr_revision, APPLY_PRIORITY]
|
19
|
+
end
|
20
|
+
|
21
|
+
def info
|
22
|
+
"Rev#{mr_revision} #{super}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module MangKeeper
|
2
|
+
class Sd2UpdateFile < AbstractUpdateFile
|
3
|
+
APPLY_PRIORITY = 1
|
4
|
+
|
5
|
+
def self.build filename
|
6
|
+
update = File.basename(filename, '.sql').split('_')
|
7
|
+
self.new :filename => filename, :database => update[1], :sd2_revision => update[0].to_i!
|
8
|
+
end
|
9
|
+
|
10
|
+
attr_reader :sd2_revision
|
11
|
+
def initialize options = {}
|
12
|
+
super
|
13
|
+
@sd2_revision = options[:sd2_revision]
|
14
|
+
raise "SD2 revision must be supplied as :sd2_revision!" unless @sd2_revision
|
15
|
+
end
|
16
|
+
|
17
|
+
def sort_data
|
18
|
+
[sd2_revision, APPLY_PRIORITY]
|
19
|
+
end
|
20
|
+
|
21
|
+
def info
|
22
|
+
"Rev#{sd2_revision} #{super}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module MangKeeper
|
2
|
+
class Sd2MrUpdateFile < AbstractUpdateFile
|
3
|
+
APPLY_PRIORITY = 1
|
4
|
+
|
5
|
+
def self.build filename
|
6
|
+
update = File.basename(filename, '.sql').split('_')
|
7
|
+
self.new :filename => filename, :database => update[1], :mr_revision => update[0].to_i!
|
8
|
+
end
|
9
|
+
|
10
|
+
attr_reader :mr_revision
|
11
|
+
def initialize options = {}
|
12
|
+
super
|
13
|
+
@mr_revision = options[:mr_revision]
|
14
|
+
raise "MR revision must be supplied as :mr_revision!" unless @mr_revision
|
15
|
+
end
|
16
|
+
|
17
|
+
def sort_data
|
18
|
+
[mr_revision, APPLY_PRIORITY]
|
19
|
+
end
|
20
|
+
|
21
|
+
def info
|
22
|
+
"Rev#{mr_revision} #{super}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module MangKeeper
|
2
|
+
class YTDBUpdateFile < AbstractUpdateFile
|
3
|
+
APPLY_PRIORITY = 5
|
4
|
+
|
5
|
+
def self.build filename
|
6
|
+
update = File.basename(filename, '.sql').split('_')
|
7
|
+
return if update[1] == 'corepatch' # skip all corepatches...
|
8
|
+
self.new :filename => filename, :database => update[1], :core_revision => update[3].to_i!
|
9
|
+
end
|
10
|
+
|
11
|
+
attr_reader :core_revision
|
12
|
+
def initialize options = {}
|
13
|
+
super
|
14
|
+
@core_revision = options[:core_revision]
|
15
|
+
raise "Core revision must be supplied as :core_revision!" unless @core_revision
|
16
|
+
end
|
17
|
+
|
18
|
+
def sort_data
|
19
|
+
[core_revision, APPLY_PRIORITY]
|
20
|
+
end
|
21
|
+
|
22
|
+
def info
|
23
|
+
"Rev#{core_revision} #{super}"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
data/mang_keeper.gemspec
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "mang_keeper/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "mang_keeper"
|
7
|
+
s.version = MangKeeper::VERSION
|
8
|
+
s.authors = ["MOZGIII"]
|
9
|
+
s.email = ["mike-n@narod.ru"]
|
10
|
+
s.homepage = "http://github.com/MOZGIII/MaNGOS-Keeper"
|
11
|
+
s.summary = %q{MaNGOS Keeper}
|
12
|
+
s.description = %q{Helps to maintain MaNGOS server.}
|
13
|
+
|
14
|
+
s.rubyforge_project = "mang_keeper"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
end
|
metadata
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mang_keeper
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- MOZGIII
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-09-10 00:00:00.000000000Z
|
13
|
+
dependencies: []
|
14
|
+
description: Helps to maintain MaNGOS server.
|
15
|
+
email:
|
16
|
+
- mike-n@narod.ru
|
17
|
+
executables:
|
18
|
+
- mangkeeper
|
19
|
+
extensions: []
|
20
|
+
extra_rdoc_files: []
|
21
|
+
files:
|
22
|
+
- .gitignore
|
23
|
+
- Gemfile
|
24
|
+
- README.md
|
25
|
+
- Rakefile
|
26
|
+
- bin/mangkeeper
|
27
|
+
- lib/mang_keeper.rb
|
28
|
+
- lib/mang_keeper/application.rb
|
29
|
+
- lib/mang_keeper/config.rb
|
30
|
+
- lib/mang_keeper/helpers/confighelpers.rb
|
31
|
+
- lib/mang_keeper/helpers/dbhelpers.rb
|
32
|
+
- lib/mang_keeper/helpers/helpers.rb
|
33
|
+
- lib/mang_keeper/helpers/initcheckhelpers.rb
|
34
|
+
- lib/mang_keeper/init_generators/configs.rb
|
35
|
+
- lib/mang_keeper/initializer.rb
|
36
|
+
- lib/mang_keeper/scenario.rb
|
37
|
+
- lib/mang_keeper/scenarios/info_scenario.rb
|
38
|
+
- lib/mang_keeper/scenarios/init_scenario.rb
|
39
|
+
- lib/mang_keeper/storage.rb
|
40
|
+
- lib/mang_keeper/updates.rb
|
41
|
+
- lib/mang_keeper/updates/core.rb
|
42
|
+
- lib/mang_keeper/updates/core_mr.rb
|
43
|
+
- lib/mang_keeper/updates/sd2.rb
|
44
|
+
- lib/mang_keeper/updates/sd2_mr.rb
|
45
|
+
- lib/mang_keeper/updates/ytdb.rb
|
46
|
+
- lib/mang_keeper/version.rb
|
47
|
+
- mang_keeper.gemspec
|
48
|
+
homepage: http://github.com/MOZGIII/MaNGOS-Keeper
|
49
|
+
licenses: []
|
50
|
+
post_install_message:
|
51
|
+
rdoc_options: []
|
52
|
+
require_paths:
|
53
|
+
- lib
|
54
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
55
|
+
none: false
|
56
|
+
requirements:
|
57
|
+
- - ! '>='
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: '0'
|
60
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
requirements: []
|
67
|
+
rubyforge_project: mang_keeper
|
68
|
+
rubygems_version: 1.8.10
|
69
|
+
signing_key:
|
70
|
+
specification_version: 3
|
71
|
+
summary: MaNGOS Keeper
|
72
|
+
test_files: []
|