prcs 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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5226b488f7cfa46183e5367e4ef71d19818801eb
4
+ data.tar.gz: 0f3e807b8bfcab98dd9d3a2251d76b7091a8a5c9
5
+ SHA512:
6
+ metadata.gz: 0442d28515238691cfbd3b5905911ed78db8ab1be5dbad023024cdaeb6d5c8f23f3e56f32bd5b2cdff637589d40c52011acd5aad54ed30ad94989ab3bc3d38b6
7
+ data.tar.gz: dfa9d858dfedd67ca28e6371f3c8461383891bae1d2e7f494eef78902309e9b472db533cafe9b0678772637eefc6a0e31a2b089021edbc0161c37de2ca681643
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in prcs.gemspec
4
+ gemspec
@@ -0,0 +1,45 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ prcs (0.1.0)
5
+ childprocess (~> 3.0.0)
6
+ ffi
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ childprocess (3.0.0)
12
+ coderay (1.1.2)
13
+ diff-lcs (1.3)
14
+ ffi (1.11.3)
15
+ method_source (0.9.2)
16
+ pry (0.12.2)
17
+ coderay (~> 1.1.0)
18
+ method_source (~> 0.9.0)
19
+ rake (10.5.0)
20
+ rspec (3.8.0)
21
+ rspec-core (~> 3.8.0)
22
+ rspec-expectations (~> 3.8.0)
23
+ rspec-mocks (~> 3.8.0)
24
+ rspec-core (3.8.2)
25
+ rspec-support (~> 3.8.0)
26
+ rspec-expectations (3.8.5)
27
+ diff-lcs (>= 1.2.0, < 2.0)
28
+ rspec-support (~> 3.8.0)
29
+ rspec-mocks (3.8.2)
30
+ diff-lcs (>= 1.2.0, < 2.0)
31
+ rspec-support (~> 3.8.0)
32
+ rspec-support (3.8.3)
33
+
34
+ PLATFORMS
35
+ ruby
36
+
37
+ DEPENDENCIES
38
+ bundler (~> 2.0)
39
+ prcs!
40
+ pry
41
+ rake (~> 10.0)
42
+ rspec (~> 3.0)
43
+
44
+ BUNDLED WITH
45
+ 2.0.2
@@ -0,0 +1,34 @@
1
+ lib = File.expand_path("lib", __dir__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require "prcs/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "prcs"
7
+ spec.version = PRCS::VERSION
8
+ spec.authors = ["Kasper Grubbe"]
9
+ spec.email = ["prcs@kaspergrubbe.com"]
10
+
11
+ spec.summary = %q{A wrapper around ChildProcess}
12
+ spec.homepage = "https://github.com/kaspergrubbe/PRCS"
13
+
14
+ spec.metadata["homepage_uri"] = spec.homepage
15
+ spec.metadata["source_code_uri"] = "https://github.com/kaspergrubbe/PRCS"
16
+ spec.metadata["changelog_uri"] = "https://github.com/kaspergrubbe/PRCS/CHANGELOG.md"
17
+
18
+ # Specify which files should be added to the gem when it is released.
19
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
20
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
21
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
22
+ end
23
+ spec.bindir = "exe"
24
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
25
+ spec.require_paths = ["lib"]
26
+
27
+ spec.add_dependency "childprocess", "~> 3.0", ">= 3.0.0"
28
+ spec.add_dependency "ffi", '~> 1.12'
29
+
30
+ spec.add_development_dependency "bundler", "~> 2.0"
31
+ spec.add_development_dependency "rake", "~> 10.0"
32
+ spec.add_development_dependency "rspec", "~> 3.0"
33
+ spec.add_development_dependency "pry", "~> 0.12"
34
+ end
@@ -0,0 +1,39 @@
1
+ # PRCS
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/prcs`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem "prcs"
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install prcs
22
+
23
+ ## Usage
24
+
25
+ ```ruby
26
+ require "prcs"
27
+
28
+ prcs = PRCS::Runner.new(["bash", "spec/scripts/test.sh"]).run!
29
+ ```
30
+
31
+ ## Development
32
+
33
+ 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.
34
+
35
+ 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).
36
+
37
+ ## Contributing
38
+
39
+ Bug reports and pull requests are welcome on GitHub at https://github.com/kaspergrubbe/PRCS.
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "prcs"
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(__FILE__)
@@ -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,142 @@
1
+ require "prcs/version"
2
+ require "prcs/core_ext"
3
+
4
+ require "childprocess"
5
+
6
+ module PRCS
7
+ class Error < StandardError; end
8
+
9
+ class Runner
10
+ def initialize(command)
11
+ @command = command
12
+ @process = nil
13
+ @stdout = ""
14
+ @stderr = ""
15
+
16
+ @external_queues = {}.tap do |it|
17
+ it[:stdout] = Queue.new
18
+ it[:stderr] = Queue.new
19
+ end
20
+ @logcollectors = {}
21
+ end
22
+
23
+ def run!
24
+ stdout_pipe, stdout_wr = IO.pipe
25
+ stderr_pipe, stderr_wr = IO.pipe
26
+
27
+ ChildProcess.posix_spawn = true
28
+ @process = ChildProcess.build(*@command)
29
+ @process.leader = true
30
+ @process.io.stdout = stdout_wr
31
+ @process.io.stderr = stderr_wr
32
+
33
+ @process.start
34
+
35
+ stdout_wr.close
36
+ stderr_wr.close
37
+
38
+ @logcollectors[:stdout] = Thread.new(stdout_pipe) do |pipe|
39
+ Thread.current[:running] = true
40
+ Thread.current[:log] = ""
41
+
42
+ while Thread.current[:running]
43
+ begin
44
+ output = pipe.readline_nonblock
45
+ @external_queues[:stdout] << output
46
+ Thread.current[:log] << output
47
+ rescue IO::EAGAINWaitReadable, EOFError
48
+ end
49
+ sleep(1)
50
+ end
51
+ end
52
+
53
+ @logcollectors[:stderr] = Thread.new(stderr_pipe) do |pipe|
54
+ Thread.current[:running] = true
55
+ Thread.current[:log] = ""
56
+
57
+ while Thread.current[:running]
58
+ begin
59
+ output = pipe.readline_nonblock
60
+ @external_queues[:stderr] << output
61
+ Thread.current[:log] << output
62
+ rescue IO::EAGAINWaitReadable, EOFError
63
+ end
64
+ sleep(1)
65
+ end
66
+ end
67
+
68
+ self
69
+ end
70
+
71
+ def kill!(timeout = 15)
72
+ @logcollectors.values.each do |collector_thread|
73
+ collector_thread[:running] = false
74
+ end
75
+
76
+ begin
77
+ @process.poll_for_exit(timeout)
78
+ rescue ChildProcess::TimeoutError
79
+ @process.stop
80
+ end
81
+
82
+ @logcollectors.values.each do |collector_thread|
83
+ Thread.kill(collector_thread)
84
+ end
85
+
86
+ @stdout = @logcollectors[:stdout][:log]
87
+ @stderr = @logcollectors[:stderr][:log]
88
+
89
+ self
90
+ end
91
+
92
+ def stdout_queue
93
+ [].tap { |it|
94
+ begin
95
+ while(true)
96
+ it << @external_queues[:stdout].pop(true)
97
+ end
98
+ rescue ThreadError
99
+ end
100
+ }.join
101
+ end
102
+
103
+ def stderr_queue
104
+ [].tap { |it|
105
+ begin
106
+ while(true)
107
+ it << @external_queues[:stderr].pop(true)
108
+ end
109
+ rescue ThreadError
110
+ end
111
+ }.join
112
+ end
113
+
114
+ def stdout
115
+ if alive?
116
+ raise "Process still alive, use queue-method instead"
117
+ else
118
+ @stdout
119
+ end
120
+ end
121
+
122
+ def stderr
123
+ if alive?
124
+ raise "Process still alive, use queue-method instead"
125
+ else
126
+ @stderr
127
+ end
128
+ end
129
+
130
+ def alive?
131
+ @process.alive?
132
+ end
133
+
134
+ def exited?
135
+ @process.exited?
136
+ end
137
+
138
+ def exit_code
139
+ @process.exit_code
140
+ end
141
+ end
142
+ end
@@ -0,0 +1,3 @@
1
+ module PRCS
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,13 @@
1
+ class IO
2
+ # Inspired by https://github.com/Homebrew/brew/blob/6b2dbbc96f7d8aa12f9b8c9c60107c9cc58befc4/Library/Homebrew/extend/io.rb
3
+ def readline_nonblock
4
+ buffer = ""
5
+ buffer << read_nonblock(1) while buffer[-1] != "\n"
6
+
7
+ buffer
8
+ rescue IO::WaitReadable => blocking
9
+ raise blocking if buffer.empty?
10
+
11
+ buffer
12
+ end
13
+ end
metadata ADDED
@@ -0,0 +1,148 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: prcs
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Kasper Grubbe
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2020-01-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: childprocess
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.0'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 3.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: '3.0'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 3.0.0
33
+ - !ruby/object:Gem::Dependency
34
+ name: ffi
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '1.12'
40
+ type: :runtime
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '1.12'
47
+ - !ruby/object:Gem::Dependency
48
+ name: bundler
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '2.0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '2.0'
61
+ - !ruby/object:Gem::Dependency
62
+ name: rake
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '10.0'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '10.0'
75
+ - !ruby/object:Gem::Dependency
76
+ name: rspec
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '3.0'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '3.0'
89
+ - !ruby/object:Gem::Dependency
90
+ name: pry
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '0.12'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '0.12'
103
+ description:
104
+ email:
105
+ - prcs@kaspergrubbe.com
106
+ executables: []
107
+ extensions: []
108
+ extra_rdoc_files: []
109
+ files:
110
+ - ".gitignore"
111
+ - ".rspec"
112
+ - Gemfile
113
+ - Gemfile.lock
114
+ - PRCS.gemspec
115
+ - README.md
116
+ - Rakefile
117
+ - bin/console
118
+ - bin/setup
119
+ - lib/PRCS.rb
120
+ - lib/PRCS/version.rb
121
+ - lib/prcs/core_ext.rb
122
+ homepage: https://github.com/kaspergrubbe/PRCS
123
+ licenses: []
124
+ metadata:
125
+ homepage_uri: https://github.com/kaspergrubbe/PRCS
126
+ source_code_uri: https://github.com/kaspergrubbe/PRCS
127
+ changelog_uri: https://github.com/kaspergrubbe/PRCS/CHANGELOG.md
128
+ post_install_message:
129
+ rdoc_options: []
130
+ require_paths:
131
+ - lib
132
+ required_ruby_version: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - ">="
135
+ - !ruby/object:Gem::Version
136
+ version: '0'
137
+ required_rubygems_version: !ruby/object:Gem::Requirement
138
+ requirements:
139
+ - - ">="
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ requirements: []
143
+ rubyforge_project:
144
+ rubygems_version: 2.6.11
145
+ signing_key:
146
+ specification_version: 4
147
+ summary: A wrapper around ChildProcess
148
+ test_files: []