musa-dsl 0.23.21 → 0.26.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
  SHA256:
3
- metadata.gz: aedf88a0a0fbde9b6f6304d49120aa1f1f8d4aa2d235eb3af32a8b5c21f4a930
4
- data.tar.gz: d96c2fe26565dd56ce1a3c6a52637612f384388a555c8e64006a3e08ecd97673
3
+ metadata.gz: 2baccb6e4a0d7c120cd44154229080d001861570f09a6c955acd2b8831d95b65
4
+ data.tar.gz: a191b5e72d8ee8086224d8e950a731854bd7ba8e01cfacf11e6d9295ad626439
5
5
  SHA512:
6
- metadata.gz: 86275e952c77624849cf77f2f51f69606fc31834bc72909f3604eb6eb91669bb8b3a74bbb1f2bf56d81e19e85b819dca73e23a386bf39f05213317000158ef7b
7
- data.tar.gz: 3eacb78ab20092b2c8b6c8adbca960321126f8d9ea09655f230564bd3cfb4e7d75ed021f3e688d2f91c63bf9abf0a49d156fa41bce87f0fad7291337c139b60a
6
+ metadata.gz: e11bb0c2cdd2bcb8086cac5c1c67c70a98e70a16ad7af1ee022cd31eff7947c6f7050ac2c4c8786c41624221fe54a7b5642863edc10cf82c4e50f4d4500bf523
7
+ data.tar.gz: 11824a54cd89809d1879396544a697060a31ec8884c7a70481962a1c341b10065fd9d404ef6d7811987d5a62f7ec082fdb722085c72b4d4f1dd07533a699b42d
@@ -0,0 +1,62 @@
1
+ name: Generate gem and push to rubygems repository
2
+
3
+ on:
4
+ push:
5
+ branches: [ master ]
6
+ pull_request:
7
+ branches: [ master ]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ matrix:
14
+ ruby-version: ['2.7']
15
+
16
+ steps:
17
+ - uses: actions/checkout@v2
18
+ - name: Set up Ruby
19
+ uses: ruby/setup-ruby@v1
20
+ with:
21
+ ruby-version: ${{ matrix.ruby-version }}
22
+ bundler-cache: true # runs 'bundle install' and caches installed gems automatically
23
+ - name: Run tests
24
+ run: bundle exec rspec -t \~slow
25
+
26
+ build:
27
+ name: Build + Publish
28
+ runs-on: ubuntu-latest
29
+ needs: test
30
+ permissions:
31
+ contents: read
32
+ packages: write
33
+
34
+ steps:
35
+ - uses: actions/checkout@v2
36
+ - name: Set up Ruby 2.7
37
+ uses: actions/setup-ruby@v1
38
+ with:
39
+ ruby-version: 2.7.x
40
+
41
+ # - name: Publish to GPR
42
+ # run: |
43
+ # mkdir -p $HOME/.gem
44
+ # touch $HOME/.gem/credentials
45
+ # chmod 0600 $HOME/.gem/credentials
46
+ # printf -- "---\n:github: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
47
+ # gem build *.gemspec
48
+ # gem push --KEY github --host https://rubygems.pkg.github.com/${OWNER} *.gem
49
+ # env:
50
+ # GEM_HOST_API_KEY: "Bearer ${{secrets.GITHUB_TOKEN}}"
51
+ # OWNER: ${{ github.repository_owner }}
52
+
53
+ - name: Publish to RubyGems
54
+ run: |
55
+ mkdir -p $HOME/.gem
56
+ touch $HOME/.gem/credentials
57
+ chmod 0600 $HOME/.gem/credentials
58
+ printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
59
+ gem build *.gemspec
60
+ gem push *.gem
61
+ env:
62
+ GEM_HOST_API_KEY: "${{secrets.RUBYGEMS_AUTH_TOKEN}}"
data/Gemfile CHANGED
@@ -1,23 +1,3 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- ruby '2.7.4'
4
-
5
- gem 'logger', '~> 1.4', '>= 1.4.3'
6
-
7
- group :neuma do
8
- gem 'citrus', '~> 3.0.0'
9
- end
10
-
11
- group :transport do
12
- gem 'midi-message', '~> 0.4', '>= 0.4.9'
13
- gem 'midi-nibbler', '~> 0.2', '>= 0.2.4'
14
- end
15
-
16
- group :test do
17
- gem 'descriptive-statistics'
18
- gem 'rspec', '~> 3.0'
19
- end
20
-
21
- group :documentation do
22
- gem 'rdoc'
23
- end
3
+ gemspec
@@ -3,6 +3,8 @@ module Musa
3
3
  module DynamicProxy
4
4
  module DynamicProxyModule
5
5
  def method_missing(method_name, *args, **key_args, &block)
6
+ raise NoMethodError, "Method '#{method_name}' is unknown because self is a DynamicProxy with undefined receiver" unless @receiver
7
+
6
8
  if @receiver.respond_to? method_name
7
9
  @receiver.send method_name, *args, **key_args, &block
8
10
  else
@@ -11,37 +13,41 @@ module Musa
11
13
  end
12
14
 
13
15
  def respond_to_missing?(method_name, include_private)
14
- @receiver.respond_to?(method_name, include_private) || super
16
+ @receiver&.respond_to?(method_name, include_private) || super
17
+ end
18
+
19
+ def has_receiver?
20
+ !@receiver.nil?
15
21
  end
16
22
 
17
23
  alias _is_a? is_a?
18
24
 
19
25
  def is_a?(klass)
20
- _is_a?(klass) || @receiver.is_a?(klass)
26
+ _is_a?(klass) || @receiver&.is_a?(klass)
21
27
  end
22
28
 
23
29
  alias _kind_of? kind_of?
24
30
 
25
31
  def kind_of?(klass)
26
- _kind_of?(klass) || @receiver.is_a?(klass)
32
+ _kind_of?(klass) || @receiver&.is_a?(klass)
27
33
  end
28
34
 
29
35
  alias _instance_of? instance_of?
30
36
 
31
37
  def instance_of?(klass)
32
- _instance_of?(klass) || @receiver.instance_of?(klass)
38
+ _instance_of?(klass) || @receiver&.instance_of?(klass)
33
39
  end
34
40
 
35
41
  alias _equalequal ==
36
42
 
37
43
  def ==(object)
38
- _equalequal(object) || @receiver.==(object)
44
+ _equalequal(object) || @receiver&.==(object)
39
45
  end
40
46
 
41
47
  alias _eql? eql?
42
48
 
43
49
  def eql?(object)
44
- _eql?(object) || @receiver.eql?(object)
50
+ _eql?(object) || @receiver&.eql?(object)
45
51
  end
46
52
  end
47
53
 
@@ -6,8 +6,9 @@ module Musa
6
6
  def with(*value_parameters, **key_parameters, &block)
7
7
  binder = Musa::Extension::SmartProcBinder::SmartProcBinder.new(block)
8
8
 
9
- keep_proc_context = @keep_proc_context_on_with
10
9
  send_self_as_underscore_parameter = binder.parameters[0][1] == :_ unless binder.parameters.empty?
10
+
11
+ keep_proc_context = @keep_proc_context_on_with
11
12
  keep_proc_context ||= send_self_as_underscore_parameter
12
13
  keep_proc_context ||= false
13
14
 
@@ -1,11 +1,11 @@
1
- require 'nibbler'
1
+ require 'midi-parser'
2
2
 
3
3
  module Musa
4
4
  module MIDIRecorder
5
5
  class MIDIRecorder
6
6
  def initialize(sequencer)
7
7
  @sequencer = sequencer
8
- @nibbler = Nibbler.new
8
+ @midi_parser = MIDIParser.new
9
9
 
10
10
  clear
11
11
  end
@@ -15,7 +15,7 @@ module Musa
15
15
  end
16
16
 
17
17
  def record(midi_bytes)
18
- m = @nibbler.parse midi_bytes
18
+ m = @midi_parser.parse midi_bytes
19
19
  m = [m] unless m.is_a? Array
20
20
 
21
21
  m.each do |mm|
@@ -37,7 +37,7 @@ module Musa
37
37
  mm = m.message
38
38
 
39
39
  case mm
40
- when MIDIMessage::NoteOn
40
+ when MIDIEvents::NoteOn
41
41
  if last_note[mm.channel]
42
42
  notes << { position: last_note[mm.channel], channel: mm.channel, pitch: :silence, duration: m.position - last_note[mm.channel] }
43
43
  last_note.delete mm.channel
@@ -50,7 +50,7 @@ module Musa
50
50
 
51
51
  notes << note
52
52
 
53
- when MIDIMessage::NoteOff
53
+ when MIDIEvents::NoteOff
54
54
  note_on[mm.channel] ||= {}
55
55
 
56
56
  note = note_on[mm.channel][mm.note]
@@ -1,5 +1,5 @@
1
1
  require 'set'
2
- require 'midi-message'
2
+ require 'midi-events'
3
3
 
4
4
  require_relative '../core-ext/arrayfy'
5
5
  require_relative '../core-ext/array-explode-ranges'
@@ -38,7 +38,7 @@ module Musa
38
38
 
39
39
  @voices.each(&:all_notes_off)
40
40
 
41
- @output.puts MIDIMessage::SystemRealtime.new(0xff) if reset
41
+ @output.puts MIDIEvents::SystemRealtime.new(0xff) if reset
42
42
  end
43
43
  end
44
44
 
@@ -72,7 +72,7 @@ module Musa
72
72
  def fast_forward=(enabled)
73
73
  if @fast_forward && !enabled
74
74
  (0..127).each do |pitch|
75
- @output.puts MIDIMessage::NoteOn.new(@channel, pitch, @active_pitches[pitch][:velocity]) unless @active_pitches[pitch][:note_controls].empty?
75
+ @output.puts MIDIEvents::NoteOn.new(@channel, pitch, @active_pitches[pitch][:velocity]) unless @active_pitches[pitch][:note_controls].empty?
76
76
  end
77
77
  end
78
78
 
@@ -114,7 +114,7 @@ module Musa
114
114
  @active_pitches.clear
115
115
  fill_active_pitches @active_pitches
116
116
 
117
- @output.puts MIDIMessage::ChannelMessage.new(0xb, @channel, 0x7b, 0)
117
+ @output.puts MIDIEvents::ChannelMessage.new(0xb, @channel, 0x7b, 0)
118
118
  end
119
119
 
120
120
  def log(msg)
@@ -147,7 +147,7 @@ module Musa
147
147
  value ||= 0
148
148
 
149
149
  @controller[number] = [[0, value].max, 0xff].min
150
- @output.puts MIDIMessage::ChannelMessage.new(0xb, @channel, number, @controller[number])
150
+ @output.puts MIDIEvents::ChannelMessage.new(0xb, @channel, number, @controller[number])
151
151
  end
152
152
 
153
153
  def [](controller_number_or_symbol)
@@ -202,7 +202,7 @@ module Musa
202
202
  @voice.active_pitches[pitch][:note_controls] << self
203
203
  @voice.active_pitches[pitch][:velocity] = velocity
204
204
 
205
- msg = MIDIMessage::NoteOn.new(@voice.channel, pitch, velocity)
205
+ msg = MIDIEvents::NoteOn.new(@voice.channel, pitch, velocity)
206
206
  @voice.log "#{msg.verbose_name} velocity: #{velocity} duration: #{@duration}"
207
207
  @voice.output.puts msg if @voice.output && !@voice.fast_forward?
208
208
  else
@@ -235,7 +235,7 @@ module Musa
235
235
 
236
236
  next unless @voice.active_pitches[pitch][:note_controls].empty?
237
237
 
238
- msg = MIDIMessage::NoteOff.new(@voice.channel, pitch, velocity_off)
238
+ msg = MIDIEvents::NoteOff.new(@voice.channel, pitch, velocity_off)
239
239
  @voice.log msg.verbose_name.to_s
240
240
  @voice.output.puts msg if @voice.output && !@voice.fast_forward?
241
241
  end
@@ -1,25 +1,21 @@
1
1
  require 'socket'
2
+ require 'pathname'
2
3
 
3
4
  module Musa
4
5
  module REPL
5
6
  class REPL
6
7
  @@repl_mutex = Mutex.new
7
8
 
8
- def initialize(binder, port: nil, after_eval: nil, logger: nil)
9
+ def initialize(binder = nil, port: nil, after_eval: nil, logger: nil)
10
+
11
+ self.binder = binder
12
+
9
13
  port ||= 1327
10
14
 
11
15
  @logger = logger || Musa::Logger::Logger.new
12
16
 
13
17
  @block_source = nil
14
18
 
15
- if binder.receiver.respond_to?(:sequencer) &&
16
- binder.receiver.sequencer.respond_to?(:on_error)
17
-
18
- binder.receiver.sequencer.on_error do |e|
19
- send_exception e, output: @connection
20
- end
21
- end
22
-
23
19
  @client_threads = []
24
20
  @run = true
25
21
 
@@ -42,7 +38,7 @@ module Musa
42
38
 
43
39
  when '#begin'
44
40
  user_path = buffer&.string
45
- binder.local_variable_set(:user_path, user_path)
41
+ @binder.receiver.instance_variable_set(:@user_pathname, Pathname.new(user_path)) if user_path
46
42
 
47
43
  buffer = StringIO.new
48
44
 
@@ -52,7 +48,7 @@ module Musa
52
48
 
53
49
  begin
54
50
  send_echo @block_source, output: @connection
55
- binder.eval @block_source, "(repl)", 1
51
+ @binder.eval @block_source, "(repl)", 1
56
52
 
57
53
  rescue StandardError, ScriptError => e
58
54
  @logger.warn('REPL') { 'code execution error' }
@@ -88,6 +84,22 @@ module Musa
88
84
  end
89
85
  end
90
86
 
87
+ def binder=(binder)
88
+ raise 'Already binded' if @binder
89
+
90
+ @binder = binder
91
+
92
+ return unless @binder
93
+
94
+ if @binder.receiver.respond_to?(:sequencer) &&
95
+ @binder.receiver.sequencer.respond_to?(:on_error)
96
+
97
+ @binder.receiver.sequencer.on_error do |e|
98
+ send_exception e, output: @connection
99
+ end
100
+ end
101
+ end
102
+
91
103
  def stop
92
104
  @run = false
93
105
 
@@ -100,6 +112,14 @@ module Musa
100
112
  @client_threads.clear
101
113
  end
102
114
 
115
+ def puts(message)
116
+ if @connection
117
+ send output: @connection, content: message&.to_s
118
+ else
119
+ @logger.warn('REPL') { "trying to print a message in Atom client but the client is not connected. Ignoring message \'#{message} \'." }
120
+ end
121
+ end
122
+
103
123
  private
104
124
 
105
125
  def send_echo(e, output:)
@@ -28,7 +28,8 @@ module Musa::Sequencer
28
28
  control.do_on_stop.each(&:call)
29
29
 
30
30
  control.do_after.each do |do_after|
31
- _numeric_at position + (interval || 0) + do_after[:bars], control, &do_after[:block]
31
+ # _numeric_at position + (interval || 0) + do_after[:bars], control, &do_after[:block]
32
+ _numeric_at position + do_after[:bars], control, &do_after[:block]
32
33
  end
33
34
  else
34
35
  _numeric_at control._start_position + control._execution_counter * interval, control do
@@ -43,8 +43,8 @@ module Musa
43
43
  @dsl.with &block if block_given?
44
44
  end
45
45
 
46
- def with(&block)
47
- @dsl.with &block
46
+ def with(*value_parameters, **key_parameters, &block)
47
+ @dsl.with(*value_parameters, **key_parameters, &block)
48
48
  end
49
49
 
50
50
  class DSLContext
@@ -1,17 +1,19 @@
1
+ require 'midi-parser'
2
+
1
3
  require_relative 'clock'
2
- require 'nibbler'
3
4
 
4
5
  module Musa
5
6
  module Clock
6
7
  class InputMidiClock < Clock
7
- def initialize(input, logger: nil, do_log: nil)
8
+ def initialize(input = nil, logger: nil, do_log: nil)
8
9
  do_log ||= false
9
10
 
10
11
  super()
11
12
 
12
- @input = input
13
13
  @logger = logger
14
14
 
15
+ self.input = input
16
+
15
17
  if logger
16
18
  @logger = logger
17
19
  else
@@ -19,21 +21,41 @@ module Musa
19
21
  @logger.debug! if do_log
20
22
  end
21
23
 
22
- @nibbler = Nibbler.new
24
+ @midi_parser = MIDIParser.new
25
+ end
26
+
27
+ attr_reader :input
28
+
29
+ def input=(input_midi_port)
30
+ @input = input_midi_port
31
+ @waiting_for_input&.wakeup
23
32
  end
24
33
 
25
34
  def run
26
35
  @run = true
27
36
 
28
37
  while @run
29
- raw_messages = @input.gets
30
- @input.buffer.clear
38
+ if @input
39
+ raw_messages = @input.gets
40
+ else
41
+ @logger.warn('InputMidiClock') { 'Waiting for clock input MIDI port' }
42
+
43
+ @waiting_for_input = Thread.current
44
+ sleep
45
+ @waiting_for_input = nil
46
+
47
+ if @input
48
+ @logger.info('InputMidiClock') { "Assigned clock input MIDI port '#{@input.name}'" }
49
+ else
50
+ @logger.warn('InputMidiClock') { 'Clock input MIDI port not found' }
51
+ end
52
+ end
31
53
 
32
54
  messages = []
33
55
  stop_index = nil
34
56
 
35
- raw_messages.each do |message|
36
- mm = @nibbler.parse message[:data]
57
+ raw_messages&.each do |message|
58
+ mm = @midi_parser.parse message[:data]
37
59
 
38
60
  if mm
39
61
  if mm.is_a? Array
@@ -48,10 +70,6 @@ module Musa
48
70
  end
49
71
  end
50
72
 
51
- @nibbler.processed.clear
52
- @nibbler.rejected.clear
53
- @nibbler.messages.clear
54
-
55
73
  size = messages.size
56
74
  index = 0
57
75
  while index < size
@@ -12,6 +12,7 @@ module Musa
12
12
  def initialize(clock,
13
13
  beats_per_bar = nil,
14
14
  ticks_per_beat = nil,
15
+ sequencer: nil,
15
16
  before_begin: nil,
16
17
  on_start: nil,
17
18
  after_stop: nil,
@@ -39,7 +40,8 @@ module Musa
39
40
 
40
41
  @do_log = do_log
41
42
 
42
- @sequencer = Musa::Sequencer::Sequencer.new beats_per_bar, ticks_per_beat, logger: logger, do_log: @do_log
43
+ @sequencer = sequencer
44
+ @sequencer ||= Musa::Sequencer::Sequencer.new beats_per_bar, ticks_per_beat, logger: logger, do_log: @do_log
43
45
 
44
46
  @clock.on_start do
45
47
  do_on_start
data/lib/musa-dsl.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module Musa
2
- VERSION = '0.23.21'
2
+ VERSION = '0.26.0'.freeze
3
3
  end
4
4
 
5
5
  require_relative 'musa-dsl/core-ext'
data/musa-dsl.gemspec CHANGED
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'musa-dsl'
3
- s.version = '0.23.21'
4
- s.date = '2021-10-26'
3
+ s.version = '0.26.0'
4
+ s.date = '2021-11-19'
5
5
  s.summary = 'A simple Ruby DSL for making complex music'
6
6
  s.description = 'Musa-DSL: A Ruby framework and DSL for algorithmic sound and musical thinking and composition'
7
7
  s.authors = ['Javier Sánchez Yeste']
@@ -20,8 +20,13 @@ Gem::Specification.new do |s|
20
20
  # "changelog_uri" => ""
21
21
  #}
22
22
 
23
- s.add_runtime_dependency 'citrus', '~> 3.0.0', '>= 3.0.0'
23
+ s.add_runtime_dependency 'logger', '~> 1.4', '>= 1.4.3'
24
24
 
25
- s.add_runtime_dependency 'midi-message', '~> 0.4', '>= 0.4.9'
26
- s.add_runtime_dependency 'midi-nibbler', '~> 0.2', '>= 0.2.4'
25
+ s.add_runtime_dependency 'citrus', '~> 3.0', '>= 3.0.0'
26
+
27
+ s.add_runtime_dependency 'midi-events', '~> 0.5', '>= 0.5.0'
28
+ s.add_runtime_dependency 'midi-parser', '~> 0.3', '>= 0.3.0'
29
+
30
+ s.add_development_dependency 'descriptive-statistics', '~> 2.2'
31
+ s.add_development_dependency 'rspec', '~> 3.0'
27
32
  end
metadata CHANGED
@@ -1,22 +1,42 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: musa-dsl
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.23.21
4
+ version: 0.26.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Javier Sánchez Yeste
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-10-26 00:00:00.000000000 Z
11
+ date: 2021-11-19 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: logger
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.4'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 1.4.3
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '1.4'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 1.4.3
13
33
  - !ruby/object:Gem::Dependency
14
34
  name: citrus
15
35
  requirement: !ruby/object:Gem::Requirement
16
36
  requirements:
17
37
  - - "~>"
18
38
  - !ruby/object:Gem::Version
19
- version: 3.0.0
39
+ version: '3.0'
20
40
  - - ">="
21
41
  - !ruby/object:Gem::Version
22
42
  version: 3.0.0
@@ -26,50 +46,78 @@ dependencies:
26
46
  requirements:
27
47
  - - "~>"
28
48
  - !ruby/object:Gem::Version
29
- version: 3.0.0
49
+ version: '3.0'
30
50
  - - ">="
31
51
  - !ruby/object:Gem::Version
32
52
  version: 3.0.0
33
53
  - !ruby/object:Gem::Dependency
34
- name: midi-message
54
+ name: midi-events
35
55
  requirement: !ruby/object:Gem::Requirement
36
56
  requirements:
37
57
  - - "~>"
38
58
  - !ruby/object:Gem::Version
39
- version: '0.4'
59
+ version: '0.5'
40
60
  - - ">="
41
61
  - !ruby/object:Gem::Version
42
- version: 0.4.9
62
+ version: 0.5.0
43
63
  type: :runtime
44
64
  prerelease: false
45
65
  version_requirements: !ruby/object:Gem::Requirement
46
66
  requirements:
47
67
  - - "~>"
48
68
  - !ruby/object:Gem::Version
49
- version: '0.4'
69
+ version: '0.5'
50
70
  - - ">="
51
71
  - !ruby/object:Gem::Version
52
- version: 0.4.9
72
+ version: 0.5.0
53
73
  - !ruby/object:Gem::Dependency
54
- name: midi-nibbler
74
+ name: midi-parser
55
75
  requirement: !ruby/object:Gem::Requirement
56
76
  requirements:
57
77
  - - "~>"
58
78
  - !ruby/object:Gem::Version
59
- version: '0.2'
79
+ version: '0.3'
60
80
  - - ">="
61
81
  - !ruby/object:Gem::Version
62
- version: 0.2.4
82
+ version: 0.3.0
63
83
  type: :runtime
64
84
  prerelease: false
65
85
  version_requirements: !ruby/object:Gem::Requirement
66
86
  requirements:
67
87
  - - "~>"
68
88
  - !ruby/object:Gem::Version
69
- version: '0.2'
89
+ version: '0.3'
70
90
  - - ">="
71
91
  - !ruby/object:Gem::Version
72
- version: 0.2.4
92
+ version: 0.3.0
93
+ - !ruby/object:Gem::Dependency
94
+ name: descriptive-statistics
95
+ requirement: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - "~>"
98
+ - !ruby/object:Gem::Version
99
+ version: '2.2'
100
+ type: :development
101
+ prerelease: false
102
+ version_requirements: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - "~>"
105
+ - !ruby/object:Gem::Version
106
+ version: '2.2'
107
+ - !ruby/object:Gem::Dependency
108
+ name: rspec
109
+ requirement: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - "~>"
112
+ - !ruby/object:Gem::Version
113
+ version: '3.0'
114
+ type: :development
115
+ prerelease: false
116
+ version_requirements: !ruby/object:Gem::Requirement
117
+ requirements:
118
+ - - "~>"
119
+ - !ruby/object:Gem::Version
120
+ version: '3.0'
73
121
  description: 'Musa-DSL: A Ruby framework and DSL for algorithmic sound and musical
74
122
  thinking and composition'
75
123
  email: javier.sy@gmail.com
@@ -77,6 +125,7 @@ executables: []
77
125
  extensions: []
78
126
  extra_rdoc_files: []
79
127
  files:
128
+ - ".github/workflows/gem-test-and-push.yml"
80
129
  - ".gitignore"
81
130
  - Gemfile
82
131
  - LICENSE.md