rake_command_filter 0.1.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.
Files changed (149) hide show
  1. checksums.yaml +7 -0
  2. data/.codeclimate.yml +26 -0
  3. data/.gitignore +13 -0
  4. data/.rspec +2 -0
  5. data/.rubocop.yml +10 -0
  6. data/.travis.yml +21 -0
  7. data/CODE_OF_CONDUCT.md +49 -0
  8. data/Gemfile +4 -0
  9. data/LICENSE.txt +21 -0
  10. data/README.md +95 -0
  11. data/Rakefile +18 -0
  12. data/bin/console +14 -0
  13. data/bin/setup +8 -0
  14. data/lib/command_definition.rb +148 -0
  15. data/lib/command_failed_error.rb +4 -0
  16. data/lib/line_filter.rb +24 -0
  17. data/lib/line_filter_result.rb +70 -0
  18. data/lib/rake_command_definition.rb +21 -0
  19. data/lib/rake_command_filter/version.rb +4 -0
  20. data/lib/rake_command_filter.rb +111 -0
  21. data/lib/rspec_command_definition.rb +49 -0
  22. data/lib/rubocop_command_definition.rb +29 -0
  23. data/lib/yard_command_definition.rb +32 -0
  24. data/rake_command_filter.gemspec +31 -0
  25. data/test_cases/rspec/fail/coverage/.last_run.json +5 -0
  26. data/test_cases/rspec/fail/coverage/.resultset.json +7 -0
  27. data/test_cases/rspec/fail/coverage/.resultset.json.lock +0 -0
  28. data/test_cases/rspec/fail/coverage/assets/0.10.0/application.css +799 -0
  29. data/test_cases/rspec/fail/coverage/assets/0.10.0/application.js +1707 -0
  30. data/test_cases/rspec/fail/coverage/assets/0.10.0/colorbox/border.png +0 -0
  31. data/test_cases/rspec/fail/coverage/assets/0.10.0/colorbox/controls.png +0 -0
  32. data/test_cases/rspec/fail/coverage/assets/0.10.0/colorbox/loading.gif +0 -0
  33. data/test_cases/rspec/fail/coverage/assets/0.10.0/colorbox/loading_background.png +0 -0
  34. data/test_cases/rspec/fail/coverage/assets/0.10.0/favicon_green.png +0 -0
  35. data/test_cases/rspec/fail/coverage/assets/0.10.0/favicon_red.png +0 -0
  36. data/test_cases/rspec/fail/coverage/assets/0.10.0/favicon_yellow.png +0 -0
  37. data/test_cases/rspec/fail/coverage/assets/0.10.0/loading.gif +0 -0
  38. data/test_cases/rspec/fail/coverage/assets/0.10.0/magnify.png +0 -0
  39. data/test_cases/rspec/fail/coverage/assets/0.10.0/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  40. data/test_cases/rspec/fail/coverage/assets/0.10.0/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  41. data/test_cases/rspec/fail/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  42. data/test_cases/rspec/fail/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  43. data/test_cases/rspec/fail/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  44. data/test_cases/rspec/fail/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  45. data/test_cases/rspec/fail/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  46. data/test_cases/rspec/fail/coverage/assets/0.10.0/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  47. data/test_cases/rspec/fail/coverage/assets/0.10.0/smoothness/images/ui-icons_222222_256x240.png +0 -0
  48. data/test_cases/rspec/fail/coverage/assets/0.10.0/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  49. data/test_cases/rspec/fail/coverage/assets/0.10.0/smoothness/images/ui-icons_454545_256x240.png +0 -0
  50. data/test_cases/rspec/fail/coverage/assets/0.10.0/smoothness/images/ui-icons_888888_256x240.png +0 -0
  51. data/test_cases/rspec/fail/coverage/assets/0.10.0/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  52. data/test_cases/rspec/fail/coverage/index.html +72 -0
  53. data/test_cases/rspec/fail/fail_spec.rb +7 -0
  54. data/test_cases/rspec/ok/coverage/.last_run.json +5 -0
  55. data/test_cases/rspec/ok/coverage/.resultset.json +15 -0
  56. data/test_cases/rspec/ok/coverage/.resultset.json.lock +0 -0
  57. data/test_cases/rspec/ok/coverage/assets/0.10.0/application.css +799 -0
  58. data/test_cases/rspec/ok/coverage/assets/0.10.0/application.js +1707 -0
  59. data/test_cases/rspec/ok/coverage/assets/0.10.0/colorbox/border.png +0 -0
  60. data/test_cases/rspec/ok/coverage/assets/0.10.0/colorbox/controls.png +0 -0
  61. data/test_cases/rspec/ok/coverage/assets/0.10.0/colorbox/loading.gif +0 -0
  62. data/test_cases/rspec/ok/coverage/assets/0.10.0/colorbox/loading_background.png +0 -0
  63. data/test_cases/rspec/ok/coverage/assets/0.10.0/favicon_green.png +0 -0
  64. data/test_cases/rspec/ok/coverage/assets/0.10.0/favicon_red.png +0 -0
  65. data/test_cases/rspec/ok/coverage/assets/0.10.0/favicon_yellow.png +0 -0
  66. data/test_cases/rspec/ok/coverage/assets/0.10.0/loading.gif +0 -0
  67. data/test_cases/rspec/ok/coverage/assets/0.10.0/magnify.png +0 -0
  68. data/test_cases/rspec/ok/coverage/assets/0.10.0/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  69. data/test_cases/rspec/ok/coverage/assets/0.10.0/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  70. data/test_cases/rspec/ok/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  71. data/test_cases/rspec/ok/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  72. data/test_cases/rspec/ok/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  73. data/test_cases/rspec/ok/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  74. data/test_cases/rspec/ok/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  75. data/test_cases/rspec/ok/coverage/assets/0.10.0/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  76. data/test_cases/rspec/ok/coverage/assets/0.10.0/smoothness/images/ui-icons_222222_256x240.png +0 -0
  77. data/test_cases/rspec/ok/coverage/assets/0.10.0/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  78. data/test_cases/rspec/ok/coverage/assets/0.10.0/smoothness/images/ui-icons_454545_256x240.png +0 -0
  79. data/test_cases/rspec/ok/coverage/assets/0.10.0/smoothness/images/ui-icons_888888_256x240.png +0 -0
  80. data/test_cases/rspec/ok/coverage/assets/0.10.0/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  81. data/test_cases/rspec/ok/coverage/index.html +136 -0
  82. data/test_cases/rspec/ok/ok_spec.rb +11 -0
  83. data/test_cases/rspec/ok/test_coverage.rb +6 -0
  84. data/test_cases/rubocop/fail/rubocop_fail.rb +3 -0
  85. data/test_cases/rubocop/ok/rubocop_ok.rb +2 -0
  86. data/test_cases/rubocop/rubocop.yml +4 -0
  87. data/test_cases/yard/.yardoc/checksums +0 -0
  88. data/test_cases/yard/.yardoc/object_types +0 -0
  89. data/test_cases/yard/.yardoc/objects/root.dat +0 -0
  90. data/test_cases/yard/.yardoc/proxy_types +0 -0
  91. data/test_cases/yard/fail/.yardoc/checksums +1 -0
  92. data/test_cases/yard/fail/.yardoc/object_types +0 -0
  93. data/test_cases/yard/fail/.yardoc/objects/root.dat +0 -0
  94. data/test_cases/yard/fail/.yardoc/proxy_types +0 -0
  95. data/test_cases/yard/fail/doc/YardUndocumented.html +306 -0
  96. data/test_cases/yard/fail/doc/_index.html +101 -0
  97. data/test_cases/yard/fail/doc/class_list.html +58 -0
  98. data/test_cases/yard/fail/doc/css/common.css +1 -0
  99. data/test_cases/yard/fail/doc/css/full_list.css +57 -0
  100. data/test_cases/yard/fail/doc/css/style.css +339 -0
  101. data/test_cases/yard/fail/doc/file_list.html +57 -0
  102. data/test_cases/yard/fail/doc/frames.html +26 -0
  103. data/test_cases/yard/fail/doc/index.html +101 -0
  104. data/test_cases/yard/fail/doc/js/app.js +219 -0
  105. data/test_cases/yard/fail/doc/js/full_list.js +181 -0
  106. data/test_cases/yard/fail/doc/js/jquery.js +4 -0
  107. data/test_cases/yard/fail/doc/method_list.html +75 -0
  108. data/test_cases/yard/fail/doc/top-level-namespace.html +112 -0
  109. data/test_cases/yard/fail/yard_fail.rb +12 -0
  110. data/test_cases/yard/ok/.yardoc/checksums +1 -0
  111. data/test_cases/yard/ok/.yardoc/object_types +0 -0
  112. data/test_cases/yard/ok/.yardoc/objects/root.dat +0 -0
  113. data/test_cases/yard/ok/.yardoc/proxy_types +0 -0
  114. data/test_cases/yard/ok/doc/YardDocumented.html +343 -0
  115. data/test_cases/yard/ok/doc/YardUndocumented.html +343 -0
  116. data/test_cases/yard/ok/doc/_index.html +101 -0
  117. data/test_cases/yard/ok/doc/class_list.html +58 -0
  118. data/test_cases/yard/ok/doc/css/common.css +1 -0
  119. data/test_cases/yard/ok/doc/css/full_list.css +57 -0
  120. data/test_cases/yard/ok/doc/css/style.css +339 -0
  121. data/test_cases/yard/ok/doc/file_list.html +57 -0
  122. data/test_cases/yard/ok/doc/frames.html +26 -0
  123. data/test_cases/yard/ok/doc/index.html +101 -0
  124. data/test_cases/yard/ok/doc/js/app.js +219 -0
  125. data/test_cases/yard/ok/doc/js/full_list.js +181 -0
  126. data/test_cases/yard/ok/doc/js/jquery.js +4 -0
  127. data/test_cases/yard/ok/doc/method_list.html +75 -0
  128. data/test_cases/yard/ok/doc/top-level-namespace.html +112 -0
  129. data/test_cases/yard/ok/yard_ok.rb +16 -0
  130. data/test_cases/yard/warn/.yardoc/checksums +1 -0
  131. data/test_cases/yard/warn/.yardoc/object_types +0 -0
  132. data/test_cases/yard/warn/.yardoc/objects/root.dat +0 -0
  133. data/test_cases/yard/warn/.yardoc/proxy_types +0 -0
  134. data/test_cases/yard/warn/doc/YardDocumented.html +343 -0
  135. data/test_cases/yard/warn/doc/_index.html +101 -0
  136. data/test_cases/yard/warn/doc/class_list.html +58 -0
  137. data/test_cases/yard/warn/doc/css/common.css +1 -0
  138. data/test_cases/yard/warn/doc/css/full_list.css +57 -0
  139. data/test_cases/yard/warn/doc/css/style.css +339 -0
  140. data/test_cases/yard/warn/doc/file_list.html +57 -0
  141. data/test_cases/yard/warn/doc/frames.html +26 -0
  142. data/test_cases/yard/warn/doc/index.html +101 -0
  143. data/test_cases/yard/warn/doc/js/app.js +219 -0
  144. data/test_cases/yard/warn/doc/js/full_list.js +181 -0
  145. data/test_cases/yard/warn/doc/js/jquery.js +4 -0
  146. data/test_cases/yard/warn/doc/method_list.html +75 -0
  147. data/test_cases/yard/warn/doc/top-level-namespace.html +112 -0
  148. data/test_cases/yard/warn/yard_warn.rb +16 -0
  149. metadata +306 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b99322995e35812faec4bd062f750776b6b7eea7
4
+ data.tar.gz: 4768b435d692f5829208ce58dd2c0640cf43bca6
5
+ SHA512:
6
+ metadata.gz: f53de448bf4b05ad4965f053f477578a02f0cc04a1b8c06f55e6131f92ab478e6c774aa3b1743639a2a8dcda4aa4989a143fb534db37466f80cde802e8394232
7
+ data.tar.gz: e3c83d48389dbe1a6c96431749878802c0acbf4e5484f2c914c6719e0bb6e6408c749139f5ef543e9c87c20e7736596dc42cbbfbebf0793998f0f7e19e897957
data/.codeclimate.yml ADDED
@@ -0,0 +1,26 @@
1
+ engines:
2
+ rubocop:
3
+ enabled: true
4
+ checks:
5
+ Rubocop/Metrics/LineLength:
6
+ enabled: true
7
+ max: 99
8
+ Rubocop/Style/TrailingWhitespace:
9
+ enabled: false
10
+ Rubocop/Style/RedundantReturn:
11
+ enabled: false
12
+
13
+ golint:
14
+ enabled: true
15
+ eslint:
16
+ enabled: true
17
+ csslint:
18
+ enabled: true
19
+ ratings:
20
+ paths:
21
+ - app/**
22
+ - lib/**
23
+ - "**.rb"
24
+ - "**.go"
25
+ exclude_paths:
26
+ - doc/**/*
data/.gitignore ADDED
@@ -0,0 +1,13 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ /test_files/yard/fail/doc
11
+ /test_files/yard/ok/doc
12
+ /test_files/yard/warn/doc
13
+ /test_files/rspec/ok/coverage
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.rubocop.yml ADDED
@@ -0,0 +1,10 @@
1
+ AllCops:
2
+ Exclude:
3
+ - Guardfile
4
+ - test_cases/**/*
5
+
6
+ Metrics/LineLength:
7
+ Max: 110
8
+
9
+ Style/RedundantReturn:
10
+ Enabled: false
data/.travis.yml ADDED
@@ -0,0 +1,21 @@
1
+ sudo: false
2
+ cache: bundler
3
+ language: ruby
4
+ rvm:
5
+ - 2.3.0
6
+ env:
7
+ # this doesn't do anything for MRI or RBX, but it doesn't hurt them either
8
+ # for JRuby, it enables us to get more accurate coverage data
9
+ - JRUBY_OPTS="--debug"
10
+ matrix:
11
+ allow_failures:
12
+ - rvm: ruby-head
13
+ - rvm: rbx-3
14
+ fast_finish: true
15
+ before_install: gem update --remote bundler
16
+ install:
17
+ - bundle install --retry=3
18
+ script:
19
+ - bundle exec rspec
20
+ - bundle exec rubocop
21
+
@@ -0,0 +1,49 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, and in the interest of
4
+ fostering an open and welcoming community, we pledge to respect all people who
5
+ contribute through reporting issues, posting feature requests, updating
6
+ documentation, submitting pull requests or patches, and other activities.
7
+
8
+ We are committed to making participation in this project a harassment-free
9
+ experience for everyone, regardless of level of experience, gender, gender
10
+ identity and expression, sexual orientation, disability, personal appearance,
11
+ body size, race, ethnicity, age, religion, or nationality.
12
+
13
+ Examples of unacceptable behavior by participants include:
14
+
15
+ * The use of sexualized language or imagery
16
+ * Personal attacks
17
+ * Trolling or insulting/derogatory comments
18
+ * Public or private harassment
19
+ * Publishing other's private information, such as physical or electronic
20
+ addresses, without explicit permission
21
+ * Other unethical or unprofessional conduct
22
+
23
+ Project maintainers have the right and responsibility to remove, edit, or
24
+ reject comments, commits, code, wiki edits, issues, and other contributions
25
+ that are not aligned to this Code of Conduct, or to ban temporarily or
26
+ permanently any contributor for other behaviors that they deem inappropriate,
27
+ threatening, offensive, or harmful.
28
+
29
+ By adopting this Code of Conduct, project maintainers commit themselves to
30
+ fairly and consistently applying these principles to every aspect of managing
31
+ this project. Project maintainers who do not follow or enforce the Code of
32
+ Conduct may be permanently removed from the project team.
33
+
34
+ This code of conduct applies both within project spaces and in public spaces
35
+ when an individual is representing the project or its community.
36
+
37
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
38
+ reported by contacting a project maintainer at chris@tripletriangle.com. All
39
+ complaints will be reviewed and investigated and will result in a response that
40
+ is deemed necessary and appropriate to the circumstances. Maintainers are
41
+ obligated to maintain confidentiality with regard to the reporter of an
42
+ incident.
43
+
44
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage],
45
+ version 1.3.0, available at
46
+ [http://contributor-covenant.org/version/1/3/0/][version]
47
+
48
+ [homepage]: http://contributor-covenant.org
49
+ [version]: http://contributor-covenant.org/version/1/3/0/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in rake_command_filter.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Chris Jones
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,95 @@
1
+ [![Build Status](https://travis-ci.org/chrisjones-tripletri/rake_command_filter.svg?branch=master)](https://travis-ci.org/chrisjones-tripletri/rake_command_filter)
2
+ [![Code Climate](https://codeclimate.com/github/chrisjones-tripletri/rake_command_filter/badges/gpa.svg)](https://codeclimate.com/github/chrisjones-tripletri/rake_command_filter)
3
+ [![Test Coverage](https://codeclimate.com/github/chrisjones-tripletri/rake_command_filter/badges/coverage.svg)](https://codeclimate.com/github/chrisjones-tripletri/rake_command_filter/coverage)
4
+
5
+ # RakeCommandFilter
6
+
7
+ RakeCommandFilter allows you to execute multiple rake commands in subprocesses and filter
8
+ their output for easy review.
9
+
10
+ ## Installation
11
+
12
+ Add this line to your application's Gemfile:
13
+
14
+ ```ruby
15
+ gem 'rake_command_filter'
16
+ ```
17
+
18
+ And then execute:
19
+
20
+ $ bundle
21
+
22
+ Or install it yourself as:
23
+
24
+ $ gem install rake_command_filter
25
+
26
+ ## Purpose
27
+
28
+ Prior to checking in, I wanted to run all my favored validation tools (rubocop, rspec with simplecov, and yard),
29
+ and review simple output like this:
30
+
31
+ ```
32
+ OK rubocop 1.27s 15 files
33
+ OK spec 7.97s 11 passed
34
+ OK spec 7.97s 96.9 test coverage
35
+ OK yard 1.46s 100.0 documented
36
+ ```
37
+
38
+ so that I did not need to dig through the results to determine if I was satisfied. Only if they failed did I want to see detailed output from a given command.
39
+
40
+ RakeCommandFilter does this, and can be extended to process the output of other tools.
41
+
42
+ ## Usage
43
+
44
+ Put this in your Rakefile, then run ```rake full_validation```.
45
+
46
+ ```ruby
47
+ require 'rake_command_filter'
48
+
49
+ RakeCommandFilter::RakeTask.new(:full_validation) do
50
+ desc 'Run full validation'
51
+ run_definition(RakeCommandFilter::RubocopCommandDefinition.new)
52
+ run_definition(RakeCommandFilter::RSpecCommandDefinition.new)
53
+ run_definition(RakeCommandFilter::YardCommandDefinition.new)
54
+ end
55
+ ```
56
+
57
+ If you setup a rake command like that above, you can use this as a git pre-commit hook:
58
+
59
+ ```bash
60
+ #!/bin/bash
61
+ rake full_validation
62
+ exit $?
63
+ ```
64
+ in order to see the nice output whenever you commit.
65
+
66
+ ## Customization
67
+
68
+ You can customize rake_command_filter to run and parse the output of other
69
+ commands by implementing your own CommandDefinition subclass. You can also
70
+ alter an existing version in a block, as in this example from the tests:
71
+
72
+ ```ruby
73
+ task = RakeCommandFilter::RakeTask.new(:test_warn) do
74
+ desc 'My deployment task'
75
+ run_definition(RakeCommandFilter::YardCommandDefinition.new) do
76
+ add_parameter(' doc yard_warn.rb')
77
+ end
78
+ end
79
+ ```
80
+
81
+ ## Development
82
+
83
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
84
+
85
+ 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).
86
+
87
+ ## Contributing
88
+
89
+ Bug reports and pull requests are welcome on GitHub at https://github.com/chrisjones-tripletri/rake_command_filter. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
90
+
91
+
92
+ ## License
93
+
94
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
95
+
data/Rakefile ADDED
@@ -0,0 +1,18 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+ require 'rubocop/rake_task'
4
+ require 'rake_command_filter'
5
+ require 'yard'
6
+
7
+ RSpec::Core::RakeTask.new(:spec)
8
+ RuboCop::RakeTask.new(:rubocop)
9
+ YARD::Rake::YardocTask.new(:yard)
10
+
11
+ RakeCommandFilter::RakeTask.new(:full_validation) do
12
+ desc 'Run full validation'
13
+ run_definition(RakeCommandFilter::RubocopCommandDefinition.new)
14
+ run_definition(RakeCommandFilter::RSpecCommandDefinition.new)
15
+ run_definition(RakeCommandFilter::YardCommandDefinition.new)
16
+ end
17
+
18
+ task default: :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'rake_command_filter'
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require 'irb'
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,148 @@
1
+ module RakeCommandFilter
2
+ # Base class for commands that get executed, and their output filtered
3
+ # rubocop:disable ClassLength
4
+ class CommandDefinition
5
+ attr_accessor :name
6
+ attr_accessor :default_line_handling
7
+ attr_accessor :filter
8
+
9
+ # if a line doesn't match any of the patterns, then
10
+ # @param name a name used to identify the command in ouput
11
+ def initialize(name)
12
+ @name = name
13
+ @default_line_handling = LINE_HANDLING_HIDE_UNTIL_ERROR
14
+ @filters = []
15
+ @parameters = []
16
+ end
17
+
18
+ # add a new filter for output from this command
19
+ # @param id [Symbol] an identifier for the filter within the command
20
+ # @param pattern [RegEx] a regular expression which matches a pattern in a line
21
+ # @yield yields back an array of matches from the pattern. The block should return
22
+ # a CommmandDefinition#result_... variant
23
+ def add_filter(id, pattern, &block)
24
+ filter = LineFilter.new(id, pattern, block)
25
+ @filters << filter
26
+ end
27
+
28
+ # add a parameter to be passed to the command when executed
29
+ def add_parameter(param)
30
+ @parameters << param
31
+ end
32
+
33
+ # override this method
34
+ def execute
35
+ end
36
+
37
+ # @return the most severe result from an array of results
38
+ def self.find_worst_result(results)
39
+ worst = []
40
+ results.each do |result|
41
+ if worst.empty? || worst.first.severity < result.severity
42
+ worst = [result]
43
+ elsif worst.first.severity == result.severity
44
+ worst << result
45
+ end
46
+ end
47
+ worst = result_failure('INTERNAL ERROR: no pattern matched a result in the output') if worst.empty?
48
+ return worst
49
+ end
50
+
51
+ protected
52
+
53
+ # @return a result indicating the command was successful
54
+ def result_success(msg)
55
+ create_result(RakeCommandFilter::MATCH_SUCCESS, msg)
56
+ end
57
+
58
+ # @return a result indicating the command failed.
59
+ def result_failure(msg)
60
+ create_result(RakeCommandFilter::MATCH_FAILURE, msg)
61
+ end
62
+
63
+ # @return a result indicating the command showed a warning.
64
+ def result_warning(msg)
65
+ create_result(RakeCommandFilter::MATCH_WARNING, msg)
66
+ end
67
+
68
+ private
69
+
70
+ def create_result(result, msg)
71
+ LineFilterResult.new(@name, result, msg)
72
+ end
73
+
74
+ def execute_system(command)
75
+ saved_lines = []
76
+ results = []
77
+ command_start = Time.now
78
+ command = add_parameters(command)
79
+ Open3.popen3(command) do |_stdin, stdout, stderr|
80
+ process_output(stdout, results, saved_lines)
81
+ process_output(stderr, results, saved_lines)
82
+ end
83
+ output_results(results, saved_lines, command_start)
84
+ return results
85
+ end
86
+
87
+ def add_parameters(command)
88
+ @parameters.each do |param|
89
+ command << " #{param}"
90
+ end
91
+ return command
92
+ end
93
+
94
+ def process_output(stdout, results, saved_lines)
95
+ until stdout.eof?
96
+ line = stdout.readline
97
+ match_line(line, results)
98
+ saved_lines << line
99
+ end
100
+ end
101
+
102
+ def output_results(results, saved_lines, command_start)
103
+ worst_results = CommandDefinition.find_worst_result(results)
104
+ # if the lines
105
+ if worst_results[0].result != RakeCommandFilter::MATCH_SUCCESS &&
106
+ @default_line_handling == RakeCommandFilter::LINE_HANDLING_HIDE_UNTIL_ERROR
107
+ print_lines(saved_lines)
108
+ end
109
+ unless @default_line_handling == RakeCommandFilter::LINE_HANDLING_HIDE_ALWAYS
110
+ worst_results.each do |result|
111
+ result.output(Time.now - command_start) unless result.result == RakeCommandFilter::MATCH_WARNING
112
+ end
113
+ end
114
+ end
115
+
116
+ def match_line(line, results)
117
+ result = process_filters(line)
118
+ results << result if result
119
+ return result
120
+ end
121
+
122
+ def process_filters(line)
123
+ result = nil
124
+ @filters.each do |filter|
125
+ result = filter.match(line)
126
+
127
+ # stop processing filters if we found a match.
128
+ break if result
129
+ end
130
+ return result
131
+ end
132
+
133
+ def process_default_line(saved_lines, line)
134
+ case @default_line_handling
135
+ when RakeCommandFilter::LINE_HANDLING_HIDE_UNTIL_ERROR
136
+ saved_lines << line
137
+ when RakeCommandFilter::LINE_HANDLING_SHOW_ALWAYS
138
+ puts line
139
+ when RakeCommandFilter::LINE_HANDLING_HIDE_ALWAYS
140
+ # do nothing
141
+ end
142
+ end
143
+
144
+ def print_lines(lines)
145
+ lines.each { |line| puts line }
146
+ end
147
+ end
148
+ end
@@ -0,0 +1,4 @@
1
+ module RakeCommandFilter
2
+ class CommandFailedError < StandardError
3
+ end
4
+ end
@@ -0,0 +1,24 @@
1
+ module RakeCommandFilter
2
+ # method for filtering a single line of output from a command
3
+ class LineFilter
4
+ attr_accessor :id, :pattern
5
+
6
+ # Do not call this directly, use {CommandDefinition#add_filter}
7
+ def initialize(id, pattern, block)
8
+ @id = id
9
+ @pattern = pattern
10
+ @block = block
11
+ end
12
+
13
+ # Called to determine if this filter matches a line. If it
14
+ # does, returns the result from the block defined with
15
+ # {CommandDefinition#add_filter}.
16
+ # @return [LineFilterResult] or nil if no match occurred
17
+ def match(source)
18
+ source.scan(@pattern) do |matches|
19
+ return @block.call(matches)
20
+ end
21
+ return nil
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,70 @@
1
+ require 'colorize'
2
+
3
+ module RakeCommandFilter
4
+ # returned by line filter block when a command is successful.
5
+ MATCH_SUCCESS = :success
6
+
7
+ # returned by line filter block when a command fails.
8
+ MATCH_FAILURE = :failure
9
+
10
+ # return by a line filter to indicate a warning from the command
11
+ MATCH_WARNING = :warning
12
+
13
+ # returned when a line filter doesn't match the specified line.
14
+ MATCH_NONE = :none
15
+
16
+ # text used to indicate failure
17
+ FAILED_TEXT = 'FAILED'.freeze
18
+
19
+ # text used to indicate success
20
+ OK_TEXT = 'OK'.freeze
21
+
22
+ # sumarizes the result of filtering a single line of command output
23
+ class LineFilterResult
24
+ attr_accessor :name, :result, :message
25
+
26
+ # Do not create this directly, use the result_... variants in
27
+ # {CommandDefinition}
28
+ def initialize(name, result, output)
29
+ @name = name
30
+ @result = result
31
+ @message = output
32
+ end
33
+
34
+ # @return an integer where 0 == success and higher numbers imply more
35
+ # serious failures.
36
+ def severity
37
+ case @result
38
+ when MATCH_SUCCESS
39
+ return 0
40
+ when MATCH_WARNING
41
+ return 1
42
+ when MATCH_FAILURE
43
+ return 2
44
+ else
45
+ raise ArgumentError, 'Unknown result'
46
+ end
47
+ end
48
+
49
+ # Called to output the result to the console.
50
+ # @param elapsed the time running the command so far
51
+ # rubocop:disable MethodLength
52
+ def output(elapsed)
53
+ case @result
54
+ when MATCH_SUCCESS
55
+ color = :green
56
+ header = 'OK'
57
+ when MATCH_FAILURE
58
+ color = :red
59
+ header = 'FAIL'
60
+ when MATCH_WARNING
61
+ color = :light_red
62
+ header = 'WARN'
63
+ end
64
+ header = header.ljust(12).colorize(color)
65
+ str_elapsed = "#{elapsed.round(2)}s"
66
+ name = @name.to_s[0..17]
67
+ puts "#{header} #{name.ljust(20)} #{str_elapsed.ljust(9)} #{@message}"
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,21 @@
1
+ module RakeCommandFilter
2
+ # command that runs a rake task
3
+ class RakeCommandDefinition < CommandDefinition
4
+ attr_accessor :test_command
5
+
6
+ # @param name will invoke rake <name> to run
7
+ # the command
8
+ def initialize(name, test_command)
9
+ super(name)
10
+ @test_command = test_command
11
+ end
12
+
13
+ # Executes a rake task in a subprocess, and
14
+ # captures and parses the output using the
15
+ # filters associated with this command
16
+ def execute
17
+ command = RakeCommandFilter.testing? ? test_command : "rake #{@name}"
18
+ return execute_system(command)
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,4 @@
1
+ module RakeCommandFilter
2
+ # version of this gem
3
+ VERSION = '0.1.0'.freeze
4
+ end