mang_keeper 0.1.0
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/.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: []
         |