logger_pipe 0.3.0 → 0.3.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fd276efaaeaec72d772ef2850226516e2fdbd75d
4
- data.tar.gz: 3a8b2f21d9a5e920db4dd4ead277e89a78a0941d
3
+ metadata.gz: d79758d6c65671d213b290ca4e08150454226cfd
4
+ data.tar.gz: 94d6e1e1dce45bb19b42ba023516435fc15fa7c5
5
5
  SHA512:
6
- metadata.gz: bf66b0f214bb5dbb5370cfec1e4339bffd2d9af0af26354e583e3f35b0732d60496b38eabb753a4b168112f87c1dfe8629fcf57a26898bd885c3d7e2396f3201
7
- data.tar.gz: d28ec1066da06d0759b41b727e2ff31f684b815f27e74193143d248908ff0c8ceafaca9854af359d3d835f284eaafe1624d4c38bb34ae565a9dc6d3bb32f4106
6
+ metadata.gz: 5adaebe24771bb24c89a2513826a51e6b62426bf25d593e74c12250895c7c544a9899b1d0bef46e5ac2436be42a7e9a5d573151210a1302ed69bf611b6cdc7ba
7
+ data.tar.gz: df6264bee36af034611c03a4af30cc1af87b8ea956d99103ebcd8e36575d24263a65e8b38c786155b3056ea9c6957e01ad8eda66b7c8b67a39a787a9ac0e8438
data/.rspec CHANGED
@@ -1,2 +1,2 @@
1
- --format documentation
1
+ --format Fuubar
2
2
  --color
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # LoggerPipe
1
+ # LoggerPipe [![Build Status](https://travis-ci.org/groovenauts/logger_pipe.svg)](https://travis-ci.org/groovenauts/logger_pipe)
2
2
 
3
3
  TODO: Write a gem description
4
4
 
@@ -3,7 +3,17 @@ require "logger_pipe/version"
3
3
  module LoggerPipe
4
4
  autoload :Runner, "logger_pipe/runner"
5
5
 
6
+ SOURCES = [:none, :stdout, :stderr, :both].freeze
7
+
6
8
  class << self
9
+ # run
10
+ # @param [Logger] logger
11
+ # @param [String] cmd Command to run on shell
12
+ # @param [Hash] options
13
+ # @option options [Integer] :timeout Seconds, default is nil.
14
+ # @option options [true|false] :dry_run If true given, command is not run actually
15
+ # @option options [Symbol] :returns Which output is used as return, one of :none, :stdout, :stderr, :both
16
+ # @option options [Symbol] :logging Which output is written to logger, one of :none, :stdout, :stderr, :both
7
17
  def run(logger, cmd, options = {})
8
18
  Runner.new(logger, cmd, options).execute
9
19
  end
@@ -16,11 +16,14 @@ module LoggerPipe
16
16
 
17
17
  class Runner
18
18
  attr_accessor :logger, :cmd, :timeout
19
+ attr_accessor :returns, :logging
19
20
 
20
21
  def initialize(logger, cmd, options = {})
21
22
  @logger, @cmd = logger, cmd
22
23
  @timeout = options[:timeout]
23
24
  @dry_run = options[:dry_run]
25
+ @returns = options[:returns] || :stdout # :none, :stdout, :stderr, :both
26
+ @logging = options[:logging] || :both # :none, :stdout, :stderr, :both
24
27
  end
25
28
 
26
29
  def execute
@@ -28,35 +31,33 @@ module LoggerPipe
28
31
  logger.info("dry run: #{cmd}")
29
32
  return nil
30
33
  end
31
- logger.info("executing: #{cmd}")
32
34
  @buf = []
33
35
  # systemをタイムアウトさせることはできないので、popenの戻り値を使っています。
34
36
  # see http://docs.ruby-lang.org/ja/2.0.0/class/Timeout.html
35
37
  @com, @pid = nil, nil
36
- stderr_buffer do |stderr_fp|
37
- timeout do
38
+ setup do |actual_cmd, log_enable|
39
+ logger.info("executing: #{actual_cmd}")
38
40
 
41
+ timeout do
39
42
  # popenにブロックを渡さないと$?がnilになってしまうので敢えてブロックで処理しています。
40
- @com = IO.popen("#{cmd} 2> #{stderr_fp.path}") do |com|
43
+ @com = IO.popen(actual_cmd) do |com|
41
44
  @com = com
42
45
  @pid = com.pid
43
46
  while line = com.gets
44
47
  @buf << line
45
- logger.debug(line.chomp)
48
+ logger.debug(line.chomp) if log_enable
46
49
  end
47
50
  end
48
51
  if $?.exitstatus == 0
49
- logging_stderr(stderr_fp)
50
- logger.info("\e[32mSUCCESS: %s\e[0m" % [cmd])
51
- return @buf.join
52
+ logger.info("\e[32mSUCCESS: %s\e[0m" % [actual_cmd])
53
+ return (returns == :none) ? nil : @buf.join
52
54
  else
53
- logging_stderr(stderr_fp)
54
- msg = "\e[31mFAILURE: %s\e[0m" % [cmd]
55
+ msg = "\e[31mFAILURE: %s\e[0m" % [actual_cmd]
55
56
  logger.error(msg)
56
57
  raise Failure.new(msg, @buf)
57
58
  end
58
-
59
59
  end
60
+
60
61
  end
61
62
  end
62
63
 
@@ -88,19 +89,46 @@ module LoggerPipe
88
89
  end
89
90
  end
90
91
 
91
- def stderr_buffer
92
- Tempfile.open("logger_pipe.stderr.log") do |f|
93
- f.close
94
- return block_given? ? yield(f) : nil
92
+ def setup
93
+ raise ArgumentError, "Invalid option :returns #{returns.inspect}" unless SOURCES.include?(returns)
94
+ raise ArgumentError, "Invalid option :logging #{logging.inspect}" unless SOURCES.include?(logging)
95
+ if (returns == :both) && ([:stdout, :stderr].include?(logging))
96
+ raise ArgumentError, "Can' set logging: #{logging.inspect} with returns: #{returns.inspect}"
97
+ elsif (returns == :none) || (logging == :none) || (returns == logging)
98
+ actual_cmd =
99
+ case logging
100
+ when :none then
101
+ case returns
102
+ when :none then "#{cmd} 1>/dev/null 2>/dev/null"
103
+ when :stdout then "#{cmd} 2>/dev/null"
104
+ when :stderr then "#{cmd} 2>&1 1>/dev/null"
105
+ when :both then "#{cmd} 2>&1"
106
+ end
107
+ when :stdout then "#{cmd} 2>/dev/null"
108
+ when :stderr then "#{cmd} 2>&1 1>/dev/null"
109
+ when :both then "#{cmd} 2>&1"
110
+ end
111
+ return block_given? ? yield(actual_cmd, logging != :none) : nil
112
+ else
113
+ Tempfile.open("logger_pipe.stderr.log") do |f|
114
+ f.close
115
+ actual_cmd =
116
+ case returns
117
+ when :stdout then "#{cmd} 2>#{f.path}"
118
+ when :stderr then "#{cmd} 2>&1 1>#{f.path}"
119
+ end
120
+ begin
121
+ return block_given? ? yield(actual_cmd, logging == :both) : nil
122
+ ensure
123
+ logging_subfile(f)
124
+ end
125
+ end
95
126
  end
96
127
  end
97
128
 
98
- def logging_stderr(f)
129
+ def logging_subfile(f)
99
130
  f.open
100
- c = f.read
101
- if !c.nil? && !c.empty?
102
- logger.info("--- begin stderr ---\n#{c}\n--- end stderr ---")
103
- end
131
+ logger.info("--- begin stderr ---\n%s\n--- end stderr ---" % f.read)
104
132
  end
105
133
  end
106
134
 
@@ -1,3 +1,3 @@
1
1
  module LoggerPipe
2
- VERSION = "0.3.0"
2
+ VERSION = "0.3.1"
3
3
  end
@@ -30,7 +30,7 @@ describe LoggerPipe do
30
30
  it "logging output" do
31
31
  LoggerPipe.run(logger, cmd)
32
32
  msg = buffer.string
33
- expect(msg.lines.length).to eq 4
33
+ expect(msg.lines.length).to be >= 4
34
34
  expect(msg.lines[0]).to match /executing: #{Regexp.escape(cmd)}/
35
35
  expect(msg.lines[1]).to match /Foo: /
36
36
  expect(msg.lines[2]).to match /Bar: /
@@ -38,7 +38,7 @@ describe LoggerPipe do
38
38
  end
39
39
  end
40
40
 
41
- context "stderr" do
41
+ context "stderr" do # default options are {return: :stdout, logging: :both}
42
42
  let(:cmd){ File.expand_path("../stderr_test.sh", __FILE__) }
43
43
  it "returns STDOUT on success" do
44
44
  res = LoggerPipe.run(logger, "#{cmd} 0")
@@ -56,6 +56,62 @@ describe LoggerPipe do
56
56
  end
57
57
  end
58
58
 
59
+ context ":returns and :logging" do
60
+ {
61
+ # [:returns, :logging] => [return of LoggerPipe.run, logging expectations]
62
+ [:none , :none ] => [nil , {foo: false, bar: false, baz: false}], # OK
63
+ [:none , :stdout] => [nil , {foo: true , bar: false, baz: true }], # OK
64
+ [:none , :stderr] => [nil , {foo: false, bar: true , baz: false}], # OK
65
+ [:none , :both ] => [nil , {foo: true , bar: true , baz: true }], # OK
66
+ [:stdout, :none ] => ["foo\nbaz\n" , {foo: false, bar: false, baz: false}], # OK
67
+ [:stdout, :stdout] => ["foo\nbaz\n" , {foo: true , bar: false, baz: true }], # BINGO
68
+ [:stdout, :stderr] => ["foo\nbaz\n" , {foo: false, bar: true , baz: false}], # NOT REALTIME
69
+ [:stdout, :both ] => ["foo\nbaz\n" , {foo: true , bar: true , baz: true }], # NOT REALTIME # DEFAULT
70
+ [:stderr, :none ] => ["bar\n" , {foo: false, bar: false, baz: false}], # OK
71
+ [:stderr, :stdout] => ["bar\n" , {foo: true , bar: false, baz: true }], # NOT REALTIME
72
+ [:stderr, :stderr] => ["bar\n" , {foo: false, bar: true , baz: false}], # BINGO
73
+ [:stderr, :both ] => ["bar\n" , {foo: true , bar: true , baz: true }], # NOT REALTIME
74
+ [:both , :none ] => ["foo\nbar\nbaz\n", {foo: false, bar: false, baz: false}], # OK
75
+ [:wrong , :none ] => :invalid,
76
+ [:none , :wrong ] => :invalid,
77
+ [:both , :stdout] => :invalid,
78
+ [:both , :stderr] => :invalid,
79
+ [:both , :both ] => ["foo\nbar\nbaz\n", {foo: true , bar: true , baz: true }], # BINGO
80
+ }.each do |options_values, expected|
81
+ options = {
82
+ returns: options_values.first,
83
+ logging: options_values.last,
84
+ }
85
+ context options do
86
+ let(:cmd){ File.expand_path("../stderr_test.sh", __FILE__) }
87
+ if expected == :invalid
88
+ it "raise invalid argument error" do
89
+ expect{ LoggerPipe.run(logger, "#{cmd} 0", options) }.to raise_error(ArgumentError)
90
+ end
91
+ else
92
+ it "returns STDOUT on success" do
93
+ res = LoggerPipe.run(logger, "#{cmd} 0", options)
94
+ expect(res).to eq expected.first
95
+ expected.last.each do |key, value|
96
+ m = value ? :to : :to_not
97
+ expect(buffer.string).send(m, match(/#{key}\n/))
98
+ end
99
+ end
100
+
101
+ it "buffer include stderr content on error" do
102
+ expect{
103
+ LoggerPipe.run(logger, "#{cmd} 1")
104
+ }.to raise_error(LoggerPipe::Failure)
105
+ # puts buffer.string
106
+ expect(buffer.string).to match /bar\n/
107
+ end
108
+ end
109
+ end
110
+
111
+ end
112
+ end
113
+
114
+
59
115
  context "dry_run: true" do
60
116
  let(:cmd){ "date +'Foo: %Y-%m-%dT%H:%M:%S'; sleep 1; date +'Bar: %Y-%m-%dT%H:%M:%S'" }
61
117
  it "returns nil" do
@@ -81,7 +137,7 @@ describe LoggerPipe do
81
137
  it "failure" do
82
138
  LoggerPipe.run(logger, cmd) rescue nil
83
139
  msg = buffer.string
84
- expect(msg.lines.length).to eq 3
140
+ expect(msg.lines.length).to be >= 3
85
141
  expect(msg.lines[0]).to match /executing: #{Regexp.escape(cmd)}/
86
142
  expect(msg.lines[1]).to match /Foo: /
87
143
  expect(msg.lines[2]).to match /FAILURE: date \+'Foo: /
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logger_pipe
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - akima