prcs 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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: f7fa54dc731ecef77d0dea7c842729eb9e969df2044876104f587675ecdf8b6e
4
+ data.tar.gz: ba6d8533b334085cfefa0bd2cce873cd5d936cc52bd8793a7b57a683c1390041
5
+ SHA512:
6
+ metadata.gz: bcc20dc8393d858b918b0566b2888518cf3e7ec43e3f9fa398b65c95fe259fb8dd2ca30eaadff163a0add5601d83af90cdd5e6e2843f254dd69f6b34caf0e684
7
+ data.tar.gz: 86b9c1f7152680b06e33da3a09d529ca699f9cd08263cb2cbe7a6ee5ccd60bd24d458e76582805af371d1ad9e28125e9c46d328e91b05dacf2d42fc53cecb292
@@ -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
@@ -0,0 +1 @@
1
+ 2.7.0
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.3.0)
5
+ childprocess (~> 3.0, >= 3.0.0)
6
+ ffi (~> 1.12)
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.12.1)
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 (~> 0.12)
41
+ rake (~> 10.0)
42
+ rspec (~> 3.0)
43
+
44
+ BUNDLED WITH
45
+ 2.1.4
@@ -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,160 @@
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
+ attr_reader :command
11
+
12
+ def initialize(command)
13
+ @command = command
14
+ @process = nil
15
+ @stdout = nil
16
+ @stderr = nil
17
+
18
+ @external_queues = {}.tap do |it|
19
+ it[:stdout] = Queue.new
20
+ it[:stderr] = Queue.new
21
+ end
22
+ @logcollectors = {}
23
+ end
24
+
25
+ def run!(stdin = nil)
26
+ stdout_pipe, stdout_wr = IO.pipe
27
+ stderr_pipe, stderr_wr = IO.pipe
28
+
29
+ ChildProcess.posix_spawn = true
30
+ @process = ChildProcess.build(*@command)
31
+ @process.duplex = true if stdin
32
+ @process.io.stdout = stdout_wr
33
+ @process.io.stderr = stderr_wr
34
+
35
+ @process.start
36
+
37
+ stdout_wr.close
38
+ stderr_wr.close
39
+
40
+ if stdin
41
+ @process.io.stdin.write(stdin)
42
+ @process.io.stdin.close
43
+ end
44
+
45
+ @logcollectors[:stdout] = Thread.new(stdout_pipe) do |pipe|
46
+ Thread.current[:running] = true
47
+ Thread.current[:log] = ""
48
+
49
+ while Thread.current[:running]
50
+ begin
51
+ output = pipe.readline_nonblock
52
+ @external_queues[:stdout] << output
53
+ Thread.current[:log] << output
54
+ sleep(0.1)
55
+ rescue IO::EAGAINWaitReadable, EOFError
56
+ end
57
+ end
58
+ end
59
+
60
+ @logcollectors[:stderr] = Thread.new(stderr_pipe) do |pipe|
61
+ Thread.current[:running] = true
62
+ Thread.current[:log] = ""
63
+
64
+ while Thread.current[:running]
65
+ begin
66
+ output = pipe.readline_nonblock
67
+ @external_queues[:stderr] << output
68
+ Thread.current[:log] << output
69
+ sleep(0.1)
70
+ rescue IO::EAGAINWaitReadable, EOFError
71
+ end
72
+ end
73
+ end
74
+
75
+ self
76
+ end
77
+
78
+ def run_and_wait!
79
+ self.run!
80
+ @process.wait
81
+
82
+ self
83
+ end
84
+
85
+ def kill!(timeout = 15)
86
+ @logcollectors.values.each do |collector_thread|
87
+ collector_thread[:running] = false
88
+ end
89
+
90
+ begin
91
+ @process.poll_for_exit(timeout)
92
+ rescue ChildProcess::TimeoutError
93
+ @process.stop
94
+ end
95
+
96
+ @logcollectors.values.each do |collector_thread|
97
+ Thread.kill(collector_thread)
98
+ end
99
+
100
+ @stdout = @logcollectors[:stdout][:log]
101
+ @stderr = @logcollectors[:stderr][:log]
102
+
103
+ self
104
+ end
105
+
106
+ def stdout_queue
107
+ "".tap { |it|
108
+ begin
109
+ while(true)
110
+ it << @external_queues[:stdout].pop(true)
111
+ end
112
+ rescue ThreadError
113
+ end
114
+ }
115
+ end
116
+
117
+ def stderr_queue
118
+ "".tap { |it|
119
+ begin
120
+ while(true)
121
+ it << @external_queues[:stderr].pop(true)
122
+ end
123
+ rescue ThreadError
124
+ end
125
+ }
126
+ end
127
+
128
+ def stdin
129
+ @process.io.stdin
130
+ end
131
+
132
+ def stdout
133
+ if alive?
134
+ raise "Process still alive, use queue-method instead"
135
+ else
136
+ @stdout
137
+ end
138
+ end
139
+
140
+ def stderr
141
+ if alive?
142
+ raise "Process still alive, use queue-method instead"
143
+ else
144
+ @stderr
145
+ end
146
+ end
147
+
148
+ def alive?
149
+ @process.alive?
150
+ end
151
+
152
+ def exited?
153
+ @process.exited?
154
+ end
155
+
156
+ def exit_code
157
+ @process.exit_code
158
+ end
159
+ end
160
+ 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
@@ -0,0 +1,3 @@
1
+ module PRCS
2
+ VERSION = "0.3.0"
3
+ end
metadata ADDED
@@ -0,0 +1,148 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: prcs
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.0
5
+ platform: ruby
6
+ authors:
7
+ - Kasper Grubbe
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2020-01-29 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
+ - ".ruby-version"
113
+ - Gemfile
114
+ - Gemfile.lock
115
+ - PRCS.gemspec
116
+ - README.md
117
+ - Rakefile
118
+ - bin/console
119
+ - bin/setup
120
+ - lib/prcs.rb
121
+ - lib/prcs/core_ext.rb
122
+ - lib/prcs/version.rb
123
+ homepage: https://github.com/kaspergrubbe/PRCS
124
+ licenses: []
125
+ metadata:
126
+ homepage_uri: https://github.com/kaspergrubbe/PRCS
127
+ source_code_uri: https://github.com/kaspergrubbe/PRCS
128
+ changelog_uri: https://github.com/kaspergrubbe/PRCS/CHANGELOG.md
129
+ post_install_message:
130
+ rdoc_options: []
131
+ require_paths:
132
+ - lib
133
+ required_ruby_version: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ version: '0'
138
+ required_rubygems_version: !ruby/object:Gem::Requirement
139
+ requirements:
140
+ - - ">="
141
+ - !ruby/object:Gem::Version
142
+ version: '0'
143
+ requirements: []
144
+ rubygems_version: 3.1.2
145
+ signing_key:
146
+ specification_version: 4
147
+ summary: A wrapper around ChildProcess
148
+ test_files: []