libis-tools 0.9.20 → 0.9.21
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 +4 -4
- data/README.md +36 -233
- data/Rakefile +5 -0
- data/lib/libis/tools.rb +1 -0
- data/lib/libis/tools/assert.rb +11 -0
- data/lib/libis/tools/checksum.rb +22 -5
- data/lib/libis/tools/command.rb +24 -3
- data/lib/libis/tools/config.rb +61 -33
- data/lib/libis/tools/config_file.rb +0 -1
- data/lib/libis/tools/deep_struct.rb +10 -2
- data/lib/libis/tools/extend/empty.rb +2 -2
- data/lib/libis/tools/extend/hash.rb +37 -18
- data/lib/libis/tools/extend/kernel.rb +9 -0
- data/lib/libis/tools/extend/string.rb +17 -8
- data/lib/libis/tools/logger.rb +95 -44
- data/lib/libis/tools/metadata.rb +5 -1
- data/lib/libis/tools/metadata/dublin_core_record.rb +22 -4
- data/lib/libis/tools/metadata/field_format.rb +49 -9
- data/lib/libis/tools/metadata/fix_field.rb +5 -0
- data/lib/libis/tools/metadata/mapper.rb +2 -1
- data/lib/libis/tools/metadata/mappers/flandrica.rb +8 -1
- data/lib/libis/tools/metadata/mappers/kuleuven.rb +6 -2
- data/lib/libis/tools/metadata/marc21_record.rb +1 -0
- data/lib/libis/tools/metadata/marc_record.rb +31 -12
- data/lib/libis/tools/metadata/parser/basic_parser.rb +2 -0
- data/lib/libis/tools/metadata/parser/dublin_core_parser.rb +2 -1
- data/lib/libis/tools/metadata/parser/marc21_parser.rb +2 -1
- data/lib/libis/tools/metadata/parser/marc_format_parser.rb +2 -1
- data/lib/libis/tools/metadata/parser/marc_rules.rb +2 -1
- data/lib/libis/tools/metadata/parser/marc_select_parser.rb +2 -1
- data/lib/libis/tools/metadata/parser/patch.rb +1 -0
- data/lib/libis/tools/metadata/parser/subfield_criteria_parser.rb +2 -1
- data/lib/libis/tools/metadata/sharepoint_mapping.rb +1 -0
- data/lib/libis/tools/metadata/sharepoint_record.rb +2 -0
- data/lib/libis/tools/metadata/var_field.rb +8 -0
- data/lib/libis/tools/mets_dnx.rb +61 -0
- data/lib/libis/tools/mets_file.rb +87 -604
- data/lib/libis/tools/mets_objects.rb +534 -0
- data/lib/libis/tools/parameter.rb +144 -21
- data/lib/libis/tools/thread_safe.rb +31 -0
- data/lib/libis/tools/version.rb +1 -1
- data/lib/libis/tools/xml_document.rb +18 -24
- data/libis-tools.gemspec +6 -2
- data/spec/config_spec.rb +3 -4
- data/spec/logger_spec.rb +13 -30
- data/spec/mets_file_spec.rb +17 -17
- metadata +53 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dc18f91c7fdaf317168eb91966d598fff6fd0252
|
4
|
+
data.tar.gz: 43d8f7c0f51f7e5e32b28680f53bb6f6dbb17658
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: db2e5d1f92574eaefab41674b23aac4aa116b01206eb5eeb1304482de6dba8213a00b3c3ccfd79a83be1523b7d947d07112dd445ddadfeb781176f0fefacf65d
|
7
|
+
data.tar.gz: 5983fc775104c2d592fdeacdec3c86489215275ab9f138bf72211696e049e21f093e2f25e197a722d854962753652c469972e22a4dd123af58b9dd951ce8b782
|
data/README.md
CHANGED
@@ -42,181 +42,64 @@ sections below for their names.
|
|
42
42
|
|
43
43
|
## Content
|
44
44
|
|
45
|
-
### assert
|
45
|
+
### {Object#assert}
|
46
46
|
|
47
|
-
The Object#assert method enables the assert functionality found in other languages.
|
48
|
-
|
49
|
-
If the boolean expression evaluates to false an AssertionFailure exception will be raised.
|
47
|
+
The {Object#assert} method enables the assert functionality found in other languages. Since it is defined on the
|
48
|
+
Object class, it is available on almost any class.
|
50
49
|
|
51
|
-
|
52
|
-
exception will be raised. In that case the first argument passed to the assert method is used as message and the second
|
53
|
-
argument is ignored.
|
50
|
+
### {::Libis::Tools::Checksum}
|
54
51
|
|
55
|
-
The
|
56
|
-
|
57
|
-
on.
|
52
|
+
The {::Libis::Tools::Checksum} class offers a standardized interface for calculating checksums of file
|
53
|
+
contents in different formats.
|
58
54
|
|
59
|
-
|
55
|
+
### {::Libis::Tools::Command}
|
60
56
|
|
61
|
-
|
62
|
-
|
63
|
-
assert(value > 0, 'value should be positive number')
|
64
|
-
```
|
65
|
-
and using a code block:
|
66
|
-
|
67
|
-
```ruby
|
68
|
-
require 'libis/tools/assert'
|
69
|
-
assert 'database is not idle' do
|
70
|
-
db = get_database
|
71
|
-
db.status == :IDLE
|
72
|
-
end
|
73
|
-
```
|
74
|
-
|
75
|
-
### Checksum
|
57
|
+
The {::Libis::Tools::Command} module offers a safe way to execute external commands and gives you access to the
|
58
|
+
exit status as well as standard output and standard error information. May have issues on older JRuby versions.
|
76
59
|
|
77
|
-
|
78
|
-
different formats. The actual list of supported checksum formats is in ::Libis::Tools::Checksum.CHECKSUM_TYPES. It
|
79
|
-
contains MD5, SHA-1 and SHA-2 (in 256-bit, 384-bit and 512-bit variants).
|
80
|
-
|
81
|
-
There are two ways this can be used: using a class instance or using class methods. When a class instance is used, the
|
82
|
-
desired checksum type has to be supplied when the instance is created. Each call to a checksum method will calculate the
|
83
|
-
checksum and reset the digest to prevent future calls to be affected by the current result. When a class method is used
|
84
|
-
besides the file name, the checksum type has to be supplied.
|
85
|
-
|
86
|
-
The available methods on both instance and class level are:
|
87
|
-
|
88
|
-
* digest: return the checksum as (binary) string.
|
89
|
-
* hexdigest: return the checksum as hexadecimal encoded string.
|
90
|
-
* base64digest: return the checksum as base64 encoded string.
|
91
|
-
|
92
|
-
Examples:
|
93
|
-
|
94
|
-
```ruby
|
95
|
-
require 'libis/tools/checksum'
|
96
|
-
checksum = ::Libis::Tools::Checksum.new(:MD5)
|
97
|
-
puts "Checksum: #{checksum.hexdigest(file_name)} (MD5, hex)"
|
98
|
-
```
|
99
|
-
|
100
|
-
```ruby
|
101
|
-
require 'libis/tools/checksum'
|
102
|
-
puts "Checksum: #{::Libis::Tools::Checksum.base64digest(file_name, :SHA384)} (SHA-2, 384 bit, base64)"
|
103
|
-
```
|
104
|
-
|
105
|
-
### Command
|
106
|
-
|
107
|
-
This module allows to run an external command safely and returns it's output, error messages and status. The run method
|
108
|
-
takes any number of arguments that will be used as command-line arguments. The method returns a Hash with:
|
109
|
-
|
110
|
-
* :out => an array with lines that were printed on the external program's standard out.
|
111
|
-
* :err => an array with lines that were printed on the external program's standard error.
|
112
|
-
* :status => exit code returned by the external program.
|
113
|
-
|
114
|
-
```ruby
|
115
|
-
require 'libis/tools/command'
|
116
|
-
result = ::Libis::Tools::Command.run('ls', '-l', File.absolute_path(__FILE__))
|
117
|
-
p result # => {out: [...], err: [...], status: 0}
|
118
|
-
```
|
119
|
-
|
120
|
-
or:
|
121
|
-
|
122
|
-
```ruby
|
123
|
-
require 'libis/tools/command'
|
124
|
-
include ::Libis::Tools::Command
|
125
|
-
result = run('ls', '-l', File.absolute_path(__FILE__))
|
126
|
-
p result # => {out: [...], err: [...], status: 0}
|
127
|
-
```
|
60
|
+
### {::Libis::Tools::DeepStruct}
|
128
61
|
|
129
|
-
|
130
|
-
|
62
|
+
A class that derives from OpenStruct through the RecursiveOpenStruct.
|
63
|
+
By wrapping a Hash recursively, it allows for easy access to the content by method names.
|
131
64
|
|
132
|
-
###
|
65
|
+
### {::Libis::Tools::ConfigFile}
|
133
66
|
|
134
|
-
A class
|
135
|
-
|
67
|
+
A base class for {::Libis::Tools::Config}, but useable on it's own.
|
68
|
+
It extends the DeepStruct with loading from and saving to YAML files.
|
136
69
|
|
137
|
-
###
|
70
|
+
### {::Libis::Tools::Config}
|
138
71
|
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
```ruby
|
143
|
-
require 'libis/tools/config_file'
|
144
|
-
cfg_file = ::Libis::Tools::ConfigFile.new
|
145
|
-
cfg_file << {foo: 'bar'}
|
146
|
-
cfg_file.my_value = 10
|
147
|
-
p cfg_file[:my_value] # => 10
|
148
|
-
cfg_file{:my_text] = 'abc'
|
149
|
-
p cfg_file['my_text'] # => 'abc'
|
150
|
-
p cfg_file.to_hash # => { :foo => 'bar', 'my_value' => 10, :my_text => 'abc' }
|
151
|
-
cfg >> 'my_config.yml'
|
152
|
-
```
|
153
|
-
### Config
|
72
|
+
This Singleton class is a convenience class for easy configuration maintenance and loading.
|
73
|
+
It also initializes a default logger.
|
154
74
|
|
155
|
-
|
156
|
-
DeepStruc, it supports code defaults and loading configurations from multiple YAML files containing ERB statements.
|
157
|
-
The Config class follows the Singleton pattern and behaves like a Hash/OpenStruct/HashWithIndifferentAccess with
|
158
|
-
recursion over hashes and arrays. It also initializes a default Logger instance.
|
75
|
+
### {::Libis::Tools::Logger}
|
159
76
|
|
160
|
-
|
161
|
-
call or via the Hash operator using the parameter name either as a string or a symbol.
|
77
|
+
The ::Libis::Tools::Logger module adds support for logging functionality to any class.
|
162
78
|
|
163
|
-
|
79
|
+
## {::Libis::Tools::Metadata}
|
164
80
|
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
cfg << 'my_config.yml'
|
169
|
-
cfg['my_value'] = 10
|
170
|
-
p cfg.instance.my_value # => 10
|
171
|
-
cfg.instance.my_text = 'abc'
|
172
|
-
p cfg[:my_text] # => 'abc'
|
173
|
-
p cfg.logger.warn('message') # => W, [2015-03-16T12:51:01.180548 #28935] WARN -- : message
|
174
|
-
```
|
81
|
+
This gem also provides some modules and classes that assist in working with metadata. There are classes that allow to
|
82
|
+
create and/or read metadata for MARC(21), Dublin Core and SharePoint. These classes all live in the
|
83
|
+
Libis::Tools::Metadata namespace.
|
175
84
|
|
176
|
-
###
|
85
|
+
### MARC
|
177
86
|
|
178
|
-
The
|
179
|
-
|
180
|
-
|
181
|
-
supplied arguments appended.
|
87
|
+
The classes {::Libis::Tools::Metadata::MarcRecord} and it's child class {::Libis::Tools::Metadata::Marc21Record} are
|
88
|
+
mainly built for reading MARC(21) records. Most of the class logic is in the base class
|
89
|
+
{::Libis::Tools::Metadata::MarcRecord MarcRecord}, which is incomplete and should be considered an abstract class.
|
182
90
|
|
183
|
-
|
184
|
-
the
|
185
|
-
|
91
|
+
{::Libis::Tools::Metadata::Marc21Record Marc21Record} on the other hand only contains the logic to parse the XML data
|
92
|
+
into the internal structure. A {::Libis::Tools::Metadata::MarcRecord MarcRecord} is created by supplying it an XML node
|
93
|
+
(from Nokogiri or {::Libis::Tools::XmlDocument}) that contains child nodes with the MARC data of a single record.
|
186
94
|
|
187
|
-
|
188
|
-
evaluated and if true debug, info and warning messages will not be printed.
|
95
|
+
The code will strip namespaces from the input in order to greatly simplify working with the XML.
|
189
96
|
|
190
|
-
|
97
|
+
## {::Libis::Tools::Parameter} and {::Libis::Tools::ParameterContainer}
|
191
98
|
|
192
|
-
|
193
|
-
|
194
|
-
class TestLogger
|
195
|
-
include ::Libis::Tools::Logger
|
196
|
-
attr_accessor :options, name
|
197
|
-
def initialize
|
198
|
-
@options = {}
|
199
|
-
@name = nil
|
200
|
-
end
|
201
|
-
end
|
202
|
-
tl = TestLogger.new
|
203
|
-
tl.debug 'message'
|
204
|
-
tl.options[:quiet] = true
|
205
|
-
tl.warn 'message'
|
206
|
-
::Libis::Tools::Config.appname = 'TestApplication'
|
207
|
-
tl.error 'huge error: [%d] %s', 1000, 'Exit'
|
208
|
-
tl.name = 'TestClass'
|
209
|
-
tl.options[:quiet] = false
|
210
|
-
tl.info 'Running application: %s', ::Libis::Tools::Config.appname
|
211
|
-
```
|
212
|
-
produces:
|
213
|
-
<pre>
|
214
|
-
D, [...] DEBUG -- TestLogger: message
|
215
|
-
E, [...] ERROR -- TestApplication: huge error: [1000] Exit
|
216
|
-
I, [...] INFO -- TestClass: Running application TestApplication
|
217
|
-
</pre>
|
99
|
+
The class {::Libis::Tools::Parameter} and the {::Libis::Tools::ParameterContainer} module provide a simple framework for
|
100
|
+
instance variables that are type-safe and can easily be documented and provide defaults.
|
218
101
|
|
219
|
-
### XmlDocument
|
102
|
+
### {::Libis::Tools::XmlDocument}
|
220
103
|
|
221
104
|
Class that embodies most used features of Nokogiri, Nori and Gyoku in one convenience class. The Nokogiri document is
|
222
105
|
stored in the class variable 'document' and can be accessed and manipulated directly - if required. The class supports
|
@@ -300,87 +183,7 @@ produces:
|
|
300
183
|
<email>harry.potter@hogwarts.edu</email>
|
301
184
|
<email>hpotter@JKRowling.com</email>
|
302
185
|
</patron>
|
303
|
-
|
304
|
-
## Metadata
|
305
|
-
|
306
|
-
This gem also provides some modules and classes that assist in working with metadata. There are classes that allow to
|
307
|
-
create and/or read metadata for MARC(21), Dublin Core and SharePoint. These classes all live in the
|
308
|
-
Libis::Tools::Metadata namespace.
|
309
|
-
|
310
|
-
### MARC
|
311
|
-
|
312
|
-
The classes Libis::Tools::Metadata::MarcRecord and it's child class Libis::Tools::Metadata::Marc21Record are mainly
|
313
|
-
built for reading MARC(21) records. Most of the class logic is in the base class MarcRecord, which is incomplete and
|
314
|
-
should be considered an abstract class. Marc21Record on the other hand only contains the logic to parse the XML data
|
315
|
-
into the internal structure. A MarcRecord is created by supplying it an XML node (from Nokogiri or
|
316
|
-
Libis::Tools::XmlDocument) that contains child nodes with the MARC data of a single record. The code will strip
|
317
|
-
namespaces from the input in order to greatly simplify working with the XML.
|
318
|
-
|
319
|
-
## Parameter
|
320
|
-
|
321
|
-
The class ::Libis::Tools::Parameter and the ::Libis::Tools::ParameterContainer module provide a simple framework for
|
322
|
-
instance variables that are type-safe and can easily be documented and provide defaults.
|
323
186
|
|
324
|
-
To use these parameters a class should include the ::Libis::Tools::ParameterContainer module and add 'parameter'
|
325
|
-
statements to the body of the class definition. It takes only one mandatory argument which is a Hash. The first entry is
|
326
|
-
interpreted as '<name> => <default>'. The name for the parameter should be unique and the default value can be any value
|
327
|
-
of type TrueClass, FalseClass, String, Integer, Float, Date, Time, DateTime, Array, Hash or NilClass.
|
328
|
-
|
329
|
-
The second up to last Hash entries are optional properties for the parameter. These are:
|
330
|
-
|
331
|
-
* datatype: the type of values the parameter will accept. Valid values are:
|
332
|
-
|
333
|
-
* 'bool' or 'boolean'
|
334
|
-
* 'string'
|
335
|
-
* 'int'
|
336
|
-
* 'float'
|
337
|
-
* 'datetime'
|
338
|
-
* 'array'
|
339
|
-
* 'hash'
|
340
|
-
|
341
|
-
Any other value will raise a RuntimeError when the parameter is used. The value is case-insensitive and if not present,
|
342
|
-
the datatype will be derived from the default value with 'string' being the default for NilClass. In any case the
|
343
|
-
parameter will try its best to convert supplied values to the proper data type. For instance, an Integer parameter will
|
344
|
-
accept 3, 3.1415, '3' and Rational(10/3) as valid values and store them as the integer value 3. Likewise DateTime
|
345
|
-
parameters will try to interprete date and time strings.
|
346
|
-
|
347
|
-
* description: any descriptive text you want to add to clarify what this parameter is used for. Any tool can ask the
|
348
|
-
class for its parameters and - for instance - can use this property to provide help in a GUI when asking the user for
|
349
|
-
input.
|
350
|
-
|
351
|
-
* constraint: adds a validation condition to the parameter. The condition value can be:
|
352
|
-
|
353
|
-
* an array: only values that convert to a value in the list are considered valid.
|
354
|
-
* a range: only values that convert to a value in the given range are considered valid.
|
355
|
-
* a regular expression: only values that match the regular expression are considered valid.
|
356
|
-
* a string: only values that are '==' to the constraint are considered valid.
|
357
|
-
|
358
|
-
* frozen: if set to true, prevents the class instance to set the parameter to any value other than the default. Mostly
|
359
|
-
useful when a derived class needs a parameter in the parent class to be set to a specific value. Setting a value on
|
360
|
-
a frozen parameter with the 'parameter(name,value)' method throws a ::Libis::Tools::ParameterFrozenError. The '[]='
|
361
|
-
method silently ignores the exception. In any case the default value will not be changed.
|
362
|
-
|
363
|
-
* options: a hash with any additional properties that you want to associate to the parameter. Any key-value pair in this
|
364
|
-
hash is added to the retrievable properties of the parameter. Likewise any property defined, that is not in the list of
|
365
|
-
known properties is added to the options hash. In this aspect the ::Libis::Tools::Parameter class behaves much like an
|
366
|
-
OpenStruct even though it is implemented as a Struct.
|
367
|
-
|
368
|
-
Besides enabling the 'parameter' class method to define parameters, the ::Libis::Tools::ParameterContainer add the class
|
369
|
-
method 'parameters' that will return a Hash with parameter names as keys and their respective parameter definitions as
|
370
|
-
values. On each class instance the 'parameter' method is added and serves as both getter and setter for parameter values:
|
371
|
-
With only one argument (the parameter name) it returns the current value for the parameter, but the optional second
|
372
|
-
argument will cause the method to set the parameter value. If the parameter is not available or the given value is not
|
373
|
-
a valid value for the parameter, the method will return the special constant ::Libis::ParameterContainer::NO_VALUE. The
|
374
|
-
methods '[]' and '[]=' serve as aliases for the getter and setter calls.
|
375
|
-
|
376
|
-
Additionally two protected methods are available on the instance:
|
377
|
-
* 'parameters': returns the Hash that keeps track of the current parameter values for the instance.
|
378
|
-
* 'get_parameter_defintion': retrieves the parameter definition from the instance's class for the given parameter name.
|
379
|
-
|
380
|
-
Any class that derives from a class that included the ::Libis::Tools::ParameterContainer module will automatically
|
381
|
-
inherit all parameter definitions from all of it's base classes and can override any of these parameter definitions e.g.
|
382
|
-
to change the default values for the parameter.
|
383
|
-
|
384
187
|
## Contributing
|
385
188
|
|
386
189
|
1. Fork it ( https://github.com/Kris-LIBIS/LIBIS_Tools/fork )
|
data/Rakefile
CHANGED
data/lib/libis/tools.rb
CHANGED
@@ -12,6 +12,7 @@ module Libis
|
|
12
12
|
autoload :Logger, 'libis/tools/logger'
|
13
13
|
autoload :MetsFile, 'libis/tools/mets_file'
|
14
14
|
autoload :Parameter, 'libis/tools/parameter'
|
15
|
+
autoload :ThreadSafe, 'libis/tools/thread_safe'
|
15
16
|
autoload :XmlDocument, 'libis/tools/xml_document'
|
16
17
|
|
17
18
|
end
|
data/lib/libis/tools/assert.rb
CHANGED
@@ -19,6 +19,17 @@ class Object
|
|
19
19
|
#
|
20
20
|
# Examples:
|
21
21
|
#
|
22
|
+
# require 'libis/tools/assert'
|
23
|
+
# assert(value > 0, 'value should be positive number')
|
24
|
+
#
|
25
|
+
# # using a code block:
|
26
|
+
# require 'libis/tools/assert'
|
27
|
+
# assert 'database is not idle' do
|
28
|
+
# db = get_database
|
29
|
+
# db.status == :IDLE
|
30
|
+
# end
|
31
|
+
#
|
32
|
+
# # using $DEBUG:
|
22
33
|
# $DEBUG = nil
|
23
34
|
# assert false, 'assert 1' # nothing happens
|
24
35
|
# $DEBUG = true
|
data/lib/libis/tools/checksum.rb
CHANGED
@@ -11,16 +11,33 @@ module Libis
|
|
11
11
|
# All methods are available on the class and on the instance. The instance has to be initialized with a checksum
|
12
12
|
# algorithm and therefore the instance methods do not have to specify the checksum type.
|
13
13
|
#
|
14
|
+
# There are two ways this can be used: using a class instance or using class methods. When a class instance is used,
|
15
|
+
# the desired checksum type has to be supplied when the instance is created. Each call to a checksum method will
|
16
|
+
# calculate the checksum and reset the digest to prevent future calls to be affected by the current result. When a
|
17
|
+
# class method is used besides the file name, the checksum type has to be supplied.
|
18
|
+
#
|
19
|
+
# Examples:
|
20
|
+
#
|
21
|
+
# require 'libis/tools/checksum'
|
22
|
+
# checksum = ::Libis::Tools::Checksum.new(:MD5)
|
23
|
+
# puts "Checksum: #{checksum.hexdigest(file_name)} (MD5, hex)"
|
24
|
+
#
|
25
|
+
# require 'libis/tools/checksum'
|
26
|
+
# puts "Checksum: #{::Libis::Tools::Checksum.base64digest(file_name, :SHA384)} (SHA-2, 384 bit, base64)"
|
14
27
|
class Checksum
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
28
|
+
# All supported checksum types
|
29
|
+
CHECKSUM_TYPES = [:MD5, :SHA1, :SHA256, :SHA384, :SHA512]
|
30
|
+
|
31
|
+
# @!visibility private
|
32
|
+
# noinspection RubyResolve
|
33
|
+
unless defined? JRUBY_VERSION
|
34
|
+
checksum_types = CHECKSUM_TYPES
|
35
|
+
checksum_types << :RMD160
|
19
36
|
end
|
20
37
|
|
21
38
|
# Create instance for a given checksum algorithm.
|
22
39
|
#
|
23
|
-
# @param [Symbol] type checksum algorithm; one of {
|
40
|
+
# @param [Symbol] type checksum algorithm; one of {CHECKSUM_TYPES}
|
24
41
|
def initialize(type)
|
25
42
|
@hasher = self.class.get_hasher(type)
|
26
43
|
end
|
data/lib/libis/tools/command.rb
CHANGED
@@ -4,6 +4,27 @@ require 'open3'
|
|
4
4
|
module Libis
|
5
5
|
module Tools
|
6
6
|
|
7
|
+
# This module allows to run an external command safely and returns it's output, error messages and status.
|
8
|
+
# The run method takes any number of arguments that will be used as command-line arguments. The method returns
|
9
|
+
# a Hash with:
|
10
|
+
# * :out => an array with lines that were printed on the external program's standard out.
|
11
|
+
# * :err => an array with lines that were printed on the external program's standard error.
|
12
|
+
# * :status => exit code returned by the external program.
|
13
|
+
#
|
14
|
+
# Examples:
|
15
|
+
#
|
16
|
+
# require 'libis/tools/command'
|
17
|
+
# result = ::Libis::Tools::Command.run('ls', '-l', File.absolute_path(__FILE__))
|
18
|
+
# p result # => {out: [...], err: [...], status: 0}
|
19
|
+
#
|
20
|
+
# require 'libis/tools/command'
|
21
|
+
# include ::Libis::Tools::Command
|
22
|
+
# result = run('ls', '-l', File.absolute_path(__FILE__))
|
23
|
+
# p result # => {out: [...], err: [...], status: 0}
|
24
|
+
#
|
25
|
+
# Note that the Command class uses Open3#popen3 internally. All arguments supplied to Command#run are passed to
|
26
|
+
# the popen3 call. Unfortunately some older JRuby versions have some known issues with popen3. Please use and
|
27
|
+
# test carefully in JRuby environments.
|
7
28
|
module Command
|
8
29
|
|
9
30
|
# Run an external program and return status, stdout and stderr.
|
@@ -12,9 +33,9 @@ module Libis
|
|
12
33
|
# @param [String] cmd program name
|
13
34
|
# @param [Array<String>] opts optional list of command line arguments
|
14
35
|
# @return [Hash] a Hash with:
|
15
|
-
# *
|
16
|
-
# *
|
17
|
-
# *
|
36
|
+
# * :status (Integer) - the exit status of the command
|
37
|
+
# * :out (Array<String>) - the stdout output of the command
|
38
|
+
# * :err (Array<String>)- the stderr output of the command
|
18
39
|
def self.run(cmd, *opts)
|
19
40
|
result = {
|
20
41
|
status: 999,
|
data/lib/libis/tools/config.rb
CHANGED
@@ -2,18 +2,19 @@
|
|
2
2
|
require 'singleton'
|
3
3
|
require 'yaml'
|
4
4
|
require 'erb'
|
5
|
-
require '
|
5
|
+
require 'logging'
|
6
6
|
|
7
|
-
|
7
|
+
require_relative 'config_file'
|
8
8
|
|
9
9
|
module Libis
|
10
10
|
module Tools
|
11
11
|
|
12
|
-
# The Config class is a convenience class for easy configuration maintenance, loading and saving.
|
13
|
-
# It
|
14
|
-
#
|
15
|
-
#
|
16
|
-
#
|
12
|
+
# The Singleton Config class is a convenience class for easy configuration maintenance, loading and saving.
|
13
|
+
# It also initializes a default logger and supports creating extra loggers. The logging infrastructure is based on
|
14
|
+
# the {http://www.rubydoc.info/gems/logging/Logging ::Logging} gem and supports the {::Libis::Tools::Logger} class.
|
15
|
+
#
|
16
|
+
# For the configuration parameters, it supports code defaults, loading configurations from multiple YAML files
|
17
|
+
# containing ERB statements. The Config class behaves like a Hash/OpenStruct/HashWithIndifferentAccess.
|
17
18
|
#
|
18
19
|
# The parameters can be accessed by getter/setter method or using the Hash syntax:
|
19
20
|
#
|
@@ -23,7 +24,7 @@ module Libis
|
|
23
24
|
# p cfg.instance.my_value # => 10
|
24
25
|
# cfg.instance.my_text = 'abc'
|
25
26
|
# p cfg[:my_text] # => 'abc'
|
26
|
-
# p cfg.logger.warn('message') # => W, [2015-03-16T12:51:01.180548 #
|
27
|
+
# p cfg.logger.warn('message') # => W, [2015-03-16T12:51:01.180548 #123.456] WARN : message
|
27
28
|
#
|
28
29
|
class Config
|
29
30
|
include Singleton
|
@@ -33,6 +34,7 @@ module Libis
|
|
33
34
|
private
|
34
35
|
|
35
36
|
# For each configuration parameter, the value can be accessed via the class or the Singleton instance.
|
37
|
+
# The class diverts to the instance automatically.
|
36
38
|
def method_missing(name, *args, &block)
|
37
39
|
result = instance.send(name, *args, &block)
|
38
40
|
self === result ? self : result
|
@@ -40,6 +42,7 @@ module Libis
|
|
40
42
|
|
41
43
|
end
|
42
44
|
|
45
|
+
# Instance method that allows to access the configuration parameters by method.
|
43
46
|
def method_missing(name, *args, &block)
|
44
47
|
result = config.send(name, *args, &block)
|
45
48
|
self === config ? self : result
|
@@ -50,8 +53,10 @@ module Libis
|
|
50
53
|
# The file paths and Hashes are memorised and loaded again by the {#reload} methods.
|
51
54
|
# @param [String,Hash] file_or_hash
|
52
55
|
def <<(file_or_hash)
|
53
|
-
|
54
|
-
|
56
|
+
sync do
|
57
|
+
@config.send('<<', (file_or_hash)) { |data| @sources << data }
|
58
|
+
self
|
59
|
+
end
|
55
60
|
end
|
56
61
|
|
57
62
|
# Load all files and Hashes again.
|
@@ -59,10 +64,12 @@ module Libis
|
|
59
64
|
# Will not reset the configuration parameters. Parameters set directly on the
|
60
65
|
# configuration are kept intact unless they also exist in the files or hashes in which case they will be overwritten.
|
61
66
|
def reload
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
67
|
+
sync do
|
68
|
+
sources = @sources.dup
|
69
|
+
@sources.clear
|
70
|
+
sources.each { |f| self << f }
|
71
|
+
self
|
72
|
+
end
|
66
73
|
end
|
67
74
|
|
68
75
|
# Clear data and load all files and Hashes again.
|
@@ -71,8 +78,10 @@ module Libis
|
|
71
78
|
# added directly (not via file or hash) will no longer be available. Parameters set explicitly that also exist in
|
72
79
|
# the files or hashes will be reset to the values in those files and hashes.
|
73
80
|
def reload!
|
74
|
-
|
75
|
-
|
81
|
+
sync do
|
82
|
+
@config.clear!
|
83
|
+
reload
|
84
|
+
end
|
76
85
|
end
|
77
86
|
|
78
87
|
# Clear all data.
|
@@ -80,38 +89,57 @@ module Libis
|
|
80
89
|
# Not only all configuration parameters are deleted, but also the memorized list of loaded files
|
81
90
|
# and hashes are cleared and the logger configuration is reset to it's default status.
|
82
91
|
def clear!
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
92
|
+
sync do
|
93
|
+
@config.clear!
|
94
|
+
@sources = Array.new
|
95
|
+
self.logger
|
96
|
+
self
|
97
|
+
end
|
88
98
|
end
|
89
99
|
|
90
|
-
#
|
91
|
-
#
|
92
|
-
#
|
100
|
+
# Gets the default ::Logging formatter.
|
101
|
+
#
|
102
|
+
# This in an instance of a layout that prints in the default message format.
|
103
|
+
#
|
104
|
+
# The default layout prints log lines like this:
|
93
105
|
#
|
94
|
-
# <first char of severity>, [<timestamp
|
106
|
+
# <first char of severity>, [<timestamp> #<process-id>.<thread-id] <severity> : <message>
|
95
107
|
#
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
108
|
+
def get_log_formatter
|
109
|
+
# noinspection RubyResolve
|
110
|
+
::Logging::Layouts::Pattern.new(DEFAULT_LOG_LAYOUT_PARAMETERS)
|
111
|
+
end
|
112
|
+
|
113
|
+
def logger(name = nil)
|
114
|
+
sync do
|
115
|
+
name ||= :root
|
116
|
+
logger = ::Logging.logger[name]
|
117
|
+
logger.appenders = ::Logging.appenders.stdout(DEFAULT_LOG_LAYOUT_PARAMETERS) if logger.appenders.empty?
|
118
|
+
logger
|
102
119
|
end
|
103
120
|
end
|
104
121
|
|
105
|
-
attr_accessor :
|
122
|
+
attr_accessor :config, :sources
|
106
123
|
|
107
124
|
protected
|
108
125
|
|
109
126
|
def initialize(hash = nil, opts = {})
|
127
|
+
@mutex = ReentrantMutex.new
|
110
128
|
@config = ConfigFile.new(hash, opts)
|
111
129
|
self.clear!
|
112
130
|
end
|
113
131
|
|
132
|
+
def sync(&block)
|
133
|
+
@mutex.synchronize(&block)
|
134
|
+
end
|
135
|
+
|
136
|
+
::Logging::init
|
137
|
+
# noinspection RubyResolve
|
138
|
+
DEFAULT_LOG_LAYOUT_PARAMETERS = {
|
139
|
+
pattern: "%.1l, [%d #%p.%t] %#{::Logging::MAX_LEVEL_LENGTH}l : %m\n",
|
140
|
+
date_pattern: '%Y-%m-%dT%H:%M:%S.%L'
|
141
|
+
}
|
142
|
+
|
114
143
|
end
|
115
144
|
end
|
116
145
|
end
|
117
|
-
|