mdt-core 0.0.1

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 670a148d5a8ff620a0fce35e9f82f5becca15c908fd3937c8c8f9b55581d1dd6
4
+ data.tar.gz: 4584b1ef1bfd9ac6dbd23fa8362a76e4fc02904f472fece82e99899520b267b9
5
+ SHA512:
6
+ metadata.gz: 8812a886a54722d0e85be85aa6336ae066e98b1634e3e29a75a4e543f2568ef409cdf27510b3bc22051cdf88f601b7dcd2bdb9a8aa861cf4e35aaa0b26590a6b
7
+ data.tar.gz: 46a38d1a5b44523c86ae8a24616e9154234d422ef6ca39bd92bcbf964cc50439d06c5cab0956141def6b61de75fca1008a4eea323c3a015b08df41ec76160e63
data/bin/mdt ADDED
@@ -0,0 +1,123 @@
1
+ #!/usr/bin/env ruby
2
+ require 'mdt-core'
3
+ require 'yaml'
4
+ require 'optparse'
5
+ puts "Modular Deployment Tool (MDT) v. #{MDT::Core::VERSION} (C) 2018 by Phitherek_"
6
+ Gem::Specification.select { |g| g.name.downcase.include?('mdt-') }.each do |g|
7
+ if require g.name.downcase
8
+ puts "Autoload: #{g.name.downcase} v. #{g.version}"
9
+ end
10
+ end
11
+ script_opts = {}
12
+ script_opts[:config_path] = 'config/mdt-deploy.yml'
13
+ op = OptionParser.new do |opts|
14
+ opts.banner = "Usage: #{$0} [options] <config_key>"
15
+ opts.on('-c PATH', '--config PATH', 'Specifies deploy configuration file path (default: "config/mdt-deploy.yml")') do |path|
16
+ script_opts[:config_path] = path
17
+ end
18
+ opts.on('-h', '--help', 'Prints this help') do
19
+ puts opts
20
+ exit 0
21
+ end
22
+ end
23
+
24
+ op.parse!
25
+
26
+ if ARGV.count < 1
27
+ puts op.banner
28
+ end
29
+
30
+ config = YAML.load_file(script_opts[:config_path])
31
+ config_key = ARGV.last
32
+
33
+ unless config.has_key?(config_key)
34
+ puts "ERROR: There is no config that matches config key: #{config_key}!"
35
+ exit 1
36
+ end
37
+
38
+ subconfig = config[config_key]
39
+ unless subconfig.has_key?('directory_chooser') && subconfig.has_key?('fetcher') && subconfig.has_key?('contents')
40
+ puts 'ERROR: directory_chooser, fetcher and contents must be defined!'
41
+ exit 1
42
+ end
43
+
44
+ dirchooser_config = subconfig['directory_chooser']
45
+
46
+ unless dirchooser_config.has_key?('type')
47
+ puts 'ERROR: directory_chooser.type must be defined!'
48
+ exit 1
49
+ end
50
+
51
+ dirchooser_key = dirchooser_config['type'].split('.').first
52
+ dirchooser_value = dirchooser_config['type'].split('.').last
53
+ dirchooser_options = dirchooser_config['options'] || {}
54
+
55
+ dirchooser = MDT::DirectoryChoosers::Base.descendants.select { |dc| dc.key == dirchooser_key }.first
56
+ if dirchooser == nil
57
+ puts "ERROR: Could not find a directory chooser set with key #{dirchooser_key}. Check its correctness or install needed MDT modules."
58
+ exit 1
59
+ end
60
+
61
+ unless dirchooser.subkeys.include?(dirchooser_value)
62
+ puts "ERROR: Directory chooser set with key #{dirchooser_key} does not have a directory chooser with value #{dirchooser_value}."
63
+ exit 1
64
+ end
65
+
66
+ dirchooser = dirchooser.new
67
+
68
+ fetcher_config = subconfig['fetcher']
69
+ unless fetcher_config.has_key?('type')
70
+ puts 'ERROR: fetcher.type must be defined!'
71
+ exit 1
72
+ end
73
+
74
+ fetcher_key = fetcher_config['type'].split('.').first
75
+ fetcher_value = fetcher_config['type'].split('.').last
76
+ fetcher_options = fetcher_config['options'] || {}
77
+
78
+ fetcher = MDT::Fetchers::Base.descendants.select { |f| f.key == fetcher_key }.first
79
+ if fetcher == nil
80
+ puts "ERROR: Could not find a fetcher set with key #{fetcher_key}. Check its correctness or install needed MDT modules."
81
+ exit 1
82
+ end
83
+
84
+ unless fetcher.subkeys.include?(fetcher_value)
85
+ puts "ERROR: Fetcher set with key #{fetcher_key} does not have a fetcher with value #{fetcher_value}."
86
+ exit 1
87
+ end
88
+
89
+ fetcher = fetcher.new
90
+
91
+ root_contents = subconfig['contents']
92
+
93
+ puts "Successfully loaded config: #{config_key}! Starting deploy..."
94
+
95
+ unless dirchooser.mkdir(dirchooser_value, dirchooser_options) == 0
96
+ puts 'ERROR: Directory chooser could not create a directory!'
97
+ exit 1
98
+ end
99
+ begin
100
+ unless dirchooser.cd(dirchooser_value, dirchooser_options) == 0
101
+ puts 'ERROR: Directory chooser could not enter a directory!'
102
+ dirchooser.rm(dirchooser_value, dirchooser_options)
103
+ exit 1
104
+ end
105
+ unless fetcher.fetch(fetcher_value, fetcher_options) == 0
106
+ puts 'ERROR: Fetcher could not fetch!'
107
+ dirchooser.rm(dirchooser_value, dirchooser_options)
108
+ exit 1
109
+ end
110
+ unless MDT::Helpers::Runner.process_contents(root_contents) == 0
111
+ puts 'ERROR: Deploy process ended with failure!'
112
+ dirchooser.rm(dirchooser_value, dirchooser_options)
113
+ exit 1
114
+ end
115
+ rescue => e
116
+ puts "Exception: #{e.message}"
117
+ puts e.backtrace
118
+ dirchooser.rm(dirchooser_value, dirchooser_options)
119
+ exit 1
120
+ end
121
+
122
+ puts 'Deploy process finished successfully!'
123
+ exit 0
@@ -0,0 +1,14 @@
1
+ require_relative '../errors/override_needed'
2
+ require_relative '../modules/extensible'
3
+
4
+ module MDT
5
+ module CommandModifiers
6
+ class Base
7
+ include MDT::Extensible
8
+
9
+ def prepend(key, command, options = {})
10
+ raise MDT::Errors::OverrideNeeded.new('prepend')
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1 @@
1
+ require_relative 'command_modifiers/base'
@@ -0,0 +1,14 @@
1
+ require_relative '../errors/override_needed'
2
+ require_relative '../modules/extensible'
3
+
4
+ module MDT
5
+ module Commands
6
+ class Base
7
+ include MDT::Extensible
8
+
9
+ def execute(key, modifiers = [], options = {})
10
+ raise MDT::Errors::OverrideNeeded.new('execute')
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1 @@
1
+ require_relative 'commands/base'
@@ -0,0 +1,23 @@
1
+ require 'fileutils'
2
+ require_relative '../errors/override_needed'
3
+ require_relative '../modules/extensible'
4
+
5
+ module MDT
6
+ module DirectoryChoosers
7
+ class Base
8
+ include MDT::Extensible
9
+
10
+ def mkdir(key, options = {})
11
+ raise MDT::Errors::OverrideNeeded.new('mkdir')
12
+ end
13
+
14
+ def cd(key, options = {})
15
+ raise MDT::Errors::OverrideNeeded.new('cd')
16
+ end
17
+
18
+ def rm(key, options = {})
19
+ raise MDT::Errors::OverrideNeeded.new('rm')
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1 @@
1
+ require_relative 'directory_choosers/base'
@@ -0,0 +1,9 @@
1
+ module MDT
2
+ module Errors
3
+ class OverrideNeeded < StandardError
4
+ def initialize(method_key)
5
+ super("Method #{method_key} must be overriden in a subclass!")
6
+ end
7
+ end
8
+ end
9
+ end
data/lib/mdt/errors.rb ADDED
@@ -0,0 +1 @@
1
+ require_relative 'errors/override_needed'
@@ -0,0 +1,14 @@
1
+ require_relative '../errors/override_needed'
2
+ require_relative '../modules/extensible'
3
+
4
+ module MDT
5
+ module Fetchers
6
+ class Base
7
+ include MDT::Extensible
8
+
9
+ def fetch(key, options ={})
10
+ raise MDT::Errors::OverrideNeeded.new('fetch')
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1 @@
1
+ require_relative 'fetchers/base'
@@ -0,0 +1,30 @@
1
+ require_relative '../command_modifiers'
2
+ module MDT
3
+ module Helpers
4
+ class Command
5
+ def self.apply_command_modifiers(command, modifiers)
6
+ modifiers.each do |modifier_config|
7
+ unless modifier_config.has_key?('type')
8
+ puts 'WARNING: Skipping command modifier because of missing type...'
9
+ next
10
+ end
11
+ modifier_key = modifier_config['type'].split('.').first
12
+ modifier_value = modifier_config['type'].split('.').last
13
+ modifier_options = modifier_config['options']
14
+ modifier = MDT::CommandModifiers::Base.descendants.select { |cm| cm.key == modifier_key }.first
15
+ if modifier == nil
16
+ puts "WARNING: Could not find a command modifier set with key #{modifier_key}. Check its correctness or install needed MDT modules."
17
+ next
18
+ end
19
+ unless modifier.subkeys.include?(modifier_value)
20
+ puts "WARNING: Command modifier set with key #{modifier_key} does not have a command modifier with key #{modifier_value}."
21
+ next
22
+ end
23
+ modifier = modifier.new
24
+ command = modifier.prepend(modifier_value, command, modifier_options)
25
+ end
26
+ command
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,80 @@
1
+ require_relative '../commands'
2
+ module MDT
3
+ module Helpers
4
+ class Runner
5
+ def self.process_contents(contents, modifiers = [])
6
+ failure = false
7
+ contents.each do |elem|
8
+ unless failure
9
+ if elem.has_key?('command')
10
+ cmd_config = elem['command']
11
+ cmd_config['break_on_failure'] ||= true
12
+ cmd_config['success_codes'] ||= [0]
13
+ unless cmd_config.has_key?('type')
14
+ puts 'ERROR: command.type must be defined!'
15
+ if cmd_config['break_on_failure']
16
+ failure = true
17
+ next
18
+ end
19
+ end
20
+ cmd_key = cmd_config['type'].split('.').first
21
+ cmd_value = cmd_config['type'].split('.').last
22
+ cmd_options = cmd_config['options'] || {}
23
+ cmd_modifiers = modifiers + (cmd_config['command_modifiers'] || [])
24
+ cmd = MDT::Commands::Base.descendants.select { |c| c.key == cmd_key }.first
25
+ if cmd == nil
26
+ puts "ERROR: Could not find a command set with key #{cmd_key}. Check its correctness or install needed MDT modules."
27
+ if cmd_config['break_on_failure']
28
+ failure = true
29
+ next
30
+ end
31
+ end
32
+ unless cmd.subkeys.include?(cmd_value)
33
+ puts "ERROR: Command set with key #{cmd_key} does not have a command with key #{cmd_value}!"
34
+ if cmd_config['break_on_failure']
35
+ failure = true
36
+ next
37
+ end
38
+ end
39
+ cmd = cmd.new
40
+ code = cmd.execute(cmd_value, cmd_modifiers, cmd_options)
41
+ if cmd_config['success_codes'].include?(code)
42
+ puts "Command exited with success code #{code}"
43
+ else
44
+ puts "Command exited with error code #{code}"
45
+ if cmd_config['break_on_failure']
46
+ failure = true
47
+ next
48
+ end
49
+ end
50
+ elsif elem.has_key?('command_group')
51
+ cg_config = elem['command_group']
52
+ cg_config['break_on_failure'] ||= true
53
+ unless cg_config.has_key?('contents')
54
+ puts "ERROR: Command group #{cg_config['name']} without contents!"
55
+ if cg_config['break_on_failure']
56
+ failure = true
57
+ next
58
+ end
59
+ end
60
+ puts "Executing command group: #{cg_config['name']}"
61
+ code = MDT::Helpers::Runner.process_contents(cg_config['contents'], modifiers + (cg_config['command_modifiers'] || []))
62
+ if code == 0
63
+ puts "Command group: #{cg_config['name']} - finished with success"
64
+ else
65
+ puts "Command group: #{cg_config['name']} - finished with failure"
66
+ if cg_config['break_on_failure']
67
+ failure = true
68
+ next
69
+ end
70
+ end
71
+ else
72
+ puts 'WARNING: Encountered a config element that is not command nor command_group, skipping...'
73
+ end
74
+ end
75
+ end
76
+ failure ? 1 : 0
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,2 @@
1
+ require_relative 'helpers/runner'
2
+ require_relative 'helpers/command'
@@ -0,0 +1,25 @@
1
+ module MDT
2
+ module Extensible
3
+ def self.included(klass)
4
+ klass.class_eval do
5
+ @descendants = []
6
+ def self.key
7
+ raise MDT::Errors::OverrideNeeded.new('key')
8
+ end
9
+
10
+ def self.subkeys
11
+ raise MDT::Errors::OverrideNeeded.new('subkeys')
12
+ end
13
+
14
+ def self.inherited(subclass)
15
+ @descendants << subclass
16
+ @descendants.uniq!
17
+ end
18
+
19
+ def self.descendants
20
+ @descendants
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,5 @@
1
+ module MDT
2
+ module Core
3
+ VERSION = '0.0.1'
4
+ end
5
+ end
data/lib/mdt-core.rb ADDED
@@ -0,0 +1,7 @@
1
+ require_relative 'mdt/version'
2
+ require_relative 'mdt/errors'
3
+ require_relative 'mdt/directory_choosers'
4
+ require_relative 'mdt/fetchers'
5
+ require_relative 'mdt/commands'
6
+ require_relative 'mdt/command_modifiers'
7
+ require_relative 'mdt/helpers'
metadata ADDED
@@ -0,0 +1,76 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mdt-core
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Phitherek_
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-02-28 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.7'
27
+ description: Core of Modular Deployment Tool
28
+ email:
29
+ - phitherek@gmail.com
30
+ executables:
31
+ - mdt
32
+ extensions: []
33
+ extra_rdoc_files: []
34
+ files:
35
+ - bin/mdt
36
+ - lib/mdt-core.rb
37
+ - lib/mdt/command_modifiers.rb
38
+ - lib/mdt/command_modifiers/base.rb
39
+ - lib/mdt/commands.rb
40
+ - lib/mdt/commands/base.rb
41
+ - lib/mdt/directory_choosers.rb
42
+ - lib/mdt/directory_choosers/base.rb
43
+ - lib/mdt/errors.rb
44
+ - lib/mdt/errors/override_needed.rb
45
+ - lib/mdt/fetchers.rb
46
+ - lib/mdt/fetchers/base.rb
47
+ - lib/mdt/helpers.rb
48
+ - lib/mdt/helpers/command.rb
49
+ - lib/mdt/helpers/runner.rb
50
+ - lib/mdt/modules/extensible.rb
51
+ - lib/mdt/version.rb
52
+ homepage: https://github.com/Phitherek/mdt-core
53
+ licenses:
54
+ - MIT
55
+ metadata: {}
56
+ post_install_message:
57
+ rdoc_options: []
58
+ require_paths:
59
+ - lib
60
+ required_ruby_version: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: '0'
65
+ required_rubygems_version: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ requirements: []
71
+ rubyforge_project:
72
+ rubygems_version: 2.7.6
73
+ signing_key:
74
+ specification_version: 4
75
+ summary: MDT Core
76
+ test_files: []