sphyg 0.2.1 → 0.3.0

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: c97ec87a49cef9bac4b9d5fd41be9db71995a06e
4
- data.tar.gz: 64be64fdc27bba014e901a948fd218ec76bac448
3
+ metadata.gz: 2d139d42bad771622c37cfacb62a29d436c0d4ca
4
+ data.tar.gz: 2e0a4741929467bc81a0216e9578cce7f56d533d
5
5
  SHA512:
6
- metadata.gz: ad1a1018342b045cdef23c65295a8aa0ac9edbac22d2f6ce4e1317bb822ba870009e2d0cd2a71d1062f915dad91fe96309a936c6227cfb3be621031b2fd4d33d
7
- data.tar.gz: cbef5bbe68f0816275ad3b7bf70107701afd10af1dc94c999345b02519c7f8969e96844fba7f221de8ec676ab7ad8a4253fcacc102e724f10a481156303b184f
6
+ metadata.gz: b9bf2ce0dc8b57af61a92585869ebdb8d43c9c821d1e837bf289afd8c376169638bb21db308672a93360416fc3aece3131f242344bc71922afa5d1079981c31b
7
+ data.tar.gz: 9ef9703521fd6782993c7f10da5a40e7a425bd5b1c9a98be460c545515b19ea8214fb11f3c1b9864345e296243cfd2271d040f19bda726ae08c5968a49641bb6
data/.gitignore CHANGED
@@ -9,3 +9,5 @@
9
9
 
10
10
  # rspec failure tracking
11
11
  .rspec_status
12
+
13
+ .ruby-version
@@ -0,0 +1,10 @@
1
+ Layout/AlignParameters:
2
+ EnforcedStyle: with_fixed_indentation
3
+
4
+ # The trailing style can be copy-and-pasted into a console
5
+ Layout/DotPosition:
6
+ EnforcedStyle: trailing
7
+
8
+ Metrics/BlockLength:
9
+ Exclude:
10
+ - spec/**/*
@@ -14,6 +14,16 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
14
14
  ### Fixed
15
15
  - None
16
16
 
17
+ ## 0.3.0 (2018-01-01)
18
+ ### Added
19
+ - API for configuring custom throbbers
20
+
21
+ ### Changed
22
+ - None
23
+
24
+ ### Fixed
25
+ - None
26
+
17
27
  ## 0.2.1 (2017-12-30)
18
28
  ### Added
19
29
  - None
data/Gemfile CHANGED
@@ -1,6 +1,6 @@
1
- source "https://rubygems.org"
1
+ source 'https://rubygems.org'
2
2
 
3
- git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
3
+ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
4
4
 
5
5
  # Specify your gem's dependencies in throbber.gemspec
6
6
  gemspec
@@ -1,12 +1,18 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- sphyg (0.2.1)
4
+ sphyg (0.3.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
+ ast (2.3.0)
9
10
  diff-lcs (1.3)
11
+ parallel (1.12.1)
12
+ parser (2.4.0.2)
13
+ ast (~> 2.3)
14
+ powerpack (0.1.1)
15
+ rainbow (3.0.0)
10
16
  rake (10.5.0)
11
17
  rspec (3.7.0)
12
18
  rspec-core (~> 3.7.0)
@@ -21,6 +27,15 @@ GEM
21
27
  diff-lcs (>= 1.2.0, < 2.0)
22
28
  rspec-support (~> 3.7.0)
23
29
  rspec-support (3.7.0)
30
+ rubocop (0.52.1)
31
+ parallel (~> 1.10)
32
+ parser (>= 2.4.0.2, < 3.0)
33
+ powerpack (~> 0.1)
34
+ rainbow (>= 2.2.2, < 4.0)
35
+ ruby-progressbar (~> 1.7)
36
+ unicode-display_width (~> 1.0, >= 1.0.1)
37
+ ruby-progressbar (1.9.0)
38
+ unicode-display_width (1.3.0)
24
39
 
25
40
  PLATFORMS
26
41
  ruby
@@ -29,6 +44,7 @@ DEPENDENCIES
29
44
  bundler (~> 1.16)
30
45
  rake (~> 10.0)
31
46
  rspec (~> 3.0)
47
+ rubocop (~> 0.52.0)
32
48
  sphyg!
33
49
 
34
50
  BUNDLED WITH
data/README.md CHANGED
@@ -1,7 +1,8 @@
1
1
  # Sphyg
2
2
 
3
- 'Sphygmos' is the Greek word for 'pulse'. Sphyg provides [throbbers](https://en.wikipedia.org/wiki/Throbber)
4
- to indicate that your long-running command line program still has a pulse.
3
+ 'Sphygmos' is the Greek word for 'pulse'. Sphyg provides an interface for
4
+ creating [throbbers](https://en.wikipedia.org/wiki/Throbber) to indicate that
5
+ your long-running command line program still has a pulse.
5
6
 
6
7
  ## Installation
7
8
 
@@ -31,7 +32,10 @@ Please wait ⡀ ⠄ ⠂ ⠁ ⠂ ⠄ # animated
31
32
 
32
33
  ### Options
33
34
 
34
- You can also pass an _options_ hash to `::Sphyg.pulse` using the following keys:
35
+ You can also pass an _options_ hash to `::Sphyg.pulse` to customize the displayed
36
+ throbber. A throbber consists of an array of _frames_, an _enumerator_, and a
37
+ _rate_. The following are built-in throbbers. You may use the `:kind` key to
38
+ choose a built-in throbber, or utilize `::Sphyg::THROBBERS` to configure them.
35
39
 
36
40
  #### `:kind`
37
41
 
@@ -47,10 +51,40 @@ Configure which kind of throbber you would like to use. Available kinds and thei
47
51
  | `:time` | 🕛 🕐 🕒 🕓 🕔 🕕 🕖 🕗 🕘 🕙 🕚 |
48
52
  | `:wave` | ⡀ ⠄ ⠂ ⠁ ⠂ ⠄ |
49
53
 
54
+ #### `:frames`
55
+
56
+ An array of glyphs from which to choose to display.
57
+
58
+ #### `:enumerator`
59
+
60
+ The string name of an object that is used to generate successive frames
61
+ to display. Must respond to `#next`. For example:
62
+
63
+ ```ruby
64
+ Randomizer = Struct.new(:frames) { def next; frames.sample; end }
65
+ options = {
66
+ frames: %w[a b c],
67
+ enumerator: 'Randomizer',
68
+ rate: 0.1
69
+ }
70
+ > Sphyg.pulse('Please wait', options) { sleep }
71
+ Please wait a # Will display a random value from `frames` every 0.1 seconds alongside the message
72
+
73
+ ```
74
+
75
+ See [`Sphyg::Enumerators`](lib/sphyg/enumerators) for more examples.
76
+
77
+ #### `:rate`
78
+
79
+ An `Integer` or `Float` representing the 'frame' rate of the throbber in
80
+ seconds. Sphyg will cycle through the enumerator at this value.
81
+
50
82
  ## Development
51
83
 
52
84
  After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
53
85
 
86
+ Run `bundle exec rake` to lint and run tests.
87
+
54
88
  To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
55
89
 
56
90
  ## Contributing
data/Rakefile CHANGED
@@ -1,6 +1,11 @@
1
- require "bundler/gem_tasks"
2
- require "rspec/core/rake_task"
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+ require 'rubocop/rake_task'
3
4
 
4
- RSpec::Core::RakeTask.new(:spec)
5
+ RSpec::Core::RakeTask.new(:spec) do |task|
6
+ task.verbose = false
7
+ end
5
8
 
6
- task :default => :spec
9
+ RuboCop::RakeTask.new(:rubocop)
10
+
11
+ task default: %i[rubocop spec]
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require "bundler/setup"
4
- require "sphyg"
3
+ require 'bundler/setup'
4
+ require 'sphyg'
5
5
 
6
6
  # You can add fixtures and/or initialization code here to make experimenting
7
7
  # with your gem easier. You can also use a different console, if you like.
@@ -10,5 +10,5 @@ require "sphyg"
10
10
  # require "pry"
11
11
  # Pry.start
12
12
 
13
- require "irb"
13
+ require 'irb'
14
14
  IRB.start(__FILE__)
@@ -1,7 +1,53 @@
1
- require "sphyg/pulse"
2
- require "sphyg/version"
1
+ require 'sphyg/pulse'
2
+ require 'sphyg/version'
3
3
 
4
+ # Top-level namespace
4
5
  module Sphyg
6
+ THROBBERS = {
7
+ ascii: {
8
+ enumerator: '::Sphyg::Enumerators::Cycle',
9
+ frames: %w[| / - \\],
10
+ rate: 0.1
11
+ },
12
+ elipsis: {
13
+ enumerator: '::Sphyg::Enumerators::Cycle',
14
+ frames: %w[. .. ... ..],
15
+ rate: 0.2
16
+ },
17
+ heart: {
18
+ enumerator: '::Sphyg::Enumerators::Cycle',
19
+ frames: %w[🧡 💛 💚 💙 💜],
20
+ rate: 0.1
21
+ },
22
+ heroku: {
23
+ enumerator: '::Sphyg::Enumerators::Cycle',
24
+ frames: %w[⣾ ⣽ ⣻ ⢿ ⡿ ⣟ ⣯ ⣷],
25
+ rate: 0.1
26
+ },
27
+ moon: {
28
+ enumerator: '::Sphyg::Enumerators::Cycle',
29
+ frames: %w[🌑 🌒 🌓 🌔 🌕 🌖 🌗 🌘],
30
+ rate: 0.2
31
+ },
32
+ time: {
33
+ enumerator: '::Sphyg::Enumerators::Cycle',
34
+ frames: %w[🕛 🕐 🕒 🕓 🕔 🕕 🕖 🕗 🕘 🕙 🕚],
35
+ rate: 1
36
+ },
37
+ wave: {
38
+ enumerator: '::Sphyg::Enumerators::Rotate',
39
+ frames: %w[⡀ ⠄ ⠂ ⠁ ⠂ ⠄],
40
+ rate: 0.1
41
+ }
42
+ }.freeze
43
+
44
+ # Presents a message and throbber
45
+ # Params:
46
+ # +message+:: friendly +string+ to display that indicates a command is running
47
+ # for example, 'Please wait'
48
+ # +options+:: configuration +hash+
49
+ # +&blk+:: a +block+ containing a long-running command to run while displaying
50
+ # the message and throbber
5
51
  def self.pulse(message, options = nil, &blk)
6
52
  ::Sphyg::Pulse.new(message, options).run { yield blk }
7
53
  end
@@ -0,0 +1,19 @@
1
+ module Sphyg
2
+ module Enumerators
3
+ # Enumerator template
4
+ class Base
5
+ class AbstractMethodCall < StandardError; end
6
+
7
+ def initialize(frames)
8
+ @frames = frames
9
+ end
10
+
11
+ # `next` is called at each iteration of a throbber's existance. It
12
+ # returns the throbber state to display. For example, simply looping
13
+ # a given array is implemented in 'Enumerators::Cycle'.
14
+ def next
15
+ raise AbstractMethodCall, 'Implement :run in a child class'
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,14 @@
1
+ require 'sphyg/enumerators/base'
2
+
3
+ module Sphyg
4
+ module Enumerators
5
+ # Loops through each individual frame of the given sequence.
6
+ # Just like Enumerator#next but wraps around the array.
7
+ class Cycle < Base
8
+ def next
9
+ @frames_index ||= 0
10
+ @frames[(@frames_index += 1) % @frames.length]
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,12 @@
1
+ require 'sphyg/enumerators/base'
2
+
3
+ module Sphyg
4
+ module Enumerators
5
+ # Rotates the whole array of frames at each iteration
6
+ class Rotate < Base
7
+ def next
8
+ @frames.rotate!.join
9
+ end
10
+ end
11
+ end
12
+ end
@@ -1,69 +1,43 @@
1
- require 'sphyg/frames'
1
+ require 'sphyg/throbber'
2
2
 
3
3
  module Sphyg
4
+ # Handles threading and running the throbber
4
5
  class Pulse
5
- def initialize(message, options)
6
+ def initialize(message, options = {})
6
7
  @message = message
7
- @options = options || { kind: :wave }
8
- @frames = Sphyg::FRAMES[@options[:kind]]
8
+ @options = parse_options(options)
9
9
  end
10
10
 
11
11
  def run(&blk)
12
- thr = Thread.new do
13
- case @options[:kind]
14
- when :ascii then unitary_frame_loop(frames(:ascii), 0.1)
15
- when :elipsis then unitary_frame_loop(frames(:elipsis), 0.2)
16
- when :heart then unitary_frame_loop(frames(:heart), 0.1)
17
- when :heroku then unitary_frame_loop(frames(:heroku), 0.1)
18
- when :moon then unitary_frame_loop(frames(:moon), 0.2)
19
- when :time then unitary_frame_loop(frames(:time), 1)
20
- when :wave then wave
21
- else wave
22
- end
23
- end
24
-
12
+ # Note: the block will continue to run even if our throbber crashed. This
13
+ # is more user-frindly than setting `abort_on_exception` for our thread.
14
+ # TODO: use `Thread#reporting_on_exception` for Ruby versions >= 2.4
15
+ thr = ::Thread.new { throbber.run }
25
16
  yield blk
26
17
  ensure
27
- Thread.kill(thr)
18
+ thr.kill
28
19
  print "\n"
29
20
  end
30
21
 
31
22
  private
32
23
 
33
- def frames(kind)
34
- Sphyg::FRAMES[kind.to_sym].dup
35
- end
36
-
37
- # For unitary-frame loops, if a frame is longer than its counterparts, then it will not
38
- # be completely replaced by the following frame. This padding ensures that each line
39
- # is longer enough to overwrite the previous frame.
40
- def padding
41
- "\s" * @frames.max { |a, b| a.length <=> b.length }.length
42
- end
43
-
44
- def print_message_and_pulser(pulser)
45
- print format "%s %s%s\r", @message, pulser, padding
46
- end
47
-
48
- def unitary_frame_loop(sequence, pulse_rate = 0.1)
49
- frames_index = 0
50
- loop do
51
- print_message_and_pulser(sequence[frames_index])
52
- frames_index = (frames_index + 1) % sequence.length
53
- sleep pulse_rate
24
+ def parse_options(options)
25
+ if options.nil?
26
+ ::Sphyg::THROBBERS[:wave]
27
+ elsif options[:kind]
28
+ ::Sphyg::THROBBERS[options[:kind]]
29
+ else
30
+ ::Sphyg::THROBBERS[:wave].merge(options)
54
31
  end
55
32
  end
56
33
 
57
- def wave
58
- frames_index = 0
59
- wave = frames(:wave)
60
- loop do
61
- print_message_and_pulser(wave.join)
62
- wave.shift
63
- frames_index = (frames_index + 1) % frames(:wave).length
64
- wave << frames(:wave)[frames_index]
65
- sleep 0.1
66
- end
34
+ def throbber
35
+ ::Sphyg::Throbber.new(
36
+ @message,
37
+ @options[:frames],
38
+ @options[:enumerator],
39
+ @options[:rate]
40
+ )
67
41
  end
68
42
  end
69
43
  end
@@ -0,0 +1,38 @@
1
+ require 'sphyg/enumerators/cycle'
2
+ require 'sphyg/enumerators/rotate'
3
+
4
+ module Sphyg
5
+ # Generates and displays a throbber with a message
6
+ class Throbber
7
+ def initialize(message, frames, enumerator, rate)
8
+ @message = message
9
+ @frames = frames
10
+ @enumerator = Object.const_get(enumerator).new(@frames)
11
+ @rate = rate
12
+ end
13
+
14
+ def run
15
+ loop do
16
+ print_throbber_iteration
17
+ sleep @rate
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ # For unitary-frame loops, if a frame is longer than its counterparts,
24
+ # then it will not be completely replaced by the following frame. This
25
+ # padding ensures that each line is long enough to overwrite the previous
26
+ # frame.
27
+ def padding
28
+ @_padding ||= "\s" * @frames.max_by(&:length).length
29
+ end
30
+
31
+ def print_throbber_iteration
32
+ print format "%<message>s %<enumeration>s%<padding>s\r",
33
+ message: @message,
34
+ enumeration: @enumerator.next,
35
+ padding: padding
36
+ end
37
+ end
38
+ end
@@ -1,3 +1,3 @@
1
1
  module Sphyg
2
- VERSION = "0.2.1"
2
+ VERSION = '0.3.0'.freeze
3
3
  end
@@ -1,27 +1,30 @@
1
1
 
2
- lib = File.expand_path("../lib", __FILE__)
2
+ lib = File.expand_path('../lib', __FILE__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require "sphyg/version"
4
+ require 'sphyg/version'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
- spec.name = "sphyg"
7
+ spec.name = 'sphyg'
8
8
  spec.version = Sphyg::VERSION
9
- spec.authors = ["Shane Cavanaugh"]
10
- spec.email = ["shane@shanecav.net"]
9
+ spec.authors = ['Shane Cavanaugh']
10
+ spec.email = ['shane@shanecav.net']
11
11
 
12
12
  spec.summary = 'Throbbers for command line programs'
13
13
  spec.description = 'Throbbers for command line programs'
14
14
  spec.homepage = nil
15
- spec.license = "MIT"
15
+ spec.license = 'MIT'
16
16
 
17
17
  spec.files = `git ls-files -z`.split("\x0").reject do |f|
18
18
  f.match(%r{^(test|spec|features)/})
19
19
  end
20
- spec.bindir = "exe"
20
+ spec.bindir = 'exe'
21
21
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
- spec.require_paths = ["lib"]
22
+ spec.require_paths = ['lib']
23
23
 
24
- spec.add_development_dependency "bundler", "~> 1.16"
25
- spec.add_development_dependency "rake", "~> 10.0"
26
- spec.add_development_dependency "rspec", "~> 3.0"
24
+ spec.required_ruby_version = '>= 2.2.9'
25
+
26
+ spec.add_development_dependency 'bundler', '~> 1.16'
27
+ spec.add_development_dependency 'rake', '~> 10.0'
28
+ spec.add_development_dependency 'rspec', '~> 3.0'
29
+ spec.add_development_dependency 'rubocop', '~> 0.52.0'
27
30
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sphyg
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shane Cavanaugh
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-12-30 00:00:00.000000000 Z
11
+ date: 2018-01-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rubocop
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.52.0
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.52.0
55
69
  description: Throbbers for command line programs
56
70
  email:
57
71
  - shane@shanecav.net
@@ -60,6 +74,7 @@ extensions: []
60
74
  extra_rdoc_files: []
61
75
  files:
62
76
  - ".gitignore"
77
+ - ".rubocop.yml"
63
78
  - CHANGELOG.md
64
79
  - CODE_OF_CONDUCT.md
65
80
  - Gemfile
@@ -70,8 +85,11 @@ files:
70
85
  - bin/console
71
86
  - bin/setup
72
87
  - lib/sphyg.rb
73
- - lib/sphyg/frames.rb
88
+ - lib/sphyg/enumerators/base.rb
89
+ - lib/sphyg/enumerators/cycle.rb
90
+ - lib/sphyg/enumerators/rotate.rb
74
91
  - lib/sphyg/pulse.rb
92
+ - lib/sphyg/throbber.rb
75
93
  - lib/sphyg/version.rb
76
94
  - sphyg.gemspec
77
95
  homepage:
@@ -86,7 +104,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
86
104
  requirements:
87
105
  - - ">="
88
106
  - !ruby/object:Gem::Version
89
- version: '0'
107
+ version: 2.2.9
90
108
  required_rubygems_version: !ruby/object:Gem::Requirement
91
109
  requirements:
92
110
  - - ">="
@@ -94,7 +112,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
94
112
  version: '0'
95
113
  requirements: []
96
114
  rubyforge_project:
97
- rubygems_version: 2.6.14
115
+ rubygems_version: 2.4.5.4
98
116
  signing_key:
99
117
  specification_version: 4
100
118
  summary: Throbbers for command line programs
@@ -1,11 +0,0 @@
1
- module Sphyg
2
- FRAMES = {
3
- ascii: %w[| / - \\],
4
- elipsis: ['.', '..', '...', '..'],
5
- heart: %w[❤️ 🧡 💛 💚 💙 💜],
6
- heroku: %w[⣾ ⣽ ⣻ ⢿ ⡿ ⣟ ⣯ ⣷],
7
- moon: %w[🌑 🌒 🌓 🌔 🌕 🌖 🌗 🌘],
8
- time: %w[🕛 🕐 🕒 🕓 🕔 🕕 🕖 🕗 🕘 🕙 🕚],
9
- wave: %w[⡀ ⠄ ⠂ ⠁ ⠂ ⠄],
10
- }.freeze
11
- end