sphyg 0.2.1 → 0.3.0

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