Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue #572: make kernel warn configurable #579

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
37 changes: 33 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ Note: `:only` regexp patterns are evaluated only against relative **file** paths

All the following options can be set through the `Listen.to` after the directory path(s) params.

```ruby
``` ruby
ignore: [%r{/foo/bar}, /\.pid$/, /\.coffee$/] # Ignore a list of paths
# default: See DEFAULT_IGNORED_FILES and DEFAULT_IGNORED_EXTENSIONS in Listen::Silencer

Expand Down Expand Up @@ -187,7 +187,7 @@ This is the primary method of debugging.

### Custom Logger
You can call `Listen.logger =` to set a custom `listen` logger for the process. For example:
```
``` ruby
Listen.logger = Rails.logger
```

Expand All @@ -197,7 +197,7 @@ If no custom logger is set, a default `listen` logger which logs to to `STDERR`
The default logger defaults to the `error` logging level (severity).
You can override the logging level by setting the environment variable `LISTEN_GEM_DEBUGGING=<level>`.
For `<level>`, all standard `::Logger` levels are supported, with any mix of upper-/lower-case:
```
``` ruby
export LISTEN_GEM_DEBUGGING=debug # or 2 [deprecated]
export LISTEN_GEM_DEBUGGING=info # or 1 or true or yes [deprecated]
export LISTEN_GEM_DEBUGGING=warn
Expand All @@ -210,9 +210,38 @@ Note: The alternate values `1`, `2`, `true` and `yes` shown above are deprecated

### Disabling Logging
If you want to disable `listen` logging, set
```
``` ruby
Listen.logger = ::Logger.new('/dev/null')
```

### Adapter Warnings
If listen is having trouble with the underlying adapter, it will display warnings with `Kernel#warn` by default,
which in turn writes to STDERR.
Sometimes this is not desirable, for example in an environment where STDERR is ignored.
For these reasons, the behavior can be configured using `Listen.adapter_warn_behavior =`:
``` ruby
Listen.adapter_warn_behavior = :warn # default (true means the same)
Listen.adapter_warn_behavior = :log # send to logger.warn
Listen.adapter_warn_behavior = :silent # suppress all adapter warnings (nil or false mean the same)
```
Also there are some cases where specific warnings are not helpful.
For example, if you are using the polling adapter--and expect to--you can suppress the warning about it
by providing a callable object like a lambda or proc that determines the behavior based on the `message`:
``` ruby
Listen.adapter_warn_behavior = ->(message) do
case message
when /Listen will be polling for changes/
:silent
when /directory is already being watched/
:log
else
:warn
end
end
```
In cases where the `Listen` gem is embedded inside another service--such as `guard`--the above configuration
can be set in the environment variable `LISTEN_GEM_ADAPTER_WARN_BEHAVIOR=warn|log|silent`.

## Listen Adapters

The `Listen` gem has a set of adapters to notify it when there are changes.
Expand Down
2 changes: 1 addition & 1 deletion lib/listen/adapter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def _usable_adapter_class

def _warn_polling_fallback(options)
msg = options.fetch(:polling_fallback_message, POLLING_FALLBACK_MESSAGE)
Kernel.warn "[Listen warning]:\n #{msg}" if msg
Listen.adapter_warn("[Listen warning]:\n #{msg}") if msg
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/listen/adapter/bsd.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def self.usable?
require 'find'
true
rescue LoadError
Kernel.warn BUNDLER_DECLARE_GEM
Listen.adapter_warn(BUNDLER_DECLARE_GEM)
false
end

Expand Down
2 changes: 1 addition & 1 deletion lib/listen/adapter/darwin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def self.usable?
require 'rb-fsevent'
fsevent_version = Gem::Version.new(FSEvent::VERSION)
return true if fsevent_version <= Gem::Version.new('0.9.4')
Kernel.warn INCOMPATIBLE_GEM_VERSION
Listen.adapter_warn(INCOMPATIBLE_GEM_VERSION)
false
end

Expand Down
2 changes: 1 addition & 1 deletion lib/listen/adapter/windows.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def self.usable?
Listen.logger.debug format('wdm - load failed: %s:%s', $ERROR_INFO,
$ERROR_POSITION * "\n")

Kernel.warn BUNDLER_DECLARE_GEM
Listen.adapter_warn(BUNDLER_DECLARE_GEM)
false
end

Expand Down
29 changes: 29 additions & 0 deletions lib/listen/logger.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,27 @@ module Listen
# Listen.logger will always be present.
# If you don't want logging, set Listen.logger = ::Logger.new('/dev/null', level: ::Logger::UNKNOWN)

@adapter_warn_behavior = :warn

class << self
attr_writer :logger
attr_accessor :adapter_warn_behavior

def logger
@logger ||= default_logger
end

def adapter_warn(message)
case ENV['LISTEN_GEM_ADAPTER_WARN_BEHAVIOR']&.to_sym || adapter_warn_behavior_callback(message)
when :log
logger.warn(message)
when :silent, nil, false
# do nothing
else # :warn
warn(message)
end
end

private

def default_logger
Expand All @@ -32,5 +46,20 @@ def default_logger

::Logger.new(STDERR, level: level)
end

def adapter_warn_behavior_callback(message)
if adapter_warn_behavior.respond_to?(:call)
case behavior = adapter_warn_behavior.call(message)
when Symbol
behavior
when false, nil
:silent
else
:warn
end
else
adapter_warn_behavior
end
end
end
end
6 changes: 6 additions & 0 deletions lib/listen/record/symlink_detector.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ def verify_unwatched!(entry)
@real_dirs.add?(real_path) or _fail(entry.sys_path, real_path)
end

# Leaving this stub here since some warning work-arounds were referring to it.
# Deprecated. Will be removed in Listen v4.0.
def warn(message)
Listen.adapter_warn(message)
end

private

def _fail(symlinked, real_path)
Expand Down
2 changes: 1 addition & 1 deletion lib/listen/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

module Listen
VERSION = '3.8.0'
VERSION = '3.9.0'
end
2 changes: 1 addition & 1 deletion spec/lib/listen/adapter/darwin_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
context 'with rb-fsevent > 0.9.4' do
before { stub_const('FSEvent::VERSION', '0.9.6') }
it 'shows a warning and should not be usable' do
expect(Kernel).to receive(:warn)
expect(Listen).to receive(:adapter_warn)
expect(subject).to_not be_usable
end
end
Expand Down
4 changes: 2 additions & 2 deletions spec/lib/listen/adapter_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@

it 'warns polling fallback with default message' do
msg = described_class::POLLING_FALLBACK_MESSAGE
expect(Kernel).to receive(:warn).with("[Listen warning]:\n #{msg}")
expect(Listen).to receive(:adapter_warn).with("[Listen warning]:\n #{msg}")
Listen::Adapter.select
end

Expand All @@ -60,7 +60,7 @@

it 'warns polling fallback with custom message if set' do
expected_msg = "[Listen warning]:\n custom fallback message"
expect(Kernel).to receive(:warn).with(expected_msg)
expect(Listen).to receive(:adapter_warn).with(expected_msg)
msg = 'custom fallback message'
Listen::Adapter.select(polling_fallback_message: msg)
end
Expand Down