admin-utils 1.2.0

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.
@@ -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