guard-sclang 0.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b18831779dae4a3711cc6c01b382941999af0425
4
+ data.tar.gz: 8e281d8977a0af9ccbdaaecb38096405053b7be2
5
+ SHA512:
6
+ metadata.gz: c3a44218758f7e3bd7236d2f9c20c54b34f9461b8b7a0b2622c73d6e498f9e37ed2fe0a8eb84897097b7c0ee66919bf553c0bd6eb74bb6009429ea57b8418fdb
7
+ data.tar.gz: 73e29afaa31bec0d8c2a67f9a3432d6d0982d7c9e56159df647f5c8ceca3afbe6cd36ec0b0ee66f71e8177640ed66f9793191f0b4757c27ae21d13ee39c2a818
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2017 Adam Spiers, Joshua Hawxwell
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,100 @@
1
+ Guard::Sclang
2
+ =============
3
+
4
+ This [Guard](http://guardgem.org/) plugin allows you to run SuperCollider [`UnitTest` test
5
+ suites](http://doc.sccode.org/Classes/UnitTest.html) commands when
6
+ files are added or altered.
7
+
8
+
9
+ Install
10
+ -------
11
+
12
+ Make sure you have [Guard](http://guardgem.org/) installed.
13
+
14
+ Install the gem with:
15
+
16
+ gem install guard-sclang
17
+
18
+ Or add it to your `Gemfile`:
19
+
20
+ gem 'guard-sclang'
21
+
22
+ And then add a basic setup to your `Guardfile`:
23
+
24
+ guard init sclang
25
+
26
+
27
+ Usage
28
+ -----
29
+
30
+ When one or more files matching a `watch` block's regular expression
31
+ changes, guard-sclang simply runs the UnitTest subclass returned by
32
+ that block:
33
+
34
+ ``` ruby
35
+ guard :sclang do
36
+ # Run any tests which are added or changed under lib/tests/
37
+ watch(%r{lib/tests/\w.*\.sc})
38
+
39
+ # For any class Foo added or changed under lib/classes/, run
40
+ # the corresponding test class TestFoo
41
+ watch(%r{lib/classes/(\w.*)\.sc}) do |m|
42
+ classname = "Test#{m[1]}"
43
+ puts "#{m[0]} changed; running #{classname}"
44
+ classname
45
+ end
46
+ end
47
+ ```
48
+
49
+ ### `sclang` CLI arguments
50
+
51
+ You can optionally provide arguments to be passed to `sclang`, e.g.
52
+
53
+ ``` ruby
54
+ # Load the ScQT IDE classes
55
+ guard :sclang, args: ["-i", "scqt"] do
56
+ ...
57
+ end
58
+ ```
59
+
60
+ ### `sclang` execution timeout
61
+
62
+ If `sclang` experiences a compilation error, it will hang, so
63
+ invocation of `sclang` is currently wrapped by
64
+ [`timeout(1)`](https://linux.die.net/man/1/timeout). (This
65
+ currently prevents `guard-sclang` from working outside Linux,
66
+ but it should not be hard to convert the timeout mechanism to native
67
+ Ruby to fix that.)
68
+
69
+ The timeout defaults to 3 seconds, but can be changed:
70
+
71
+ ``` ruby
72
+ guard :sclang, timeout: 10 do
73
+ ...
74
+ end
75
+ ```
76
+
77
+ ### Other options
78
+
79
+ To run everything on start pass `:all_on_start` to `#guard`:
80
+
81
+ ``` ruby
82
+ guard :sclang, all_on_start: true do
83
+ ...
84
+ end
85
+ ```
86
+
87
+
88
+ Development / support / feedback
89
+ --------------------------------
90
+
91
+ Please see [the CONTRIBUTING file](CONTRIBUTING.md).
92
+
93
+
94
+ History and license
95
+ -------------------
96
+
97
+ This plugin was based on
98
+ [`guard-shell`](https://github.com/guard/guard-shell) by Joshua
99
+ Hawxwell, so the original license has been preserved - see
100
+ [LICENSE](LICENSE).
@@ -0,0 +1,152 @@
1
+ require 'pathname'
2
+ require 'pty'
3
+
4
+ require 'guard/compat/plugin'
5
+ require 'guard/sclang/version'
6
+
7
+ module Guard
8
+ class Sclang < Plugin
9
+ def initialize(options={})
10
+ super
11
+ options[:args] ||= []
12
+ options[:timeout] ||= 3
13
+ end
14
+
15
+ # Calls #run_all if the :all_on_start option is present.
16
+ def start
17
+ run_all if options[:all_on_start]
18
+ end
19
+
20
+ # Defined only to make callback(:stop_begin) and callback(:stop_end) working
21
+ def stop
22
+ end
23
+
24
+ # Call #run_on_change for all files which match this guard.
25
+ def run_all
26
+ all = Compat.matching_files(self, Dir.glob('{,**/}*.sc{,d}'))
27
+ run_on_modifications(all)
28
+ end
29
+
30
+ def run_on_additions(paths)
31
+ run_sclang(paths)
32
+ end
33
+
34
+ def run_on_modifications(paths)
35
+ run_sclang(paths)
36
+ end
37
+
38
+ def run_on_removals(paths)
39
+ run_sclang(paths)
40
+ end
41
+
42
+ def _get_cmd_and_title(paths)
43
+ # -i scqt is required to compile IDE libraries, otherwise we get
44
+ # compile warnings on Quarks which extend classes provided by those
45
+ # IDE libraries.
46
+ here = Pathname.new(__FILE__).dirname
47
+ runner = here.parent.parent + "unit-test-cli.scd"
48
+ tester = ["sclang"] + options[:args] + [runner.to_s]
49
+ cmd = ["timeout", options[:timeout].to_s] + tester
50
+ if paths
51
+ cmd += paths
52
+ title = paths.join " "
53
+ else
54
+ title = tester.join " "
55
+ end
56
+ [cmd, title]
57
+ end
58
+
59
+ def run_sclang(paths)
60
+ paths = paths.uniq
61
+ cmd, title = _get_cmd_and_title(paths)
62
+
63
+ outerr = ''
64
+ print Compat::UI.color("=" * (ENV["COLUMNS"] || "72").to_i, :blue)
65
+ print Compat::UI.color("Running: " + cmd.join(" ") + "\n", :blue)
66
+
67
+ got_status, exit_status = _run_cmd(cmd, title)
68
+
69
+ unless got_status
70
+ _handle_missing_status(exit_status, title)
71
+ end
72
+ end
73
+
74
+ def _run_cmd(cmd, title)
75
+ command, *args = *cmd
76
+
77
+ got_status = false
78
+ exit_status = nil
79
+
80
+ # Using PTY instead of Open3.popen2e should work around
81
+ # https://github.com/supercollider/supercollider/issues/3366
82
+ begin
83
+ PTY.spawn command, *args do |stdouterr, stdin, pid|
84
+ begin
85
+ stdouterr.each do |line|
86
+ #Compat::UI.info(line)
87
+ colors =
88
+ if line =~ /^PASS:/
89
+ [:green]
90
+ elsif line =~ /^FAIL:/
91
+ [:red]
92
+ elsif line =~ /^ERROR:/
93
+ [:bright, :red]
94
+ elsif line =~ /^WARNING:/
95
+ [:yellow]
96
+ else
97
+ []
98
+ end
99
+
100
+ status, msg, line = _check_line_for_status(line)
101
+ if status
102
+ got_status = true
103
+ Compat::UI.notify(msg, title: title, image: status)
104
+ end
105
+
106
+ print Compat::UI.color(line, *colors)
107
+ end
108
+
109
+ # stdouterr should always raise Errno::EIO when EOF is reached.
110
+ # If this doesn't happen, probably the test suite is running.
111
+ raise Errno::EIO
112
+ rescue Errno::EIO => e
113
+ # Ran out of output to read
114
+ exit_status = $?
115
+ end
116
+ end
117
+ rescue PTY::ChildExited => e
118
+ $stdout.puts "The child process exited! #{e}"
119
+ exit_status = e.status.exitstatus
120
+ end
121
+
122
+ [got_status, exit_status]
123
+ end
124
+
125
+ def _check_line_for_status(line)
126
+ status, msg = nil
127
+
128
+ if line =~ /Finished running test\(s\): (\d+ pass(?:es), (\d+) failures?)/
129
+ msg, failures = $1, $2
130
+ status = failures == "0" ? :success : :failed # :pending also supported
131
+ elsif line =~ /(Library has not been compiled successfully)\./
132
+ msg = $1
133
+ status = :failed
134
+ end
135
+
136
+ if status
137
+ line = Compat::UI.color(line, status == :success ? :green : :red)
138
+ end
139
+
140
+ [status, msg, line]
141
+ end
142
+
143
+ def _handle_missing_status(exit_status, title)
144
+ msg = "Pid %d exited with status %d" % [exit_status.pid, exit_status.exitstatus]
145
+ status = exit_status == 0 ? :success : :failed
146
+ Compat::UI.notify(msg, title: title, image: status)
147
+ level = status == :success ? :warning : :error
148
+ Compat::UI.send(level, msg)
149
+ Compat::UI.warning("Didn't find test results in output")
150
+ end
151
+ end
152
+ end
@@ -0,0 +1,166 @@
1
+ require 'open3'
2
+ require 'pathname'
3
+
4
+ require 'guard/compat/plugin'
5
+ require 'guard/sclang/version'
6
+
7
+ module Guard
8
+ class Sclang < Plugin
9
+ <<<<<<< HEAD
10
+ def initialize
11
+ =======
12
+ def initialize(options)
13
+ >>>>>>> c984ace... fix tests
14
+ super
15
+ options[:args] ||= []
16
+ options[:timeout] ||= 3
17
+ end
18
+
19
+ # Calls #run_all if the :all_on_start option is present.
20
+ def start
21
+ run_all if options[:all_on_start]
22
+ end
23
+
24
+ # Defined only to make callback(:stop_begin) and callback(:stop_end) working
25
+ def stop
26
+ end
27
+
28
+ # Call #run_on_change for all files which match this guard.
29
+ def run_all
30
+ all = Compat.matching_files(self, Dir.glob('{,**/}*.sc{,d}'))
31
+ run_on_modifications(all)
32
+ end
33
+
34
+ def run_on_additions(paths)
35
+ run_sclang(paths)
36
+ end
37
+
38
+ def run_on_modifications(paths)
39
+ run_sclang(paths)
40
+ end
41
+
42
+ def run_on_removals(paths)
43
+ run_sclang(paths)
44
+ end
45
+
46
+ def _get_cmd_and_title(paths)
47
+ # -i scqt is required to compile IDE libraries, otherwise we get
48
+ # compile warnings on Quarks which extend classes provided by those
49
+ # IDE libraries.
50
+ here = Pathname.new(__FILE__).dirname
51
+ runner = here.parent.parent + "unit-test-cli.scd"
52
+ tester = ["sclang"] + options[:args] + [runner.to_s]
53
+ cmd = ["timeout", options[:timeout].to_s] + tester
54
+ if paths
55
+ cmd += paths
56
+ title = paths.join " "
57
+ else
58
+ title = tester.join " "
59
+ end
60
+ [cmd, title]
61
+ end
62
+
63
+ def run_sclang(paths)
64
+ cmd, title = _get_cmd_and_title(paths)
65
+
66
+ outerr = ''
67
+ print Compat::UI.color("=" * (ENV["COLUMNS"] || "72").to_i, :blue)
68
+ print Compat::UI.color("Running: " + cmd.join(" ") + "\n", :blue)
69
+
70
+ got_status, exit_status = _run_cmd(cmd, title)
71
+
72
+ unless got_status
73
+ _handle_missing_status(exit_status)
74
+ end
75
+ end
76
+
77
+ def _run_cmd(cmd, title)
78
+ got_status = false
79
+ exit_status = nil
80
+
81
+ Open3.popen2e(*cmd) do |stdin, stdouterr, wait_thr|
82
+ stdouterr.each do |line|
83
+ #Compat::UI.info(line)
84
+ colors =
85
+ if line =~ /^PASS:/
86
+ [:green]
87
+ elsif line =~ /^FAIL:/
88
+ [:red]
89
+ elsif line =~ /^ERROR:/
90
+ [:bright, :red]
91
+ elsif line =~ /^WARNING:/
92
+ [:yellow]
93
+ else
94
+ []
95
+ end
96
+
97
+ status, msg, line = _check_line_for_status(line)
98
+ if status
99
+ got_status = true
100
+ Compat::UI.notify(msg, title: title, image: status)
101
+ end
102
+
103
+ print Compat::UI.color(line, *colors)
104
+ end
105
+
106
+ exit_status = wait_thr.value
107
+ end
108
+
109
+ [got_status, exit_status]
110
+ end
111
+
112
+ def _check_line_for_status(line)
113
+ status, msg = nil
114
+
115
+ if line =~ /Finished running test\(s\): (\d+ pass(?:es), (\d+) failures?)/
116
+ msg, failures = $1, $2
117
+ status = failures == "0" ? :success : :failed # :pending also supported
118
+ elsif line =~ /(Library has not been compiled successfully)\./
119
+ msg = $1
120
+ status = :failed
121
+ end
122
+
123
+ if status
124
+ line = Compat::UI.color(line, status == :success ? :green : :red)
125
+ end
126
+
127
+ [status, msg, line]
128
+ end
129
+
130
+ def _handle_missing_status(exit_status)
131
+ msg = "Pid %d exited with status %d" % [exit_status.pid, exit_status]
132
+ status = exit_status == 0 ? :success : :failed
133
+ Compat::UI.notify(msg, title: title, image: status)
134
+ level = status == :success ? :warning : :error
135
+ Compat::UI.send(level, msg)
136
+ Compat::UI.warning("Didn't find test results in output")
137
+ end
138
+ end
139
+
140
+ class Dsl
141
+ # Easy method to display a notification
142
+ def n(msg, title='', image=nil)
143
+ Compat::UI.notify(msg, :title => title, :image => image)
144
+ end
145
+
146
+ # Eager prints the result for stdout and stderr as it would be written when
147
+ # running the command from the terminal. This is useful for long running
148
+ # tasks.
149
+ def eager(command)
150
+ require 'pty'
151
+
152
+ begin
153
+ PTY.spawn command do |r, w, pid|
154
+ begin
155
+ $stdout.puts
156
+ r.each {|line| print line }
157
+ rescue Errno::EIO
158
+ # the process has finished
159
+ end
160
+ end
161
+ rescue PTY::ChildExited
162
+ $stdout.puts "The child process exited!"
163
+ end
164
+ end
165
+ end
166
+ end
@@ -0,0 +1,12 @@
1
+ guard :sclang do
2
+ # Run any tests which are added or changed under lib/tests/
3
+ watch(%r{lib/tests/\w.*\.sc})
4
+
5
+ # For any class Foo added or changed under lib/classes/, run
6
+ # the corresponding test class TestFoo
7
+ watch(%r{lib/classes/(\w.*)\.sc}) do |m|
8
+ classname = "Test#{m[1]}"
9
+ puts "#{m[0]} changed; running #{classname}"
10
+ classname
11
+ end
12
+ end
@@ -0,0 +1,5 @@
1
+ module Guard
2
+ module SclangVersion
3
+ VERSION = '0.0.1'
4
+ end
5
+ end
metadata ADDED
@@ -0,0 +1,127 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: guard-sclang
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Adam Spiers
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-12-29 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: guard
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 2.0.0
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '2.0'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 2.0.0
33
+ - !ruby/object:Gem::Dependency
34
+ name: guard-compat
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '1.0'
40
+ type: :runtime
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '1.0'
47
+ - !ruby/object:Gem::Dependency
48
+ name: rake
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '12.3'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '12.3'
61
+ - !ruby/object:Gem::Dependency
62
+ name: rspec
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '3.1'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '3.1'
75
+ - !ruby/object:Gem::Dependency
76
+ name: guard-rspec
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '4.7'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '4.7'
89
+ description: |2
90
+ Guard::Sclang automatically runs sclang commands when watched files are
91
+ modified.
92
+ email: guard@adamspiers.org
93
+ executables: []
94
+ extensions: []
95
+ extra_rdoc_files: []
96
+ files:
97
+ - LICENSE
98
+ - README.md
99
+ - lib/guard/sclang.rb
100
+ - lib/guard/sclang.rb.orig
101
+ - lib/guard/sclang/templates/Guardfile
102
+ - lib/guard/sclang/version.rb
103
+ homepage: http://github.com/aspiers/guard-sclang
104
+ licenses:
105
+ - MIT
106
+ metadata: {}
107
+ post_install_message:
108
+ rdoc_options: []
109
+ require_paths:
110
+ - lib
111
+ required_ruby_version: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - ">="
114
+ - !ruby/object:Gem::Version
115
+ version: '0'
116
+ required_rubygems_version: !ruby/object:Gem::Requirement
117
+ requirements:
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
121
+ requirements: []
122
+ rubyforge_project:
123
+ rubygems_version: 2.6.8
124
+ signing_key:
125
+ specification_version: 4
126
+ summary: Guard gem for running sclang commands
127
+ test_files: []