guard-sclang 0.1.0 → 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 +5 -5
- data/CONTRIBUTING.md +4 -0
- data/README.md +57 -12
- data/lib/guard/sclang.rb +67 -15
- data/lib/guard/sclang/version.rb +1 -1
- data/unit-test-cli.scd +3 -1
- metadata +17 -4
- data/lib/guard/sclang.rb.orig +0 -166
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: ea35a0bfba850d4f17a1f3cf76f1df062053c28630e5eb17f7ccafa8f221de99
|
4
|
+
data.tar.gz: 30aa8b33db6642b9490f3ac451943acabfb6fe63e0a50bac88d240982560de62
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6191fde9ce607a751469a55c78250c7ba77106c7beb02e9cc43039d1d87db39d0d709806664539ba056373c49807d5153d59991e2cffd20e0b9c4dbd68fbbb9c
|
7
|
+
data.tar.gz: c7d8a6ec4df2c08a2391ddf2ffb589f8d04b55c0ba979ce1346c743c62799cfeb6199d55823f7ff6e9ddd4dfc59c8ccbc6054145b71e95840af1eabe1b46c3d4
|
data/CONTRIBUTING.md
CHANGED
@@ -19,3 +19,7 @@ please follow these
|
|
19
19
|
[guidelines on contributing](http://blog.adamspiers.org/2012/11/10/7-principles-for-contributing-patches-to-software-projects/) so that you can help me to help you ;-)
|
20
20
|
|
21
21
|
Thanks in advance!
|
22
|
+
|
23
|
+
## Guide for maintainers
|
24
|
+
|
25
|
+
See [`MAINTAINERS.md`](MAINTAINERS.md).
|
data/README.md
CHANGED
@@ -1,13 +1,17 @@
|
|
1
|
+
[](https://travis-ci.org/aspiers/guard-sclang)
|
2
|
+
|
1
3
|
Guard::Sclang
|
2
4
|
=============
|
3
5
|
|
4
|
-
This [Guard](http://guardgem.org/) plugin allows you to run
|
5
|
-
|
6
|
-
|
6
|
+
This [Guard](http://guardgem.org/) plugin allows you to run
|
7
|
+
SuperCollider [`UnitTest` test
|
8
|
+
suites](http://doc.sccode.org/Classes/UnitTest.html) automatically
|
9
|
+
when files are added or altered, so that you can immediately see the
|
10
|
+
impact of code changes on your tests.
|
7
11
|
|
8
12
|
|
9
|
-
|
10
|
-
|
13
|
+
Installation
|
14
|
+
------------
|
11
15
|
|
12
16
|
Make sure you have [Guard](http://guardgem.org/) installed.
|
13
17
|
|
@@ -15,17 +19,25 @@ Install the gem with:
|
|
15
19
|
|
16
20
|
gem install guard-sclang
|
17
21
|
|
18
|
-
Or add it to your `Gemfile
|
22
|
+
Or, better, add it to your `Gemfile`, and then use
|
23
|
+
[Bundler](http://bundler.io/) to install it:
|
19
24
|
|
20
|
-
gem 'guard-sclang'
|
25
|
+
echo "gem 'guard-sclang'" >> Gemfile
|
26
|
+
bundle install
|
21
27
|
|
22
|
-
And then add a basic setup to your `Guardfile`:
|
23
28
|
|
24
|
-
|
29
|
+
Configuring a `Guardfile`
|
30
|
+
---------------------------
|
25
31
|
|
32
|
+
Before you can launch Guard, you need to configure a `Guardfile` which
|
33
|
+
tells Guard which of your SuperCollider tests to run via the
|
34
|
+
`guard-sclang` plugin.
|
26
35
|
|
27
|
-
|
28
|
-
|
36
|
+
You can create a stub `Guardfile` from a built-in template via:
|
37
|
+
|
38
|
+
bundle exec guard init sclang
|
39
|
+
|
40
|
+
The rest of this section explains how to configure the `Guardfile`.
|
29
41
|
|
30
42
|
When one or more files matching a `watch` block's regular expression
|
31
43
|
changes, guard-sclang simply runs the UnitTest subclass returned by
|
@@ -76,7 +88,7 @@ end
|
|
76
88
|
|
77
89
|
### Other options
|
78
90
|
|
79
|
-
To run everything on start pass `:all_on_start` to `#guard`:
|
91
|
+
To run everything on start, pass `:all_on_start` to `#guard`:
|
80
92
|
|
81
93
|
``` ruby
|
82
94
|
guard :sclang, all_on_start: true do
|
@@ -84,6 +96,39 @@ guard :sclang, all_on_start: true do
|
|
84
96
|
end
|
85
97
|
```
|
86
98
|
|
99
|
+
To run everything after previously failing tests succeeded, pass
|
100
|
+
`:all_after_pass` to `#guard`:
|
101
|
+
|
102
|
+
``` ruby
|
103
|
+
guard :sclang, all_after_pass: true do
|
104
|
+
...
|
105
|
+
end
|
106
|
+
```
|
107
|
+
|
108
|
+
|
109
|
+
Usage
|
110
|
+
-----
|
111
|
+
|
112
|
+
Once you have set up your `Guardfile` with the `guard-sclang` plugin
|
113
|
+
enabled, you are ready to launch Guard.
|
114
|
+
|
115
|
+
`guard-sclang` assumes that the `sclang` interpreter is to be found
|
116
|
+
somewhere on your `$PATH`. If you installed SuperCollider on Linux
|
117
|
+
via a distribution package, this should happen automatically, in which
|
118
|
+
case you can simply launch Guard by typing this into your shell:
|
119
|
+
|
120
|
+
bundle exec guard
|
121
|
+
|
122
|
+
However if you installed from source, or you are using MacOS, maybe
|
123
|
+
`sclang` won't be on the `$PATH`, in which case you will need to set
|
124
|
+
it. This can either be done temporarily for each invocation of Guard,
|
125
|
+
e.g.
|
126
|
+
|
127
|
+
PATH=/path/to/dir/containing/sclang:$PATH bundle exec guard
|
128
|
+
|
129
|
+
or by configuring your interactive shell setup (e.g. `~/.bashrc`) to
|
130
|
+
set `$PATH` on startup.
|
131
|
+
|
87
132
|
|
88
133
|
Development / support / feedback
|
89
134
|
--------------------------------
|
data/lib/guard/sclang.rb
CHANGED
@@ -6,10 +6,13 @@ require 'guard/sclang/version'
|
|
6
6
|
|
7
7
|
module Guard
|
8
8
|
class Sclang < Plugin
|
9
|
+
attr_accessor :last_failed
|
10
|
+
|
9
11
|
def initialize(options={})
|
10
12
|
super
|
11
13
|
options[:args] ||= []
|
12
14
|
options[:timeout] ||= 3
|
15
|
+
@last_failed = false
|
13
16
|
end
|
14
17
|
|
15
18
|
# Calls #run_all if the :all_on_start option is present.
|
@@ -21,10 +24,13 @@ module Guard
|
|
21
24
|
def stop
|
22
25
|
end
|
23
26
|
|
24
|
-
#
|
27
|
+
# Test for all files which match this guard.
|
25
28
|
def run_all
|
26
|
-
|
27
|
-
|
29
|
+
run_sclang
|
30
|
+
end
|
31
|
+
|
32
|
+
def all_paths
|
33
|
+
Compat.matching_files(self, Dir.glob('{,**/}*.sc{,d}'))
|
28
34
|
end
|
29
35
|
|
30
36
|
def run_on_additions(paths)
|
@@ -53,10 +59,19 @@ module Guard
|
|
53
59
|
else
|
54
60
|
title = tester.join " "
|
55
61
|
end
|
56
|
-
[cmd, title]
|
62
|
+
return [cmd, title]
|
63
|
+
end
|
64
|
+
|
65
|
+
def run_sclang(paths=nil)
|
66
|
+
success = run_sclang_once(paths || all_paths)
|
67
|
+
if paths && options[:all_after_pass] && success && last_failed
|
68
|
+
success = run_all
|
69
|
+
end
|
70
|
+
@last_failed = !success
|
71
|
+
return success
|
57
72
|
end
|
58
73
|
|
59
|
-
def
|
74
|
+
def run_sclang_once(paths)
|
60
75
|
paths = paths.uniq
|
61
76
|
cmd, title = _get_cmd_and_title(paths)
|
62
77
|
|
@@ -64,17 +79,40 @@ module Guard
|
|
64
79
|
print Compat::UI.color("=" * (ENV["COLUMNS"] || "72").to_i, :blue)
|
65
80
|
print Compat::UI.color("Running: " + cmd.join(" ") + "\n", :blue)
|
66
81
|
|
67
|
-
|
82
|
+
run_status, exit_status = _run_cmd(cmd, title)
|
68
83
|
|
69
|
-
|
84
|
+
if run_status
|
85
|
+
return run_status == :success
|
86
|
+
else
|
87
|
+
# Couldn't figure out the result from the output. Even if
|
88
|
+
# the exit code is 0, this could simply mean something went
|
89
|
+
# wrong in unit-test-cli.scd's handling of an error, so we
|
90
|
+
# assume the worst.
|
70
91
|
_handle_missing_status(exit_status, title)
|
92
|
+
return :failed
|
71
93
|
end
|
72
94
|
end
|
73
95
|
|
96
|
+
# Returns [run_status, exit_status] pair.
|
97
|
+
#
|
98
|
+
# Run the test runner, add colour for PASS/FAIL/ERROR/WARNING, and
|
99
|
+
# try to extract the final test result (100% pass / some failures
|
100
|
+
# / compilation error) from the runner output. If the test result
|
101
|
+
# is successfully extracted from the output, the appropriate
|
102
|
+
# notification will be sent, and the run_status value returned
|
103
|
+
# will be :success or :failed. However if something goes wrong
|
104
|
+
# then we won't be able to determine the result from the output,
|
105
|
+
# in which case at least we capture the exit status of the runner
|
106
|
+
# process, and success is determined based on this exit status.
|
107
|
+
#
|
108
|
+
# Note that due to quirks in SuperCollider which are not yet
|
109
|
+
# understood, it is possible for the exit code to be non-zero even
|
110
|
+
# when the test suite passes 100% and the test runner is
|
111
|
+
# apparently working as designed.
|
74
112
|
def _run_cmd(cmd, title)
|
75
113
|
command, *args = *cmd
|
76
114
|
|
77
|
-
|
115
|
+
run_status = nil
|
78
116
|
exit_status = nil
|
79
117
|
|
80
118
|
# Using PTY instead of Open3.popen2e should work around
|
@@ -87,7 +125,7 @@ module Guard
|
|
87
125
|
colors =
|
88
126
|
if line =~ /^PASS:/
|
89
127
|
[:green]
|
90
|
-
elsif line =~ /^FAIL
|
128
|
+
elsif line =~ /^FAIL:|^There were failures/
|
91
129
|
[:red]
|
92
130
|
elsif line =~ /^ERROR:/
|
93
131
|
[:bright, :red]
|
@@ -97,10 +135,18 @@ module Guard
|
|
97
135
|
[]
|
98
136
|
end
|
99
137
|
|
100
|
-
|
101
|
-
if
|
102
|
-
|
103
|
-
|
138
|
+
line_status, msg, line = _check_line_for_status(line)
|
139
|
+
if line_status
|
140
|
+
# Allow for multiple summary lines just in case, e.g.
|
141
|
+
# some with no failures and others with failures.
|
142
|
+
# Hopefully this won't happen though.
|
143
|
+
if line_status == :success
|
144
|
+
run_status ||= line_status
|
145
|
+
else
|
146
|
+
run_status = line_status
|
147
|
+
end
|
148
|
+
|
149
|
+
Compat::UI.notify(msg, title: title, image: line_status)
|
104
150
|
end
|
105
151
|
|
106
152
|
print Compat::UI.color(line, *colors)
|
@@ -112,6 +158,9 @@ module Guard
|
|
112
158
|
rescue Errno::EIO => e
|
113
159
|
# Ran out of output to read
|
114
160
|
exit_status = $?
|
161
|
+
unless exit_status
|
162
|
+
Compat::UI.error("$? returned #{exit_status}")
|
163
|
+
end
|
115
164
|
end
|
116
165
|
end
|
117
166
|
rescue PTY::ChildExited => e
|
@@ -119,7 +168,7 @@ module Guard
|
|
119
168
|
exit_status = e.status.exitstatus
|
120
169
|
end
|
121
170
|
|
122
|
-
[
|
171
|
+
[run_status, exit_status]
|
123
172
|
end
|
124
173
|
|
125
174
|
def _check_line_for_status(line)
|
@@ -140,13 +189,16 @@ module Guard
|
|
140
189
|
[status, msg, line]
|
141
190
|
end
|
142
191
|
|
192
|
+
# Couldn't figure out the result from the output, so rely on
|
193
|
+
# the exit code instead.
|
143
194
|
def _handle_missing_status(exit_status, title)
|
144
195
|
msg = "Pid %d exited with status %d" % [exit_status.pid, exit_status.exitstatus]
|
145
|
-
status = exit_status
|
196
|
+
status = exit_status.success? ? :success : :failed
|
146
197
|
Compat::UI.notify(msg, title: title, image: status)
|
147
198
|
level = status == :success ? :warning : :error
|
148
199
|
Compat::UI.send(level, msg)
|
149
200
|
Compat::UI.warning("Didn't find test results in output")
|
201
|
+
exit_status.success?
|
150
202
|
end
|
151
203
|
end
|
152
204
|
end
|
data/lib/guard/sclang/version.rb
CHANGED
data/unit-test-cli.scd
CHANGED
@@ -31,6 +31,8 @@ var excludes = [
|
|
31
31
|
// Have to wrap this in a Task so that we can wait.
|
32
32
|
t = Task.new {
|
33
33
|
UnitTest.reset;
|
34
|
+
//UnitTest.reportPasses = false;
|
35
|
+
UnitTest.passVerbosity = UnitTest.brief;
|
34
36
|
if (thisProcess.argv.isEmpty) {
|
35
37
|
UnitTest.allSubclasses.do { |testClass|
|
36
38
|
if (excludes.includes(testClass.asString).not) {
|
@@ -44,7 +46,7 @@ t = Task.new {
|
|
44
46
|
} {
|
45
47
|
thisProcess.argv.do { |name|
|
46
48
|
if (name.contains("/")) {
|
47
|
-
name = name.basename.
|
49
|
+
name = PathName(name.basename).fileNameWithoutExtension;
|
48
50
|
};
|
49
51
|
if (name.contains(":")) {
|
50
52
|
UnitTest.runTest(name);
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: guard-sclang
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adam Spiers
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-04-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: guard
|
@@ -44,6 +44,20 @@ dependencies:
|
|
44
44
|
- - "~>"
|
45
45
|
- !ruby/object:Gem::Version
|
46
46
|
version: '1.0'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: bundler
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 1.13.0
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: 1.13.0
|
47
61
|
- !ruby/object:Gem::Dependency
|
48
62
|
name: rake
|
49
63
|
requirement: !ruby/object:Gem::Requirement
|
@@ -98,7 +112,6 @@ files:
|
|
98
112
|
- LICENSE
|
99
113
|
- README.md
|
100
114
|
- lib/guard/sclang.rb
|
101
|
-
- lib/guard/sclang.rb.orig
|
102
115
|
- lib/guard/sclang/templates/Guardfile
|
103
116
|
- lib/guard/sclang/version.rb
|
104
117
|
- unit-test-cli.scd
|
@@ -122,7 +135,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
122
135
|
version: '0'
|
123
136
|
requirements: []
|
124
137
|
rubyforge_project:
|
125
|
-
rubygems_version: 2.6
|
138
|
+
rubygems_version: 2.7.6
|
126
139
|
signing_key:
|
127
140
|
specification_version: 4
|
128
141
|
summary: Guard gem for running sclang commands
|
data/lib/guard/sclang.rb.orig
DELETED
@@ -1,166 +0,0 @@
|
|
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
|