siba 0.4.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
data/lib/siba/globals.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module Siba
|
4
|
+
|
5
|
+
class << self
|
6
|
+
include Siba::TmpDirPlug
|
7
|
+
include Siba::FilePlug
|
8
|
+
|
9
|
+
attr_accessor :settings, :backup_name, :current_dir
|
10
|
+
Siba.settings = {}
|
11
|
+
Siba.current_dir = Siba::FilePlug.siba_file.file_utils_pwd
|
12
|
+
|
13
|
+
def cleanup
|
14
|
+
Siba.cleanup_tmp_dir
|
15
|
+
ensure
|
16
|
+
LoggerPlug.close
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module Siba
|
4
|
+
class EncodingHelper
|
5
|
+
EXTERNAL_ENCODING = Encoding.find "external"
|
6
|
+
INTERNAL_ENCODING = Encoding::UTF_8
|
7
|
+
|
8
|
+
class << self
|
9
|
+
def encode_to_external(value)
|
10
|
+
encode value, EXTERNAL_ENCODING, INTERNAL_ENCODING
|
11
|
+
end
|
12
|
+
|
13
|
+
protected
|
14
|
+
|
15
|
+
def encode(value, dst_encoding, src_encoding=nil)
|
16
|
+
return encode_str value, dst_encoding, src_encoding if value.instance_of? String
|
17
|
+
return encode_array value, dst_encoding, src_encoding if value.instance_of? Array
|
18
|
+
value
|
19
|
+
end
|
20
|
+
|
21
|
+
def encode_str(str, dst_encoding, src_encoding=nil)
|
22
|
+
return nil if str.nil?
|
23
|
+
return str unless str.instance_of? String
|
24
|
+
if str.encoding != dst_encoding
|
25
|
+
str = str.encode(dst_encoding, src_encoding, {:invalid => :replace, :undef => :replace})
|
26
|
+
end
|
27
|
+
str
|
28
|
+
end
|
29
|
+
|
30
|
+
def encode_array(array, dst_encoding, src_encoding=nil)
|
31
|
+
return nil if array.nil?
|
32
|
+
return array unless array.instance_of? Array
|
33
|
+
array.map {|a| encode_str a, dst_encoding, src_encoding}
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
@@ -0,0 +1,89 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module Siba
|
4
|
+
class FileHelper
|
5
|
+
class << self
|
6
|
+
include Siba::FilePlug
|
7
|
+
|
8
|
+
def dir_empty?(dir)
|
9
|
+
entries(dir).empty?
|
10
|
+
end
|
11
|
+
|
12
|
+
def dirs_count(dir)
|
13
|
+
entries(dir).count do |a|
|
14
|
+
siba_file.file_directory? File.join(dir, a)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# Reads a file in UTF-8 encoding
|
19
|
+
def read(file)
|
20
|
+
str = File.read file, { open_args: ["r:bom|utf-8"]}
|
21
|
+
unless str.valid_encoding?
|
22
|
+
raise Siba::Error, "Incorrect file encoding. Please save the options with UTF-8 encoding."
|
23
|
+
end
|
24
|
+
str
|
25
|
+
end
|
26
|
+
|
27
|
+
# Write to file in UTF-8 encoding
|
28
|
+
def write(file, data)
|
29
|
+
siba_file.file_utils_remove_entry_secure file if siba_file.file_file? file
|
30
|
+
siba_file.file_open(file, "w:utf-8") do |file|
|
31
|
+
file << data
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Used to replace text in file
|
36
|
+
# Example:
|
37
|
+
# change_file("/path") do |file_text|
|
38
|
+
# file_text.gsub "one", "two"
|
39
|
+
# end
|
40
|
+
def change_file(path_to_file, &block)
|
41
|
+
file_text = Siba::FileHelper.read path_to_file
|
42
|
+
file_text = block.call file_text
|
43
|
+
Siba::FileHelper.write path_to_file, file_text
|
44
|
+
end
|
45
|
+
|
46
|
+
# Retuns an array containing all dir entires except '.' and '..' dirs
|
47
|
+
def entries(dir)
|
48
|
+
siba_file.dir_entries(dir) - %w{ . .. }
|
49
|
+
end
|
50
|
+
|
51
|
+
# Raises error if dirs are not identical
|
52
|
+
def dirs_same?(dir1, dir2)
|
53
|
+
dir1_entries = siba_file.dir_entries dir1
|
54
|
+
dir2_entries = siba_file.dir_entries dir2
|
55
|
+
diff1 = (dir1_entries - dir2_entries).map{|i| File.join(dir1,i)}
|
56
|
+
diff2 = (dir2_entries - dir1_entries).map{|i| File.join(dir2,i)}
|
57
|
+
diff = diff1 + diff2
|
58
|
+
msg = "The directories '#{File.basename(dir1)}' and '#{File.basename(dir2)}' are different: "
|
59
|
+
raise Siba::Error, "#{msg}#{diff.take(10).join(', ')}" unless diff.empty?
|
60
|
+
|
61
|
+
# compare files and directories
|
62
|
+
dir1_entries.each do |dir|
|
63
|
+
next if dir == "." || dir == ".."
|
64
|
+
sub_dir1_entry = File.join dir1, dir
|
65
|
+
sub_dir2_entry = File.join dir2, dir
|
66
|
+
|
67
|
+
# compare files
|
68
|
+
if siba_file.file_file? sub_dir1_entry
|
69
|
+
raise "#{msg}'#{sub_dir2_entry}' is not a file" unless siba_file.file_file? sub_dir2_entry
|
70
|
+
unless siba_file.file_utils_compare_file sub_dir1_entry, sub_dir2_entry
|
71
|
+
raise Siba::Error, "#{msg}'#{sub_dir1_entry}' and '#{sub_dir2_entry}' files are different."
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# compare permissions
|
76
|
+
if (siba_file.file_stat(sub_dir1_entry).mode % 01000) != (siba_file.file_stat(sub_dir2_entry).mode % 01000)
|
77
|
+
raise Siba::Error, "#{msg}'#{sub_dir1_entry}' and '#{sub_dir2_entry}' entries have different permissions."
|
78
|
+
end
|
79
|
+
|
80
|
+
# compare sub-dirs
|
81
|
+
if siba_file.file_directory? sub_dir1_entry
|
82
|
+
raise Siba::Error, "#{msg}'#{sub_dir2_entry}' is not a directory" unless siba_file.file_directory? sub_dir2_entry
|
83
|
+
dirs_same? sub_dir1_entry, sub_dir2_entry
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module Siba
|
4
|
+
class GemHelper
|
5
|
+
class << self
|
6
|
+
def all_local_gems
|
7
|
+
@local_gems ||= begin
|
8
|
+
Gem::Specification.all = nil
|
9
|
+
all = Gem::Specification.to_a
|
10
|
+
Gem::Specification.reset
|
11
|
+
all
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def gem_path(name)
|
16
|
+
gem_spec = all_local_gems.find {|a| a.name==name}
|
17
|
+
raise Siba::Error, "Gem #{name} is not installed" if gem_spec.nil?
|
18
|
+
gem_spec.full_gem_path
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module Siba
|
4
|
+
# Password strength calculator based on:
|
5
|
+
# http://snippets.dzone.com/posts/show/4698
|
6
|
+
# https://www.grc.com/haystack.htm
|
7
|
+
class PasswordStrength
|
8
|
+
PASSWORD_SETS = {
|
9
|
+
/[a-z]/ => 26,
|
10
|
+
/[A-Z]/ => 26,
|
11
|
+
/[0-9]/ => 10,
|
12
|
+
/[^\w]/ => 33
|
13
|
+
}
|
14
|
+
|
15
|
+
AinB = {
|
16
|
+
second: 60,
|
17
|
+
minute: 60,
|
18
|
+
hour: 24,
|
19
|
+
day: 30,
|
20
|
+
month: 12,
|
21
|
+
year: 100,
|
22
|
+
century: 1
|
23
|
+
}
|
24
|
+
|
25
|
+
Illions = {
|
26
|
+
hundred: 100,
|
27
|
+
thousand: 10,
|
28
|
+
million: 1000,
|
29
|
+
billion: 1000,
|
30
|
+
trillion: 1000
|
31
|
+
}
|
32
|
+
|
33
|
+
TRIES_PER_SECOND = 100 * 10 ** 12 # 100 TFLOPS
|
34
|
+
AGE_OF_THE_UNIVERSE_SECONDS = 4.336 * 10 ** 17 # the best estimate in 2011
|
35
|
+
|
36
|
+
class << self
|
37
|
+
def seconds_to_crack(password)
|
38
|
+
set_size = 0
|
39
|
+
PASSWORD_SETS.each_pair {|k,v| set_size += v if password =~ k}
|
40
|
+
combinations = 0
|
41
|
+
1.upto(password.length) {|i| combinations += set_size ** i }
|
42
|
+
combinations.to_f / TRIES_PER_SECOND
|
43
|
+
end
|
44
|
+
|
45
|
+
# Password is considered weak if it takes less than a year to crack it
|
46
|
+
def is_weak?(seconds_to_crack)
|
47
|
+
seconds_to_crack < 60 * 60 * 24 * 365
|
48
|
+
end
|
49
|
+
|
50
|
+
# Convert the number of seconds human-friendly timespan string
|
51
|
+
# Example:
|
52
|
+
# 130: 2 minutes
|
53
|
+
# 12345: 3 hours
|
54
|
+
def seconds_to_timespan(seconds)
|
55
|
+
return "forever" if seconds > AGE_OF_THE_UNIVERSE_SECONDS
|
56
|
+
ticks = seconds
|
57
|
+
AinB.each_pair do |a,b|
|
58
|
+
ticks_next = ticks.to_f / b
|
59
|
+
return get_timespan_str ticks, a if ticks_next < 1
|
60
|
+
ticks = ticks_next
|
61
|
+
end
|
62
|
+
|
63
|
+
# century or longer
|
64
|
+
ticks = ticks.floor
|
65
|
+
return get_timespan_str ticks, "century", "centuries" if ticks < 100
|
66
|
+
illion_unit, ticks = get_illions ticks
|
67
|
+
"#{ticks} #{illion_unit} centuries".strip
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
def get_timespan_str(ticks, unit, unit_plural=nil)
|
73
|
+
ticks = ticks.floor
|
74
|
+
return case
|
75
|
+
when ticks < 1 then "less than a #{unit}"
|
76
|
+
when ticks == 1 then "1 #{unit}"
|
77
|
+
else "#{ticks} #{unit_plural || unit.to_s+"s"}"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def get_illions(ticks)
|
82
|
+
illion_unit = ""
|
83
|
+
Illions.each_pair do |a,b|
|
84
|
+
ticks_next = ticks.to_f / b
|
85
|
+
break if ticks_next < 1
|
86
|
+
illion_unit = a
|
87
|
+
ticks = ticks_next
|
88
|
+
end
|
89
|
+
|
90
|
+
return illion_unit, ticks.floor
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require 'securerandom'
|
4
|
+
|
5
|
+
module Siba
|
6
|
+
class SecurityHelper
|
7
|
+
class << self
|
8
|
+
def generate_password_for_yaml(length = 16)
|
9
|
+
characters = (32..126).to_a - "\\\"".bytes.to_a
|
10
|
+
|
11
|
+
(0...length).map{
|
12
|
+
characters[SecureRandom.random_number(characters.size)].chr
|
13
|
+
}.join
|
14
|
+
end
|
15
|
+
|
16
|
+
def alphanumeric_password(length = 16, lowercase_only=false, non_ambiguous = false)
|
17
|
+
characters = ('a'..'z').to_a + ('0'..'9').to_a
|
18
|
+
characters += ('A'..'Z').to_a unless lowercase_only
|
19
|
+
|
20
|
+
%w{I O l 0 1}.each{ |ambiguous_character|
|
21
|
+
characters.delete ambiguous_character
|
22
|
+
} if non_ambiguous
|
23
|
+
|
24
|
+
(0...length).map{
|
25
|
+
characters[SecureRandom.random_number(characters.size)]
|
26
|
+
}.join
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module Siba
|
4
|
+
class StringHelper
|
5
|
+
class << self
|
6
|
+
# Helps to use a string in URLs and file names by
|
7
|
+
# replacing all non-alphanumeric characters with '-'
|
8
|
+
# and converting to lowercase
|
9
|
+
def str_to_alphnumeric(str)
|
10
|
+
str.downcase.gsub(/[^ a-z0-9]/,' ').strip.gsub(/ {1,}/,'-')
|
11
|
+
end
|
12
|
+
|
13
|
+
def nil_or_empty(str)
|
14
|
+
str.nil? || str.strip.empty?
|
15
|
+
end
|
16
|
+
|
17
|
+
# Convers a string to CamelCase. Based on Rails ActiveSupport::Inflector.camelize.
|
18
|
+
def camelize(str)
|
19
|
+
str = str.capitalize
|
20
|
+
str.gsub(/(?:_|-)([a-z\d]*)/i) { "#{$1.capitalize}" }
|
21
|
+
end
|
22
|
+
|
23
|
+
def escape_for_yaml(str)
|
24
|
+
str.gsub("\\","\\\\\\").gsub("\"","\\\"")
|
25
|
+
end
|
26
|
+
|
27
|
+
def format_time(time)
|
28
|
+
time.strftime("%B %e, %Y")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
class MiniTest::Unit::TestCase
|
4
|
+
include Siba::FilePlug
|
5
|
+
def must_log(level)
|
6
|
+
verify_log true, level, true
|
7
|
+
end
|
8
|
+
|
9
|
+
def wont_log(level)
|
10
|
+
verify_log false, level, true
|
11
|
+
end
|
12
|
+
|
13
|
+
def must_log_from(level)
|
14
|
+
verify_log true, level, false
|
15
|
+
end
|
16
|
+
|
17
|
+
def wont_log_from(level)
|
18
|
+
verify_log false, level, false
|
19
|
+
end
|
20
|
+
|
21
|
+
def show_log
|
22
|
+
puts Siba::SibaLogger.messages.map{|a| a.msg}.join("\n")
|
23
|
+
end
|
24
|
+
|
25
|
+
def mock_file(name, retval, args=[])
|
26
|
+
mock = new_mock_file
|
27
|
+
mock.expect name, retval, args
|
28
|
+
mock
|
29
|
+
end
|
30
|
+
|
31
|
+
def new_mock_file
|
32
|
+
Siba::FilePlug.siba_file = MiniTest::Mock.new
|
33
|
+
end
|
34
|
+
|
35
|
+
def create_plugin(yml_file_name_or_options_hash)
|
36
|
+
if yml_file_name_or_options_hash.is_a? String
|
37
|
+
load_options yml_file_name_or_options_hash
|
38
|
+
else
|
39
|
+
@options = yml_file_name_or_options_hash
|
40
|
+
end
|
41
|
+
|
42
|
+
unless @plugin_category
|
43
|
+
raise Siba::Error, "Initialize '@plugin_category' variable (#{Siba::Plugins.categories_str})"
|
44
|
+
end
|
45
|
+
|
46
|
+
unless @plugin_type
|
47
|
+
raise Siba::Error, "Initialize '@plugin_type' variable with your gem name ('cloud', 'ftp' etc)."
|
48
|
+
end
|
49
|
+
|
50
|
+
Siba::PluginLoader.loader.load(@plugin_category, @plugin_type, @options)
|
51
|
+
end
|
52
|
+
|
53
|
+
def load_options(yml_name)
|
54
|
+
unless @yml_path
|
55
|
+
raise Siba::Error, "Initialize '@yml_path' variable with the dir to test YAML files."
|
56
|
+
end
|
57
|
+
yml_name = yml_name + ".yml" unless yml_name =~ /\.yml$/
|
58
|
+
@options = SibaTest.load_options File.join(@yml_path, yml_name)
|
59
|
+
end
|
60
|
+
|
61
|
+
def prepare_test_dir(dir_name_part, tmp_dir = nil)
|
62
|
+
tmp_dir ||= SibaTest.tmp_dir
|
63
|
+
Siba::TestFiles::prepare_test_dir dir_name_part, tmp_dir
|
64
|
+
end
|
65
|
+
|
66
|
+
def prepare_test_file(file_name_part, tmp_dir = nil)
|
67
|
+
tmp_dir ||= SibaTest.tmp_dir
|
68
|
+
Siba::TestFiles::prepare_test_file file_name_part, tmp_dir
|
69
|
+
end
|
70
|
+
|
71
|
+
def generate_path(file_name_part, tmp_dir = nil)
|
72
|
+
tmp_dir ||= SibaTest.tmp_dir
|
73
|
+
Siba::TestFiles::generate_path file_name_part, tmp_dir
|
74
|
+
end
|
75
|
+
|
76
|
+
def mkdir_in_tmp_dir(prefix, tmp_dir = nil)
|
77
|
+
tmp_dir ||= SibaTest.tmp_dir
|
78
|
+
Siba::TestFiles::mkdir_in_tmp_dir prefix, tmp_dir
|
79
|
+
end
|
80
|
+
|
81
|
+
def dirs_same?(a,b)
|
82
|
+
Siba::FileHelper::dirs_same? a, b
|
83
|
+
end
|
84
|
+
|
85
|
+
def prepare_options(src_yml_path, replace_data)
|
86
|
+
Siba::TestFiles::prepare_options(src_yml_path, replace_data)
|
87
|
+
end
|
88
|
+
|
89
|
+
def prepare_yml(src_yml_path, replace_data, tmp_dir=nil)
|
90
|
+
tmp_dir ||= SibaTest.tmp_dir
|
91
|
+
Siba::TestFiles::prepare_yml src_yml_path, replace_data, tmp_dir
|
92
|
+
end
|
93
|
+
|
94
|
+
private
|
95
|
+
|
96
|
+
def verify_log(must_change, log_level, exact_level = true)
|
97
|
+
log_count = Siba::SibaLogger.count log_level, exact_level
|
98
|
+
|
99
|
+
if exact_level
|
100
|
+
message = "'#{log_level}' log messages"
|
101
|
+
else
|
102
|
+
message = "log messages"
|
103
|
+
end
|
104
|
+
|
105
|
+
if must_change
|
106
|
+
message = "Expected " + message
|
107
|
+
raise message if log_count == 0
|
108
|
+
else
|
109
|
+
message = "Unexpected " + message
|
110
|
+
raise message if log_count > 0
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|