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.
- data/.gitignore +7 -0
- data/Gemfile +4 -0
- data/Guardfile +18 -0
- data/LICENSE +22 -0
- data/README.md +47 -0
- data/Rakefile +27 -0
- data/bin/siba +5 -0
- data/lib/siba.rb +27 -0
- data/lib/siba/backup.rb +31 -0
- data/lib/siba/console.rb +196 -0
- data/lib/siba/errors.rb +8 -0
- data/lib/siba/generator.rb +115 -0
- data/lib/siba/globals.rb +19 -0
- data/lib/siba/helpers/encoding_helper.rb +38 -0
- data/lib/siba/helpers/file_helper.rb +89 -0
- data/lib/siba/helpers/gem_helper.rb +22 -0
- data/lib/siba/helpers/password_strength.rb +94 -0
- data/lib/siba/helpers/security_helper.rb +30 -0
- data/lib/siba/helpers/string_helper.rb +32 -0
- data/lib/siba/helpers/test/extend_test.rb +114 -0
- data/lib/siba/helpers/test/file_mock.rb +38 -0
- data/lib/siba/helpers/test/helper.rb +55 -0
- data/lib/siba/helpers/test/kernel_mock.rb +44 -0
- data/lib/siba/helpers/test/removable_constants.rb +18 -0
- data/lib/siba/helpers/test/require.rb +12 -0
- data/lib/siba/logger_plug.rb +36 -0
- data/lib/siba/options_backup.rb +37 -0
- data/lib/siba/options_loader.rb +38 -0
- data/lib/siba/plugins/archive/tar/archive.rb +117 -0
- data/lib/siba/plugins/archive/tar/init.rb +38 -0
- data/lib/siba/plugins/archive/tar/options.yml +1 -0
- data/lib/siba/plugins/destination/dir/dest_dir.rb +77 -0
- data/lib/siba/plugins/destination/dir/init.rb +31 -0
- data/lib/siba/plugins/destination/dir/options.yml +2 -0
- data/lib/siba/plugins/encryption/gpg/encryption.rb +140 -0
- data/lib/siba/plugins/encryption/gpg/init.rb +45 -0
- data/lib/siba/plugins/encryption/gpg/options.yml +2 -0
- data/lib/siba/plugins/installed_plugins.rb +77 -0
- data/lib/siba/plugins/plugin_loader.rb +100 -0
- data/lib/siba/plugins/plugins.rb +57 -0
- data/lib/siba/plugins/plugins.yml +9 -0
- data/lib/siba/plugins/source/files/files.rb +166 -0
- data/lib/siba/plugins/source/files/init.rb +33 -0
- data/lib/siba/plugins/source/files/options.yml +11 -0
- data/lib/siba/restore.rb +113 -0
- data/lib/siba/scaffold.rb +166 -0
- data/lib/siba/siba_check.rb +75 -0
- data/lib/siba/siba_file.rb +89 -0
- data/lib/siba/siba_kernel.rb +37 -0
- data/lib/siba/siba_logger.rb +172 -0
- data/lib/siba/tasks/siba_task.rb +42 -0
- data/lib/siba/tasks/siba_tasks.rb +120 -0
- data/lib/siba/test_files.rb +76 -0
- data/lib/siba/test_files/a_file +1 -0
- data/lib/siba/test_files/files_and_dirs/.hidden +1 -0
- data/lib/siba/test_files/files_and_dirs/.hidden_dir/file10 +1 -0
- data/lib/siba/test_files/files_and_dirs/File With Spaces +1 -0
- data/lib/siba/test_files/files_and_dirs/dir1/file10 +1 -0
- data/lib/siba/test_files/files_and_dirs/dir1/sub-dir/file111.txt +1 -0
- data/lib/siba/test_files/files_and_dirs/file1 +1 -0
- data/lib/siba/test_files/files_and_dirs/file2.txt +1 -0
- data/lib/siba/tmp_dir.rb +94 -0
- data/lib/siba/version.rb +5 -0
- data/scaffolds/archive.rb +26 -0
- data/scaffolds/destination.rb +20 -0
- data/scaffolds/encryption.rb +26 -0
- data/scaffolds/project/.gitignore +5 -0
- data/scaffolds/project/Gemfile +4 -0
- data/scaffolds/project/Guardfile +9 -0
- data/scaffolds/project/LICENSE +22 -0
- data/scaffolds/project/README.md +33 -0
- data/scaffolds/project/Rakefile +28 -0
- data/scaffolds/project/lib/siba-c6y-demo.rb +11 -0
- data/scaffolds/project/lib/siba-c6y-demo/options.yml +2 -0
- data/scaffolds/project/lib/siba-c6y-demo/version.rb +9 -0
- data/scaffolds/project/siba-c6y-demo.gemspec +26 -0
- data/scaffolds/project/test/helper/require_integration.rb +5 -0
- data/scaffolds/project/test/helper/require_unit.rb +4 -0
- data/scaffolds/project/test/integration/i9n_init.rb +35 -0
- data/scaffolds/project/test/unit/test_init.rb +43 -0
- data/scaffolds/project/test/unit/yml/valid.yml +8 -0
- data/scaffolds/shared/examples.rb +47 -0
- data/scaffolds/shared/init_example.rb +13 -0
- data/scaffolds/source.rb +25 -0
- data/siba.gemspec +30 -0
- data/test/helper/require_integration.rb +4 -0
- data/test/helper/require_unit.rb +4 -0
- data/test/integration/helpers/i9n_file_helper.rb +50 -0
- data/test/integration/i9n_backup.rb +53 -0
- data/test/integration/i9n_console.rb +16 -0
- data/test/integration/i9n_generator.rb +29 -0
- data/test/integration/i9n_options_backup.rb +22 -0
- data/test/integration/i9n_scaffold.rb +27 -0
- data/test/integration/i9n_siba_file.rb +30 -0
- data/test/integration/i9n_test_unicode_files.rb +40 -0
- data/test/integration/i9n_tmp_dir.rb +44 -0
- data/test/integration/plugins/archive/tar/i9n_archive.rb +18 -0
- data/test/integration/plugins/destination/dir/i9n_dest_dir.rb +52 -0
- data/test/integration/plugins/encryption/gpg/i9n_encryption.rb +87 -0
- data/test/integration/plugins/i9n_installed_plugins.rb +13 -0
- data/test/integration/plugins/source/files/i9n_files.rb +146 -0
- data/test/integration/tasks/i9n_siba_tasks.rb +30 -0
- data/test/integration/yml/valid.yml +16 -0
- data/test/unit/helpers/test_encoding_helper.rb +17 -0
- data/test/unit/helpers/test_gem_helper.rb +17 -0
- data/test/unit/helpers/test_security_helper.rb +21 -0
- data/test/unit/helpers/test_string_helper.rb +35 -0
- data/test/unit/plugins/archive/tar/test_archive.rb +41 -0
- data/test/unit/plugins/archive/tar/test_init.rb +36 -0
- data/test/unit/plugins/archive/tar/yml/archive/check_installed.yml +2 -0
- data/test/unit/plugins/archive/tar/yml/init/default_compression.yml +1 -0
- data/test/unit/plugins/archive/tar/yml/init/invalid_compression.yml +2 -0
- data/test/unit/plugins/archive/tar/yml/init/valid.yml +2 -0
- data/test/unit/plugins/destination/dir/test_dest_dir.rb +41 -0
- data/test/unit/plugins/destination/dir/test_init.rb +36 -0
- data/test/unit/plugins/destination/dir/yml/init/valid.yml +2 -0
- data/test/unit/plugins/encryption/gpg/test_encryption.rb +70 -0
- data/test/unit/plugins/encryption/gpg/test_init.rb +47 -0
- data/test/unit/plugins/source/files/test_files.rb +44 -0
- data/test/unit/plugins/source/files/test_init.rb +48 -0
- data/test/unit/plugins/source/files/test_path_match.rb +140 -0
- data/test/unit/plugins/source/files/yml/ignore_list.yml +8 -0
- data/test/unit/plugins/source/files/yml/ignore_not_array.yml +5 -0
- data/test/unit/plugins/source/files/yml/include_not_array.yml +3 -0
- data/test/unit/plugins/source/files/yml/include_subdirs_false.yml +6 -0
- data/test/unit/plugins/source/files/yml/include_subdirs_missing.yml +5 -0
- data/test/unit/plugins/source/files/yml/no_ignore.yml +4 -0
- data/test/unit/plugins/source/files/yml/no_include.yml +1 -0
- data/test/unit/plugins/source/files/yml/valid.yml +9 -0
- data/test/unit/plugins/test_installed_plugins.rb +32 -0
- data/test/unit/plugins/test_plugin_loader.rb +27 -0
- data/test/unit/plugins/test_plugins.rb +44 -0
- data/test/unit/tasks/test_siba_task.rb +30 -0
- data/test/unit/tasks/test_siba_tasks.rb +84 -0
- data/test/unit/tasks/yml/task/invalid.yml +4 -0
- data/test/unit/tasks/yml/task/valid.yml +7 -0
- data/test/unit/test_backup.rb +18 -0
- data/test/unit/test_console.rb +166 -0
- data/test/unit/test_generator.rb +21 -0
- data/test/unit/test_globals.rb +34 -0
- data/test/unit/test_log_message.rb +26 -0
- data/test/unit/test_logger_plug.rb +49 -0
- data/test/unit/test_options_backup.rb +21 -0
- data/test/unit/test_options_loader.rb +72 -0
- data/test/unit/test_password_strength.rb +76 -0
- data/test/unit/test_restore.rb +18 -0
- data/test/unit/test_scaffold.rb +26 -0
- data/test/unit/test_siba_check.rb +118 -0
- data/test/unit/test_siba_logger.rb +174 -0
- data/test/unit/test_tmp_dir.rb +21 -0
- data/test/unit/yml/options_loader/array.yml +2 -0
- data/test/unit/yml/options_loader/empty.yml +0 -0
- data/test/unit/yml/options_loader/invalid.yml +4 -0
- data/test/unit/yml/options_loader/string.yml +1 -0
- data/test/unit/yml/options_loader/utf8_with_bom.yml +2 -0
- data/test/unit/yml/options_loader/valid.yml +12 -0
- data/test/unit/yml/siba_options_backup.yml +20 -0
- data/test/unit/yml/valid.yml +18 -0
- metadata +240 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
|
|
3
|
+
require 'siba/plugins/plugin_loader.rb'
|
|
4
|
+
require 'siba/plugins/installed_plugins.rb'
|
|
5
|
+
|
|
6
|
+
module Siba
|
|
7
|
+
class Plugins
|
|
8
|
+
PLUGINS_HASH = Siba::OptionsLoader.load_hash_from_yml(File.expand_path "../plugins.yml", __FILE__)
|
|
9
|
+
CATEGORIES = PLUGINS_HASH.keys
|
|
10
|
+
|
|
11
|
+
class << self
|
|
12
|
+
def valid_category?(category)
|
|
13
|
+
Siba::Plugins::CATEGORIES.include? category
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def categories_str
|
|
17
|
+
Siba::Plugins::CATEGORIES.join(", ")
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def category_and_type_correct?(category, type)
|
|
21
|
+
PLUGINS_HASH.keys.include?(category) && PLUGINS_HASH[category].keys.include?(type)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def plugin_description(category, type)
|
|
25
|
+
unless category_and_type_correct? category, type
|
|
26
|
+
raise Siba::Error, "Incorrect category '#{category}' or type '#{type}'."
|
|
27
|
+
end
|
|
28
|
+
PLUGINS_HASH[category][type]
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def plugin_type_and_description(category, type, name_column_length)
|
|
32
|
+
desc = plugin_description category, type
|
|
33
|
+
sprintf("%-#{name_column_length}s %s", type, desc)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def get_list
|
|
37
|
+
str = ""
|
|
38
|
+
all_names = PLUGINS_HASH.values.map{|a| a.keys}.flatten
|
|
39
|
+
max_name_length = all_names.max do |a,b|
|
|
40
|
+
a.length <=> b.length
|
|
41
|
+
end.length + 5
|
|
42
|
+
|
|
43
|
+
PLUGINS_HASH.each do |category, plugins|
|
|
44
|
+
str << "#{category.capitalize}"
|
|
45
|
+
str << "s" if plugins.size > 1
|
|
46
|
+
str << ":\n"
|
|
47
|
+
plugins.each do |type, desc|
|
|
48
|
+
installed = InstalledPlugins.installed?(category, type) ? "*" : " "
|
|
49
|
+
str << " #{installed} #{plugin_type_and_description(category, type, max_name_length)}\n"
|
|
50
|
+
end
|
|
51
|
+
str << "\n"
|
|
52
|
+
end
|
|
53
|
+
str
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
source:
|
|
2
|
+
files: Backup local files and directories
|
|
3
|
+
archive:
|
|
4
|
+
tar: Archive with optional gzip or bzip2 compression
|
|
5
|
+
encryption:
|
|
6
|
+
gpg: Encrypt with AES256, Blowfish, Twofish, 3DES and other ciphers
|
|
7
|
+
destination:
|
|
8
|
+
dir: Backup to local directory
|
|
9
|
+
aws-s3: Upload backup to Amazon S3 storage
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
|
|
3
|
+
module Siba::Source
|
|
4
|
+
module Files
|
|
5
|
+
class Files
|
|
6
|
+
include Siba::LoggerPlug
|
|
7
|
+
include Siba::FilePlug
|
|
8
|
+
attr_accessor :files_to_include, :ignore, :include_subdirs
|
|
9
|
+
|
|
10
|
+
def initialize(files_to_include, ignore, include_subdirs)
|
|
11
|
+
@files_to_include = files_to_include
|
|
12
|
+
@ignore = ignore
|
|
13
|
+
@include_subdirs = include_subdirs
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def backup(dest_dir)
|
|
17
|
+
siba_file.run_this "backup" do
|
|
18
|
+
size_digits = files_to_include.size.to_s.length
|
|
19
|
+
files_to_include.each_index do |i|
|
|
20
|
+
file = files_to_include[i]
|
|
21
|
+
file = siba_file.file_expand_path file
|
|
22
|
+
next if ignored? file
|
|
23
|
+
|
|
24
|
+
is_file = siba_file.file_file? file
|
|
25
|
+
unless is_file || siba_file.file_directory?(file)
|
|
26
|
+
logger.error "Source file or directory does not exist: #{file}"
|
|
27
|
+
next
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
path_to_subdir = Files.sub_dir_name i+1, size_digits, is_file, file, dest_dir
|
|
31
|
+
siba_file.file_utils_mkpath path_to_subdir
|
|
32
|
+
|
|
33
|
+
logger.debug file
|
|
34
|
+
if is_file
|
|
35
|
+
copy_file file, path_to_subdir
|
|
36
|
+
else
|
|
37
|
+
copy_dir file, path_to_subdir, false
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def restore(from_dir)
|
|
44
|
+
siba_file.run_this do
|
|
45
|
+
backup_dirs = Siba::FileHelper.entries(from_dir).select do |e|
|
|
46
|
+
siba_file.file_directory? File.join(from_dir, e)
|
|
47
|
+
end.sort
|
|
48
|
+
|
|
49
|
+
if backup_dirs.size != files_to_include.size
|
|
50
|
+
raise Siba::Error, "Number of source files does not equal the number of files that are in the backup"
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
backup_dirs.each_index do |i|
|
|
54
|
+
backup_dir = backup_dirs[i]
|
|
55
|
+
splitted = backup_dir.split "-"
|
|
56
|
+
if splitted.size < 3
|
|
57
|
+
logger.error "Failed to parse backup dir #{backup_dir}"
|
|
58
|
+
next
|
|
59
|
+
end
|
|
60
|
+
dir_or_file = splitted[1]
|
|
61
|
+
if dir_or_file != "dir" && dir_or_file != "file"
|
|
62
|
+
logger.error "Failed to parse backup dir #{backup_dir}"
|
|
63
|
+
next
|
|
64
|
+
end
|
|
65
|
+
is_dir = dir_or_file == "dir"
|
|
66
|
+
path_to_backup_dir = File.join from_dir, backup_dir
|
|
67
|
+
entry_name_to_restore = files_to_include[i]
|
|
68
|
+
path_to_source = siba_file.file_expand_path entry_name_to_restore
|
|
69
|
+
if is_dir
|
|
70
|
+
siba_file.file_utils_mkpath path_to_source
|
|
71
|
+
siba_file.file_utils_cp_r File.join(path_to_backup_dir, "."), path_to_source
|
|
72
|
+
logger.info "Dir: #{path_to_source}"
|
|
73
|
+
else
|
|
74
|
+
restore_file path_to_backup_dir, entry_name_to_restore, path_to_source
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def restore_file(path_to_backup_dir, entry_name_to_restore, path_to_source)
|
|
81
|
+
backup_dir_entries = Siba::FileHelper.entries path_to_backup_dir
|
|
82
|
+
if backup_dir_entries.size != 1
|
|
83
|
+
logger.error "Failed to restore file: #{entry_name_to_restore}"
|
|
84
|
+
return
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
backup_file_name = backup_dir_entries[0]
|
|
89
|
+
path_to_backup_file = File.join path_to_backup_dir, backup_file_name
|
|
90
|
+
unless siba_file.file_file? path_to_backup_file
|
|
91
|
+
logger.error "Failed to restore file: #{path_to_backup_file}"
|
|
92
|
+
return
|
|
93
|
+
end
|
|
94
|
+
source_file_name = File.basename path_to_source
|
|
95
|
+
unless source_file_name == backup_file_name
|
|
96
|
+
logger.error "Failed to restore file, source file name '#{source_file_name}' is not the same as backup file name #{backup_file_name}"
|
|
97
|
+
return
|
|
98
|
+
end
|
|
99
|
+
path_to_source_dir = File.dirname path_to_source
|
|
100
|
+
siba_file.file_utils_mkpath path_to_source_dir
|
|
101
|
+
siba_file.file_utils_cp path_to_backup_file, path_to_source_dir
|
|
102
|
+
logger.info "File: #{path_to_source}"
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def copy_file(file, dest_dir)
|
|
106
|
+
siba_file.run_this "copy file" do
|
|
107
|
+
return if ignored? file
|
|
108
|
+
siba_file.file_utils_cp(file, dest_dir)
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def copy_dir(dir, dest_dir, create_subdir=false)
|
|
113
|
+
siba_file.run_this "copy dir" do
|
|
114
|
+
return if ignored? dir
|
|
115
|
+
|
|
116
|
+
if create_subdir
|
|
117
|
+
dest_dir = File.join(dest_dir, File.basename(dir))
|
|
118
|
+
siba_file.file_utils_mkpath dest_dir
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
Siba::FileHelper.entries(dir).each do |entry|
|
|
122
|
+
entry = File.join dir, entry
|
|
123
|
+
if siba_file.file_file? entry
|
|
124
|
+
copy_file entry, dest_dir
|
|
125
|
+
elsif siba_file.file_directory? entry
|
|
126
|
+
copy_dir entry, dest_dir, true if include_subdirs
|
|
127
|
+
else
|
|
128
|
+
logger.error "Failed to backup: #{file}."
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def ignored?(file)
|
|
135
|
+
return false if ignore.nil?
|
|
136
|
+
ignore.each do |pattern|
|
|
137
|
+
if Siba::Source::Files::Files.path_match? pattern, file
|
|
138
|
+
logger.info "Ignoring #{file}"
|
|
139
|
+
return true
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
false
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
class << self
|
|
146
|
+
def path_match?(pattern, file)
|
|
147
|
+
file.strip!
|
|
148
|
+
pattern.strip!
|
|
149
|
+
basename = File.basename(file)
|
|
150
|
+
|
|
151
|
+
return File.fnmatch(pattern, basename, File::FNM_CASEFOLD) || # match basename against pattern
|
|
152
|
+
File.fnmatch(pattern, file, File::FNM_CASEFOLD) # match whole path against pattern
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def sub_dir_name(num, size_digits, is_file, src_file, dest_dir)
|
|
156
|
+
basename = File.basename src_file
|
|
157
|
+
basename = "root" if basename.empty? || basename == "/"
|
|
158
|
+
sub_dir_name = "%0#{size_digits}d" % num
|
|
159
|
+
sub_dir_name += is_file ? "-file" : "-dir"
|
|
160
|
+
sub_dir_name += "-#{basename}"
|
|
161
|
+
File.join dest_dir, sub_dir_name
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
|
|
3
|
+
require 'siba/plugins/source/files/files'
|
|
4
|
+
|
|
5
|
+
module Siba::Source
|
|
6
|
+
module Files
|
|
7
|
+
class Init
|
|
8
|
+
include Siba::LoggerPlug
|
|
9
|
+
attr_accessor :files
|
|
10
|
+
|
|
11
|
+
def initialize(options)
|
|
12
|
+
files_to_include = Siba::SibaCheck.options_string_array options, "include"
|
|
13
|
+
ignore = Siba::SibaCheck.options_string_array options, "ignore", true
|
|
14
|
+
include_subdirs = Siba::SibaCheck.options_bool options, "include_subdirs", true, true
|
|
15
|
+
@files = Siba::Source::Files::Files.new files_to_include, ignore, include_subdirs
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Collect sources and put them into dest_dir
|
|
19
|
+
# No return value is expected
|
|
20
|
+
def backup(dest_dir)
|
|
21
|
+
logger.info "Collecting files"
|
|
22
|
+
@files.backup dest_dir
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Restore source files and dirs from_dir
|
|
26
|
+
# No return value is expected
|
|
27
|
+
def restore(from_dir)
|
|
28
|
+
logger.info "Restoring files"
|
|
29
|
+
@files.restore from_dir
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
data/lib/siba/restore.rb
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
|
|
3
|
+
module Siba
|
|
4
|
+
class Restore
|
|
5
|
+
include Siba::LoggerPlug
|
|
6
|
+
include Siba::FilePlug
|
|
7
|
+
include Siba::KernelPlug
|
|
8
|
+
|
|
9
|
+
def restore(path_to_options_yml)
|
|
10
|
+
run_restore path_to_options_yml
|
|
11
|
+
ensure
|
|
12
|
+
Siba.cleanup
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
private
|
|
16
|
+
|
|
17
|
+
def run_restore(path_to_options_yml)
|
|
18
|
+
LoggerPlug.create "Restore", nil
|
|
19
|
+
options = Siba::OptionsLoader.load_yml path_to_options_yml
|
|
20
|
+
Siba.current_dir = File.dirname path_to_options_yml
|
|
21
|
+
Siba.settings = options["settings"] || {}
|
|
22
|
+
Siba.backup_name = File.basename path_to_options_yml, ".yml"
|
|
23
|
+
TmpDir.test_access
|
|
24
|
+
tasks = SibaTasks.new options, path_to_options_yml, true
|
|
25
|
+
file_name = get_backup_choice tasks
|
|
26
|
+
unless file_name.nil?
|
|
27
|
+
if user_wants_to_proceed?
|
|
28
|
+
tasks.restore file_name
|
|
29
|
+
else
|
|
30
|
+
logger.show_finish_message = false
|
|
31
|
+
logger.info "Cancelled by user"
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
Siba.cleanup_tmp_dir
|
|
35
|
+
rescue Exception => e
|
|
36
|
+
logger.fatal e
|
|
37
|
+
logger.log_exception e, true
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def get_backup_choice(tasks)
|
|
41
|
+
list = tasks.get_backups_list
|
|
42
|
+
|
|
43
|
+
siba_file.run_this do
|
|
44
|
+
if list.empty?
|
|
45
|
+
logger.show_finish_message = false
|
|
46
|
+
logger.info "No backups named '#{Siba.backup_name}' found"
|
|
47
|
+
return
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
if list.size == 1
|
|
51
|
+
return list[0][0]
|
|
52
|
+
else
|
|
53
|
+
list.sort_by!{|a| a[1]}
|
|
54
|
+
siba_kernel.puts "\nAvailable '#{Siba.backup_name}' backups:\n"
|
|
55
|
+
show_backups list
|
|
56
|
+
file_name = get_backup_user_choice list
|
|
57
|
+
|
|
58
|
+
if file_name.nil?
|
|
59
|
+
logger.show_finish_message = false
|
|
60
|
+
logger.info "Cancelled by user"
|
|
61
|
+
end
|
|
62
|
+
return file_name
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def show_backups(list)
|
|
68
|
+
list.map! {|a| a << Siba::StringHelper.format_time(a[1])}
|
|
69
|
+
max_date_length = list.max do |a,b|
|
|
70
|
+
a[2].length <=> b[2].length
|
|
71
|
+
end[2].length + 5
|
|
72
|
+
|
|
73
|
+
rows = list.size / 2 + list.size % 2
|
|
74
|
+
1.upto(rows) do |i|
|
|
75
|
+
num1 = "#{i.to_s.rjust(2)}."
|
|
76
|
+
str1 = list[i-1][2]
|
|
77
|
+
column1 = sprintf("%s %-#{max_date_length}s", num1, str1)
|
|
78
|
+
|
|
79
|
+
if (i+rows) <= list.size
|
|
80
|
+
num2 = "#{(i+rows).to_s.rjust(2)}."
|
|
81
|
+
str2 = list[i+rows-1][2]
|
|
82
|
+
column2 = "#{num2} #{str2}"
|
|
83
|
+
end
|
|
84
|
+
siba_kernel.puts " #{column1}#{column2}"
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def user_wants_to_proceed?
|
|
89
|
+
siba_kernel.printf "\nWarning: backup will be restored into your original source location.
|
|
90
|
+
Your current source data will be overwritten and WILL BE LOST.
|
|
91
|
+
Type 'yes' if you want to proceed:
|
|
92
|
+
(yes/n) > "
|
|
93
|
+
user_choice = siba_kernel.gets.chomp.strip
|
|
94
|
+
return user_choice.downcase == "yes"
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def get_backup_user_choice(list)
|
|
98
|
+
msg = "\nChoose a backup to restore.\nEnter backup number from 1 to #{list.size}, or 0 to exit.\n> "
|
|
99
|
+
siba_kernel.printf msg
|
|
100
|
+
while true
|
|
101
|
+
user_choice = siba_kernel.gets.chomp.strip
|
|
102
|
+
number = Integer(user_choice) rescue -1
|
|
103
|
+
if number >= 0 && number <= list.size
|
|
104
|
+
return if number == 0
|
|
105
|
+
return list[number-1][0]
|
|
106
|
+
else
|
|
107
|
+
siba_kernel.printf msg
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
end
|
|
113
|
+
end
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
|
|
3
|
+
module Siba
|
|
4
|
+
class Scaffold
|
|
5
|
+
include Siba::FilePlug
|
|
6
|
+
include Siba::LoggerPlug
|
|
7
|
+
attr_accessor :category, :name, :name_camelized
|
|
8
|
+
CATEGORY_REPLACE_TEXT = "c6y"
|
|
9
|
+
NAME_REPLACE_TEXT = "demo"
|
|
10
|
+
|
|
11
|
+
def initialize(category, name)
|
|
12
|
+
@category = category
|
|
13
|
+
unless Siba::Plugins.valid_category? category
|
|
14
|
+
raise Siba::Error, "Invalid category '#{category}'. Available categories are: #{Siba::Plugins.categories_str}"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
@name = Siba::StringHelper.str_to_alphnumeric name
|
|
18
|
+
raise Siba::Error, "first character of gem name can not be number" if name =~ /^[0-9]/
|
|
19
|
+
|
|
20
|
+
@name_camelized = StringHelper.camelize name
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def scaffold(dest_dir)
|
|
24
|
+
run_scaffold dest_dir
|
|
25
|
+
ensure
|
|
26
|
+
Siba.cleanup
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
def run_scaffold(dest_dir)
|
|
32
|
+
siba_file.run_this "scaffold" do
|
|
33
|
+
LoggerPlug.create "Scaffolding", nil, false
|
|
34
|
+
logger.debug "Scaffolding started"
|
|
35
|
+
dest_dir = File.join dest_dir, name
|
|
36
|
+
if siba_file.file_directory?(dest_dir) || siba_file.file_file?(dest_dir)
|
|
37
|
+
raise Siba::Error, "Directory already exists #{dest_dir}."
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
logger.debug "Checking if GIT is installed"
|
|
41
|
+
raise Siba::Error, "Please install GIT first" unless siba_file.shell_ok? "git help"
|
|
42
|
+
scaffolds_dir = siba_file.file_expand_path "../../../scaffolds", __FILE__
|
|
43
|
+
|
|
44
|
+
logger.debug "Creating a tmp dir"
|
|
45
|
+
dest_tmp_dir = Siba::TestFiles.mkdir_in_tmp_dir "scaffold"
|
|
46
|
+
|
|
47
|
+
logger.debug "Copying project files"
|
|
48
|
+
project_dir = File.join scaffolds_dir, "project"
|
|
49
|
+
unless siba_file.file_directory? project_dir
|
|
50
|
+
raise Siba::Error, "Scaffold project dir does not exist '#{project_dir}'"
|
|
51
|
+
end
|
|
52
|
+
siba_file.file_utils_cp_r File.join(project_dir,"."), dest_tmp_dir
|
|
53
|
+
|
|
54
|
+
logger.debug "Copying init file"
|
|
55
|
+
init_file = File.join scaffolds_dir, "#{category}.rb"
|
|
56
|
+
unless siba_file.file_file? init_file
|
|
57
|
+
raise Siba::Error, "Scaffold init file does not exist '#{init_file}'"
|
|
58
|
+
end
|
|
59
|
+
init_dir = File.join dest_tmp_dir, "lib", "siba-#{CATEGORY_REPLACE_TEXT}-demo"
|
|
60
|
+
unless siba_file.file_directory? init_dir
|
|
61
|
+
raise Siba::Error, "Source dir does not exist '#{init_dir}'"
|
|
62
|
+
end
|
|
63
|
+
init_file_dest = File.join init_dir,"init.rb"
|
|
64
|
+
siba_file.file_utils_cp init_file, init_file_dest
|
|
65
|
+
unless siba_file.file_file? init_file_dest
|
|
66
|
+
raise Siba::Error, "Filed to create init file '#{init_file_dest}'"
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
logger.debug "Writing examples to init.rb"
|
|
70
|
+
replace_init_examples scaffolds_dir, init_file_dest
|
|
71
|
+
|
|
72
|
+
logger.debug "Setting siba gem dependency"
|
|
73
|
+
replace_siba_version dest_tmp_dir
|
|
74
|
+
|
|
75
|
+
logger.debug "Setting gem category and name in file names and contents"
|
|
76
|
+
replace_category_and_name dest_tmp_dir
|
|
77
|
+
|
|
78
|
+
gitify dest_tmp_dir
|
|
79
|
+
|
|
80
|
+
logger.debug "Copying the project to destination"
|
|
81
|
+
siba_file.file_utils_mkpath dest_dir
|
|
82
|
+
siba_file.file_utils_cp_r File.join(dest_tmp_dir,"."), dest_dir
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
logger.info "Project created in #{dest_dir}"
|
|
86
|
+
logger.info "There is a README file with instructions there"
|
|
87
|
+
logger.show_finish_message = false
|
|
88
|
+
end
|
|
89
|
+
rescue Exception => e
|
|
90
|
+
logger.fatal e
|
|
91
|
+
logger.log_exception e, true
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def replace_category_and_name(dir)
|
|
95
|
+
Siba::FileHelper.entries(dir).each do |entry|
|
|
96
|
+
entry_path = replace_path dir, entry
|
|
97
|
+
if siba_file.file_directory? entry_path
|
|
98
|
+
replace_category_and_name entry_path
|
|
99
|
+
else
|
|
100
|
+
replace_file_contents entry_path
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def replace_path(dir, entry)
|
|
106
|
+
entry_path = File.join dir, entry
|
|
107
|
+
entry_after = entry.gsub CATEGORY_REPLACE_TEXT, category
|
|
108
|
+
entry_after = entry_after.gsub NAME_REPLACE_TEXT, name
|
|
109
|
+
if entry_after != entry
|
|
110
|
+
entry_path_after = File.join(dir, entry_after)
|
|
111
|
+
siba_file.file_utils_mv entry_path, entry_path_after
|
|
112
|
+
entry_path = entry_path_after
|
|
113
|
+
end
|
|
114
|
+
entry_path
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def replace_file_contents(path_to_file)
|
|
118
|
+
return unless siba_file.file_file? path_to_file
|
|
119
|
+
Siba::FileHelper.change_file(path_to_file) do |file_text|
|
|
120
|
+
file_text.gsub! CATEGORY_REPLACE_TEXT, category
|
|
121
|
+
file_text.gsub! CATEGORY_REPLACE_TEXT.capitalize, category.capitalize
|
|
122
|
+
file_text.gsub! NAME_REPLACE_TEXT, name
|
|
123
|
+
file_text.gsub! NAME_REPLACE_TEXT.capitalize, name_camelized
|
|
124
|
+
file_text
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def gitify(path_to_project)
|
|
129
|
+
logger.debug "Initializing GIT repository"
|
|
130
|
+
siba_file.file_utils_cd path_to_project
|
|
131
|
+
siba_file.run_shell "git init", "Failed to init git repository"
|
|
132
|
+
siba_file.run_shell "git add ."
|
|
133
|
+
siba_file.run_shell "git commit -a -m 'Initial commit'"
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def replace_siba_version(project_dir)
|
|
137
|
+
path_to_gemspec = File.join project_dir, "siba-c6y-demo.gemspec"
|
|
138
|
+
raise Siba::Error, "Can not find gemspec file #{path_to_gemspec}" unless siba_file.file_file? path_to_gemspec
|
|
139
|
+
Siba::FileHelper.change_file(path_to_gemspec) do |file_text|
|
|
140
|
+
version = Siba::VERSION.split('.')[0..-2].join('.')
|
|
141
|
+
file_text.gsub "siba_version", version
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def replace_init_examples(scaffolds_dir, init_file_dest)
|
|
146
|
+
replace_init_example scaffolds_dir, init_file_dest, "init_example.rb"
|
|
147
|
+
replace_init_example scaffolds_dir, init_file_dest, "examples.rb"
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def replace_init_example(scaffolds_dir, init_file_dest, example_file_name)
|
|
151
|
+
shared_dir = siba_file.file_expand_path File.join(scaffolds_dir, "shared")
|
|
152
|
+
init_example_file = File.join shared_dir, example_file_name
|
|
153
|
+
unless siba_file.file_file? init_example_file
|
|
154
|
+
raise Siba::Error, "Can not find init example file: '#{init_example_file}'"
|
|
155
|
+
end
|
|
156
|
+
init_example = Siba::FileHelper.read init_example_file
|
|
157
|
+
Siba::FileHelper.change_file(init_file_dest) do |f|
|
|
158
|
+
replace_text = "## #{example_file_name} ##"
|
|
159
|
+
unless f.include? replace_text
|
|
160
|
+
raise Siba::Error, "Can not replacement text: #{replace_text}"
|
|
161
|
+
end
|
|
162
|
+
f.gsub! replace_text, init_example
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
end
|