graphql-activerecord 0.12.6 → 0.13.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/.rubocop.yml +581 -11
- data/CHANGELOG.md +6 -0
- data/Gemfile +1 -0
- data/README.md +69 -37
- data/Rakefile +1 -0
- data/bin/bundle +105 -0
- data/bin/coderay +12 -0
- data/bin/htmldiff +12 -0
- data/bin/ldiff +12 -0
- data/bin/pry +12 -0
- data/bin/rake +12 -0
- data/bin/rspec +12 -0
- data/bin/rubocop +12 -0
- data/bin/ruby-parse +12 -0
- data/bin/ruby-rewrite +12 -0
- data/graphql-activerecord.gemspec +6 -6
- data/lib/graphql/activerecord.rb +6 -2
- data/lib/graphql/models/active_record_extension.rb +2 -1
- data/lib/graphql/models/association_load_request.rb +1 -0
- data/lib/graphql/models/attribute_loader.rb +1 -0
- data/lib/graphql/models/backed_by_model.rb +1 -0
- data/lib/graphql/models/database_types.rb +1 -0
- data/lib/graphql/models/definer.rb +1 -0
- data/lib/graphql/models/definition_helpers.rb +3 -2
- data/lib/graphql/models/definition_helpers/associations.rb +3 -2
- data/lib/graphql/models/definition_helpers/attributes.rb +1 -0
- data/lib/graphql/models/hash_combiner.rb +1 -0
- data/lib/graphql/models/helpers.rb +1 -0
- data/lib/graphql/models/instrumentation.rb +6 -4
- data/lib/graphql/models/monkey_patches/graphql_query_context.rb +1 -0
- data/lib/graphql/models/mutation_field_map.rb +9 -7
- data/lib/graphql/models/mutation_helpers/apply_changes.rb +16 -5
- data/lib/graphql/models/mutation_helpers/authorization.rb +1 -0
- data/lib/graphql/models/mutation_helpers/print_input_fields.rb +4 -3
- data/lib/graphql/models/mutation_helpers/validation.rb +1 -0
- data/lib/graphql/models/mutation_helpers/validation_error.rb +1 -0
- data/lib/graphql/models/mutator.rb +3 -2
- data/lib/graphql/models/promise_relation_connection.rb +1 -0
- data/lib/graphql/models/reflection.rb +2 -0
- data/lib/graphql/models/relation_load_request.rb +1 -0
- data/lib/graphql/models/relation_loader.rb +1 -0
- data/lib/graphql/models/version.rb +2 -1
- metadata +23 -22
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
# 0.13.0
|
4
|
+
Changed the way that null values are handled inside of mutators. Take a look at [(#49)](https://github.com/goco-inc/graphql-activerecord/pull/49)
|
5
|
+
for details. If you need to get back to the old behavior (ie, `unsetFields`), you can either:
|
6
|
+
- Add the `legacy_nulls: true` option when defining your mutator, or
|
7
|
+
- Set `GraphQL::Models.legacy_nulls = true` in an initializer
|
8
|
+
|
3
9
|
# 0.12.6
|
4
10
|
- Fixed a bug when you used a `nested` mutator, and provided a symbol for the `:name` kwarg
|
5
11
|
- Fixed a bug where the `context` parameter was not being passed to `MutationHelpers::match_inputs_to_models`
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,5 +1,23 @@
|
|
1
1
|
# GraphQL::Models
|
2
2
|
|
3
|
+
## WARNING!
|
4
|
+
This gem was designed as a helper for building GraphQL schema's based on the [`graphql`](https://github.com/rmosolgo/graphql-ruby) gem. Primarily, it was meant to reduce redundancy when your object types were virtually identical to the attributes on your models in a few ways:
|
5
|
+
1. It uses some clever tricks to automatically infer field types based on the data types of your database columns
|
6
|
+
2. It automatically camelizes your attributes names
|
7
|
+
3. It has some helpers to optimize association loading
|
8
|
+
|
9
|
+
But in the time since I originally wrote this gem, a lot has transpired in the GraphQL world:
|
10
|
+
- For #2: The 1.8 release of the graphql gem solves field camelization
|
11
|
+
- For #3: Better solutions for association loading, that aren't quite as heavy as this library, have surfaced. One example is outlined in a [gist](https://gist.github.com/theorygeek/a1a59a2bf9c59e4b3706ac68d12c8434) that I wrote on Association Loading. That gist has proven to be more popular than this library 😁
|
12
|
+
|
13
|
+
I don't know if there's a good solution out there for #1, but it was probably the least important problem to solve.
|
14
|
+
|
15
|
+
We use GraphQL extensively at GoCo. Our schema has thousands of types. We'll be rethinking our implementation soon, and taking a closer look at the patterns that we use to DRY up our schema definition, to see if there are better patterns in the 1.8+ world.
|
16
|
+
|
17
|
+
This gem may evolve into something better, or we may eventually deprecate it. But as of right now, I can't recommend that you build any major projects on top of it, since its future is a bit uncertain. I apologize if that makes more work for you :( but I want to be honest about the state of the project.
|
18
|
+
|
19
|
+
## Overview
|
20
|
+
|
3
21
|
This gem is designed to help you map Active Record models to GraphQL types, both for queries and mutations, using the [`graphql`](https://github.com/rmosolgo/graphql-ruby)
|
4
22
|
gem. It assumes that you're using Rails and have `graphql-batch` set up.
|
5
23
|
|
@@ -11,7 +29,7 @@ In the process, this gem also converts `snake_case` attribute names into `camelC
|
|
11
29
|
|
12
30
|
Here's an example:
|
13
31
|
```ruby
|
14
|
-
|
32
|
+
EmployeeType = GraphQL::ObjectType.define do
|
15
33
|
name "Employee"
|
16
34
|
|
17
35
|
# Looks for an Active Record model called "Employee"
|
@@ -38,6 +56,22 @@ EmployeeGraph = GraphQL::ObjectType.define do
|
|
38
56
|
end
|
39
57
|
```
|
40
58
|
|
59
|
+
Then in your query file:
|
60
|
+
```ruby
|
61
|
+
QueryType = GraphQL::ObjectType.define do
|
62
|
+
name "Query"
|
63
|
+
|
64
|
+
field :employees, types[EmployeeType] do
|
65
|
+
resolve -> (_obj, _args, _ctx) { Employee.all }
|
66
|
+
end
|
67
|
+
|
68
|
+
field :employee, EmployeeType do
|
69
|
+
argument :id, !types.ID
|
70
|
+
resolve -> (obj, args, ctx) { Employee.find(args[:id])}
|
71
|
+
end
|
72
|
+
end
|
73
|
+
```
|
74
|
+
|
41
75
|
You can also build a corresponding mutation, using a very similar syntax. Mutations are more complicated, since they involve
|
42
76
|
not just changing the data, but also validating it. Here's an example:
|
43
77
|
```ruby
|
@@ -49,7 +83,7 @@ UpdateEmployeeMutation = GraphQL::Relay::Mutation.define do
|
|
49
83
|
# For mutations, you create a mutator definition. This will add the input fields to your
|
50
84
|
# mutation, and also return an object that you'll use in the resolver to perform the mutation.
|
51
85
|
# The parameters you pass are explained below.
|
52
|
-
mutator_definition = GraphQL::Models.define_mutator(self, Employee
|
86
|
+
mutator_definition = GraphQL::Models.define_mutator(self, Employee) do
|
53
87
|
attr :title
|
54
88
|
attr :salary
|
55
89
|
|
@@ -60,7 +94,7 @@ UpdateEmployeeMutation = GraphQL::Relay::Mutation.define do
|
|
60
94
|
|
61
95
|
# You can use nested input object types to allow making changes across associations with a single mutation.
|
62
96
|
# Unlike querying, you need to be explicit about what fields on associated objects can be changed.
|
63
|
-
nested :address
|
97
|
+
nested :address do
|
64
98
|
attr :line_1
|
65
99
|
attr :line_2
|
66
100
|
attr :city
|
@@ -70,7 +104,7 @@ UpdateEmployeeMutation = GraphQL::Relay::Mutation.define do
|
|
70
104
|
end
|
71
105
|
end
|
72
106
|
|
73
|
-
return_field :employee,
|
107
|
+
return_field :employee, EmployeeType
|
74
108
|
|
75
109
|
resolve -> (inputs, context) {
|
76
110
|
# Fetch (or create) the model that the mutation should change
|
@@ -96,6 +130,15 @@ UpdateEmployeeMutation = GraphQL::Relay::Mutation.define do
|
|
96
130
|
end
|
97
131
|
```
|
98
132
|
|
133
|
+
In your mutation file:
|
134
|
+
```ruby
|
135
|
+
MutationType = GraphQL::ObjectType.define do
|
136
|
+
name "Mutation"
|
137
|
+
|
138
|
+
field :updateEmployee, UpdateEmployeeMutation.field
|
139
|
+
end
|
140
|
+
```
|
141
|
+
|
99
142
|
## Installation
|
100
143
|
|
101
144
|
To get started, you should add this line to your application's Gemfile:
|
@@ -132,15 +175,14 @@ GraphQL::Models.authorize = -> (context, action, model) {
|
|
132
175
|
|
133
176
|
# The gem assumes that if your model is called `MyModel`, the corresponding type is `MyModelType`.
|
134
177
|
# You can override that convention. Return `nil` if the model doesn't have a GraphQL type:
|
135
|
-
GraphQL::Models.model_to_graphql_type = -> (model_class) { "#{model_class.name}
|
178
|
+
GraphQL::Models.model_to_graphql_type = -> (model_class) { "#{model_class.name}Type".safe_constantize }
|
136
179
|
```
|
137
180
|
|
138
181
|
Finally, you need to set a few options on your schema:
|
139
182
|
```ruby
|
140
183
|
GraphQL::Schema.define do
|
141
184
|
# Set up the graphql-batch gem
|
142
|
-
|
143
|
-
instrument(:query, GraphQL::Batch::Setup)
|
185
|
+
use GraphQL::Batch
|
144
186
|
|
145
187
|
# Set up the graphql-activerecord gem
|
146
188
|
instrument(:field, GraphQL::Models::Instrumentation.new)
|
@@ -309,7 +351,7 @@ end
|
|
309
351
|
MyModel.graphql_enum_types[:status]
|
310
352
|
|
311
353
|
# When you use it inside of your GraphQL schema, it'll know to use the GraphQL enum type:
|
312
|
-
|
354
|
+
MyModelType = GraphQL::ObjectType.define do
|
313
355
|
backed_by_model :my_model do
|
314
356
|
attr :status
|
315
357
|
end
|
@@ -326,13 +368,12 @@ You can also manually specify the type to use, if you just want the type mapping
|
|
326
368
|
When you define a mutation, there are a few parameters that you need to pass. Here's an example:
|
327
369
|
|
328
370
|
```ruby
|
329
|
-
mutator_definition = GraphQL::Models.define_mutator(self, Employee
|
371
|
+
mutator_definition = GraphQL::Models.define_mutator(self, Employee)
|
330
372
|
```
|
331
373
|
|
332
374
|
The parameters are:
|
333
375
|
- The definer object: it needs this so that it can create the input fields. You should always pass `self` for this parameter.
|
334
376
|
- The model class that the mutator is changing: it needs this so that it can map attributes to the correct input types.
|
335
|
-
- `null_behavior`: this lets you choose how null values are treated. It's explained below.
|
336
377
|
|
337
378
|
#### Virtual Attributes
|
338
379
|
In your mutator, you can specify virtual attributes on your model, you just need to provide the type:
|
@@ -340,39 +381,30 @@ In your mutator, you can specify virtual attributes on your model, you just need
|
|
340
381
|
attr :some_fake_attribute, type: types.String
|
341
382
|
```
|
342
383
|
|
343
|
-
####
|
344
|
-
|
345
|
-
When you build a mutation, you have two options that control how null values are treated. They are meant to allow you
|
346
|
-
to choose behavior similar to HTTP PATCH or HTTP POST, where you may want to update just part of a model without having to supply
|
347
|
-
values for every field.
|
348
|
-
|
349
|
-
You specify which option you'd like using the `null_behavior` parameter when defining the mutation:
|
350
|
-
- `leave_unchanged` means that if the input field contains a null value, it is ignored
|
351
|
-
- `set_null` means that if the input field contains a null value, the attribute will actually be set to `nil`
|
384
|
+
#### Implicit Null Values
|
352
385
|
|
353
|
-
|
354
|
-
|
355
|
-
null values behave as you would expect: they cause the attribute to be set to `nil`.
|
386
|
+
By default, input fields that are not supplied to a mutation (ie, they are left blank when the mutation is executed) will
|
387
|
+
be ignored. You must explicitly provide a value (including `null`) for the attribute to be updated.
|
356
388
|
|
357
|
-
|
358
|
-
|
389
|
+
You can override this behavior by using the `null_behavior: :set_null` option. This will cause two side-effects:
|
390
|
+
- The input fields on your mutation will be marked non-null if they are required in your model
|
391
|
+
- If any input field is not supplied, it will be treated as if the value `null` was actually supplied.
|
359
392
|
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
The important side-effect here is that `leave_unchanged` causes all of the input fields on the mutation to be nullable.
|
393
|
+
Example:
|
394
|
+
```ruby
|
395
|
+
nested :emergency_contacts, null_behavior: :set_null do
|
396
|
+
attr :first_name
|
397
|
+
attr :last_name
|
398
|
+
attr :phone
|
399
|
+
end
|
400
|
+
```
|
369
401
|
|
370
402
|
### Mutations and has_many associations
|
371
403
|
You can create mutations that update models across a `has_many` association, by using a `nested` block just like you would for
|
372
404
|
`has_one` or `belongs_to` associations:
|
373
405
|
|
374
406
|
```ruby
|
375
|
-
nested :emergency_contacts
|
407
|
+
nested :emergency_contacts do
|
376
408
|
attr :first_name
|
377
409
|
attr :last_name
|
378
410
|
attr :phone
|
@@ -382,7 +414,7 @@ end
|
|
382
414
|
By default, inputs are matched to associated models by position (ie, the first input to the first model, etc). However, if you
|
383
415
|
have an attribute that should instead be used to match them, you can specify it:
|
384
416
|
```ruby
|
385
|
-
nested :emergency_contacts, find_by: :priority
|
417
|
+
nested :emergency_contacts, find_by: :priority do
|
386
418
|
attr :first_name
|
387
419
|
attr :last_name
|
388
420
|
attr :phone
|
@@ -392,8 +424,8 @@ end
|
|
392
424
|
This causes the gem to automatically include `priority` as an input field. You could also manually specify the
|
393
425
|
`priority` field if you wanted to override its name or type.
|
394
426
|
|
395
|
-
Also, an important note is that the gem assumes that
|
396
|
-
them. It will destroy extra models, or create missing models.
|
427
|
+
Also, an important note is that the gem assumes that your input is providing values for _all_ of the associated models, and not just
|
428
|
+
some of them. It will destroy extra models, or create missing models.
|
397
429
|
|
398
430
|
### Other things that need to be documented
|
399
431
|
- Custom scalar types
|
data/Rakefile
CHANGED
data/bin/bundle
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
#
|
5
|
+
# This file was generated by Bundler.
|
6
|
+
#
|
7
|
+
# The application 'bundle' is installed as part of a gem, and
|
8
|
+
# this file is here to facilitate running it.
|
9
|
+
#
|
10
|
+
|
11
|
+
require "rubygems"
|
12
|
+
|
13
|
+
m = Module.new do
|
14
|
+
module_function
|
15
|
+
|
16
|
+
def invoked_as_script?
|
17
|
+
File.expand_path($0) == File.expand_path(__FILE__)
|
18
|
+
end
|
19
|
+
|
20
|
+
def env_var_version
|
21
|
+
ENV["BUNDLER_VERSION"]
|
22
|
+
end
|
23
|
+
|
24
|
+
def cli_arg_version
|
25
|
+
return unless invoked_as_script? # don't want to hijack other binstubs
|
26
|
+
return unless "update".start_with?(ARGV.first || " ") # must be running `bundle update`
|
27
|
+
bundler_version = nil
|
28
|
+
update_index = nil
|
29
|
+
ARGV.each_with_index do |a, i|
|
30
|
+
if update_index && update_index.succ == i && a =~ Gem::Version::ANCHORED_VERSION_PATTERN
|
31
|
+
bundler_version = a
|
32
|
+
end
|
33
|
+
next unless a =~ /\A--bundler(?:[= ](#{Gem::Version::VERSION_PATTERN}))?\z/
|
34
|
+
bundler_version = $1 || ">= 0.a"
|
35
|
+
update_index = i
|
36
|
+
end
|
37
|
+
bundler_version
|
38
|
+
end
|
39
|
+
|
40
|
+
def gemfile
|
41
|
+
gemfile = ENV["BUNDLE_GEMFILE"]
|
42
|
+
return gemfile if gemfile && !gemfile.empty?
|
43
|
+
|
44
|
+
File.expand_path("../../Gemfile", __FILE__)
|
45
|
+
end
|
46
|
+
|
47
|
+
def lockfile
|
48
|
+
lockfile =
|
49
|
+
case File.basename(gemfile)
|
50
|
+
when "gems.rb" then gemfile.sub(/\.rb$/, gemfile)
|
51
|
+
else "#{gemfile}.lock"
|
52
|
+
end
|
53
|
+
File.expand_path(lockfile)
|
54
|
+
end
|
55
|
+
|
56
|
+
def lockfile_version
|
57
|
+
return unless File.file?(lockfile)
|
58
|
+
lockfile_contents = File.read(lockfile)
|
59
|
+
return unless lockfile_contents =~ /\n\nBUNDLED WITH\n\s{2,}(#{Gem::Version::VERSION_PATTERN})\n/
|
60
|
+
Regexp.last_match(1)
|
61
|
+
end
|
62
|
+
|
63
|
+
def bundler_version
|
64
|
+
@bundler_version ||= begin
|
65
|
+
env_var_version || cli_arg_version ||
|
66
|
+
lockfile_version || "#{Gem::Requirement.default}.a"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def load_bundler!
|
71
|
+
ENV["BUNDLE_GEMFILE"] ||= gemfile
|
72
|
+
|
73
|
+
# must dup string for RG < 1.8 compatibility
|
74
|
+
activate_bundler(bundler_version.dup)
|
75
|
+
end
|
76
|
+
|
77
|
+
def activate_bundler(bundler_version)
|
78
|
+
if Gem::Version.correct?(bundler_version) && Gem::Version.new(bundler_version).release < Gem::Version.new("2.0")
|
79
|
+
bundler_version = "< 2"
|
80
|
+
end
|
81
|
+
gem_error = activation_error_handling do
|
82
|
+
gem "bundler", bundler_version
|
83
|
+
end
|
84
|
+
return if gem_error.nil?
|
85
|
+
require_error = activation_error_handling do
|
86
|
+
require "bundler/version"
|
87
|
+
end
|
88
|
+
return if require_error.nil? && Gem::Requirement.new(bundler_version).satisfied_by?(Gem::Version.new(Bundler::VERSION))
|
89
|
+
warn "Activating bundler (#{bundler_version}) failed:\n#{gem_error.message}\n\nTo install the version of bundler this project requires, run `gem install bundler -v '#{bundler_version}'`"
|
90
|
+
exit 42
|
91
|
+
end
|
92
|
+
|
93
|
+
def activation_error_handling
|
94
|
+
yield
|
95
|
+
nil
|
96
|
+
rescue StandardError, LoadError => e
|
97
|
+
e
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
m.load_bundler!
|
102
|
+
|
103
|
+
if m.invoked_as_script?
|
104
|
+
load Gem.bin_path("bundler", "bundle")
|
105
|
+
end
|
data/bin/coderay
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# frozen_string_literal: true
|
3
|
+
|
3
4
|
#
|
4
5
|
# This file was generated by Bundler.
|
5
6
|
#
|
@@ -11,6 +12,17 @@ require "pathname"
|
|
11
12
|
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
12
13
|
Pathname.new(__FILE__).realpath)
|
13
14
|
|
15
|
+
bundle_binstub = File.expand_path("../bundle", __FILE__)
|
16
|
+
|
17
|
+
if File.file?(bundle_binstub)
|
18
|
+
if File.read(bundle_binstub, 150) =~ /This file was generated by Bundler/
|
19
|
+
load(bundle_binstub)
|
20
|
+
else
|
21
|
+
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
22
|
+
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
14
26
|
require "rubygems"
|
15
27
|
require "bundler/setup"
|
16
28
|
|
data/bin/htmldiff
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# frozen_string_literal: true
|
3
|
+
|
3
4
|
#
|
4
5
|
# This file was generated by Bundler.
|
5
6
|
#
|
@@ -11,6 +12,17 @@ require "pathname"
|
|
11
12
|
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
12
13
|
Pathname.new(__FILE__).realpath)
|
13
14
|
|
15
|
+
bundle_binstub = File.expand_path("../bundle", __FILE__)
|
16
|
+
|
17
|
+
if File.file?(bundle_binstub)
|
18
|
+
if File.read(bundle_binstub, 150) =~ /This file was generated by Bundler/
|
19
|
+
load(bundle_binstub)
|
20
|
+
else
|
21
|
+
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
22
|
+
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
14
26
|
require "rubygems"
|
15
27
|
require "bundler/setup"
|
16
28
|
|
data/bin/ldiff
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# frozen_string_literal: true
|
3
|
+
|
3
4
|
#
|
4
5
|
# This file was generated by Bundler.
|
5
6
|
#
|
@@ -11,6 +12,17 @@ require "pathname"
|
|
11
12
|
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
12
13
|
Pathname.new(__FILE__).realpath)
|
13
14
|
|
15
|
+
bundle_binstub = File.expand_path("../bundle", __FILE__)
|
16
|
+
|
17
|
+
if File.file?(bundle_binstub)
|
18
|
+
if File.read(bundle_binstub, 150) =~ /This file was generated by Bundler/
|
19
|
+
load(bundle_binstub)
|
20
|
+
else
|
21
|
+
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
22
|
+
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
14
26
|
require "rubygems"
|
15
27
|
require "bundler/setup"
|
16
28
|
|
data/bin/pry
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# frozen_string_literal: true
|
3
|
+
|
3
4
|
#
|
4
5
|
# This file was generated by Bundler.
|
5
6
|
#
|
@@ -11,6 +12,17 @@ require "pathname"
|
|
11
12
|
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
12
13
|
Pathname.new(__FILE__).realpath)
|
13
14
|
|
15
|
+
bundle_binstub = File.expand_path("../bundle", __FILE__)
|
16
|
+
|
17
|
+
if File.file?(bundle_binstub)
|
18
|
+
if File.read(bundle_binstub, 150) =~ /This file was generated by Bundler/
|
19
|
+
load(bundle_binstub)
|
20
|
+
else
|
21
|
+
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
22
|
+
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
14
26
|
require "rubygems"
|
15
27
|
require "bundler/setup"
|
16
28
|
|
data/bin/rake
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# frozen_string_literal: true
|
3
|
+
|
3
4
|
#
|
4
5
|
# This file was generated by Bundler.
|
5
6
|
#
|
@@ -11,6 +12,17 @@ require "pathname"
|
|
11
12
|
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
12
13
|
Pathname.new(__FILE__).realpath)
|
13
14
|
|
15
|
+
bundle_binstub = File.expand_path("../bundle", __FILE__)
|
16
|
+
|
17
|
+
if File.file?(bundle_binstub)
|
18
|
+
if File.read(bundle_binstub, 150) =~ /This file was generated by Bundler/
|
19
|
+
load(bundle_binstub)
|
20
|
+
else
|
21
|
+
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
22
|
+
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
14
26
|
require "rubygems"
|
15
27
|
require "bundler/setup"
|
16
28
|
|