logger_pipe 0.3.0 → 0.3.1

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: 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