admin-utils 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 359f5d2fa758b9fa2b453f6dbc1753696448abfa
4
+ data.tar.gz: 785e9751425618469417d4b82f3f7df0c2fdb15f
5
+ SHA512:
6
+ metadata.gz: 0f3ab116acf980ef44ee00239dd3f1f986a73aabc16aa41faac44351dc531af9b24c2bd0db85df60566d69b9ffd81650e0844047ab6755146931f3f3f5303fe2
7
+ data.tar.gz: 83d9b09e41f4fab949780585a6c3d501af9710116a6893b1407386bf214e6e95be7844a007c893633fc53a00dd85c2473e828a97faa116125aea065bfb90b50b
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'http://rubygems.org'
2
+ #source 'http://gems.github.com/'
3
+ gemspec
4
+ #gem 'devver-construct', source: 'https://gems.github.com'
@@ -0,0 +1,40 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ admin-utils (1.2.0)
5
+ log4r
6
+ rake
7
+
8
+ GEM
9
+ remote: http://rubygems.org/
10
+ specs:
11
+ devver-construct (1.1.0)
12
+ diff-lcs (1.3)
13
+ fake_ftp (0.3.0)
14
+ log4r (1.1.10)
15
+ rake (12.3.1)
16
+ rspec (3.7.0)
17
+ rspec-core (~> 3.7.0)
18
+ rspec-expectations (~> 3.7.0)
19
+ rspec-mocks (~> 3.7.0)
20
+ rspec-core (3.7.1)
21
+ rspec-support (~> 3.7.0)
22
+ rspec-expectations (3.7.0)
23
+ diff-lcs (>= 1.2.0, < 2.0)
24
+ rspec-support (~> 3.7.0)
25
+ rspec-mocks (3.7.0)
26
+ diff-lcs (>= 1.2.0, < 2.0)
27
+ rspec-support (~> 3.7.0)
28
+ rspec-support (3.7.1)
29
+
30
+ PLATFORMS
31
+ ruby
32
+
33
+ DEPENDENCIES
34
+ admin-utils!
35
+ devver-construct
36
+ fake_ftp
37
+ rspec
38
+
39
+ BUNDLED WITH
40
+ 1.16.1
@@ -0,0 +1,12 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new do |t|
5
+ t.pattern = 'spec/**/*.rb'
6
+ t.rcov = false
7
+ t.verbose = true
8
+ end
9
+
10
+ desc "Run tests"
11
+ task :default => :spec
12
+ task :default => :build
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path('../lib', __FILE__)
3
+ require 'admin-utils/version'
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'admin-utils'
7
+ s.version = Au::Admin::Utils::VERSION
8
+ s.authors = 'Stefan Wendler'
9
+ s.email = 'stefan@binarysun.de'
10
+ s.homepage = 'https://github.com/mrmarbury/admin_utils'
11
+ s.licenses = 'Apache-2.0'
12
+ s.summary = 'The Admin Utils'
13
+ s.description = 'Some basic utilities that I need often when writing Ruby Code'
14
+ s.files = Dir.glob('{lib,spec}/**/*') + %w[Rakefile Gemfile Gemfile.lock admin-utils.gemspec]
15
+ s.test_files = Dir.glob('spec/**/*')
16
+ s.executables = Dir.glob('*.rb')
17
+ s.require_paths = %w[lib]
18
+ s.required_ruby_version = '~> 2.4'
19
+ s.add_dependency('log4r')
20
+ s.add_dependency('rake')
21
+ s.add_development_dependency('rspec')
22
+ s.add_development_dependency('devver-construct')
23
+ s.add_development_dependency('fake_ftp')
24
+ end
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+
3
+ require 'admin-utils/version'
4
+ require 'admin-utils/au_config'
5
+ require 'admin-utils/au_logger'
6
+ require 'admin-utils/au_ftp'
7
+ require 'admin-utils/au_util'
8
+ require 'admin-utils/au_defaults'
9
+ require 'admin-utils/string'
10
+
@@ -0,0 +1,43 @@
1
+ require 'yaml' unless defined? YAML
2
+ require 'admin-utils/au_defaults' unless defined? AuDefaults
3
+ require 'admin-utils/au_util' unless defined? AuUtil
4
+
5
+ module AuConfig
6
+
7
+ # Method that loads a yml file and return an object of type +OpenStruct+
8
+ #
9
+ # Params:
10
+ # * +config_file+ Name of the config file to load
11
+ # * +override_path+ Path to the directory that contains the yml file. If left blank, the default is taken which is configured in
12
+ # +AuDefaults+'s +CONFIG_PATH+ array. Can be either an array of path names or a single path as a string
13
+ #
14
+ # If +override_path+ is an array (e.g. when using the default), the first occurrence of the config file ist loaded.
15
+ def load_config(config_file, override_path = nil)
16
+ raise ArgumentError 'Plain config file name needed as string!' unless config_file
17
+ @config_path = AuDefaults.config_path override_path
18
+ begin
19
+ @configuration = get_config_file_for_path(@config_path, config_file)
20
+ logger.debug 'Using Config File: ' + @configuration.path
21
+ @yml_data = YAML.load @configuration
22
+ AuUtil.hash_to_ostruct @yml_data.merge(_config_file: @configuration.path)
23
+ rescue => error
24
+ logger.error "Error opening file #{@configuration}. The Message was: #{error.message}\n#{error.backtrace.join("\n")}"
25
+ raise
26
+ end
27
+ end
28
+
29
+ ########
30
+ private
31
+ ########
32
+
33
+ def get_config_file_for_path(cfg_path, config_file)
34
+ if cfg_path.respond_to? "each"
35
+ cfg_path.each do |path|
36
+ return File.new(File.join(path, config_file)) if File.exists? path + "/" + config_file
37
+ end
38
+ raise IOError, "File #{config_file} not found in path: #{cfg_path}"
39
+ else
40
+ File.new(File.join(cfg_path, config_file))
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,30 @@
1
+ module AuDefaults
2
+
3
+ LOGGER_BASE = '/var/log'
4
+
5
+ DEFAULT_INIT_SCRIPT_PATH = '/etc/init.d'
6
+
7
+ # Retrieves the default config path that holds the yml files for the current application.
8
+ # The +path+ variable can be used to override the default config path. The method can then be called
9
+ # without argument to retrieve the currently set config path.
10
+ #
11
+ # NOTE: As a default this method returns an array.
12
+ #
13
+ def config_path(path = nil)
14
+ AuDefaults.config_path(path)
15
+ end
16
+
17
+ class << self
18
+
19
+ CONFIG_PATH = [ ENV['HOME'] + '/.config', '/etc', '/usr/local/etc', '../config' ]
20
+
21
+ def config_path(path = nil)
22
+ @path_for_the_config = path || (@path_for_the_config || CONFIG_PATH)
23
+ end
24
+
25
+ # Call this to reset the config path to the default values of the +CONFIG_PATH+ array
26
+ def reset_config_path
27
+ @path_for_the_config = nil
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,104 @@
1
+ require 'net/ftp' unless defined? Net::FTP
2
+ require 'open3' unless defined? Open3
3
+ require 'admin-utils/au_logger' unless defined? AuLogger
4
+
5
+ include AuLogger
6
+
7
+ module AuFtp
8
+
9
+ # Transfers files to a remote ftp host
10
+ #
11
+ # Params:
12
+ # * +ftp+ Valid object of type +Net::FTP+. The connection must be open
13
+ # * +directory+ The remote directory the files are put to.
14
+ # * +transfered_file+ A single file or an array of files that should be transfered
15
+ #
16
+ # Raises:
17
+ # * +Net::FTPPermError+ if there is a FTP permission problem of any kind
18
+ # * +Net::FTPError+ if anything goes wrong during FTP transfer
19
+ # * +TypeError+ if any of the input variables have the wrong type (including being nil)
20
+ #
21
+ def transfer_via_ftp(ftp, directory, transfered_files)
22
+ raise "\"ftp\" must be an object of type Net::FTP and the conenction must be open" unless ftp.is_a? Net::FTP
23
+ begin
24
+ entry_dir = ftp.pwd
25
+ ftp.chdir directory
26
+ if transfered_files.empty?
27
+ logger.warn "No file(s) for ftp transfer to directory \"#{directory}\" given. Doing nothing ... "
28
+ elsif transfered_files.respond_to?("each")
29
+ transfered_files.each do |file|
30
+ logger.info "Putting file \"#{file}\" to ftp server"
31
+ ftp.putbinaryfile file
32
+ end
33
+ else
34
+ logger.info "Putting single file \"#{transfered_files}\" to ftp server"
35
+ ftp.putbinaryfile transfered_files
36
+ end
37
+ ftp.chdir entry_dir
38
+ rescue Net::FTPPermError => ftpPerm
39
+ logger.error "Permission problems encountered during ftp transfer. Message was: " +
40
+ ftpPerm.message + "\n" + ftpPerm.backtrace.join("\n")
41
+ close_ftp_connection ftp
42
+ raise
43
+ rescue TypeError => typeError
44
+ logger.error "A type error occured. Make sure all variables contain the correct value types and are not nil! Message was: " +
45
+ typeError.message + "\n" + typeError.backtrace.join("\n")
46
+ close_ftp_connection ftp
47
+ raise
48
+ rescue Net::FTPError => ftpError
49
+ logger.error "Error during ftp transfer. Message was:" +
50
+ ftpError.message + "\n" + ftpError.backtrace.join("\n")
51
+ close_ftp_connection ftp
52
+ raise
53
+ else
54
+ logger.info "ftp transfer finished successfully"
55
+ end
56
+ end
57
+
58
+ # Opens an FTP connection
59
+ # Basically it is a convenience method that wraps the +Net::FTP+ methods
60
+ # +connect+ and +login+. So the input variables match those needed by those two
61
+ # methods.
62
+ #
63
+ # NOTE: +port+, +user+, +passwd+, +acct+ can be nil. +port+ will be set to 21 by default.
64
+ #
65
+ def open_ftp_connection(host, port=21, user=nil, passwd=nil, acct=nil)
66
+ begin
67
+ logger.info "Opening ftp connection"
68
+
69
+ ftp = Net::FTP.new
70
+ ftp.connect(host, port)
71
+ ftp.login(user,passwd,acct)
72
+ rescue Net::FTPPermError => ftp_perm
73
+ logger.error "Permission problems encountered during ftp connect. Message was: " +
74
+ ftp_perm.message + "\n" + ftp_perm.backtrace.join("\n")
75
+ close_ftp_connection ftp
76
+ raise
77
+ rescue Net::FTPError => ftp_error
78
+ logger.error "Error during ftp operation. Message was:" +
79
+ ftp_error.message + "\n" + ftp_error.backtrace.join("\n")
80
+ close_ftp_connection ftp
81
+ raise
82
+ rescue SocketError => socket_error
83
+ logger.error "There was an error while accessing a socket. The Message was: " +
84
+ socket_error.message + "\n" + socket_error.backtrace.join("\n")
85
+ raise
86
+ end
87
+ ftp
88
+ end
89
+
90
+ # Closes the ftp conncetion given as parameter +ftp+ which must be a valid object of type +Net::FTP+
91
+ #
92
+ # NOTE: Does nothing, when +ftp+ is nil. Just logs a warning message in case a +Net::FTPConnectionError+ is catched.
93
+ #
94
+ def close_ftp_connection(ftp)
95
+ raise "\"ftp\" must be an object of type Net::FTP" unless ftp.is_a? Net::FTP
96
+ begin
97
+ ftp.close unless ftp.nil?
98
+ rescue Net::FTPConnectionError => conError
99
+ logger.warn "There was an error when trying to close the ftp connection. The message was: #{conError.message}"
100
+ else
101
+ logger.info "Ftp connection closed"
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,90 @@
1
+ require 'log4r' unless defined? Log4r
2
+
3
+ module AuLogger
4
+
5
+ # Retrieves the current logger instance or initializes a new one.
6
+ #
7
+ # For parameters to use during initialization, see +AuLogger.initialize_logger+
8
+ #
9
+ # Default Usage Example:
10
+ #
11
+ # logger.info "my info text"
12
+ #
13
+ #
14
+ def logger(hash={})
15
+ AuLogger.logger(hash)
16
+ end
17
+
18
+ class << self
19
+
20
+ PATTERN="%d -= %l =- : %m"
21
+ UNINITIALIZED_NAME='UNINITIALIZED'
22
+
23
+ def logger(hash={})
24
+ @logger ||= initialize_logger(hash)
25
+ end
26
+
27
+ # Used to initialize the logging system.
28
+ #
29
+ # Params:
30
+ # * +hash+ The hash containing all config varables
31
+ #
32
+ # The possible +hash+ variables are as follows:
33
+ # * :mode => The logging mode to use. See below. If unset, command line only logging will be used
34
+ # * :filename => Path to the logfile that should be written
35
+ # * :name => The name the logger will have (See +Log4r+ documentation on this!). Default is 'UNINITIALIZED_NAME'
36
+ # * :level => The log level according to +Log4r::<LEVEL>+ (See +Log4r+ documentation on this!). Set to INFO by default
37
+ # * :additive => Is the logger additive (See +Log4r+ documentation on this!)
38
+ # * :trace => Record trace information (See +Log4r+ documentation on this!)
39
+ #
40
+ # Example:
41
+ #
42
+ # AuLogger.initialize_logger(
43
+ # name: 'my_logger',
44
+ # filename: '/var/log/my_logger.log'
45
+ # )
46
+ #
47
+ # Current Modes:
48
+ # * +cronjob+ Log everything to a log file but messages with level WARN and above to stdout as well so they will be included in the crond status email
49
+ # * +daemon+ Log to a log file only
50
+ # * +dual+ Log everything to log file and to the console
51
+ #
52
+ def initialize_logger(hash={})
53
+ Log4r.define_levels(*Log4r::Log4rConfig::LogLevels)
54
+ @mode = (hash[:mode] or '')
55
+ @filename = (hash[:filename] or nil)
56
+ @ncurses_window = (hash[:ncurses_window] or nil)
57
+ @logger = Log4r::Logger.new(
58
+ (hash[:name] or UNINITIALIZED_NAME),
59
+ (hash[:level] or Log4r::INFO),
60
+ (hash[:additive]),
61
+ (hash[:trace])
62
+ )
63
+
64
+ log_pattern = Log4r::PatternFormatter.new(pattern: (hash[:pattern] or PATTERN))
65
+
66
+ if @mode == 'cronjob'
67
+ raise ArgumentError, 'Path to a log file must be added in cronjob mode!' unless @filename
68
+ @logger.outputters = Log4r::StdoutOutputter.new('cronjob stdout', level: Log4r::WARN, formatter: log_pattern)
69
+ @logger.add Log4r::FileOutputter.new('log', filename: @filename, formatter: log_pattern)
70
+ @logger.debug 'Logger initialized in cronjob mode'
71
+ elsif @mode == 'daemon'
72
+ raise ArgumentError, 'Path to a log file needed in daemon mode!' unless @filename
73
+ @logger.outputters = Log4r::FileOutputter.new('daemon log', filename: @filename, formatter: log_pattern)
74
+ @logger.debug 'Logger initialized in daemon mode'
75
+ elsif @mode == 'dual'
76
+ raise ArgumentError, 'Path to a log file needed in dual mode!' unless @filename
77
+ @logger.outputters = Log4r::StdoutOutputter.new('dual stdout', formatter: log_pattern)
78
+ @logger.add Log4r::FileOutputter.new('log', filename: @filename, formatter: log_pattern)
79
+ @logger.debug 'Logger initialized in dual mode. Log output will be logged to Console and Logfile'
80
+ else
81
+ @logger.outputters = Log4r::StdoutOutputter.new('stdout', formatter: log_pattern)
82
+ @logger.debug 'Logger initialized for stdout only mode'
83
+ end
84
+ if logger.name == UNINITIALIZED_NAME
85
+ logger.debug 'Logger uses the default name at the moment'
86
+ end
87
+ @logger
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,54 @@
1
+ require 'ostruct' unless defined? OpenStruct
2
+
3
+ module AuUtil
4
+
5
+ def self.hash_to_ostruct(object)
6
+ return case object
7
+ when Hash
8
+ object = object.clone
9
+ object.each do |key, value|
10
+ object[key] = hash_to_ostruct(value)
11
+ end
12
+ OpenStruct.new(object)
13
+ when Array
14
+ object = object.clone
15
+ object.map! { |i| hash_to_ostruct(i) }
16
+ else
17
+ object
18
+ end
19
+ end
20
+
21
+ # Basicaly this method can unzip any gzipped file
22
+ #
23
+ # Params:
24
+ # * +archive_name+ Filename (including path) of the dump file to extract
25
+ # * +extract_dir+ The directory the dump should be extracted to. If left +nil+, the dir name of the +dump_archive_name+ is used. Otherwise it is just set
26
+ # to "."
27
+ #
28
+ # Raises:
29
+ # * +File::IOError+ In case there was an error during extraction
30
+ #
31
+ def self.extract_gzip(archive_name, extract_dir = (File.dirname(archive_name) or '.'))
32
+ raise ArgumentError, "File #{archive_name} does not exist!" unless File.exists? archive_name
33
+ logger.info "Extracting \"#{archive_name}\" to directory \"#{extract_dir}\""
34
+ Open3.popen3 "gunzip -c #{archive_name} > " + extract_dir + "/" + File.basename(archive_name).chomp('.gz') do |stdin, stdout, stderr, t|
35
+ unless t.value.to_s.include? "exit 0"
36
+ raise File::IOError, "gzipped file #{archive_name} could not be extracted!\nThe error message was: #{stderr.read}"
37
+ end
38
+ end
39
+ end
40
+
41
+ # Executes Unix which and checks, if a binary is in path. Only works on Unix alike systems
42
+ #
43
+ # Params:
44
+ # * +name+ Command to check for
45
+ #
46
+ # Returns:
47
+ # * +true+ - Command in path
48
+ # * +false+ - Command not in path
49
+ #
50
+ def self.command?(name)
51
+ `which #{name}`
52
+ $?.success?
53
+ end
54
+ end
@@ -0,0 +1,25 @@
1
+ class String
2
+
3
+ # Custom String method to check if a string can be parsed to a number (Integer)
4
+ #
5
+ # This method is called directly on a String object
6
+ #
7
+ # Returns:
8
+ # * +true+ String can be parsed to an Integer
9
+ # * +false+ String can not be parsed to an Integer
10
+ #
11
+ # Example:
12
+ #
13
+ # require 'admin-utils/string'
14
+ # .
15
+ # .
16
+ # .
17
+ # puts "is a number" if "12345".is_number?
18
+ #
19
+ def is_number?
20
+ Integer(self)
21
+ true
22
+ rescue
23
+ false
24
+ end
25
+ end
@@ -0,0 +1,7 @@
1
+ module Au
2
+ module Admin
3
+ module Utils
4
+ VERSION = '1.2.0'
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,73 @@
1
+ require 'rspec'
2
+ require 'construct'
3
+ require 'construct/helpers'
4
+
5
+ require 'admin-utils/au_logger'
6
+ require 'admin-utils/au_config'
7
+ require 'admin-utils/au_defaults'
8
+ require 'admin-utils/au_util'
9
+
10
+ include Construct::Helpers
11
+ include AuLogger
12
+ include AuConfig
13
+
14
+ describe "Loading Config Files" do
15
+
16
+ it "should load a config file from a single path" do
17
+
18
+ config_dir = "config/dir"
19
+
20
+ within_construct do |const|
21
+ const.directory config_dir do |dir|
22
+ dir.file('config.yml', 'rabbit_hole: kinky_fudge')
23
+ end
24
+
25
+ config = load_config('config.yml', config_dir)
26
+ config.rabbit_hole.should == 'kinky_fudge'
27
+ end
28
+ end
29
+
30
+ it "should load a config file when an array of paths is given" do
31
+ config_dir_one = 'config/dir/one'
32
+ config_dir_two = 'config/dir/two'
33
+ conf_dirs = [config_dir_two, config_dir_one]
34
+
35
+ within_construct do |const|
36
+ const.directory config_dir_one do |dir|
37
+ dir.file('config.yml', 'fiasco_drive: ladyada')
38
+ end
39
+ const.directory config_dir_two
40
+
41
+ config = load_config('config.yml', conf_dirs)
42
+ config.fiasco_drive.should == 'ladyada'
43
+ end
44
+ end
45
+
46
+ it "should load a the first found config file when an array of paths is given" do
47
+ config_dir_one = 'config/dir/one'
48
+ config_dir_two = 'config/dir/two'
49
+ conf_dirs = [config_dir_two, config_dir_one]
50
+
51
+ within_construct do |const|
52
+ const.directory config_dir_one do |dir|
53
+ dir.file('config.yml', 'fiasco_drive: ladyada')
54
+ end
55
+ const.directory config_dir_two do |dir|
56
+ dir.file('config.yml', 'fiasco_drive: bagel_and_a_smeer')
57
+ end
58
+
59
+ config = load_config('config.yml', conf_dirs)
60
+ config.fiasco_drive.should == 'bagel_and_a_smeer'
61
+ end
62
+ end
63
+
64
+ it 'should raise an IOError, if it cannot find a config file' do
65
+ config_dir_one = 'config/dir/one'
66
+ config_dir_two = 'config/dir/two'
67
+ conf_dirs = [config_dir_two, config_dir_one]
68
+
69
+ within_construct do |const|
70
+ lambda { load_config('config.yml', conf_dirs) }.should raise_error(IOError)
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,40 @@
1
+ require 'rspec'
2
+ require 'admin-utils/au_defaults'
3
+
4
+ describe "Defaults" do
5
+
6
+ before(:each) do
7
+ AuDefaults.reset_config_path
8
+ end
9
+
10
+ it "should have a couple of default variables with the apropriate values" do
11
+ AuDefaults::LOGGER_BASE.should == '/var/log'
12
+ end
13
+
14
+ it "should return the default config path when called for the first time" do
15
+ AuDefaults.config_path.should == [ENV['HOME'] + '/.config', '/etc', '/usr/local/etc', '../config']
16
+ end
17
+
18
+ it "should return the the path, when given as argument" do
19
+ AuDefaults.config_path('test').should == 'test'
20
+ end
21
+
22
+ it "should always return the same path once initialized with it" do
23
+ AuDefaults.config_path('test').should == 'test'
24
+ AuDefaults.config_path.should == 'test'
25
+ end
26
+
27
+ it "should return the new path, when reinitialized" do
28
+ AuDefaults.config_path('test').should == 'test'
29
+ AuDefaults.config_path('reinit').should == 'reinit'
30
+ AuDefaults.config_path.should == 'reinit'
31
+ end
32
+
33
+ it "should return the default again, when reset" do
34
+ AuDefaults.config_path('test').should == 'test'
35
+ AuDefaults.config_path.should == 'test'
36
+ AuDefaults.reset_config_path
37
+ AuDefaults.config_path.should == [ENV['HOME'] + '/.config', '/etc', '/usr/local/etc', '../config']
38
+ end
39
+
40
+ end
@@ -0,0 +1,58 @@
1
+ require 'rspec'
2
+ require 'admin-utils/au_ftp'
3
+
4
+ include AuFtp
5
+
6
+ describe "Ftp Works" do
7
+
8
+ it "should open an ftp connection" do
9
+ ftp = double('Ftp Server')
10
+ Net::FTP.should_receive(:new).and_return(ftp)
11
+ ftp.should_receive(:connect).with('host', 21)
12
+ ftp.should_receive(:login).with('user', 'passwd', 'acct')
13
+ AuFtp.open_ftp_connection('host', 21, 'user', 'passwd', 'acct')
14
+ end
15
+
16
+ it "should upload a file via ftp" do
17
+ ftp = Net::FTP.new
18
+ ftp.should_receive(:pwd)
19
+ ftp.should_receive(:chdir).with('test_dir')
20
+ ftp.should_receive(:putbinaryfile).with('test_file')
21
+ ftp.should_receive(:chdir)
22
+ transfer_via_ftp(ftp, 'test_dir', 'test_file')
23
+ end
24
+
25
+ it "should upload multiple files" do
26
+ ftp = Net::FTP.new
27
+ ftp.should_receive(:pwd)
28
+ ftp.should_receive(:chdir).with('test_dir')
29
+ ftp.should_receive(:putbinaryfile).with('file1')
30
+ ftp.should_receive(:putbinaryfile).with('file2')
31
+ ftp.should_receive(:chdir)
32
+ transfer_via_ftp(ftp, 'test_dir', %w[file1 file2])
33
+ end
34
+
35
+ it "should not upload on an empty file string" do
36
+ ftp = Net::FTP.new
37
+ ftp.should_receive(:pwd)
38
+ ftp.should_receive(:chdir).with('test_dir')
39
+ ftp.should_not_receive(:putbinaryfile)
40
+ ftp.should_receive(:chdir)
41
+ transfer_via_ftp(ftp, 'test_dir', '')
42
+ end
43
+
44
+ it "should not upload on an empty array" do
45
+ ftp = Net::FTP.new
46
+ ftp.should_receive(:pwd)
47
+ ftp.should_receive(:chdir).with('test_dir')
48
+ ftp.should_not_receive(:putbinaryfile).with([])
49
+ ftp.should_receive(:chdir)
50
+ transfer_via_ftp(ftp, 'test_dir', [])
51
+ end
52
+
53
+ it "should close an ftp connection" do
54
+ ftp = Net::FTP.new
55
+ ftp.should_receive(:close)
56
+ close_ftp_connection(ftp)
57
+ end
58
+ end
@@ -0,0 +1,20 @@
1
+ require 'rspec'
2
+ require 'admin-utils/au_util'
3
+
4
+ describe "Create OpenStruct from Hash" do
5
+
6
+ it "should convert a Hash to an OpenStruct" do
7
+ my_hash = { key1: "value", key2: "otherValue" }
8
+ my_ostruct = AuUtil.hash_to_ostruct my_hash
9
+
10
+ my_ostruct.key1.should == "value"
11
+ my_ostruct.key2.should == "otherValue"
12
+ end
13
+
14
+ it "should treat an array just like an array" do
15
+ my_array = %w[ word1 word2 ]
16
+ my_ostruct = AuUtil.hash_to_ostruct my_array
17
+ my_ostruct[0].should == "word1"
18
+ my_ostruct[1].should == "word2"
19
+ end
20
+ end
@@ -0,0 +1,22 @@
1
+ require 'rspec'
2
+ require 'admin-utils/string'
3
+
4
+ describe "Is Number Test" do
5
+
6
+ it "should tell the an integer disguised as a string can be parsed to an integer" do
7
+ "45".is_number?.should == true
8
+ end
9
+
10
+ it "should tell that a string with letters and numbers is not an integer" do
11
+ "skd93l".is_number?.should == false
12
+ end
13
+
14
+ it "should tell that a string with just letters is not an integer" do
15
+ "though shall not pass".is_number?.should == false
16
+ end
17
+
18
+ it "should tell that a string containing a float is not an integer" do
19
+ "23.42".is_number?.should == false
20
+ end
21
+
22
+ end
metadata ADDED
@@ -0,0 +1,135 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: admin-utils
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Stefan Wendler
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-05-09 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: log4r
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: devver-construct
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: fake_ftp
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: Some basic utilities that I need often when writing Ruby Code
84
+ email: stefan@binarysun.de
85
+ executables: []
86
+ extensions: []
87
+ extra_rdoc_files: []
88
+ files:
89
+ - Gemfile
90
+ - Gemfile.lock
91
+ - Rakefile
92
+ - admin-utils.gemspec
93
+ - lib/admin-utils.rb
94
+ - lib/admin-utils/au_config.rb
95
+ - lib/admin-utils/au_defaults.rb
96
+ - lib/admin-utils/au_ftp.rb
97
+ - lib/admin-utils/au_logger.rb
98
+ - lib/admin-utils/au_util.rb
99
+ - lib/admin-utils/string.rb
100
+ - lib/admin-utils/version.rb
101
+ - spec/admin-utils/au_config_spec.rb
102
+ - spec/admin-utils/au_defaults_spec.rb
103
+ - spec/admin-utils/au_ftp_spec.rb
104
+ - spec/admin-utils/au_util_spec.rb
105
+ - spec/admin-utils/string_spec.rb
106
+ homepage: https://github.com/mrmarbury/admin_utils
107
+ licenses:
108
+ - Apache-2.0
109
+ metadata: {}
110
+ post_install_message:
111
+ rdoc_options: []
112
+ require_paths:
113
+ - lib
114
+ required_ruby_version: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - "~>"
117
+ - !ruby/object:Gem::Version
118
+ version: '2.4'
119
+ required_rubygems_version: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ requirements: []
125
+ rubyforge_project:
126
+ rubygems_version: 2.6.14
127
+ signing_key:
128
+ specification_version: 4
129
+ summary: The Admin Utils
130
+ test_files:
131
+ - spec/admin-utils/string_spec.rb
132
+ - spec/admin-utils/au_util_spec.rb
133
+ - spec/admin-utils/au_config_spec.rb
134
+ - spec/admin-utils/au_ftp_spec.rb
135
+ - spec/admin-utils/au_defaults_spec.rb