mongoid 9.0.6 → 9.0.7
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 +4 -4
- data/Rakefile +9 -9
- data/lib/mongoid/association/embedded/embeds_one/proxy.rb +1 -1
- data/lib/mongoid/contextual/mongo.rb +1 -1
- data/lib/mongoid/validatable/associated.rb +1 -1
- data/lib/mongoid/validatable/macros.rb +15 -0
- data/lib/mongoid/validatable/numericality.rb +19 -0
- data/lib/mongoid/validatable.rb +1 -0
- data/lib/mongoid/version.rb +5 -2
- data/spec/integration/app_spec.rb +6 -0
- data/spec/integration/associations/embeds_one_spec.rb +25 -6
- data/spec/mongoid/association_spec.rb +0 -60
- data/spec/mongoid/contextual/mongo_spec.rb +6 -0
- data/spec/mongoid/validatable/numericality_spec.rb +16 -0
- data/spec/shared/LICENSE +20 -0
- data/spec/shared/bin/get-mongodb-download-url +17 -0
- data/spec/shared/bin/s3-copy +45 -0
- data/spec/shared/bin/s3-upload +69 -0
- data/spec/shared/lib/mrss/child_process_helper.rb +80 -0
- data/spec/shared/lib/mrss/cluster_config.rb +231 -0
- data/spec/shared/lib/mrss/constraints.rb +378 -0
- data/spec/shared/lib/mrss/docker_runner.rb +298 -0
- data/spec/shared/lib/mrss/eg_config_utils.rb +51 -0
- data/spec/shared/lib/mrss/event_subscriber.rb +210 -0
- data/spec/shared/lib/mrss/lite_constraints.rb +238 -0
- data/spec/shared/lib/mrss/release/candidate.rb +281 -0
- data/spec/shared/lib/mrss/release/product_data.rb +144 -0
- data/spec/shared/lib/mrss/server_version_registry.rb +113 -0
- data/spec/shared/lib/mrss/session_registry.rb +69 -0
- data/spec/shared/lib/mrss/session_registry_legacy.rb +60 -0
- data/spec/shared/lib/mrss/spec_organizer.rb +179 -0
- data/spec/shared/lib/mrss/utils.rb +37 -0
- data/spec/shared/lib/tasks/candidate.rake +64 -0
- data/spec/shared/share/Dockerfile.erb +251 -0
- data/spec/shared/share/haproxy-1.conf +16 -0
- data/spec/shared/share/haproxy-2.conf +17 -0
- data/spec/shared/shlib/config.sh +27 -0
- data/spec/shared/shlib/distro.sh +84 -0
- data/spec/shared/shlib/server.sh +423 -0
- data/spec/shared/shlib/set_env.sh +110 -0
- data/spec/support/expectations.rb +20 -18
- metadata +59 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 72ad16d0232a1f1c1144801896ec7322b6c452100e02e9bc5c1ba6d21e015e62
|
4
|
+
data.tar.gz: 5ca24809ea6498805807e80e78d347a8f2d517862d2ace0c39a73fb81918e178
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 82a45afa6174672d301145d1910eb6ef4d86433f078fd6514c22d644c101637404f5c2562e497dd3c9576935ce0f267fb3993d3493c520645a85e42799d0601f
|
7
|
+
data.tar.gz: d01a7d34d5b01aa5b7629b4dad7735f6c86756e86e4cbe6695301f1fe1864043041ccf4beb785bb28e48b2886d85a2c7dc4d54dddbf644a24f07b9852e15ba17
|
data/Rakefile
CHANGED
@@ -11,16 +11,16 @@ $: << File.join(ROOT, 'spec/shared/lib')
|
|
11
11
|
require "rake"
|
12
12
|
require "rspec/core/rake_task"
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
14
|
+
if File.exist?('./spec/shared/lib/tasks/candidate.rake')
|
15
|
+
load 'spec/shared/lib/tasks/candidate.rake'
|
16
|
+
end
|
17
|
+
|
18
|
+
desc 'Build the gem'
|
18
19
|
task :build do
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
WARNING
|
20
|
+
command = %w[ gem build ]
|
21
|
+
command << "--output=#{ENV['GEM_FILE_NAME']}" if ENV['GEM_FILE_NAME']
|
22
|
+
command << (ENV['GEMSPEC'] || 'mongoid.gemspec')
|
23
|
+
system(*command)
|
24
24
|
end
|
25
25
|
|
26
26
|
# `rake version` is used by the deployment system so get the release version
|
@@ -1063,7 +1063,7 @@ module Mongoid
|
|
1063
1063
|
end
|
1064
1064
|
|
1065
1065
|
def retrieve_nth_to_last_with_limit(n, limit)
|
1066
|
-
v = view.sort(inverse_sorting).
|
1066
|
+
v = view.sort(inverse_sorting).limit(limit || 1)
|
1067
1067
|
v = v.skip(n) if n > 0
|
1068
1068
|
raw_docs = v.to_a.reverse
|
1069
1069
|
process_raw_docs(raw_docs, limit)
|
@@ -74,7 +74,7 @@ module Mongoid
|
|
74
74
|
# use map.all? instead of just all?, because all? will do short-circuit
|
75
75
|
# evaluation and terminate on the first failed validation.
|
76
76
|
list.map do |value|
|
77
|
-
if value && !value.flagged_for_destroy?
|
77
|
+
if value && !value.flagged_for_destroy? && (!value.persisted? || value.changed?)
|
78
78
|
value.validated? ? true : value.valid?
|
79
79
|
else
|
80
80
|
true
|
@@ -89,6 +89,21 @@ module Mongoid
|
|
89
89
|
def validates_presence_of(*args)
|
90
90
|
validates_with(PresenceValidator, _merge_attributes(args))
|
91
91
|
end
|
92
|
+
|
93
|
+
# Validates whether or not a field contains a numeric value.
|
94
|
+
#
|
95
|
+
# @example
|
96
|
+
# class Person
|
97
|
+
# include Mongoid::Document
|
98
|
+
# field :cost
|
99
|
+
#
|
100
|
+
# validates_numericality_of :cost
|
101
|
+
# end
|
102
|
+
#
|
103
|
+
# @param [ Object... ] *args The names of the field(s) to validate.
|
104
|
+
def validates_numericality_of(*args)
|
105
|
+
validates_with(NumericalityValidator, _merge_attributes(args))
|
106
|
+
end
|
92
107
|
end
|
93
108
|
end
|
94
109
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mongoid
|
4
|
+
module Validatable
|
5
|
+
# A specialization of the ActiveModel numericality validator, which adds
|
6
|
+
# logic to recognize and accept BSON::Decimal128 as a number.
|
7
|
+
class NumericalityValidator < ActiveModel::Validations::NumericalityValidator
|
8
|
+
private
|
9
|
+
|
10
|
+
# Ensure that BSON::Decimal128 is treated as a BigDecimal during the
|
11
|
+
# validation step.
|
12
|
+
def prepare_value_for_validation(value, record, attr_name)
|
13
|
+
result = super
|
14
|
+
|
15
|
+
result.is_a?(BSON::Decimal128) ? result.to_big_decimal : result
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/mongoid/validatable.rb
CHANGED
@@ -6,6 +6,7 @@ require "mongoid/validatable/localizable"
|
|
6
6
|
require "mongoid/validatable/associated"
|
7
7
|
require "mongoid/validatable/format"
|
8
8
|
require "mongoid/validatable/length"
|
9
|
+
require "mongoid/validatable/numericality"
|
9
10
|
require "mongoid/validatable/queryable"
|
10
11
|
require "mongoid/validatable/presence"
|
11
12
|
require "mongoid/validatable/uniqueness"
|
data/lib/mongoid/version.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
# rubocop:todo all
|
3
2
|
|
4
3
|
module Mongoid
|
5
|
-
|
4
|
+
# The current version of Mongoid
|
5
|
+
#
|
6
|
+
# Note that this file is automatically updated via `rake candidate:create`.
|
7
|
+
# Manual changes to this file will be overwritten by that rake task.
|
8
|
+
VERSION = '9.0.7'
|
6
9
|
end
|
@@ -127,6 +127,12 @@ describe 'Mongoid application tests' do
|
|
127
127
|
end
|
128
128
|
|
129
129
|
context 'new application - rails' do
|
130
|
+
before(:all) do
|
131
|
+
if SpecConfig.instance.rails_version < '7.1'
|
132
|
+
skip '`rails new` with rails < 7.1 fails because modern concurrent-ruby removed logger dependency'
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
130
136
|
it 'creates' do
|
131
137
|
prepare_new_rails_app 'mongoid-test' do
|
132
138
|
check_call(%w(rails g model post), env: clean_env)
|
@@ -1,11 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
# rubocop:todo all
|
3
2
|
|
4
3
|
require 'spec_helper'
|
5
4
|
|
6
5
|
describe 'embeds_one associations' do
|
7
|
-
|
8
|
-
context 're-associating the same object' do
|
6
|
+
context 'when re-associating the same object' do
|
9
7
|
context 'with dependent: destroy' do
|
10
8
|
let(:canvas) do
|
11
9
|
Canvas.create!(palette: Palette.new)
|
@@ -17,7 +15,7 @@ describe 'embeds_one associations' do
|
|
17
15
|
canvas.palette = canvas.palette
|
18
16
|
canvas.save!
|
19
17
|
canvas.reload
|
20
|
-
canvas.palette.
|
18
|
+
expect(canvas.palette).to eq palette
|
21
19
|
end
|
22
20
|
end
|
23
21
|
end
|
@@ -31,12 +29,33 @@ describe 'embeds_one associations' do
|
|
31
29
|
end
|
32
30
|
|
33
31
|
it 'loads the association correctly' do
|
34
|
-
expect { klass }.
|
35
|
-
expect { klass.new.address }.
|
32
|
+
expect { klass }.not_to raise_error
|
33
|
+
expect { klass.new.address }.not_to raise_error
|
36
34
|
instance = klass.new
|
37
35
|
address = Address.new
|
38
36
|
instance.address = address
|
39
37
|
expect(instance.address).to eq address
|
40
38
|
end
|
41
39
|
end
|
40
|
+
|
41
|
+
context 'when parent is persisted' do
|
42
|
+
let!(:person) do
|
43
|
+
Person.create!
|
44
|
+
end
|
45
|
+
|
46
|
+
context 'when assigning the new child' do
|
47
|
+
context 'when assigning an attribute to the child' do
|
48
|
+
before do
|
49
|
+
# person.reload
|
50
|
+
person.name = Name.new
|
51
|
+
person.name.first_name = 'Dmitry'
|
52
|
+
person.save!
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'persists the child' do
|
56
|
+
expect(person.reload.name.first_name).to eq 'Dmitry'
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
42
61
|
end
|
@@ -115,66 +115,6 @@ describe Mongoid::Association do
|
|
115
115
|
expect(name).to_not be_an_embedded_many
|
116
116
|
end
|
117
117
|
end
|
118
|
-
|
119
|
-
context "when validation depends on association" do
|
120
|
-
before(:all) do
|
121
|
-
class Author
|
122
|
-
include Mongoid::Document
|
123
|
-
embeds_many :books, cascade_callbacks: true
|
124
|
-
field :condition, type: Boolean
|
125
|
-
end
|
126
|
-
|
127
|
-
class Book
|
128
|
-
include Mongoid::Document
|
129
|
-
embedded_in :author
|
130
|
-
validate :parent_condition_is_not_true
|
131
|
-
|
132
|
-
def parent_condition_is_not_true
|
133
|
-
return unless author&.condition
|
134
|
-
errors.add :base, "Author condition is true."
|
135
|
-
end
|
136
|
-
end
|
137
|
-
|
138
|
-
Author.delete_all
|
139
|
-
Book.delete_all
|
140
|
-
end
|
141
|
-
|
142
|
-
let(:author) { Author.new }
|
143
|
-
let(:book) { Book.new }
|
144
|
-
|
145
|
-
context "when author is not persisted" do
|
146
|
-
it "is valid without books" do
|
147
|
-
expect(author.valid?).to be true
|
148
|
-
end
|
149
|
-
|
150
|
-
it "is valid with a book" do
|
151
|
-
author.books << book
|
152
|
-
expect(author.valid?).to be true
|
153
|
-
end
|
154
|
-
|
155
|
-
it "is not valid when condition is true with a book" do
|
156
|
-
author.condition = true
|
157
|
-
author.books << book
|
158
|
-
expect(author.valid?).to be false
|
159
|
-
end
|
160
|
-
end
|
161
|
-
|
162
|
-
context "when author is persisted" do
|
163
|
-
before do
|
164
|
-
author.books << book
|
165
|
-
author.save
|
166
|
-
end
|
167
|
-
|
168
|
-
it "remains valid initially" do
|
169
|
-
expect(author.valid?).to be true
|
170
|
-
end
|
171
|
-
|
172
|
-
it "becomes invalid when condition is set to true" do
|
173
|
-
author.update_attributes(condition: true)
|
174
|
-
expect(author.valid?).to be false
|
175
|
-
end
|
176
|
-
end
|
177
|
-
end
|
178
118
|
end
|
179
119
|
|
180
120
|
describe "#embedded_one?" do
|
@@ -3282,6 +3282,12 @@ describe Mongoid::Contextual::Mongo do
|
|
3282
3282
|
it "limits the results" do
|
3283
3283
|
expect(context.skip(1).entries).to eq([ new_order ])
|
3284
3284
|
end
|
3285
|
+
|
3286
|
+
context "with #last" do
|
3287
|
+
it "returns the nth from last element" do
|
3288
|
+
expect(context.skip(1).last).to eq(depeche_mode)
|
3289
|
+
end
|
3290
|
+
end
|
3285
3291
|
end
|
3286
3292
|
|
3287
3293
|
describe "#sort" do
|
@@ -29,5 +29,21 @@ describe ActiveModel::Validations::NumericalityValidator do
|
|
29
29
|
expect(model).to_not be_valid
|
30
30
|
end
|
31
31
|
end
|
32
|
+
|
33
|
+
context 'when the value is numeric' do
|
34
|
+
let(:model) { TestModel.new(amount: '15.0') }
|
35
|
+
|
36
|
+
it 'returns true' do
|
37
|
+
expect(model).to be_valid
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context 'when the value is a BSON::Decimal128' do
|
42
|
+
let(:model) { TestModel.new(amount: BSON::Decimal128.new('15.0')) }
|
43
|
+
|
44
|
+
it 'returns true' do
|
45
|
+
expect(model).to be_valid
|
46
|
+
end
|
47
|
+
end
|
32
48
|
end
|
33
49
|
end
|
data/spec/shared/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2020 MongoDB, Inc.
|
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.
|
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
desired_version, arch = ARGV
|
4
|
+
if arch.nil?
|
5
|
+
STDERR.puts "Usage: get-mongodb-download-url desired-version arch"
|
6
|
+
exit 1
|
7
|
+
end
|
8
|
+
|
9
|
+
$: << File.join(File.dirname(__FILE__), '../lib')
|
10
|
+
require 'mrss/server_version_registry'
|
11
|
+
|
12
|
+
begin
|
13
|
+
puts Mrss::ServerVersionRegistry.new(desired_version, arch).download_url
|
14
|
+
rescue Mrss::ServerVersionRegistry::Error => exc
|
15
|
+
STDERR.puts "Error: #{exc}"
|
16
|
+
exit 2
|
17
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'optparse'
|
4
|
+
require 'aws-sdk-s3'
|
5
|
+
|
6
|
+
options = {}
|
7
|
+
OptionParser.new do |opts|
|
8
|
+
opts.banner = "Usage: s3-copy options"
|
9
|
+
|
10
|
+
opts.on("-r", "--region=REGION", "AWS region to use (default us-east-1)") do |v|
|
11
|
+
options[:region] = v
|
12
|
+
end
|
13
|
+
|
14
|
+
opts.on("-p", "--param=KEY=VALUE", "Specify parameter for new files") do |v|
|
15
|
+
options[:params] ||= {}
|
16
|
+
k, v = v.split('=', 2)
|
17
|
+
options[:params][k.to_sym] = v
|
18
|
+
end
|
19
|
+
|
20
|
+
opts.on("-f", "--from=BUCKET:PATH", "Bucket name and key (or path) to copy from") do |v|
|
21
|
+
options[:from] = v
|
22
|
+
end
|
23
|
+
|
24
|
+
opts.on("-t", "--to=BUCKET:PATH", "Bucket name and key (or path) to write to (may be specified more than once)") do |v|
|
25
|
+
options[:to] ||= []
|
26
|
+
options[:to] << v
|
27
|
+
end
|
28
|
+
end.parse!
|
29
|
+
|
30
|
+
ENV['AWS_REGION'] ||= options[:region] || 'us-east-1'
|
31
|
+
|
32
|
+
bucket, key = options.fetch(:from).split(':', 2)
|
33
|
+
|
34
|
+
s3 = Aws::S3::Client.new
|
35
|
+
|
36
|
+
options.fetch(:to).each do |dest|
|
37
|
+
STDERR.puts "Copying to #{dest}"
|
38
|
+
dbucket, dkey = dest.split(':', 2)
|
39
|
+
s3.copy_object(
|
40
|
+
bucket: dbucket,
|
41
|
+
key: dkey,
|
42
|
+
copy_source: "/#{bucket}/#{key}",
|
43
|
+
**options[:params] || {},
|
44
|
+
)
|
45
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'optparse'
|
4
|
+
require 'aws-sdk-s3'
|
5
|
+
|
6
|
+
options = {}
|
7
|
+
OptionParser.new do |opts|
|
8
|
+
opts.banner = "Usage: s3-upload options"
|
9
|
+
|
10
|
+
opts.on("-r", "--region=REGION", "AWS region to use (default us-east-1)") do |v|
|
11
|
+
options[:region] = v
|
12
|
+
end
|
13
|
+
|
14
|
+
opts.on("-p", "--param=KEY=VALUE", "Specify parameter for S3 upload") do |v|
|
15
|
+
options[:params] ||= {}
|
16
|
+
k, v = v.split('=', 2)
|
17
|
+
options[:params][k.to_sym] = v
|
18
|
+
end
|
19
|
+
|
20
|
+
opts.on("-f", "--file=PATH", "Path to the file to upload, - to upload standard input") do |v|
|
21
|
+
options[:file] = v
|
22
|
+
end
|
23
|
+
|
24
|
+
opts.on("-w", "--write=BUCKET:PATH", "Bucket name and key (or path) to upload to") do |v|
|
25
|
+
options[:write] = v
|
26
|
+
end
|
27
|
+
|
28
|
+
opts.on("-c", "--copy=BUCKET:PATH", "Bucket name and key (or path) to copy to (may be specified more than once)") do |v|
|
29
|
+
options[:copy] ||= []
|
30
|
+
options[:copy] << v
|
31
|
+
end
|
32
|
+
end.parse!
|
33
|
+
|
34
|
+
ENV['AWS_REGION'] ||= options[:region] || 'us-east-1'
|
35
|
+
|
36
|
+
def upload(f, options)
|
37
|
+
s3 = Aws::S3::Client.new
|
38
|
+
write = options.fetch(:write)
|
39
|
+
STDERR.puts "Writing #{write}"
|
40
|
+
bucket, key = write.split(':', 2)
|
41
|
+
s3.put_object(
|
42
|
+
body: f.read,
|
43
|
+
bucket: bucket,
|
44
|
+
key: key,
|
45
|
+
**options[:params] || {},
|
46
|
+
)
|
47
|
+
if copy = options[:copy]
|
48
|
+
copy.each do |dest|
|
49
|
+
STDERR.puts "Copying to #{dest}"
|
50
|
+
dbucket, dkey = dest.split(':', 2)
|
51
|
+
s3.copy_object(
|
52
|
+
bucket: dbucket,
|
53
|
+
key: dkey,
|
54
|
+
copy_source: "/#{bucket}/#{key}",
|
55
|
+
**options[:params] || {},
|
56
|
+
)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
if options[:file] == '-'
|
62
|
+
upload(STDIN, options)
|
63
|
+
elsif options[:file]
|
64
|
+
File.open(options[:file]) do |f|
|
65
|
+
upload(f, options)
|
66
|
+
end
|
67
|
+
else
|
68
|
+
upload(STDIN, options)
|
69
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
autoload :ChildProcess, 'childprocess'
|
5
|
+
autoload :Tempfile, 'tempfile'
|
6
|
+
|
7
|
+
module Mrss
|
8
|
+
module ChildProcessHelper
|
9
|
+
class SpawnError < StandardError; end
|
10
|
+
|
11
|
+
module_function def call(cmd, env: nil, cwd: nil)
|
12
|
+
process = ChildProcess.new(*cmd)
|
13
|
+
process.io.inherit!
|
14
|
+
if cwd
|
15
|
+
process.cwd = cwd
|
16
|
+
end
|
17
|
+
if env
|
18
|
+
env.each do |k, v|
|
19
|
+
process.environment[k.to_s] = v
|
20
|
+
end
|
21
|
+
end
|
22
|
+
process.start
|
23
|
+
process.wait
|
24
|
+
process
|
25
|
+
end
|
26
|
+
|
27
|
+
module_function def check_call(cmd, env: nil, cwd: nil)
|
28
|
+
process = call(cmd, env: env, cwd: cwd)
|
29
|
+
unless process.exit_code == 0
|
30
|
+
raise SpawnError, "Failed to execute: #{cmd}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
module_function def get_output(cmd, env: nil, cwd: nil)
|
35
|
+
process = ChildProcess.new(*cmd)
|
36
|
+
process.io.inherit!
|
37
|
+
if cwd
|
38
|
+
process.cwd = cwd
|
39
|
+
end
|
40
|
+
if env
|
41
|
+
env.each do |k, v|
|
42
|
+
process.environment[k.to_s] = v
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
output = ''
|
47
|
+
r, w = IO.pipe
|
48
|
+
|
49
|
+
begin
|
50
|
+
process.io.stdout = w
|
51
|
+
process.start
|
52
|
+
w.close
|
53
|
+
|
54
|
+
thread = Thread.new do
|
55
|
+
begin
|
56
|
+
loop do
|
57
|
+
output << r.readpartial(16384)
|
58
|
+
end
|
59
|
+
rescue EOFError
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
process.wait
|
64
|
+
thread.join
|
65
|
+
ensure
|
66
|
+
r.close
|
67
|
+
end
|
68
|
+
|
69
|
+
[process, output]
|
70
|
+
end
|
71
|
+
|
72
|
+
module_function def check_output(*args)
|
73
|
+
process, output = get_output(*args)
|
74
|
+
unless process.exit_code == 0
|
75
|
+
raise SpawnError,"Failed to execute: #{args}"
|
76
|
+
end
|
77
|
+
output
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|