Skip to content

Commit

Permalink
beep plugin updates
Browse files Browse the repository at this point in the history
- Removed unneeded tool element definitions
- Revised and exapanded documentation
- Added three sound options (tools) for more platform options
- Added more appropriate logging and shell execution tooling
  • Loading branch information
mkarlesky committed Jan 3, 2024
1 parent 06baa49 commit c96e300
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 30 deletions.
81 changes: 71 additions & 10 deletions plugins/beep/README.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,83 @@
ceedling-beep
=============
# Ceedling Plugin: Beep

This is a simple plugin that just beeps at the end of a build and/or test sequence. Are you getting too distracted surfing
the internet, chatting with coworkers, or swordfighting while it's building or testing? The friendly beep will let you know
# Overview

This plugin simply beeps at the end of a build.

Are you getting too distracted surfing the internet, chatting with coworkers, or swordfighting while a long build runs? A friendly beep will let you know
it's time to pay attention again.

This plugin has very few configuration options. At this time it can beep on completion of a task and/or on an error condition.
For each of these, you can configure the method that it should beep.
# Configuration

Beep includes a default configuration. By just enabling the plugin, the simplest cross-platform sound mechanism (`:bell` below) is automatically enabled for both
build completion and build error events.

If you would like to customize your beeps, the following explains your options.

## Events

When this plugin is enabled, a beep is sounded when:

* A test build or release build finish successfully.
* An error condition breaks a build.

To change the default sound for each event, define `:on_done` and `:on_error` beneath a top-level `:beep` entry in your configuration file. See example below.

## Sound options

The following options are fixed. At present, this plugin does not expose customization settings.

* `:bell`

`:bell` is the simplest and most widely available option for beeping. This option simply `echo`s the unprintable [ASCII bell character][ascii-bel-character] to a command terminal. This option is generally available on all platforms, including Windows.

[ascii-bel-character]: https://en.wikipedia.org/wiki/Bell_character

* `:tput`

[`tput`][tput] is a command line utility widely availble among Unix derivatives, including Linux and macOS. The `tput` utility uses the terminfo database to make the values of terminal-dependent capabilities (including the [ASCII bell character][ascii-bel-character]) and terminal information available to the shell.

If the `echo`-based method used by the `:bell` option is not successful, `:tput` is a good backup option (except on Windows).

[tput]: https://linux.die.net/man/1/tput

* `:beep`

[`beep`][beep] is an old but widely available Linux package for tone generation using the PC speaker.

`beep` requires isntallation and the possibility of a complementary kernel module.

The original audio device in a PC before sound cards was a simple and limited speaker directly wired to a motherboard. Rarely, modern systems still have this device. More commonly, its functions are routed to a default mode of modern audio hardware. `beep` may not work on modern Linux systems. If it is a viable option, this utility is typically dependent on a PC speaker kernel module and related configuration.

[beep]: https://linux.die.net/man/1/beep

* `:speaker_test`

[`speaker-test`][speaker-test] is a Linux package commonly available for tone generation using a system's audio features.

`speaker-test` requires installation as well as audio subsystem configuration.

_Note:_ `speaker-test` typically mandates a 4 second minimum run, even if the configured sound plays for less than this minimum. Options to limit `speaker-test`'s minimum time are likely possible but would require combining advanced Ceedling features.

[speaker-test]: https://linux.die.net/man/1/speaker-test

* `:say`

macOS includes a built-in text-to-speech command line application, [`say`][say]. When Ceedling is running on macOS and this beep option is selected, Ceedling events will be verbally announced.

[say]: https://ss64.com/mac/say.html

## Example beep configurations in YAML

In fact, this is the default configuration (and need not be duplicated in your project file).

```yaml
:beep:
:on_done: :bell
:on_error: :bell
```
Each of these have the following options:
# Notes
- :bell - this option uses the ASCII bell character out stdout
- :speaker_test - this uses the linux speaker-test command if installed
* Some terminal emulators intercept and/or silence beeps. Remote terminal sessions can add further complication. Be sure to check relevant configuration options to accomplish what you want.
Very likely, we'll be adding to this list if people find this to be useful.
39 changes: 31 additions & 8 deletions plugins/beep/lib/beep.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require 'ceedling/plugin'
require 'ceedling/exceptions'
require 'beep_tools'

BEEP_ROOT_NAME = 'beep'.freeze
Expand All @@ -15,24 +16,46 @@ def setup
}

if @tools[:beep_on_done].nil?
@ceedling[:streaminator].stderr_puts("Tool :beep_on_done is not defined.", verbosity=Verbosity::COMPLAIN)
raise CeedlingException.new("Option '#{@config[:on_done]}' for plugin :beep ↳ :on_done configuration did not map to a tool.")
end

if @tools[:beep_on_error].nil?
@ceedling[:streaminator].stderr_puts("Tool :beep_on_error is not defined.", verbosity=Verbosity::COMPLAIN)
raise CeedlingException.new("Option '#{@config[:on_done]}' for plugin :beep ↳ :on_error configuration did not map to a tool.")
end
end

def post_build
return if @tools[:beep_on_done].nil?
command = @ceedling[:tool_executor].build_command_line(@tools[:beep_on_done], [])
system(command[:line])
if @tools[:beep_on_done].nil?
@ceedling[:streaminator].stderr_puts("Tool for :beep ↳ :on_done event handling is not available", Verbosity::COMPLAIN)
return
end

command = @ceedling[:tool_executor].build_command_line(
@tools[:beep_on_done],
[],
["ceedling build done"]) # Only used by tools with `${1}` replacement arguments

@ceedling[:streaminator].stdout_puts("Command: #{command}", Verbosity::DEBUG)

# Verbosity is enabled to allow shell output (primarily for sake of the bell character)
@ceedling[:system_wrapper].shell_system( command: command[:line], verbose: true )
end

def post_error
return if @tools[:beep_on_error].nil?
command = @ceedling[:tool_executor].build_command_line(@tools[:beep_on_error], [])
system(command[:line])
if @tools[:beep_on_error].nil?
@ceedling[:streaminator].stderr_puts("Tool for :beep ↳ :on_error event handling is not available", Verbosity::COMPLAIN)
return
end

command = @ceedling[:tool_executor].build_command_line(
@tools[:beep_on_error],
[],
["ceedling build error"]) # Only used by tools with `${1}` replacement arguments

@ceedling[:streaminator].stdout_puts("Command: #{command}", Verbosity::DEBUG)

# Verbosity is enabled to allow shell output (primarily for sake of the bell character)
@ceedling[:system_wrapper].shell_system( command: command[:line], verbose: true )
end

end
50 changes: 38 additions & 12 deletions plugins/beep/lib/beep_tools.rb
Original file line number Diff line number Diff line change
@@ -1,23 +1,49 @@
BEEP_TOOLS = {

# Most generic beep option across all platforms -- echo the ASCII bell character
:bell => {
:executable => 'echo'.freeze,
:executable => 'echo'.freeze, # Using `echo` shell command / command line application
:name => 'default_beep_bell'.freeze,
:stderr_redirect => StdErrRedirect::NONE.freeze,
:optional => false.freeze,
:arguments => [
*('-ne'.freeze unless SystemWrapper.windows?),
"\x07".freeze
*('-n'.freeze unless SystemWrapper.windows?), # No trailing newline for Unix-style echo (argument omitted on Windows)
"\x07".freeze # Unprintable ASCII bell character, escaped in Ruby string
].freeze
}.freeze,

# Terminal put the bell character on Unix-derived platforms
:tput => {
:executable => 'tput'.freeze, # `tput` command line application
:name => 'default_beep_tput'.freeze,
:arguments => [
"bel".freeze # `tput` argument for bell character (named 'bel' in ASCII standard)
].freeze
}.freeze,

# Old but widely available `beep` tone generator package for Unix-derived platforms (not macOS)
:beep => {
:executable => 'beep'.freeze, # `beep` command line application
:name => 'default_beep_beep'.freeze,
:arguments => [].freeze # Default beep (no arguments)
}.freeze,

# Widely available tone generator package for Unix-derived platforms (not macOS)
:speaker_test => {
:executable => 'speaker-test'.freeze,
:executable => 'speaker-test'.freeze, # `speaker-test` command line application
:name => 'default_beep_speaker_test'.freeze,
:stderr_redirect => StdErrRedirect::NONE.freeze,
:optional => false.freeze,
:arguments => [ # 1000 hz sine wave frequency
'-t sine'.freeze,
'-f 1000'.freeze,
'-l 1'.freeze
].freeze
}.freeze,

# macOS text to speech
:say => {
:executable => 'say'.freeze, # macOS `say` command line application
:name => 'default_beep_say'.freeze,
:arguments => [
- '-t sine'.freeze,
- '-f 1000'.freeze,
- '-l 1'.freeze
"\"${1}\"" # Replacement argument for text
].freeze
}.freeze
}.freeze,

}.freeze

0 comments on commit c96e300

Please sign in to comment.