siba 0.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (159) hide show
  1. data/.gitignore +7 -0
  2. data/Gemfile +4 -0
  3. data/Guardfile +18 -0
  4. data/LICENSE +22 -0
  5. data/README.md +47 -0
  6. data/Rakefile +27 -0
  7. data/bin/siba +5 -0
  8. data/lib/siba.rb +27 -0
  9. data/lib/siba/backup.rb +31 -0
  10. data/lib/siba/console.rb +196 -0
  11. data/lib/siba/errors.rb +8 -0
  12. data/lib/siba/generator.rb +115 -0
  13. data/lib/siba/globals.rb +19 -0
  14. data/lib/siba/helpers/encoding_helper.rb +38 -0
  15. data/lib/siba/helpers/file_helper.rb +89 -0
  16. data/lib/siba/helpers/gem_helper.rb +22 -0
  17. data/lib/siba/helpers/password_strength.rb +94 -0
  18. data/lib/siba/helpers/security_helper.rb +30 -0
  19. data/lib/siba/helpers/string_helper.rb +32 -0
  20. data/lib/siba/helpers/test/extend_test.rb +114 -0
  21. data/lib/siba/helpers/test/file_mock.rb +38 -0
  22. data/lib/siba/helpers/test/helper.rb +55 -0
  23. data/lib/siba/helpers/test/kernel_mock.rb +44 -0
  24. data/lib/siba/helpers/test/removable_constants.rb +18 -0
  25. data/lib/siba/helpers/test/require.rb +12 -0
  26. data/lib/siba/logger_plug.rb +36 -0
  27. data/lib/siba/options_backup.rb +37 -0
  28. data/lib/siba/options_loader.rb +38 -0
  29. data/lib/siba/plugins/archive/tar/archive.rb +117 -0
  30. data/lib/siba/plugins/archive/tar/init.rb +38 -0
  31. data/lib/siba/plugins/archive/tar/options.yml +1 -0
  32. data/lib/siba/plugins/destination/dir/dest_dir.rb +77 -0
  33. data/lib/siba/plugins/destination/dir/init.rb +31 -0
  34. data/lib/siba/plugins/destination/dir/options.yml +2 -0
  35. data/lib/siba/plugins/encryption/gpg/encryption.rb +140 -0
  36. data/lib/siba/plugins/encryption/gpg/init.rb +45 -0
  37. data/lib/siba/plugins/encryption/gpg/options.yml +2 -0
  38. data/lib/siba/plugins/installed_plugins.rb +77 -0
  39. data/lib/siba/plugins/plugin_loader.rb +100 -0
  40. data/lib/siba/plugins/plugins.rb +57 -0
  41. data/lib/siba/plugins/plugins.yml +9 -0
  42. data/lib/siba/plugins/source/files/files.rb +166 -0
  43. data/lib/siba/plugins/source/files/init.rb +33 -0
  44. data/lib/siba/plugins/source/files/options.yml +11 -0
  45. data/lib/siba/restore.rb +113 -0
  46. data/lib/siba/scaffold.rb +166 -0
  47. data/lib/siba/siba_check.rb +75 -0
  48. data/lib/siba/siba_file.rb +89 -0
  49. data/lib/siba/siba_kernel.rb +37 -0
  50. data/lib/siba/siba_logger.rb +172 -0
  51. data/lib/siba/tasks/siba_task.rb +42 -0
  52. data/lib/siba/tasks/siba_tasks.rb +120 -0
  53. data/lib/siba/test_files.rb +76 -0
  54. data/lib/siba/test_files/a_file +1 -0
  55. data/lib/siba/test_files/files_and_dirs/.hidden +1 -0
  56. data/lib/siba/test_files/files_and_dirs/.hidden_dir/file10 +1 -0
  57. data/lib/siba/test_files/files_and_dirs/File With Spaces +1 -0
  58. data/lib/siba/test_files/files_and_dirs/dir1/file10 +1 -0
  59. data/lib/siba/test_files/files_and_dirs/dir1/sub-dir/file111.txt +1 -0
  60. data/lib/siba/test_files/files_and_dirs/file1 +1 -0
  61. data/lib/siba/test_files/files_and_dirs/file2.txt +1 -0
  62. data/lib/siba/tmp_dir.rb +94 -0
  63. data/lib/siba/version.rb +5 -0
  64. data/scaffolds/archive.rb +26 -0
  65. data/scaffolds/destination.rb +20 -0
  66. data/scaffolds/encryption.rb +26 -0
  67. data/scaffolds/project/.gitignore +5 -0
  68. data/scaffolds/project/Gemfile +4 -0
  69. data/scaffolds/project/Guardfile +9 -0
  70. data/scaffolds/project/LICENSE +22 -0
  71. data/scaffolds/project/README.md +33 -0
  72. data/scaffolds/project/Rakefile +28 -0
  73. data/scaffolds/project/lib/siba-c6y-demo.rb +11 -0
  74. data/scaffolds/project/lib/siba-c6y-demo/options.yml +2 -0
  75. data/scaffolds/project/lib/siba-c6y-demo/version.rb +9 -0
  76. data/scaffolds/project/siba-c6y-demo.gemspec +26 -0
  77. data/scaffolds/project/test/helper/require_integration.rb +5 -0
  78. data/scaffolds/project/test/helper/require_unit.rb +4 -0
  79. data/scaffolds/project/test/integration/i9n_init.rb +35 -0
  80. data/scaffolds/project/test/unit/test_init.rb +43 -0
  81. data/scaffolds/project/test/unit/yml/valid.yml +8 -0
  82. data/scaffolds/shared/examples.rb +47 -0
  83. data/scaffolds/shared/init_example.rb +13 -0
  84. data/scaffolds/source.rb +25 -0
  85. data/siba.gemspec +30 -0
  86. data/test/helper/require_integration.rb +4 -0
  87. data/test/helper/require_unit.rb +4 -0
  88. data/test/integration/helpers/i9n_file_helper.rb +50 -0
  89. data/test/integration/i9n_backup.rb +53 -0
  90. data/test/integration/i9n_console.rb +16 -0
  91. data/test/integration/i9n_generator.rb +29 -0
  92. data/test/integration/i9n_options_backup.rb +22 -0
  93. data/test/integration/i9n_scaffold.rb +27 -0
  94. data/test/integration/i9n_siba_file.rb +30 -0
  95. data/test/integration/i9n_test_unicode_files.rb +40 -0
  96. data/test/integration/i9n_tmp_dir.rb +44 -0
  97. data/test/integration/plugins/archive/tar/i9n_archive.rb +18 -0
  98. data/test/integration/plugins/destination/dir/i9n_dest_dir.rb +52 -0
  99. data/test/integration/plugins/encryption/gpg/i9n_encryption.rb +87 -0
  100. data/test/integration/plugins/i9n_installed_plugins.rb +13 -0
  101. data/test/integration/plugins/source/files/i9n_files.rb +146 -0
  102. data/test/integration/tasks/i9n_siba_tasks.rb +30 -0
  103. data/test/integration/yml/valid.yml +16 -0
  104. data/test/unit/helpers/test_encoding_helper.rb +17 -0
  105. data/test/unit/helpers/test_gem_helper.rb +17 -0
  106. data/test/unit/helpers/test_security_helper.rb +21 -0
  107. data/test/unit/helpers/test_string_helper.rb +35 -0
  108. data/test/unit/plugins/archive/tar/test_archive.rb +41 -0
  109. data/test/unit/plugins/archive/tar/test_init.rb +36 -0
  110. data/test/unit/plugins/archive/tar/yml/archive/check_installed.yml +2 -0
  111. data/test/unit/plugins/archive/tar/yml/init/default_compression.yml +1 -0
  112. data/test/unit/plugins/archive/tar/yml/init/invalid_compression.yml +2 -0
  113. data/test/unit/plugins/archive/tar/yml/init/valid.yml +2 -0
  114. data/test/unit/plugins/destination/dir/test_dest_dir.rb +41 -0
  115. data/test/unit/plugins/destination/dir/test_init.rb +36 -0
  116. data/test/unit/plugins/destination/dir/yml/init/valid.yml +2 -0
  117. data/test/unit/plugins/encryption/gpg/test_encryption.rb +70 -0
  118. data/test/unit/plugins/encryption/gpg/test_init.rb +47 -0
  119. data/test/unit/plugins/source/files/test_files.rb +44 -0
  120. data/test/unit/plugins/source/files/test_init.rb +48 -0
  121. data/test/unit/plugins/source/files/test_path_match.rb +140 -0
  122. data/test/unit/plugins/source/files/yml/ignore_list.yml +8 -0
  123. data/test/unit/plugins/source/files/yml/ignore_not_array.yml +5 -0
  124. data/test/unit/plugins/source/files/yml/include_not_array.yml +3 -0
  125. data/test/unit/plugins/source/files/yml/include_subdirs_false.yml +6 -0
  126. data/test/unit/plugins/source/files/yml/include_subdirs_missing.yml +5 -0
  127. data/test/unit/plugins/source/files/yml/no_ignore.yml +4 -0
  128. data/test/unit/plugins/source/files/yml/no_include.yml +1 -0
  129. data/test/unit/plugins/source/files/yml/valid.yml +9 -0
  130. data/test/unit/plugins/test_installed_plugins.rb +32 -0
  131. data/test/unit/plugins/test_plugin_loader.rb +27 -0
  132. data/test/unit/plugins/test_plugins.rb +44 -0
  133. data/test/unit/tasks/test_siba_task.rb +30 -0
  134. data/test/unit/tasks/test_siba_tasks.rb +84 -0
  135. data/test/unit/tasks/yml/task/invalid.yml +4 -0
  136. data/test/unit/tasks/yml/task/valid.yml +7 -0
  137. data/test/unit/test_backup.rb +18 -0
  138. data/test/unit/test_console.rb +166 -0
  139. data/test/unit/test_generator.rb +21 -0
  140. data/test/unit/test_globals.rb +34 -0
  141. data/test/unit/test_log_message.rb +26 -0
  142. data/test/unit/test_logger_plug.rb +49 -0
  143. data/test/unit/test_options_backup.rb +21 -0
  144. data/test/unit/test_options_loader.rb +72 -0
  145. data/test/unit/test_password_strength.rb +76 -0
  146. data/test/unit/test_restore.rb +18 -0
  147. data/test/unit/test_scaffold.rb +26 -0
  148. data/test/unit/test_siba_check.rb +118 -0
  149. data/test/unit/test_siba_logger.rb +174 -0
  150. data/test/unit/test_tmp_dir.rb +21 -0
  151. data/test/unit/yml/options_loader/array.yml +2 -0
  152. data/test/unit/yml/options_loader/empty.yml +0 -0
  153. data/test/unit/yml/options_loader/invalid.yml +4 -0
  154. data/test/unit/yml/options_loader/string.yml +1 -0
  155. data/test/unit/yml/options_loader/utf8_with_bom.yml +2 -0
  156. data/test/unit/yml/options_loader/valid.yml +12 -0
  157. data/test/unit/yml/siba_options_backup.yml +20 -0
  158. data/test/unit/yml/valid.yml +18 -0
  159. metadata +240 -0
@@ -0,0 +1,7 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ *.swp
6
+ *.log
7
+ tags
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in siba.gemspec
4
+ gemspec
@@ -0,0 +1,18 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard 'minitest', :notify=>false do
5
+ watch(%r|^test/unit/(.*\/)*test_(.*)\.rb|)
6
+ watch(%r|^lib/siba/(.*\/)*([^/]+)\.rb|) { |m| "test/unit/#{m[1]}test_#{m[2]}.rb" unless m[2][0] == '.' }
7
+ #watch(%r|^lib/(.*)([^/]+)\.rb|) { "test" }
8
+
9
+ # with Minitest::Unit
10
+ # watch(%r|^test/test_(.*)\.rb|)
11
+ #watch(%r|^lib/(.*)([^/]+)\.rb|) { |m| "test/#{m[1]}test_#{m[2]}.rb" }
12
+ # watch(%r|^test/test_helper\.rb|) { "test" }
13
+
14
+ # with Minitest::Spec
15
+ # watch(%r|^spec/(.*)_spec\.rb|)
16
+ # watch(%r|^lib/(.*)\.rb|) { |m| "spec/#{m[1]}_spec.rb" }
17
+ # watch(%r|^spec/spec_helper\.rb|) { "spec" }
18
+ end
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Evgeny Neumerzhitskiy
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,47 @@
1
+ # Overview
2
+
3
+ SIBA is a simple backup and restore utility. It implements daily backup rotation scheme. It is most suitable in sutuations when you need to have a history of backups and not just the last one. If run daily, SIBA retains full year history of backups by keeping only 23 files: 6 daily, 5 weekly and 12 monthly full backups.
4
+
5
+ ## Main features
6
+
7
+ * **Ease of use.** Configure, backup and restore with a single command.
8
+ * **Secure.** All backups are encrypted on your computer before reaching backup destination.
9
+ * **Cross platform.** Utility can be run on any computer with Ruby 1.9 or later.
10
+ * **Easy to extend.** Developers can easily add new backup sources, archivers, encryptors and destinations.
11
+ * **Free and open source.** Use SIBA for any purpose without restrictions.
12
+
13
+ ## Installation
14
+
15
+ $ gem install siba
16
+
17
+ (assuming that Ruby 1.9 and RubyGems are installed)
18
+
19
+ ## Usage
20
+
21
+ 1. Create a configuration file
22
+
23
+ $ siba generate mybak
24
+
25
+ 2. Backup
26
+
27
+ $ siba backup mybak
28
+
29
+ 3. Restore
30
+
31
+ $ siba restore mybak
32
+
33
+ 4. Show available plugins
34
+
35
+ $ siba list
36
+
37
+ 5. Create a gem project for a new destination plugin (or for a source, archive, encryption plugin).
38
+
39
+ $ siba scaffold destination my-cloud
40
+
41
+ 6. Show other commands and options
42
+
43
+ $ siba
44
+
45
+ ## Scheduling backups
46
+
47
+ It is recommended to run `siba backup` command daily or hourly. Use your favourite scheduler: Cron, Scheduled Tasks, iCal etc.
@@ -0,0 +1,27 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake/testtask'
3
+
4
+ namespace "test" do
5
+ desc "Run all unit tests"
6
+ Rake::TestTask.new("unit") do |t|
7
+ t.pattern = "test/unit/**/test*.rb"
8
+ t.libs << 'test'
9
+ end
10
+
11
+ desc "Run all integration tests"
12
+ Rake::TestTask.new("integration") do |t|
13
+ t.pattern = "test/integration/**/i9n_*.rb"
14
+ t.libs << 'test'
15
+ end
16
+
17
+ desc "Run all integration tests"
18
+ task :i9n => ["test:integration"] do
19
+ end
20
+ end
21
+
22
+ desc "Run all unit tests"
23
+ task :test => ["test:unit"] do
24
+ end
25
+
26
+ desc "Run tests"
27
+ task :default => "test:unit"
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'siba'
4
+ Siba::Console.new.parse ARGV
5
+
@@ -0,0 +1,27 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'siba/version'
4
+ require 'siba/errors'
5
+ require 'siba/helpers/string_helper'
6
+ require 'siba/helpers/encoding_helper'
7
+ require 'siba/helpers/gem_helper'
8
+ require 'siba/helpers/security_helper'
9
+ require 'siba/siba_file'
10
+ require 'siba/siba_kernel'
11
+ require 'siba/helpers/file_helper'
12
+ require 'siba/logger_plug'
13
+ require 'siba/tmp_dir'
14
+ require 'siba/siba_check'
15
+ require 'siba/globals'
16
+ require 'siba/test_files'
17
+ require 'siba/options_loader'
18
+ require 'siba/plugins/plugins'
19
+ require 'siba/tasks/siba_tasks'
20
+ require 'siba/console'
21
+ require 'siba/options_backup'
22
+ require 'siba/backup'
23
+ require 'siba/restore'
24
+
25
+ module Siba
26
+ # Your code goes here...
27
+ end
@@ -0,0 +1,31 @@
1
+ # encoding: UTF-8
2
+
3
+ module Siba
4
+ class Backup
5
+ include Siba::LoggerPlug
6
+ include Siba::FilePlug
7
+
8
+ def backup(path_to_options_yml, path_to_log_file)
9
+ run_backup path_to_options_yml, path_to_log_file
10
+ ensure
11
+ Siba.cleanup
12
+ end
13
+
14
+ private
15
+
16
+ def run_backup(path_to_options_yml, path_to_log_file)
17
+ LoggerPlug.create "Backup", path_to_log_file
18
+ options = Siba::OptionsLoader.load_yml path_to_options_yml
19
+ Siba.current_dir = File.dirname path_to_options_yml
20
+ Siba.settings = options["settings"] || {}
21
+ Siba.backup_name = File.basename path_to_options_yml, ".yml"
22
+
23
+ TmpDir.test_access
24
+ SibaTasks.new(options, path_to_options_yml, false).backup
25
+ Siba.cleanup_tmp_dir
26
+ rescue Exception => e
27
+ logger.fatal e
28
+ logger.log_exception e, true
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,196 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'optparse'
4
+ require 'siba/scaffold'
5
+ require 'siba/generator'
6
+
7
+ module Siba
8
+ class Console
9
+ include Siba::FilePlug
10
+
11
+ UNUSED_COMMAND = "unused" # unused command for testing command line options
12
+ attr_accessor :test_mode, :parser, :options
13
+
14
+ def initialize(test_mode=false)
15
+ @test_mode = test_mode
16
+ @options = {}
17
+ end
18
+
19
+ def parse(argv)
20
+ @parser = parse_options argv
21
+ return if parser.nil?
22
+ parse_command argv
23
+ end
24
+
25
+ private
26
+
27
+ def parse_options(argv)
28
+ parser = OptionParser.new do |o|
29
+ o.banner = "Usage: siba command ARGUMENTS [options...]
30
+
31
+ Examples:
32
+ siba generate mybak Generate mybak.yml options file
33
+ siba backup mybak Run backup, reading options from mybak.yml
34
+ siba restore mybak Restore the backup
35
+ siba list Show available plugins
36
+ siba scaffold source my-db Create a new gem for a source plugin
37
+ (or archive, encryption or destination)
38
+
39
+ Note: single letter commands are also supported, like b for backup
40
+
41
+ Options:"
42
+
43
+ o.on("--log FILE", "Set path to log FILE") do |log|
44
+ options['log'] = log
45
+ end
46
+
47
+ o.on("--no-log", "Work without logging") do
48
+ SibaLogger.no_log = true
49
+ end
50
+
51
+ o.on("-q", "--quiet", "No output to console") do
52
+ SibaLogger.quiet = true
53
+ end
54
+
55
+ o.on("-v", "--verbose", "Detailed progress messages and error reports") do
56
+ SibaLogger.verbose = true
57
+ end
58
+
59
+ o.on("-h", "--help", "Show this message") do
60
+ show_message o
61
+ return
62
+ end
63
+
64
+ o.on("--version", "Show version") do
65
+ show_message "SIBA (SImple BAckup) #{Siba::VERSION}"
66
+ return
67
+ end
68
+ end
69
+
70
+ if argv.empty?
71
+ show_message parser.to_s
72
+ return
73
+ end
74
+
75
+ begin
76
+ parser.parse! argv
77
+ rescue Exception => e
78
+ @parser = parser
79
+ show_error e.to_s, true, e
80
+ end
81
+
82
+ if !options['log'].nil? && SibaLogger.no_log
83
+ show_error "ambiguous usage of both --log and --no-log switches"
84
+ return
85
+ end
86
+
87
+ parser
88
+ end
89
+
90
+ def parse_command(argv)
91
+ command = argv.shift
92
+ show_error "missing a command", true if command.nil?
93
+
94
+ case command.downcase
95
+ when "b", "backup"
96
+ backup argv
97
+ when "s", "scaffold"
98
+ scaffold argv
99
+ when "l", "list"
100
+ list
101
+ when "g", "generate"
102
+ generate argv
103
+ when "r", "restore"
104
+ restore argv
105
+ when Siba::Console::UNUSED_COMMAND
106
+ else
107
+ show_error "Invalid command '#{command}'", true
108
+ end
109
+
110
+ exit_with_error if Siba::SibaLogger.count("warn",false) > 0
111
+ end
112
+
113
+ def show_error(msg, show_help = false, exception = nil)
114
+ if msg.is_a? Exception
115
+ exception = msg
116
+ msg = msg.message
117
+ end
118
+ msg += "\n\n#{parser.to_s}" if show_help
119
+ show_message "Error: #{msg}"
120
+ exit_with_error
121
+ raise (exception || Siba::ConsoleArgumentError.new(msg))
122
+ end
123
+
124
+ def show_message(msg)
125
+ puts msg unless test_mode
126
+ end
127
+
128
+ def exit_with_error
129
+ exit 1 unless test_mode
130
+ end
131
+
132
+ def backup(argv)
133
+ path_to_options = argv.shift
134
+ show_error "missing backup options file argument" if path_to_options.nil?
135
+ show_error "needless arguments: #{argv.join(', ')}" unless argv.empty?
136
+ path_to_options = siba_file.file_expand_path path_to_options
137
+ path_to_log = options['log']
138
+
139
+ unless path_to_log.nil?
140
+ path_to_log = siba_file.file_expand_path path_to_log
141
+ else
142
+ log_name = "#{File.basename(path_to_options,".yml")}.log"
143
+ path_to_log = File.join(File.dirname(path_to_options), "#{log_name}")
144
+ end
145
+
146
+ path_to_options += ".yml" unless path_to_options =~ /\.yml$/
147
+ Siba::Backup.new.backup path_to_options, path_to_log
148
+ end
149
+
150
+ def scaffold(argv)
151
+ category = argv.shift
152
+ if category.nil?
153
+ show_error "missing category argument"
154
+ end
155
+
156
+ name = argv.shift
157
+ show_error "missing name argument" if name.nil?
158
+ show_error "needless arguments: #{argv.join(', ')}" unless argv.empty?
159
+
160
+ begin
161
+ Siba::Scaffold.new(category, name).scaffold(siba_file.dir_pwd)
162
+ rescue Exception => ex
163
+ show_error ex
164
+ end
165
+ end
166
+
167
+ def list
168
+ show_message "Available SIBA plugins:
169
+
170
+ #{Siba::Plugins.get_list} * Currently installed"
171
+ end
172
+
173
+ def generate(argv)
174
+ file = argv.shift
175
+ if file.nil?
176
+ show_error "missing file name"
177
+ end
178
+ begin
179
+ path_to_yaml = Siba::Generator.new(file).generate
180
+ show_message "Options file generated: #{path_to_yaml}
181
+ Edit it and run backup command" unless path_to_yaml.nil?
182
+ rescue Exception => ex
183
+ show_error ex
184
+ end
185
+ end
186
+
187
+ def restore(argv)
188
+ path_to_options = argv.shift
189
+ show_error "missing backup options file argument" if path_to_options.nil?
190
+ show_error "needless arguments: #{argv.join(', ')}" unless argv.empty?
191
+ path_to_options = siba_file.file_expand_path path_to_options
192
+ path_to_options += ".yml" unless path_to_options =~ /\.yml$/
193
+ Siba::Restore.new.restore path_to_options
194
+ end
195
+ end
196
+ end
@@ -0,0 +1,8 @@
1
+ # encoding: UTF-8
2
+
3
+ module Siba
4
+ class Error < RuntimeError; end
5
+ class PluginLoadError < RuntimeError; end
6
+ class CheckError < RuntimeError; end
7
+ class ConsoleArgumentError < RuntimeError; end
8
+ end
@@ -0,0 +1,115 @@
1
+ # encoding: UTF-8
2
+
3
+ module Siba
4
+ class Generator
5
+ include Siba::FilePlug
6
+ include Siba::KernelPlug
7
+
8
+ PLUGIN_YAML_NAME = "options.yml"
9
+
10
+ attr_accessor :name
11
+ def initialize(name)
12
+ @name = String.new name
13
+ end
14
+
15
+ # Generates yaml options file and returns its path
16
+ def generate
17
+ siba_file.run_this do
18
+ file_path = @name.gsub /\.yml$/, ""
19
+ file_path += ".yml"
20
+ file_path = siba_file.file_expand_path file_path
21
+ if siba_file.file_file?(file_path) || siba_file.file_directory?(file_path)
22
+ raise Siba::Error, "Options file already exists: #{file_path}"
23
+ end
24
+
25
+ options_data = []
26
+ Siba::Plugins::PLUGINS_HASH.each do |category, types|
27
+ type = nil
28
+ if types.size > 1
29
+ max_type_length = types.keys.max do |a,b|
30
+ a.length <=> b.length
31
+ end.length + 5
32
+
33
+ siba_kernel.puts "\nChoose #{category} plugin:"
34
+ types.keys.each_index do |i|
35
+ type = types.keys[i]
36
+ siba_kernel.puts " #{i+1}. #{Siba::Plugins.plugin_type_and_description(category, type, max_type_length)}"
37
+ end
38
+
39
+ type = Siba::Generator.get_plugin_user_choice types.keys
40
+ if type.nil?
41
+ siba_kernel.puts "Cancelled by user"
42
+ return
43
+ end
44
+
45
+ unless Siba::InstalledPlugins.installed? category, type
46
+ siba_kernel.puts "#{type} plugin is not installed."
47
+ siba_kernel.puts "Run 'gem install #{Siba::InstalledPlugins.gem_name(category, type)}' to install it and try again."
48
+ return
49
+ end
50
+ else
51
+ type = types.keys.first
52
+ end
53
+
54
+ options = Siba::Generator.load_plugin_yaml_content category, type
55
+ unless options =~ /^\s*type:/
56
+ options = "type: #{type}\n" + options
57
+ end
58
+
59
+ options.gsub! /^/, " "
60
+ options = "#{category}:\n" + options
61
+ options_data << options
62
+ end
63
+
64
+ file_data = options_data.join("\n")
65
+ file_data = "# SIBA options file\n" + file_data
66
+ dest_dir = File.dirname file_path
67
+ siba_file.file_utils_mkpath(dest_dir) unless siba_file.file_directory?(dest_dir)
68
+ Siba::FileHelper.write file_path, file_data
69
+ file_path
70
+ end
71
+ end
72
+
73
+ class << self
74
+ include Siba::FilePlug
75
+ include Siba::KernelPlug
76
+
77
+ def load_plugin_yaml_content(category, type)
78
+ siba_file.run_this do
79
+ path = get_plugin_yaml_path category, type
80
+ begin
81
+ Siba::OptionsLoader.load_erb path
82
+ rescue Exception => ex
83
+ raise "Failed to load options for #{InstalledPlugins.plugin_category_and_type(category, type)} plugin from file: #{path}. Error: #{ex.message}"
84
+ end
85
+ end
86
+ end
87
+
88
+ def get_plugin_yaml_path(category, type)
89
+ siba_file.run_this do
90
+ dir = InstalledPlugins.plugin_path(category, type)
91
+ options_path = File.join dir, PLUGIN_YAML_NAME
92
+ unless siba_file.file_file? options_path
93
+ raise Siba::Error, "Failed to load options for #{InstalledPlugins.plugin_category_and_type(category, type)} plugin from file: #{options_path}"
94
+ end
95
+ options_path
96
+ end
97
+ end
98
+
99
+ def get_plugin_user_choice(types)
100
+ msg = "\nEnter plugin number from 1 to #{types.size}, or 0 to exit.\n> "
101
+ siba_kernel.printf msg
102
+ while true
103
+ user_choice = siba_kernel.gets.chomp.strip
104
+ number = Integer(user_choice) rescue -1
105
+ if number >= 0 && number <= types.size
106
+ return if number == 0
107
+ return types[number-1]
108
+ else
109
+ siba_kernel.printf msg
110
+ end
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end