dle 0.1.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.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +71 -0
- data/Rakefile +1 -0
- data/VERSION +1 -0
- data/bin/dle +3 -0
- data/bin/dle.sh +14 -0
- data/dle.gemspec +24 -0
- data/lib/active_support/core_ext/object/blank.rb +112 -0
- data/lib/active_support/core_ext/object/try.rb +53 -0
- data/lib/banana/logger.rb +258 -0
- data/lib/dle.rb +24 -0
- data/lib/dle/application.rb +96 -0
- data/lib/dle/application/dispatch.rb +151 -0
- data/lib/dle/dl_file.rb +111 -0
- data/lib/dle/filesystem.rb +109 -0
- data/lib/dle/filesystem/destructive.rb +115 -0
- data/lib/dle/filesystem/node.rb +44 -0
- data/lib/dle/filesystem/softnode.rb +6 -0
- data/lib/dle/helpers.rb +43 -0
- data/lib/dle/version.rb +4 -0
- metadata +112 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 954b6dbb956a5a13cab35c61df14f1d614f246d2
|
4
|
+
data.tar.gz: 5e80a17b73437a40587f6be58b1d0f48d87d33bf
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1a75351e1d3d18792ed530564364a773a8d5e7e83fe65cea779c232c6f35ad448184c93ef33f82085482bba4616962aea4283cb5d9390ca781b47d25eacbcafe
|
7
|
+
data.tar.gz: 2e13b0f57002f7e517cbbbc166cd1aec9bd41d42a7cd6960711f19a18306d495f769e1cd36f98a5a818c18fcd58659e91fe151ae8a454517fd55501c1004e041
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Sven Pachnit
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
# DLE
|
2
|
+
|
3
|
+
**Directory List Edit – Edit file structures in your favorite editor!**
|
4
|
+
You can copy, move, rename, chmod, chown or remove individual files or directories with your favorite text editor.
|
5
|
+
|
6
|
+
**BETA product, use at your own risk, use `--simulate` to be sure, always have a backup!**
|
7
|
+
|
8
|
+
## Requirements
|
9
|
+
|
10
|
+
You will need a UNIX system with a working Ruby installation, sorry Windozer!
|
11
|
+
|
12
|
+
## Installation
|
13
|
+
|
14
|
+
Simple as:
|
15
|
+
|
16
|
+
$ gem install dle
|
17
|
+
|
18
|
+
You may also want to define your favorite editor by setting this enviromental variable (in your profile or bashrc):
|
19
|
+
|
20
|
+
export DLE_EDITOR="subl -w"
|
21
|
+
|
22
|
+
Note that you need a blocking call to the editor (for GUI editors). Sublime and Textmate both accept `-w` or `--wait`.
|
23
|
+
|
24
|
+
## Usage
|
25
|
+
|
26
|
+
To get a list of available options invoke DLE with the `--help` or `-h` option:
|
27
|
+
|
28
|
+
Usage: dle [options] base_directory
|
29
|
+
-d, --dotfiles Include dotfiles (unix invisible)
|
30
|
+
-r, --skip-review Skip review changes before applying
|
31
|
+
-s, --simulate Don't apply changes, show commands instead
|
32
|
+
-f, --file DLFILE Use input file (be careful)
|
33
|
+
-m, --monochrome Don't colorize output
|
34
|
+
-h, --help Shows this help
|
35
|
+
-v, --version Shows version and other info
|
36
|
+
-z Do not check for updates on GitHub (with -v/--version)
|
37
|
+
|
38
|
+
Change into a directory you want to work with and invoke DLE:
|
39
|
+
|
40
|
+
dle .
|
41
|
+
dle ~/some_path
|
42
|
+
|
43
|
+
Your editor will open with a list of your directory structure which you can edit accordingly to these rules:
|
44
|
+
|
45
|
+
* If you remove a line we just don't care!
|
46
|
+
* If you add a line we just don't care!
|
47
|
+
* If you change a path we will "mkdir -p" the destination and move the file/dir
|
48
|
+
* If you change the owner we will "chown" the file/dir
|
49
|
+
* If you change the mode we will "chmod" the file/dir
|
50
|
+
* If you change the mode to "cp" and modify the path we will copy instead of moving/renaming
|
51
|
+
* If you change the mode to "del" we will "rm" the file
|
52
|
+
* If you change the mode to "delr" we will "rm" the file or directory
|
53
|
+
* If you change the mode to "delf" or "delrf" we will "rm -f" the file or directory
|
54
|
+
* We will apply changes in this order (inside-out):
|
55
|
+
* Ownership
|
56
|
+
* Permissions
|
57
|
+
* Rename/Move
|
58
|
+
* Copy
|
59
|
+
* Delete
|
60
|
+
|
61
|
+
## Caveats
|
62
|
+
|
63
|
+
DLE relies on inode values, do not use with hardlinks! This may lead to unexpected file operations or data loss!
|
64
|
+
|
65
|
+
## Contributing
|
66
|
+
|
67
|
+
1. Fork it ( http://github.com/2called-chaos/dle/fork )
|
68
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
69
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
70
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
71
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
data/bin/dle
ADDED
data/bin/dle.sh
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
# That's __FILE__ in BASH :)
|
4
|
+
# From: http://stackoverflow.com/questions/59895/can-a-bash-script-tell-what-directory-its-stored-in
|
5
|
+
SOURCE="${BASH_SOURCE[0]}"
|
6
|
+
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
|
7
|
+
MCLDIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
|
8
|
+
SOURCE="$(readlink "$SOURCE")"
|
9
|
+
[[ $SOURCE != /* ]] && SOURCE="$MCLDIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
|
10
|
+
done
|
11
|
+
PROJECT_ROOT="$( cd -P "$( dirname "$SOURCE" )"/.. && pwd )"
|
12
|
+
|
13
|
+
# Actually run script
|
14
|
+
cd $PROJECT_ROOT && bundle exec ruby bin/dle "$@"
|
data/dle.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'dle/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "dle"
|
8
|
+
spec.version = Dle::VERSION
|
9
|
+
spec.authors = ["Sven Pachnit"]
|
10
|
+
spec.email = ["sven@bmonkeys.net"]
|
11
|
+
spec.summary = %q{Directory List Edit – Edit file structures in your favorite editor!}
|
12
|
+
spec.description = %q{You can move, rename, chmod, chown or remove individual files or directories with your favorite text editor.}
|
13
|
+
spec.homepage = "https://github.com/2called-chaos/dle"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "pry"
|
22
|
+
spec.add_development_dependency "bundler", "~> 1.5"
|
23
|
+
spec.add_development_dependency "rake"
|
24
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
class Object
|
4
|
+
# An object is blank if it's false, empty, or a whitespace string.
|
5
|
+
# For example, '', ' ', +nil+, [], and {} are all blank.
|
6
|
+
#
|
7
|
+
# This simplifies:
|
8
|
+
#
|
9
|
+
# if address.nil? || address.empty?
|
10
|
+
#
|
11
|
+
# ...to:
|
12
|
+
#
|
13
|
+
# if address.blank?
|
14
|
+
def blank?
|
15
|
+
respond_to?(:empty?) ? empty? : !self
|
16
|
+
end
|
17
|
+
|
18
|
+
# An object is present if it's not <tt>blank?</tt>.
|
19
|
+
def present?
|
20
|
+
!blank?
|
21
|
+
end
|
22
|
+
|
23
|
+
# Returns object if it's <tt>present?</tt> otherwise returns +nil+.
|
24
|
+
# <tt>object.presence</tt> is equivalent to <tt>object.present? ? object : nil</tt>.
|
25
|
+
#
|
26
|
+
# This is handy for any representation of objects where blank is the same
|
27
|
+
# as not present at all. For example, this simplifies a common check for
|
28
|
+
# HTTP POST/query parameters:
|
29
|
+
#
|
30
|
+
# state = params[:state] if params[:state].present?
|
31
|
+
# country = params[:country] if params[:country].present?
|
32
|
+
# region = state || country || 'US'
|
33
|
+
#
|
34
|
+
# ...becomes:
|
35
|
+
#
|
36
|
+
# region = params[:state].presence || params[:country].presence || 'US'
|
37
|
+
def presence
|
38
|
+
self if present?
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
class NilClass
|
43
|
+
# +nil+ is blank:
|
44
|
+
#
|
45
|
+
# nil.blank? # => true
|
46
|
+
#
|
47
|
+
def blank?
|
48
|
+
true
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
class FalseClass
|
53
|
+
# +false+ is blank:
|
54
|
+
#
|
55
|
+
# false.blank? # => true
|
56
|
+
#
|
57
|
+
def blank?
|
58
|
+
true
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
class TrueClass
|
63
|
+
# +true+ is not blank:
|
64
|
+
#
|
65
|
+
# true.blank? # => false
|
66
|
+
#
|
67
|
+
def blank?
|
68
|
+
false
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
class Array
|
73
|
+
# An array is blank if it's empty:
|
74
|
+
#
|
75
|
+
# [].blank? # => true
|
76
|
+
# [1,2,3].blank? # => false
|
77
|
+
#
|
78
|
+
alias_method :blank?, :empty?
|
79
|
+
end
|
80
|
+
|
81
|
+
class Hash
|
82
|
+
# A hash is blank if it's empty:
|
83
|
+
#
|
84
|
+
# {}.blank? # => true
|
85
|
+
# {:key => 'value'}.blank? # => false
|
86
|
+
#
|
87
|
+
alias_method :blank?, :empty?
|
88
|
+
end
|
89
|
+
|
90
|
+
class String
|
91
|
+
# A string is blank if it's empty or contains whitespaces only:
|
92
|
+
#
|
93
|
+
# ''.blank? # => true
|
94
|
+
# ' '.blank? # => true
|
95
|
+
# ' '.blank? # => true
|
96
|
+
# ' something here '.blank? # => false
|
97
|
+
#
|
98
|
+
def blank?
|
99
|
+
self !~ /[^[:space:]]/
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
class Numeric #:nodoc:
|
104
|
+
# No number is blank:
|
105
|
+
#
|
106
|
+
# 1.blank? # => false
|
107
|
+
# 0.blank? # => false
|
108
|
+
#
|
109
|
+
def blank?
|
110
|
+
false
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
class Object
|
2
|
+
# Invokes the public method identified by the symbol +method+, passing it any arguments
|
3
|
+
# and/or the block specified, just like the regular Ruby <tt>Object#public_send</tt> does.
|
4
|
+
#
|
5
|
+
# *Unlike* that method however, a +NoMethodError+ exception will *not* be raised
|
6
|
+
# and +nil+ will be returned instead, if the receiving object is a +nil+ object or NilClass.
|
7
|
+
#
|
8
|
+
# If try is called without a method to call, it will yield any given block with the object.
|
9
|
+
#
|
10
|
+
# ==== Examples
|
11
|
+
#
|
12
|
+
# Without +try+
|
13
|
+
# @person && @person.name
|
14
|
+
# or
|
15
|
+
# @person ? @person.name : nil
|
16
|
+
#
|
17
|
+
# With +try+
|
18
|
+
# @person.try(:name)
|
19
|
+
#
|
20
|
+
# +try+ also accepts arguments and/or a block, for the method it is trying
|
21
|
+
# Person.try(:find, 1)
|
22
|
+
# @people.try(:collect) {|p| p.name}
|
23
|
+
#
|
24
|
+
# Without a method argument try will yield to the block unless the receiver is nil.
|
25
|
+
# @person.try { |p| "#{p.first_name} #{p.last_name}" }
|
26
|
+
#--
|
27
|
+
# +try+ behaves like +Object#public_send+, unless called on +NilClass+.
|
28
|
+
def try(*a, &b)
|
29
|
+
if a.empty? && block_given?
|
30
|
+
yield self
|
31
|
+
else
|
32
|
+
public_send(*a, &b)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
class NilClass
|
38
|
+
# Calling +try+ on +nil+ always returns +nil+.
|
39
|
+
# It becomes specially helpful when navigating through associations that may return +nil+.
|
40
|
+
#
|
41
|
+
# === Examples
|
42
|
+
#
|
43
|
+
# nil.try(:name) # => nil
|
44
|
+
#
|
45
|
+
# Without +try+
|
46
|
+
# @person && !@person.children.blank? && @person.children.first.name
|
47
|
+
#
|
48
|
+
# With +try+
|
49
|
+
# @person.try(:children).try(:first).try(:name)
|
50
|
+
def try(*args)
|
51
|
+
nil
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,258 @@
|
|
1
|
+
module Banana
|
2
|
+
# This class provides a simple logger which maintains and displays the runtime of the logger instance.
|
3
|
+
# It is intended to be used with the colorize gem but it brings its own colorization to eliminate a
|
4
|
+
# dependency. You should initialize the logger as soon as possible to get an accurate runtime.
|
5
|
+
#
|
6
|
+
# @example
|
7
|
+
# logger = Banana::Logger.new
|
8
|
+
# logger.log "foo"
|
9
|
+
# logger.prefix = "[a] "
|
10
|
+
# logger.debug "bar"
|
11
|
+
# sleep 2
|
12
|
+
# logger.ensure_prefix("[b] ") { logger.warn "baz" }
|
13
|
+
# logger.log("rab!", :abort)
|
14
|
+
#
|
15
|
+
# # Result:
|
16
|
+
# # [00:00:00.000 INFO] foo
|
17
|
+
# # [00:00:00.000 DEBUG] [a] bar
|
18
|
+
# # [00:00:02.001 WARN] [b] baz
|
19
|
+
# # [00:00:02.001 ABORT] [a] rab!
|
20
|
+
#
|
21
|
+
# @!attribute [r] startup
|
22
|
+
# @return [DateTime] Point of time where the logger was initiated.
|
23
|
+
# @!attribute [r] channel
|
24
|
+
# @return [Object] The object where messages are getting send to.
|
25
|
+
# @!attribute [r] method
|
26
|
+
# @return [Object] The method used to send messages to {#channel}.
|
27
|
+
# @!attribute [r] logged
|
28
|
+
# @return [Integer] Amount of messages send to channel.
|
29
|
+
# @note This counter starts from 0 in every {#ensure_method} or {#log_with_print} block but gets
|
30
|
+
# added to the main counter after the call.
|
31
|
+
# @!attribute timestr
|
32
|
+
# @return [Boolean] Set to false if the runtime indicator should not be printed (default: true).
|
33
|
+
# @!attribute colorize
|
34
|
+
# @return [Boolean] Set to false if output should not be colored (default: true).
|
35
|
+
# @!attribute prefix
|
36
|
+
# @return [String] Current prefix string for logged messages.
|
37
|
+
class Logger
|
38
|
+
attr_reader :startup, :channel, :method, :logged
|
39
|
+
attr_accessor :colorize, :prefix
|
40
|
+
|
41
|
+
# Foreground color values
|
42
|
+
COLORMAP = {
|
43
|
+
black: 30,
|
44
|
+
red: 31,
|
45
|
+
green: 32,
|
46
|
+
yellow: 33,
|
47
|
+
blue: 34,
|
48
|
+
magenta: 35,
|
49
|
+
cyan: 36,
|
50
|
+
white: 37,
|
51
|
+
}
|
52
|
+
|
53
|
+
# Initializes a new logger instance. The internal runtime measurement starts here!
|
54
|
+
#
|
55
|
+
# There are 4 default log levels: info (yellow), warn & abort (red) and debug (blue).
|
56
|
+
# All are enabled by default. You propably want to {#disable disable(:debug)}.
|
57
|
+
#
|
58
|
+
# @param scope Only for backward compatibility, not used
|
59
|
+
# @todo add option hash
|
60
|
+
def initialize scope = nil
|
61
|
+
@startup = Time.now.utc
|
62
|
+
@colorize = true
|
63
|
+
@prefix = ""
|
64
|
+
@enabled = true
|
65
|
+
@timestr = true
|
66
|
+
@channel = ::Kernel
|
67
|
+
@method = :puts
|
68
|
+
@logged = 0
|
69
|
+
@levels = {
|
70
|
+
info: { color: "yellow", enabled: true },
|
71
|
+
warn: { color: "red", enabled: true },
|
72
|
+
abort: { color: "red", enabled: true },
|
73
|
+
debug: { color: "blue", enabled: true },
|
74
|
+
}
|
75
|
+
end
|
76
|
+
|
77
|
+
# The default channel is `Kernel` which is Ruby's normal `puts`.
|
78
|
+
# Attach it to a open file with write access and it will write into
|
79
|
+
# the file. Ensure to close the file in your code.
|
80
|
+
#
|
81
|
+
# @param channel Object which responds to puts and print
|
82
|
+
def attach channel
|
83
|
+
@channel = channel
|
84
|
+
end
|
85
|
+
|
86
|
+
# Print raw message onto {#channel} using {#method}.
|
87
|
+
#
|
88
|
+
# @param [String] msg Message to send to {#channel}.
|
89
|
+
# @param [Symbol] method Override {#method}.
|
90
|
+
def raw msg, method = @method
|
91
|
+
@channel.send(method, msg)
|
92
|
+
end
|
93
|
+
|
94
|
+
# Add additional log levels which are automatically enabled.
|
95
|
+
# @param [Hash] levels Log levels in the format `{ debug: "red" }`
|
96
|
+
def log_level levels = {}
|
97
|
+
levels.each do |level, color|
|
98
|
+
@levels[level.to_sym] ||= { enabled: true }
|
99
|
+
@levels[level.to_sym][:color] = color
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# Calls the block with the given prefix and ensures that the prefix
|
104
|
+
# will be the same as before.
|
105
|
+
#
|
106
|
+
# @param [String] prefix Prefix to use for the block
|
107
|
+
# @param [Proc] block Block to call
|
108
|
+
def ensure_prefix prefix, &block
|
109
|
+
old_prefix, @prefix = @prefix, prefix
|
110
|
+
block.call
|
111
|
+
ensure
|
112
|
+
@prefix = old_prefix
|
113
|
+
end
|
114
|
+
|
115
|
+
# Calls the block after changing the output method.
|
116
|
+
# It also ensures to set back the method to what it was before.
|
117
|
+
#
|
118
|
+
# @param [Symbol] method Method to call on {#channel}
|
119
|
+
def ensure_method method, &block
|
120
|
+
old_method, old_logged = @method, @logged
|
121
|
+
@method, @logged = method, 0
|
122
|
+
block.call
|
123
|
+
ensure
|
124
|
+
@method = old_method
|
125
|
+
@logged += old_logged
|
126
|
+
end
|
127
|
+
|
128
|
+
# Calls the block after changing the output method to `:print`.
|
129
|
+
# It also ensures to set back the method to what it was before.
|
130
|
+
#
|
131
|
+
# @param [Boolean] clear If set to true and any message was printed inside the block
|
132
|
+
# a \n newline character will be printed.
|
133
|
+
def log_with_print clear = true, &block
|
134
|
+
ensure_method :print do
|
135
|
+
begin
|
136
|
+
block.call
|
137
|
+
ensure
|
138
|
+
puts if clear && @logged > 0
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
# Calls the block after disabling the runtime indicator.
|
144
|
+
# It also ensures to set back the old setting after execution.
|
145
|
+
def log_without_timestr &block
|
146
|
+
timestr, @timestr = @timestr, false
|
147
|
+
block.call
|
148
|
+
ensure
|
149
|
+
@timestr = timestr
|
150
|
+
end
|
151
|
+
|
152
|
+
# @return [Boolean] returns true if the log level format :debug is enabled.
|
153
|
+
def debug?
|
154
|
+
enabled? :debug
|
155
|
+
end
|
156
|
+
|
157
|
+
# If a `level` is provided it will return true if this log level is enabled.
|
158
|
+
# If no `level` is provided it will return true if the logger is enabled generally.
|
159
|
+
#
|
160
|
+
# @return [Boolean] returns true if the given log level is enabled
|
161
|
+
def enabled? level = nil
|
162
|
+
level.nil? ? @enabled : @levels[level.to_sym][:enabled]
|
163
|
+
end
|
164
|
+
|
165
|
+
# Same as {#enabled?} just negated.
|
166
|
+
def disabled? level = nil
|
167
|
+
!enabled?(level)
|
168
|
+
end
|
169
|
+
|
170
|
+
# Same as {#enable} just negated.
|
171
|
+
#
|
172
|
+
# @param [Symbol, String] level Loglevel to disable.
|
173
|
+
def disable level = nil
|
174
|
+
if level.nil?
|
175
|
+
@enabled = false
|
176
|
+
else
|
177
|
+
@levels[level.to_sym][:enabled] = false
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
# Enables the given `level` or the logger generally if no `level` is given.
|
182
|
+
# If the logger is disabled no messages will be printed. If it is enabled
|
183
|
+
# only messages for enabled log levels will be printed.
|
184
|
+
#
|
185
|
+
# @param [Symbol, String] level Loglevel to enable.
|
186
|
+
def enable level = nil
|
187
|
+
if level.nil?
|
188
|
+
@enabled = true
|
189
|
+
else
|
190
|
+
@levels[level.to_sym][:enabled] = true
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
# Colorizes the given string with the given color. It uses the build-in
|
195
|
+
# colorization feature. You may want to use the colorize gem.
|
196
|
+
#
|
197
|
+
# @param [String] str The string to colorize
|
198
|
+
# @param [Symbol, String] color The color to use (see {COLORMAP})
|
199
|
+
# @raise [ArgumentError] if color does not exist in {COLORMAP}.
|
200
|
+
def colorize str, color
|
201
|
+
ccode = COLORMAP[color.to_sym] || raise(ArgumentError, "Unknown color #{color}!")
|
202
|
+
"\e[#{ccode}m#{str}\e[0m"
|
203
|
+
end
|
204
|
+
|
205
|
+
def colorize?
|
206
|
+
@colorize
|
207
|
+
end
|
208
|
+
|
209
|
+
# This method is the only method which sends the message `msg` to `@channel` via `@method`.
|
210
|
+
# It also increments the message counter `@logged` by one.
|
211
|
+
#
|
212
|
+
# This method instantly returns nil if the logger or the given log level `type` is disabled.
|
213
|
+
#
|
214
|
+
# @param [String] msg The message to send to the channel
|
215
|
+
# @param [Symbol] type The log level
|
216
|
+
def log msg, type = :info
|
217
|
+
return if !@enabled || !@levels[type][:enabled]
|
218
|
+
if @levels[type.to_sym] || !@levels.key?(type.to_sym)
|
219
|
+
time = Time.at(Time.now.utc - @startup).utc
|
220
|
+
timestr = @timestr ? "[#{time.strftime("%H:%M:%S.%L")} #{type.to_s.upcase}]\t" : ""
|
221
|
+
|
222
|
+
if @colorize
|
223
|
+
msg = "#{colorize(timestr, @levels[type.to_sym][:color])}" <<
|
224
|
+
"#{@prefix}" <<
|
225
|
+
"#{colorize(msg, @levels[type.to_sym][:color])}"
|
226
|
+
else
|
227
|
+
msg = "#{timestr}#{@prefix}#{msg}"
|
228
|
+
end
|
229
|
+
@logged += 1
|
230
|
+
@channel.send(@method, msg)
|
231
|
+
end
|
232
|
+
end
|
233
|
+
alias_method :info, :log
|
234
|
+
|
235
|
+
# Shortcut for {#log #log(msg, :debug)}
|
236
|
+
#
|
237
|
+
# @param [String] msg The message to send to {#log}.
|
238
|
+
def debug msg
|
239
|
+
log(msg, :debug)
|
240
|
+
end
|
241
|
+
|
242
|
+
# Shortcut for {#log #log(msg, :warn)} but sets channel method to "warn".
|
243
|
+
#
|
244
|
+
# @param [String] msg The message to send to {#log}.
|
245
|
+
def warn msg
|
246
|
+
ensure_method(:warn) { log(msg, :warn) }
|
247
|
+
end
|
248
|
+
|
249
|
+
# Shortcut for {#log #log(msg, :abort)} but sets channel method to "warn".
|
250
|
+
#
|
251
|
+
# @param [String] msg The message to send to {#log}.
|
252
|
+
# @param [Integer] exit_code Exits with given code or does nothing when falsy.
|
253
|
+
def abort msg, exit_code = false
|
254
|
+
ensure_method(:warn) { log(msg, :abort) }
|
255
|
+
exit(exit_code) if exit_code
|
256
|
+
end
|
257
|
+
end
|
258
|
+
end
|