hoodie 0.4.6 → 0.4.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 62365f7e782e882ae3769a0f11495a15662baffd
4
- data.tar.gz: 5c174acce11e7d7e22ebbe43533b52f2bc91a6c6
3
+ metadata.gz: 1cc89e655be60fd07041f5142b3ce00d8998abea
4
+ data.tar.gz: 43d8d7c519bd16d6d7bc8872979f7187b30315b3
5
5
  SHA512:
6
- metadata.gz: 89700fd2bed82cc9abfd889db31551694ac271b49eb3ae5554c1ab3def161948218cd6062ccde5cbd5202634a569458d96ebb51744a68a321f3b74af404c6393
7
- data.tar.gz: b18ae1e33e1f0b9abaaa2cab448e76411a71c8804c2524d0f2aada6319addd65aa0bd749c6ebd17b3a5b4e906757ab426ecf1b28c78694e4d55878a62ba1b8b9
6
+ metadata.gz: aff45c5e404ef4944924ab67f1b1dd8e8b1f9cbd782023d2214411501122dd8b1241bc25cd10cdbfeadeeab1c289a45ea429736f09b0246434e153ee9e2e20f7
7
+ data.tar.gz: 368898a15a8a4dbcf40f4f1274009ecd4feddacc2b3934d98ddb4b2e5dc6a7fcf8980e720cf70b60fe6c8954d5622e504100020f580c0b6fe0a421d02532f34c
data/hoodie.gemspec CHANGED
@@ -22,10 +22,10 @@ Gem::Specification.new do |s|
22
22
  # s.add_runtime_dependency 'anemone', '>= 0.7.2'
23
23
  s.add_runtime_dependency 'hitimes'
24
24
 
25
- s.add_development_dependency 'rubocop', '>= 0.26.0'
26
- s.add_development_dependency 'rake', '>= 10.3.2'
27
- s.add_development_dependency 'coveralls', '>= 0.7.1'
28
- s.add_development_dependency 'rspec', '>= 3.1.0'
29
- s.add_development_dependency 'fuubar', '>= 2.0.0'
30
- s.add_development_dependency 'timecop', '>= 0.7.1'
25
+ s.add_development_dependency 'rubocop'
26
+ s.add_development_dependency 'rake'
27
+ s.add_development_dependency 'yard'
28
+ s.add_development_dependency 'yard-redcarpet-ext'
29
+ s.add_development_dependency 'redcarpet'
30
+ s.add_development_dependency 'github-markup'
31
31
  end
@@ -0,0 +1,33 @@
1
+ # encoding: UTF-8
2
+
3
+ module Hoodie
4
+
5
+ # A Configuration instance
6
+ class Configuration
7
+
8
+ # Access the logging setting for this instance
9
+ attr_accessor :logging
10
+
11
+ # Access to the logging level for this instance
12
+ attr_accessor :level
13
+
14
+ # Initialized a configuration instance
15
+ #
16
+ # @return [undefined]
17
+ #
18
+ # @api private
19
+ def initialize(options={})
20
+ @logging = options.fetch(:logging, false)
21
+ @level = options.fetch(:level, :info)
22
+
23
+ yield self if block_given?
24
+ end
25
+
26
+ # @api private
27
+ def to_h
28
+ { logging: logging,
29
+ level: level
30
+ }.freeze
31
+ end
32
+ end
33
+ end
@@ -2,7 +2,7 @@
2
2
  #
3
3
  # Author: Stefano Harding <riddopic@gmail.com>
4
4
  #
5
- # Copyright (C) 2014 Stefano Harding
5
+ # Copyright (C) 2014-2015 Stefano Harding
6
6
  #
7
7
  # Licensed under the Apache License, Version 2.0 (the "License");
8
8
  # you may not use this file except in compliance with the License.
@@ -2,7 +2,7 @@
2
2
  #
3
3
  # Author: Stefano Harding <riddopic@gmail.com>
4
4
  #
5
- # Copyright (C) 2014 Stefano Harding
5
+ # Copyright (C) 2014-2015 Stefano Harding
6
6
  #
7
7
  # Licensed under the Apache License, Version 2.0 (the "License");
8
8
  # you may not use this file except in compliance with the License.
@@ -43,7 +43,7 @@ class Hash
43
43
  # @return [Hash]
44
44
  #
45
45
  def transform_keys
46
- return enum_for(:transform_keys) unless block_given?
46
+ enum_for(:transform_keys) unless block_given?
47
47
  result = self.class.new
48
48
  each_key do |key|
49
49
  result[yield(key)] = self[key]
@@ -91,7 +91,7 @@ class Hash
91
91
  # @return [Hash]
92
92
  #
93
93
  def recursively_symbolize_keys
94
- recursively_transform_keys { |key| key.downcase.to_sym rescue key }
94
+ recursively_transform_keys { |key| key.to_sym rescue key }
95
95
  end
96
96
 
97
97
  # Returns a new hash with all keys converted to strings.
@@ -110,8 +110,52 @@ class Hash
110
110
  recursively_transform_keys { |key| key.to_s rescue key }
111
111
  end
112
112
 
113
+ # Returns a new hash with all keys converted to strings and the
114
+ # first letter capitalized.
115
+ #
116
+ # @return [Hash]
117
+ #
118
+ def capitalize_keys
119
+ transform_keys { |key| key.to_s.capitalize rescue key }
120
+ end
121
+
122
+ # Returns a new Hash, recursively converting all keys to strings
123
+ # and the first letter capitalized.
124
+ #
125
+ # @return [Hash]
126
+ #
127
+ def recursively_capitalize_key
128
+ recursively_transform_keys { |key| key.to_s.capitalize rescue key }
129
+ end
130
+
131
+ class UndefinedPathError < StandardError; end
132
+ # Recursively searchs a nested datastructure for a key and returns
133
+ # the value. If a block is provided its value will be returned if
134
+ # the key does not exist
135
+ #
136
+ # @example
137
+ # options = { server: { location: { row: { rack: 34 } } } }
138
+ # options.recursive_fetch :server, :location, :row, :rack
139
+ # # => 34
140
+ # options.recursive_fetch(:non_existent_key) { 'default' }
141
+ # # => "default"
142
+ #
143
+ # @return [Hash, Array, String] value for key
144
+ #
145
+ def recursive_fetch(*args, &block)
146
+ args.reduce(self) do |obj, arg|
147
+ begin
148
+ arg = Integer(arg) if obj.is_a? Array
149
+ obj.fetch(arg)
150
+ rescue ArgumentError, IndexError, NoMethodError => e
151
+ break block.call(arg) if block
152
+ raise UndefinedPathError, "Could not fetch path (#{args.join(' > ')}) at #{arg}", e.backtrace
153
+ end
154
+ end
155
+ end
156
+
113
157
  def recursive_merge(other)
114
- hash = dup
158
+ hash = self.dup
115
159
  other.each do |key, value|
116
160
  myval = self[key]
117
161
  if value.is_a?(Hash) && myval.is_a?(Hash)
@@ -0,0 +1,54 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Author: Stefano Harding <riddopic@gmail.com>
4
+ #
5
+ # Copyright (C) 2014-2015 Stefano Harding
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+
20
+ class String
21
+ def clear; colorize(self, "\e[0m"); end
22
+ def erase_line; colorize(self, "\e[K"); end
23
+ def erase_char; colorize(self, "\e[P"); end
24
+ def bold; colorize(self, "\e[1m"); end
25
+ def dark; colorize(self, "\e[2m"); end
26
+ def underline; colorize(self, "\e[4m"); end
27
+ def blink; colorize(self, "\e[5m"); end
28
+ def reverse; colorize(self, "\e[7m"); end
29
+ def concealed; colorize(self, "\e[8m"); end
30
+ def black; colorize(self, "\e[0;30m"); end
31
+ def gray; colorize(self, "\e[1;30m"); end
32
+ def red; colorize(self, "\e[0;31m"); end
33
+ def magenta; colorize(self, "\e[1;31m"); end
34
+ def green; colorize(self, "\e[0;32m"); end
35
+ def olive; colorize(self, "\e[1;32m"); end
36
+ def yellow; colorize(self, "\e[0;33m"); end
37
+ def cream; colorize(self, "\e[1;33m"); end
38
+ def blue; colorize(self, "\e[0;34m"); end
39
+ def purple; colorize(self, "\e[1;34m"); end
40
+ def orange; colorize(self, "\e[0;35m"); end
41
+ def mustard; colorize(self, "\e[1;35m"); end
42
+ def cyan; colorize(self, "\e[0;36m"); end
43
+ def cyan2; colorize(self, "\e[1;36m"); end
44
+ def white; colorize(self, "\e[0;97m"); end
45
+ def on_black; colorize(self, "\e[40m"); end
46
+ def on_red; colorize(self, "\e[41m"); end
47
+ def on_green; colorize(self, "\e[42m"); end
48
+ def on_yellow; colorize(self, "\e[43m"); end
49
+ def on_blue; colorize(self, "\e[44m"); end
50
+ def on_magenta; colorize(self, "\e[45m"); end
51
+ def on_cyan; colorize(self, "\e[46m"); end
52
+ def on_white; colorize(self, "\e[47m"); end
53
+ def colorize(text, color_code) "#{color_code}#{text}\e[0m" end
54
+ end
@@ -2,7 +2,7 @@
2
2
  #
3
3
  # Author: Stefano Harding <riddopic@gmail.com>
4
4
  #
5
- # Copyright (C) 2014 Stefano Harding
5
+ # Copyright (C) 2014-2015 Stefano Harding
6
6
  #
7
7
  # Licensed under the Apache License, Version 2.0 (the "License");
8
8
  # you may not use this file except in compliance with the License.
@@ -0,0 +1,62 @@
1
+ # encoding: UTF-8
2
+
3
+ Inflections.inflections do |inflect|
4
+ inflect.plural(/$/, 's')
5
+ inflect.plural(/s$/i, 's')
6
+ inflect.plural(/^(ax|test)is$/i, '\1es')
7
+ inflect.plural(/(octop|vir)us$/i, '\1i')
8
+ inflect.plural(/(octop|vir)i$/i, '\1i')
9
+ inflect.plural(/(alias|status)$/i, '\1es')
10
+ inflect.plural(/(bu)s$/i, '\1ses')
11
+ inflect.plural(/(buffal|tomat)o$/i, '\1oes')
12
+ inflect.plural(/([ti])um$/i, '\1a')
13
+ inflect.plural(/([ti])a$/i, '\1a')
14
+ inflect.plural(/sis$/i, 'ses')
15
+ inflect.plural(/(?:([^f])fe|([lr])f)$/i, '\1\2ves')
16
+ inflect.plural(/(hive)$/i, '\1s')
17
+ inflect.plural(/([^aeiouy]|qu)y$/i, '\1ies')
18
+ inflect.plural(/(x|ch|ss|sh)$/i, '\1es')
19
+ inflect.plural(/(matr|vert|ind)(?:ix|ex)$/i, '\1ices')
20
+ inflect.plural(/^(m|l)ouse$/i, '\1ice')
21
+ inflect.plural(/^(m|l)ice$/i, '\1ice')
22
+ inflect.plural(/^(ox)$/i, '\1en')
23
+ inflect.plural(/^(oxen)$/i, '\1')
24
+ inflect.plural(/(quiz)$/i, '\1zes')
25
+
26
+ inflect.singular(/s$/i, '')
27
+ inflect.singular(/(ss)$/i, '\1')
28
+ inflect.singular(/(n)ews$/i, '\1ews')
29
+ inflect.singular(/([ti])a$/i, '\1um')
30
+ inflect.singular(/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)(sis|ses)$/i, '\1sis')
31
+ inflect.singular(/(^analy)(sis|ses)$/i, '\1sis')
32
+ inflect.singular(/([^f])ves$/i, '\1fe')
33
+ inflect.singular(/(hive)s$/i, '\1')
34
+ inflect.singular(/(tive)s$/i, '\1')
35
+ inflect.singular(/([lr])ves$/i, '\1f')
36
+ inflect.singular(/([^aeiouy]|qu)ies$/i, '\1y')
37
+ inflect.singular(/(s)eries$/i, '\1eries')
38
+ inflect.singular(/(m)ovies$/i, '\1ovie')
39
+ inflect.singular(/(x|ch|ss|sh)es$/i, '\1')
40
+ inflect.singular(/^(m|l)ice$/i, '\1ouse')
41
+ inflect.singular(/(bus)(es)?$/i, '\1')
42
+ inflect.singular(/(o)es$/i, '\1')
43
+ inflect.singular(/(shoe)s$/i, '\1')
44
+ inflect.singular(/(cris|test)(is|es)$/i, '\1is')
45
+ inflect.singular(/^(a)x[ie]s$/i, '\1xis')
46
+ inflect.singular(/(octop|vir)(us|i)$/i, '\1us')
47
+ inflect.singular(/(alias|status)(es)?$/i, '\1')
48
+ inflect.singular(/^(ox)en/i, '\1')
49
+ inflect.singular(/(vert|ind)ices$/i, '\1ex')
50
+ inflect.singular(/(matr)ices$/i, '\1ix')
51
+ inflect.singular(/(quiz)zes$/i, '\1')
52
+ inflect.singular(/(database)s$/i, '\1')
53
+
54
+ inflect.irregular('person', 'people')
55
+ inflect.irregular('man', 'men')
56
+ inflect.irregular('child', 'children')
57
+ inflect.irregular('sex', 'sexes')
58
+ inflect.irregular('move', 'moves')
59
+ inflect.irregular('zombie', 'zombies')
60
+
61
+ inflect.uncountable(%w(hovercraft moose milk rain Swiss grass equipment information rice money species series fish sheep jeans))
62
+ end
@@ -0,0 +1,161 @@
1
+ # encoding: UTF-8
2
+
3
+ module Inflections
4
+ # A singleton instance of this class is yielded by Inflections.inflections,
5
+ # which can then be used to specify additional inflection rules. Examples:
6
+ #
7
+ # Inflections.inflections do |inflect|
8
+ # inflect.plural /^(ox)$/i, '\1\2en'
9
+ # inflect.singular /^(ox)en/i, '\1'
10
+ #
11
+ # inflect.irregular 'octopus', 'octopi'
12
+ #
13
+ # inflect.uncountable "equipment"
14
+ # end
15
+ #
16
+ # New rules are added at the top. So in the example above, the irregular rule
17
+ # for octopus will now be the first of the pluralization and singularization
18
+ # rules that is runs. This guarantees that your rules run before any of the
19
+ # rules that may already have been loaded.
20
+ #
21
+ class Inflections
22
+
23
+ # Return instance
24
+ #
25
+ # @return [Inflections]
26
+ # @api private
27
+ def self.instance
28
+ @__instance__ ||= new
29
+ end
30
+
31
+ # @return [Array] plurals
32
+ # @api private
33
+ attr_reader :plurals
34
+
35
+ # @return [Array] singulars
36
+ # @api private
37
+ attr_reader :singulars
38
+
39
+ # @return [Array] uncountables
40
+ # @api private
41
+ attr_reader :uncountables
42
+
43
+ # @return [Array] humans
44
+ # @api private
45
+ attr_reader :humans
46
+
47
+ # Initialize object
48
+ #
49
+ # @return [undefined]
50
+ # @api private
51
+ def initialize
52
+ @plurals = RulesCollection.new
53
+ @singulars = RulesCollection.new
54
+ @humans = RulesCollection.new
55
+ @uncountables = Set[]
56
+ end
57
+
58
+ # Specifies a new pluralization rule and its replacement. The rule can
59
+ # either be a string or a regular expression. The replacement should always
60
+ # be a string that may include references to the matched data from the rule.
61
+ #
62
+ # @param [String, Regexp] rule
63
+ # @param [String, Regexp] replacement
64
+ # @return [self]
65
+ # @api private
66
+ def plural(rule, replacement)
67
+ rule(rule, replacement, @plurals)
68
+ self
69
+ end
70
+
71
+ # Specifies a new singularization rule and its replacement. The rule can
72
+ # either be a string or a regular expression. The replacement should always
73
+ # be a string that may include references to the matched data from the rule.
74
+ #
75
+ # @param [String, Regexp] rule
76
+ # @param [String, Regexp] replacement
77
+ # @return [self]
78
+ # @api private
79
+ def singular(rule, replacement)
80
+ rule(rule, replacement, @singulars)
81
+ self
82
+ end
83
+
84
+ # Specifies a new irregular that applies to both pluralization and
85
+ # singularization at the same time. This can only be used for strings, not
86
+ # regular expressions. You simply pass the irregular in singular and plural
87
+ # form.
88
+ #
89
+ # @param [String] singular
90
+ # @param [String] plural
91
+ # @return [self]
92
+ # @api private
93
+ def irregular(singular, plural)
94
+ @uncountables.delete(singular)
95
+ @uncountables.delete(plural)
96
+ add_irregular(singular, plural, @plurals)
97
+ add_irregular(plural, singular, @singulars)
98
+ self
99
+ end
100
+
101
+ # Uncountable will not be inflected
102
+ #
103
+ # @param [Enumerable<String>] words
104
+ # @return [self]
105
+ # @api private
106
+ def uncountable(*words)
107
+ @uncountables.merge(words.flatten)
108
+ self
109
+ end
110
+
111
+ # Specifies a humanized form of a string by a regular expression rule or by
112
+ # a string mapping. When using a regular expression based replacement, the
113
+ # normal humanize formatting is called after the replacement. When a string
114
+ # is used, the human form should be specified as desired (example: 'The
115
+ # name', not 'the_name')
116
+ #
117
+ # @param [String, Regexp] rule
118
+ # @param [String, Regexp] replacement
119
+ # @return [self]
120
+ # @api private
121
+ def human(rule, replacement)
122
+ @humans.insert(0, [rule, replacement])
123
+ self
124
+ end
125
+
126
+ # Clear all inflection rules
127
+ #
128
+ # @return [self]
129
+ # @api private
130
+ def clear
131
+ initialize
132
+ self
133
+ end
134
+
135
+ private
136
+
137
+ # Add irregular inflection
138
+ #
139
+ # @param [String] rule
140
+ # @param [String] replacement
141
+ # @return [undefined]
142
+ # @api private
143
+ def add_irregular(rule, replacement, target)
144
+ head, *tail = rule.chars.to_a
145
+ rule(/(#{head})#{tail.join}\z/i, '\1' + replacement[1..-1], target)
146
+ end
147
+
148
+ # Add a new rule
149
+ #
150
+ # @param [String, Regexp] rule
151
+ # @param [String, Regexp] replacement
152
+ # @param [Array] target
153
+ # @return [undefined]
154
+ # @api private
155
+ def rule(rule, replacement, target)
156
+ @uncountables.delete(rule)
157
+ @uncountables.delete(replacement)
158
+ target.insert(0, [rule, replacement])
159
+ end
160
+ end
161
+ end
@@ -0,0 +1,18 @@
1
+ # encoding: UTF-8
2
+
3
+ module Inflections
4
+ # Wraps inflections array
5
+ #
6
+ class RulesCollection < Array
7
+ # Applies first found rule to given word
8
+ #
9
+ # @param [String] word
10
+ # @return [String] modified word
11
+ # @api private
12
+ def apply_to(word)
13
+ result = word.dup
14
+ each { |rule, replacement| break if result.gsub!(rule, replacement) }
15
+ result
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,172 @@
1
+
2
+ require 'set'
3
+
4
+ # The Inflections transforms words from singular to plural, class names to table
5
+ # names, modularized class names to ones without, and class names to foreign
6
+ # keys. The default inflections for pluralization, singularization, and
7
+ # uncountable words are kept in inflections.rb.
8
+ #
9
+ module Inflections
10
+
11
+ # Convert input to UpperCamelCase. Will also convert '/' to '::' which is
12
+ # useful for converting paths to namespaces.
13
+ #
14
+ # @param [String] input
15
+ # @return [String]
16
+ def self.camelize(input)
17
+ input.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:\A|_)(.)/) { $1.upcase }
18
+ end
19
+
20
+ # Convert input to underscored, lowercase string. Changes '::' to '/' to
21
+ # convert namespaces to paths.
22
+ #
23
+ # @param [String] input
24
+ # @return [String]
25
+ def self.underscore(input)
26
+ word = input.gsub(/::/, '/')
27
+ underscorize(word)
28
+ end
29
+
30
+ # Convert input underscores to dashes.
31
+ #
32
+ # @param [String] input
33
+ # @return [String]
34
+ def self.dasherize(input)
35
+ input.tr('_', '-')
36
+ end
37
+
38
+ # Return unscoped constant name.
39
+ #
40
+ # @param [String] input
41
+ # @return [String]
42
+ def self.demodulize(input)
43
+ input.split('::').last
44
+ end
45
+
46
+ # Creates a foreign key name
47
+ #
48
+ # @param [String] input
49
+ # @return [String]
50
+ def self.foreign_key(input)
51
+ "#{underscorize(demodulize(input))}_id"
52
+ end
53
+
54
+ # Find a constant with the name specified in the argument string. The name is
55
+ # assumed to be the one of a top-level constant, constant scope of caller is
56
+ # igored.
57
+ #
58
+ # @param [String] input
59
+ # @return [Class, Module]
60
+ def self.constantize(input)
61
+ names = input.split('::')
62
+ names.shift if names.first.empty?
63
+
64
+ names.inject(Object) do |constant, name|
65
+ if constant.const_defined?(name)
66
+ constant.const_get(name)
67
+ else
68
+ constant.const_missing(name)
69
+ end
70
+ end
71
+ end
72
+
73
+ ORDINALIZE_TH = (4..16).to_set.freeze
74
+
75
+ # Convert a number into an ordinal string.
76
+ #
77
+ # @param [Fixnum] number
78
+ # @return [String]
79
+ def self.ordinalize(number)
80
+ abs_value = number.abs
81
+
82
+ if ORDINALIZE_TH.include?(abs_value % 100)
83
+ "#{number}th"
84
+ else
85
+ case abs_value % 10
86
+ when 1; "#{number}st"
87
+ when 2; "#{number}nd"
88
+ when 3; "#{number}rd"
89
+ end
90
+ end
91
+ end
92
+
93
+ # Convert input word string to plural
94
+ #
95
+ # @param [String] word
96
+ # @return [String]
97
+ def self.pluralize(word)
98
+ return word if uncountable?(word)
99
+ inflections.plurals.apply_to(word)
100
+ end
101
+
102
+ # Convert word to singular
103
+ #
104
+ # @param [String] word
105
+ # @return [String]
106
+ def self.singularize(word)
107
+ return word if uncountable?(word)
108
+ inflections.singulars.apply_to(word)
109
+ end
110
+
111
+ # Humanize string.
112
+ #
113
+ # @param [String] input
114
+ # @return [String]
115
+ def self.humanize(input)
116
+ result = inflections.humans.apply_to(input)
117
+ result.gsub!(/_id\z/, "")
118
+ result.tr!('_', " ")
119
+ result.capitalize!
120
+ result
121
+ end
122
+
123
+ # Tabelize input string.
124
+ #
125
+ # @param [String] input
126
+ # @return [String]
127
+ def self.tableize(input)
128
+ pluralize(underscore(input).gsub('/', '_'))
129
+ end
130
+
131
+ # Create a class name from a plural table name like Rails does for table
132
+ # names to models.
133
+ #
134
+ # @param [String] input
135
+ # @return [String]
136
+ def self.classify(table_name)
137
+ camelize(singularize(table_name.sub(/.*\./, '')))
138
+ end
139
+
140
+ # Test if word is uncountable.
141
+ #
142
+ # @param [String] word
143
+ # @return [Boolean] true, if word is uncountable
144
+ def self.uncountable?(word)
145
+ word.empty? || inflections.uncountables.include?(word.downcase)
146
+ end
147
+
148
+ # Convert input to underscored, lowercase string
149
+ #
150
+ # @param [String] input
151
+ # @return [String]
152
+ def self.underscorize(word)
153
+ word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
154
+ word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
155
+ word.tr!('-', '_')
156
+ word.downcase!
157
+ word
158
+ end
159
+ private_class_method :underscorize
160
+
161
+ # Yields a singleton instance of Inflecto::Inflections.
162
+ #
163
+ # @return [Inflections::Inflections]
164
+ def self.inflections
165
+ instance = Inflections.instance
166
+ block_given? ? yield(instance) : instance
167
+ end
168
+ end
169
+
170
+ require 'hoodie/inflections/rules_collection'
171
+ require 'hoodie/inflections/inflections'
172
+ require 'hoodie/inflections/defaults'
@@ -1,9 +1,8 @@
1
1
  # encoding: UTF-8
2
2
  #
3
- # Author: Tom Santos <santos.tom@gmail.com>
4
3
  # Author: Stefano Harding <riddopic@gmail.com>
5
4
  #
6
- # Copyright (C) 2012-2014 Tom Santos, Stefano Harding
5
+ # Copyright (C) 2014-2015 Stefano Harding
7
6
  #
8
7
  # Licensed under the Apache License, Version 2.0 (the "License");
9
8
  # you may not use this file except in compliance with the License.
@@ -22,53 +21,66 @@ require 'logger'
22
21
  require 'time'
23
22
 
24
23
  module Hoodie
25
- module Logging
24
+ module Log
25
+ @loggers ||= {}
26
+
27
+ def demodulize(class_name_in_module)
28
+ class_name_in_module.to_s.sub(/^.*::/, '')
29
+ end
30
+
26
31
  class << self
27
32
 
28
- # The Zero Log for Class
29
33
  class NoLogger < Logger
30
- def initialize(*args); end
31
- def add(*args, &block); end
34
+ def initialize(*args)
35
+ end
36
+
37
+ def add(*args, &block)
38
+ end
32
39
  end
33
40
 
34
- def no_logger
35
- @log ||= NoLogger.new
41
+ def demodulize(class_name_in_module)
42
+ class_name_in_module.to_s.sub(/^.*::/, '')
36
43
  end
37
44
 
38
- def log(log_prefix)
39
- @log ||= Logger.new($stdout).tap do |log|
40
- log.progname = self.class == Class ? self.to_s : self.class.to_s
41
- log.formatter = Hoodie::Formatter.new
42
- log.formatter.datetime_format = '%F %T'
43
- log.level = Logger::DEBUG
44
- end
45
+ def log(prefix)
46
+ @loggers[prefix] ||= logger_for(prefix)
47
+ end
48
+
49
+ def logger_for(prefix)
50
+
51
+ log = logger
52
+ log.progname = prefix
53
+ log.formatter = Hoodie::Formatter.new
54
+ log.formatter.datetime_format = '%F %T'
55
+ log.level = self.send(log_level)
56
+ log
45
57
  end
46
58
 
47
59
  def log=(log)
48
60
  @log = log
49
61
  end
50
62
 
51
- def log_prefix
52
- self.class == Class ? self.to_s : self.class.to_s
63
+ def logger
64
+ Hoodie.configuration.logging ? Logger.new($stdout) : NoLogger.new
53
65
  end
54
66
 
55
- def level
56
- "Logger::#{@level.to_s.upcase}"
67
+ def log_level
68
+ "Logger::#{Hoodie.configuration.level.to_s.upcase}"
57
69
  end
58
70
  end
59
71
 
60
72
  def self.included(base)
61
73
  class << base
62
74
  def log
63
- log_prefix = self.class == Class ? self.to_s : self.class.to_s
64
- Hoodie::Logging.log log_prefix
75
+ prefix = self.class == Class ? self.to_s : self.class.to_s
76
+ Hoodie::Logging.log(demodulize(prefix))
65
77
  end
66
78
  end
67
79
  end
68
80
 
69
81
  def log
70
- log_prefix = self.class == Class ? self.to_s : self.class.to_s
71
- Hoodie::Logging.log log_prefix
82
+ prefix = self.class == Class ? self.to_s : self.class.to_s
83
+ Hoodie::Logging.log(demodulize(prefix))
72
84
  end
73
85
  end
74
86
 
@@ -82,18 +94,16 @@ module Hoodie
82
94
 
83
95
  def call(severity, time, progname, msg)
84
96
  format % [
85
- format_datetime(time).BLUE,
86
- progname.CYAN,
87
- $$,
88
- severity.GREEN,
89
- msg2str(msg).strip.ORANGE
97
+ format_datetime(time).blue,
98
+ severity.green,
99
+ msg2str(msg).strip.orange
90
100
  ]
91
101
  end
92
102
 
93
103
  private # P R O P R I E T À P R I V A T A Vietato L'accesso
94
104
 
95
105
  def format
96
- "%s [%s#%d] %5s: %s\n"
106
+ "[%s] %5s: %s\n"
97
107
  end
98
108
 
99
109
  def format_datetime(time)
@@ -105,52 +115,3 @@ module Hoodie
105
115
  end
106
116
  end
107
117
  end
108
-
109
- class String
110
- def clear; colorize(self, "\e[0m"); end
111
- # Erase the current line of terminal output.
112
- def erase_line; colorize(self, "\e[K"); end
113
- # Erase the character under the cursor.
114
- def erase_char; colorize(self, "\e[P"); end
115
- # The start of an ANSI bold sequence.
116
- def bold; colorize(self, "\e[1m"); end
117
- # The start of an ANSI dark sequence.
118
- def dark; colorize(self, "\e[2m"); end
119
- # The start of an ANSI underline sequence.
120
- def underline; colorize(self, "\e[4m"); end
121
- # The start of an ANSI blink sequence.
122
- def blink; colorize(self, "\e[5m"); end
123
- # The start of an ANSI reverse sequence.
124
- def reverse; colorize(self, "\e[7m"); end
125
- # The start of an ANSI concealed sequence.
126
- def concealed; colorize(self, "\e[8m"); end
127
-
128
- # Set the terminal's foreground ANSI color to
129
- def BLACK; colorize(self, "\e[0;30m"); end
130
- def GRAY; colorize(self, "\e[1;30m"); end
131
- def RED; colorize(self, "\e[0;31m"); end
132
- def MAGENTA; colorize(self, "\e[1;31m"); end
133
- def GREEN; colorize(self, "\e[0;32m"); end
134
- def OLIVE; colorize(self, "\e[1;32m"); end
135
- def YELLOW; colorize(self, "\e[0;33m"); end
136
- def CREAM; colorize(self, "\e[1;33m"); end
137
- def BLUE; colorize(self, "\e[0;34m"); end
138
- def PURPLE; colorize(self, "\e[1;34m"); end
139
- def ORANGE; colorize(self, "\e[0;35m"); end
140
- def MUSTARD; colorize(self, "\e[1;35m"); end
141
- def CYAN; colorize(self, "\e[0;36m"); end
142
- def CYAN2; colorize(self, "\e[1;36m"); end
143
- def WHITE; colorize(self, "\e[0;97m"); end
144
-
145
- # Set the terminal's background ANSI color to
146
- def on_black; colorize(self, "\e[40m"); end
147
- def on_red; colorize(self, "\e[41m"); end
148
- def on_green; colorize(self, "\e[42m"); end
149
- def on_yellow; colorize(self, "\e[43m"); end
150
- def on_blue; colorize(self, "\e[44m"); end
151
- def on_magenta; colorize(self, "\e[45m"); end
152
- def on_cyan; colorize(self, "\e[46m"); end
153
- def on_white; colorize(self, "\e[47m"); end
154
-
155
- def colorize(text, color_code) "#{color_code}#{text}\e[0m" end
156
- end
@@ -2,7 +2,7 @@
2
2
  #
3
3
  # Author: Stefano Harding <riddopic@gmail.com>
4
4
  #
5
- # Copyright (C) 2014 Stefano Harding
5
+ # Copyright (C) 2014-2015 Stefano Harding
6
6
  #
7
7
  # Licensed under the Apache License, Version 2.0 (the "License");
8
8
  # you may not use this file except in compliance with the License.
@@ -2,7 +2,7 @@
2
2
  #
3
3
  # Author: Stefano Harding <riddopic@gmail.com>
4
4
  #
5
- # Copyright (C) 2014 Stefano Harding
5
+ # Copyright (C) 2014-2015 Stefano Harding
6
6
  #
7
7
  # Licensed under the Apache License, Version 2.0 (the "License");
8
8
  # you may not use this file except in compliance with the License.
data/lib/hoodie/os.rb CHANGED
@@ -2,7 +2,7 @@
2
2
  #
3
3
  # Author: Stefano Harding <riddopic@gmail.com>
4
4
  #
5
- # Copyright (C) 2014 Stefano Harding
5
+ # Copyright (C) 2014-2015 Stefano Harding
6
6
  #
7
7
  # Licensed under the Apache License, Version 2.0 (the "License");
8
8
  # you may not use this file except in compliance with the License.
data/lib/hoodie/rash.rb CHANGED
@@ -2,7 +2,7 @@
2
2
  #
3
3
  # Author: Stefano Harding <riddopic@gmail.com>
4
4
  #
5
- # Copyright (C) 2014 Stefano Harding
5
+ # Copyright (C) 2014-2015 Stefano Harding
6
6
  #
7
7
  # Licensed under the Apache License, Version 2.0 (the "License");
8
8
  # you may not use this file except in compliance with the License.
@@ -2,7 +2,7 @@
2
2
  #
3
3
  # Author: Stefano Harding <riddopic@gmail.com>
4
4
  #
5
- # Copyright (C) 2014 Stefano Harding
5
+ # Copyright (C) 2014-2015 Stefano Harding
6
6
  #
7
7
  # Licensed under the Apache License, Version 2.0 (the "License");
8
8
  # you may not use this file except in compliance with the License.
@@ -2,7 +2,7 @@
2
2
  #
3
3
  # Author: Stefano Harding <riddopic@gmail.com>
4
4
  #
5
- # Copyright (C) 2014 Stefano Harding
5
+ # Copyright (C) 2014-2015 Stefano Harding
6
6
  #
7
7
  # Licensed under the Apache License, Version 2.0 (the "License");
8
8
  # you may not use this file except in compliance with the License.
data/lib/hoodie/utils.rb CHANGED
@@ -2,7 +2,7 @@
2
2
  #
3
3
  # Author: Stefano Harding <riddopic@gmail.com>
4
4
  #
5
- # Copyright (C) 2014 Stefano Harding
5
+ # Copyright (C) 2014-2015 Stefano Harding
6
6
  #
7
7
  # Licensed under the Apache License, Version 2.0 (the "License");
8
8
  # you may not use this file except in compliance with the License.
@@ -2,7 +2,7 @@
2
2
  #
3
3
  # Author: Stefano Harding <riddopic@gmail.com>
4
4
  #
5
- # Copyright (C) 2014 Stefano Harding
5
+ # Copyright (C) 2014-2015 Stefano Harding
6
6
  #
7
7
  # Licensed under the Apache License, Version 2.0 (the "License");
8
8
  # you may not use this file except in compliance with the License.
@@ -18,5 +18,5 @@
18
18
  #
19
19
 
20
20
  module Hoodie
21
- VERSION = '0.4.6'
21
+ VERSION = '0.4.7'
22
22
  end
data/lib/hoodie.rb CHANGED
@@ -2,7 +2,7 @@
2
2
  #
3
3
  # Author: Stefano Harding <riddopic@gmail.com>
4
4
  #
5
- # Copyright (C) 2014 Stefano Harding
5
+ # Copyright (C) 2014-2015 Stefano Harding
6
6
  #
7
7
  # Licensed under the Apache License, Version 2.0 (the "License");
8
8
  # you may not use this file except in compliance with the License.
@@ -17,9 +17,66 @@
17
17
  # limitations under the License.
18
18
  #
19
19
 
20
+ require 'hoodie/configuration'
21
+
22
+ module Hoodie
23
+
24
+ # Raised when errors occur during configuration.
25
+ ConfigurationError = Class.new(StandardError)
26
+
27
+ # Raised when an object's methods are called when it has not been
28
+ # properly initialized.
29
+ InitializationError = Class.new(StandardError)
30
+
31
+ # Raised when an operation times out.
32
+ TimeoutError = Class.new(StandardError)
33
+
34
+ class << self
35
+ # @param [TrueClass, FalseClass] sets the global logging configuration.
36
+ # @return [Hoodie]
37
+ # @api public
38
+ def logging=(value)
39
+ configuration.logging = value
40
+ self
41
+ end
42
+
43
+ # @return [TrueClass, FalseClass] the global logging setting.
44
+ # @api public
45
+ def logging
46
+ configuration.logging
47
+ end
48
+
49
+ # Provides access to the global configuration.
50
+ #
51
+ # @example
52
+ # Hoodie.config do |config|
53
+ # config.logging = true
54
+ # end
55
+ #
56
+ # @return [Configuration]
57
+ #
58
+ # @api public
59
+ def config(&block)
60
+ yield configuration if block_given?
61
+ configuration
62
+ end
63
+
64
+ # @return [Configuration] global configuration instance.
65
+ # @api private
66
+ def configuration
67
+ @configuration ||= Configuration.new
68
+ end
69
+ end
70
+ end
71
+
72
+ require 'hoodie/core_ext/string'
73
+ require 'hoodie/core_ext/blank'
74
+ require 'hoodie/core_ext/hash'
75
+
20
76
  require 'hoodie/stash/mem_store'
21
77
  require 'hoodie/stash/disk_store'
22
78
  require 'hoodie/identity_map'
79
+ require 'hoodie/inflections'
23
80
  require 'hoodie/memoizable'
24
81
  require 'hoodie/obfuscate'
25
82
  require 'hoodie/logging'
@@ -27,6 +84,4 @@ require 'hoodie/version'
27
84
  require 'hoodie/timers'
28
85
  require 'hoodie/utils'
29
86
  require 'hoodie/stash'
30
- require 'hoodie/blank'
31
- require 'hoodie/hash'
32
87
  require 'hoodie/os'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hoodie
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.6
4
+ version: 0.4.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stefano Harding
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-28 00:00:00.000000000 Z
11
+ date: 2015-01-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: hitimes
@@ -30,84 +30,84 @@ dependencies:
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: 0.26.0
33
+ version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: 0.26.0
40
+ version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: 10.3.2
47
+ version: '0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: 10.3.2
54
+ version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: coveralls
56
+ name: yard
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - ">="
60
60
  - !ruby/object:Gem::Version
61
- version: 0.7.1
61
+ version: '0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
- version: 0.7.1
68
+ version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
- name: rspec
70
+ name: yard-redcarpet-ext
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - ">="
74
74
  - !ruby/object:Gem::Version
75
- version: 3.1.0
75
+ version: '0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
- version: 3.1.0
82
+ version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
- name: fuubar
84
+ name: redcarpet
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - ">="
88
88
  - !ruby/object:Gem::Version
89
- version: 2.0.0
89
+ version: '0'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - ">="
95
95
  - !ruby/object:Gem::Version
96
- version: 2.0.0
96
+ version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
- name: timecop
98
+ name: github-markup
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - ">="
102
102
  - !ruby/object:Gem::Version
103
- version: 0.7.1
103
+ version: '0'
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - ">="
109
109
  - !ruby/object:Gem::Version
110
- version: 0.7.1
110
+ version: '0'
111
111
  description: A collection of hipster methods and hoodie tools to make even the nerdy
112
112
  rubyist look cool
113
113
  email: riddopic@gmail.com
@@ -123,9 +123,15 @@ files:
123
123
  - Rakefile
124
124
  - hoodie.gemspec
125
125
  - lib/hoodie.rb
126
- - lib/hoodie/blank.rb
127
- - lib/hoodie/hash.rb
126
+ - lib/hoodie/configuration.rb
127
+ - lib/hoodie/core_ext/blank.rb
128
+ - lib/hoodie/core_ext/hash.rb
129
+ - lib/hoodie/core_ext/string.rb
128
130
  - lib/hoodie/identity_map.rb
131
+ - lib/hoodie/inflections.rb
132
+ - lib/hoodie/inflections/defaults.rb
133
+ - lib/hoodie/inflections/inflections.rb
134
+ - lib/hoodie/inflections/rules_collection.rb
129
135
  - lib/hoodie/logging.rb
130
136
  - lib/hoodie/memoizable.rb
131
137
  - lib/hoodie/obfuscate.rb