doorkeeper-jwt 0.4.1 → 0.4.3
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/.github/workflows/changelog.yml +36 -0
- data/.github/workflows/ci.yml +0 -2
- data/CHANGELOG.md +15 -1
- data/Gemfile +2 -2
- data/README.md +17 -10
- data/doorkeeper-jwt.gemspec +11 -2
- data/lib/doorkeeper/jwt/config.rb +13 -67
- data/lib/doorkeeper/jwt/version.rb +1 -1
- data/lib/doorkeeper/jwt.rb +12 -12
- metadata +23 -11
- data/bin/console +0 -17
- data/bin/setup +0 -8
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a2d8dbcaba58c45f27f3e2b7ca2c7800e4dc34826e90b537b67850beeca32796
|
|
4
|
+
data.tar.gz: 191472dd355643ddf4143cccc2e42e8962d4482d51dfc6729be3f83c5dcba915
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 013ecc163c7cbbb640165971572f37bb11a9903289a643dfbaf0cee41166cb24bb45a7903e111cc7ef21a5f7856fc8d267dbd797d5108d36fc85b5e8158fda09
|
|
7
|
+
data.tar.gz: 35b106bd511644278a27df3b2c7c396f95d5b8786a642d63e1600ef00929e05795f135caf8832838c5b35b66563e2b7677e3fbea9f8b8b86ec2f39350acd57be
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
name: "Changelog verifier"
|
|
2
|
+
on:
|
|
3
|
+
pull_request:
|
|
4
|
+
# The specific activity types are listed here to include "labeled" and "unlabeled"
|
|
5
|
+
# (which are not included by default for the "pull_request" trigger).
|
|
6
|
+
# This is needed to allow skipping enforcement of the changelog in PRs with specific labels,
|
|
7
|
+
# as defined in the (optional) "skipLabels" property.
|
|
8
|
+
types: [opened, synchronize, reopened, ready_for_review, labeled, unlabeled]
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
# Enforces the update of a changelog file on every pull request
|
|
12
|
+
changelog:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v7
|
|
16
|
+
- name: Check changed paths
|
|
17
|
+
id: changes
|
|
18
|
+
uses: dorny/paths-filter@v4
|
|
19
|
+
with:
|
|
20
|
+
filters: |
|
|
21
|
+
gem_changes:
|
|
22
|
+
- 'lib/**'
|
|
23
|
+
- 'app/**'
|
|
24
|
+
- 'config/**'
|
|
25
|
+
- '*.gemspec'
|
|
26
|
+
- 'Gemfile'
|
|
27
|
+
- 'Gemfile.lock'
|
|
28
|
+
- 'ext/**'
|
|
29
|
+
|
|
30
|
+
- name: Enforce changelog
|
|
31
|
+
if: |
|
|
32
|
+
steps.changes.outputs.gem_changes == 'true'
|
|
33
|
+
uses: dangoslen/changelog-enforcer@v3
|
|
34
|
+
with:
|
|
35
|
+
changeLogPath: CHANGELOG.md
|
|
36
|
+
skipLabels: "dependencies"
|
data/.github/workflows/ci.yml
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -6,7 +6,21 @@ project adheres to [Semantic Versioning](http://semver.org/).
|
|
|
6
6
|
|
|
7
7
|
## master
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
- Add your entry here
|
|
10
|
+
|
|
11
|
+
## [0.4.2] - 2024-08-12
|
|
12
|
+
|
|
13
|
+
- Reuse Doorkeeper core config options DSL [#58](https://github.com/doorkeeper-gem/doorkeeper-jwt/pull/58)
|
|
14
|
+
- Include bin directory in gemspec correctly [#59](https://github.com/doorkeeper-gem/doorkeeper-jwt/pull/59)
|
|
15
|
+
|
|
16
|
+
## [0.4.2] - 2024-08-12
|
|
17
|
+
|
|
18
|
+
- Rename encryption_method to signing_method [#53](https://github.com/doorkeeper-gem/doorkeeper-jwt/pull/53)
|
|
19
|
+
- Fix default token generation [#56](https://github.com/doorkeeper-gem/doorkeeper-jwt/pull/56)
|
|
20
|
+
|
|
21
|
+
### Fixed
|
|
22
|
+
|
|
23
|
+
- Fixed default token generation to return a random hex value [#56](https://github.com/doorkeeper-gem/doorkeeper-jwt/pull/56)
|
|
10
24
|
|
|
11
25
|
## [0.4.1] - 2022-02-23
|
|
12
26
|
|
data/Gemfile
CHANGED
|
@@ -5,6 +5,6 @@ source "https://rubygems.org"
|
|
|
5
5
|
# Specify your gem's dependencies in doorkeeper-jwt.gemspec
|
|
6
6
|
gemspec
|
|
7
7
|
|
|
8
|
-
gem "
|
|
8
|
+
gem "coveralls_reborn", require: false
|
|
9
9
|
gem "rubocop", "~> 1.8", require: false
|
|
10
|
-
gem "rubocop-rspec", "~>
|
|
10
|
+
gem "rubocop-rspec", "~> 3.0", require: false
|
data/README.md
CHANGED
|
@@ -46,43 +46,50 @@ Doorkeeper::JWT.configure do
|
|
|
46
46
|
token_payload do |opts|
|
|
47
47
|
user = User.find(opts[:resource_owner_id])
|
|
48
48
|
|
|
49
|
-
{
|
|
49
|
+
payload = {
|
|
50
50
|
iss: 'My App',
|
|
51
|
-
iat:
|
|
51
|
+
iat: opts[:created_at].utc.to_i,
|
|
52
|
+
aud: opts[:application][:uid],
|
|
52
53
|
|
|
53
54
|
# @see JWT reserved claims - https://tools.ietf.org/html/draft-jones-json-web-token-07#page-7
|
|
54
55
|
jti: SecureRandom.uuid,
|
|
56
|
+
sub: user.id,
|
|
55
57
|
|
|
56
58
|
user: {
|
|
57
59
|
id: user.id,
|
|
58
60
|
email: user.email
|
|
59
61
|
}
|
|
60
62
|
}
|
|
63
|
+
|
|
64
|
+
payload[:exp] = (opts[:created_at] + opts[:expires_in]).utc.to_i if opts[:expires_in]
|
|
65
|
+
payload
|
|
61
66
|
end
|
|
62
67
|
|
|
63
68
|
# Optionally set additional headers for the JWT. See
|
|
64
69
|
# https://tools.ietf.org/html/rfc7515#section-4.1
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
70
|
+
# JWK can be used to automatically verify RS* tokens client-side if token's kid matches a public kid in /oauth/discovery/keys
|
|
71
|
+
# token_headers do |_opts|
|
|
72
|
+
# key = OpenSSL::PKey::RSA.new(File.read(File.join('path', 'to', 'file.pem')))
|
|
73
|
+
# { kid: JWT::JWK.new(key)[:kid] }
|
|
74
|
+
# end
|
|
68
75
|
|
|
69
76
|
# Use the application secret specified in the access grant token. Defaults to
|
|
70
77
|
# `false`. If you specify `use_application_secret true`, both `secret_key` and
|
|
71
78
|
# `secret_key_path` will be ignored.
|
|
72
79
|
use_application_secret false
|
|
73
80
|
|
|
74
|
-
# Set the
|
|
75
|
-
# that should be able to
|
|
81
|
+
# Set the signing secret. This would be shared with any other applications
|
|
82
|
+
# that should be able to verify the authenticity of the token. Defaults to "secret".
|
|
76
83
|
secret_key ENV['JWT_SECRET']
|
|
77
84
|
|
|
78
|
-
# If you want to use RS*
|
|
85
|
+
# If you want to use RS* algorithms specify the path to the RSA key to use for
|
|
79
86
|
# signing. If you specify a `secret_key_path` it will be used instead of
|
|
80
87
|
# `secret_key`.
|
|
81
88
|
secret_key_path File.join('path', 'to', 'file.pem')
|
|
82
89
|
|
|
83
|
-
# Specify
|
|
90
|
+
# Specify cryptographic signing algorithm type (https://github.com/progrium/ruby-jwt). Defaults to
|
|
84
91
|
# `nil`.
|
|
85
|
-
|
|
92
|
+
signing_method :hs512
|
|
86
93
|
end
|
|
87
94
|
```
|
|
88
95
|
|
data/doorkeeper-jwt.gemspec
CHANGED
|
@@ -17,14 +17,23 @@ Gem::Specification.new do |spec|
|
|
|
17
17
|
spec.license = "MIT"
|
|
18
18
|
|
|
19
19
|
spec.bindir = "exe"
|
|
20
|
-
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
|
20
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features|bin)/}) }
|
|
21
21
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
22
22
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
|
23
23
|
spec.require_paths = ["lib"]
|
|
24
24
|
|
|
25
|
+
spec.metadata = {
|
|
26
|
+
"homepage_uri" => "https://github.com/doorkeeper-gem/doorkeeper-jwt",
|
|
27
|
+
"changelog_uri" => "https://github.com/doorkeeper-gem/doorkeeper-jwt/blob/main/CHANGELOG.md",
|
|
28
|
+
"source_code_uri" => "https://github.com/doorkeeper-gem/doorkeeper-jwt",
|
|
29
|
+
"bug_tracker_uri" => "https://github.com/doorkeeper-gem/doorkeeper-jwt/issues",
|
|
30
|
+
"funding_uri" => "https://opencollective.com/doorkeeper-gem",
|
|
31
|
+
}
|
|
32
|
+
|
|
25
33
|
spec.add_dependency "jwt", ">= 2.1"
|
|
26
34
|
|
|
27
|
-
spec.add_development_dependency "bundler", ">= 1.16"
|
|
35
|
+
spec.add_development_dependency "bundler", ">= 1.16"
|
|
36
|
+
spec.add_development_dependency "doorkeeper"
|
|
28
37
|
spec.add_development_dependency "pry", "~> 0"
|
|
29
38
|
spec.add_development_dependency "rake", "~> 13.0"
|
|
30
39
|
spec.add_development_dependency "rspec", "~> 3.8"
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "doorkeeper/config/option"
|
|
4
|
+
|
|
3
5
|
module Doorkeeper
|
|
4
6
|
module JWT
|
|
5
7
|
class MissingConfiguration < StandardError
|
|
@@ -39,86 +41,30 @@ module Doorkeeper
|
|
|
39
41
|
@config.instance_variable_set("@secret_key_path", value)
|
|
40
42
|
end
|
|
41
43
|
|
|
44
|
+
# For backward compatibility. This library does not support encryption.
|
|
42
45
|
def encryption_method(value)
|
|
43
|
-
@config.instance_variable_set("@
|
|
44
|
-
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
module Option
|
|
48
|
-
# Defines configuration options.
|
|
49
|
-
#
|
|
50
|
-
# When you call option, it defines two methods. One method will take
|
|
51
|
-
# place in the +Config+ class and the other method will take place in
|
|
52
|
-
# the +Builder+ class.
|
|
53
|
-
#
|
|
54
|
-
# The +name+ parameter will set both builder method and config
|
|
55
|
-
# attribute. If the +:as+ option is defined, the builder method will be
|
|
56
|
-
# the specified option while the config attribute will be the +name+
|
|
57
|
-
# parameter.
|
|
58
|
-
#
|
|
59
|
-
# If you want to introduce another level of config DSL you can define
|
|
60
|
-
# +builder_class+ parameter. Builder should take a block as the
|
|
61
|
-
# initializer parameter and respond to function +build+ that returns the
|
|
62
|
-
# value of the config attribute.
|
|
63
|
-
#
|
|
64
|
-
# ==== Options
|
|
65
|
-
#
|
|
66
|
-
# * [+:as+] Set the builder method that goes inside +configure+ block.
|
|
67
|
-
# * [+:default+] The default value in case no option was set.
|
|
68
|
-
#
|
|
69
|
-
# ==== Examples
|
|
70
|
-
#
|
|
71
|
-
# option :name
|
|
72
|
-
# option :name, as: :set_name
|
|
73
|
-
# option :name, default: 'My Name'
|
|
74
|
-
# option :scopes, builder_class: ScopesBuilder
|
|
75
|
-
def option(name, options = {})
|
|
76
|
-
attribute = options[:as] || name
|
|
77
|
-
attribute_builder = options[:builder_class]
|
|
78
|
-
attribute_symbol = :"@#{attribute}"
|
|
79
|
-
|
|
80
|
-
Builder.instance_eval do
|
|
81
|
-
define_method name do |*args, &block|
|
|
82
|
-
# TODO: is builder_class option being used?
|
|
83
|
-
value =
|
|
84
|
-
if attribute_builder
|
|
85
|
-
attribute_builder.new(&block).build
|
|
86
|
-
else
|
|
87
|
-
block || args.first
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
@config.instance_variable_set(attribute_symbol, value)
|
|
91
|
-
end
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
define_method attribute do |*|
|
|
95
|
-
if instance_variable_defined?(attribute_symbol)
|
|
96
|
-
instance_variable_get(attribute_symbol)
|
|
97
|
-
else
|
|
98
|
-
options[:default]
|
|
99
|
-
end
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
public attribute
|
|
46
|
+
@config.instance_variable_set("@signing_method", value)
|
|
47
|
+
Kernel.warn("[DOORKEEPER-JWT]: Please use signing_method instead, this option is deprecated and will be removed soon")
|
|
103
48
|
end
|
|
104
49
|
|
|
105
|
-
def
|
|
106
|
-
|
|
50
|
+
def signing_method(value)
|
|
51
|
+
@config.instance_variable_set("@signing_method", value)
|
|
107
52
|
end
|
|
108
53
|
end
|
|
109
54
|
|
|
110
|
-
|
|
55
|
+
mattr_reader(:builder_class) { Config::Builder }
|
|
56
|
+
extend ::Doorkeeper::Config::Option
|
|
111
57
|
|
|
112
58
|
option(
|
|
113
59
|
:token_payload,
|
|
114
|
-
default: proc { { token: SecureRandom.
|
|
60
|
+
default: proc { { token: SecureRandom.hex } },
|
|
115
61
|
)
|
|
116
62
|
|
|
117
63
|
option :token_headers, default: proc { {} }
|
|
118
64
|
option :use_application_secret, default: false
|
|
119
65
|
option :secret_key, default: nil
|
|
120
66
|
option :secret_key_path, default: nil
|
|
121
|
-
option :
|
|
67
|
+
option :signing_method, default: nil
|
|
122
68
|
|
|
123
69
|
def use_application_secret
|
|
124
70
|
@use_application_secret ||= false
|
|
@@ -132,8 +78,8 @@ module Doorkeeper
|
|
|
132
78
|
@secret_key_path ||= nil
|
|
133
79
|
end
|
|
134
80
|
|
|
135
|
-
def
|
|
136
|
-
@
|
|
81
|
+
def signing_method
|
|
82
|
+
@signing_method ||= nil
|
|
137
83
|
end
|
|
138
84
|
end
|
|
139
85
|
end
|
data/lib/doorkeeper/jwt.rb
CHANGED
|
@@ -11,7 +11,7 @@ module Doorkeeper
|
|
|
11
11
|
::JWT.encode(
|
|
12
12
|
token_payload(opts),
|
|
13
13
|
secret_key(opts),
|
|
14
|
-
|
|
14
|
+
signing_method,
|
|
15
15
|
token_headers(opts)
|
|
16
16
|
)
|
|
17
17
|
end
|
|
@@ -31,22 +31,22 @@ module Doorkeeper
|
|
|
31
31
|
|
|
32
32
|
return application_secret(opts) if use_application_secret?
|
|
33
33
|
return secret_key_file unless secret_key_file.nil?
|
|
34
|
-
return rsa_key if
|
|
35
|
-
return ecdsa_key if
|
|
34
|
+
return rsa_key if rsa_signing?
|
|
35
|
+
return ecdsa_key if ecdsa_signing?
|
|
36
36
|
|
|
37
37
|
Doorkeeper::JWT.configuration.secret_key
|
|
38
38
|
end
|
|
39
39
|
|
|
40
40
|
def secret_key_file
|
|
41
41
|
return nil if Doorkeeper::JWT.configuration.secret_key_path.nil?
|
|
42
|
-
return rsa_key_file if
|
|
43
|
-
return ecdsa_key_file if
|
|
42
|
+
return rsa_key_file if rsa_signing?
|
|
43
|
+
return ecdsa_key_file if ecdsa_signing?
|
|
44
44
|
end
|
|
45
45
|
|
|
46
|
-
def
|
|
47
|
-
return "none" unless Doorkeeper::JWT.configuration.
|
|
46
|
+
def signing_method
|
|
47
|
+
return "none" unless Doorkeeper::JWT.configuration.signing_method
|
|
48
48
|
|
|
49
|
-
Doorkeeper::JWT.configuration.
|
|
49
|
+
Doorkeeper::JWT.configuration.signing_method.to_s.upcase
|
|
50
50
|
end
|
|
51
51
|
|
|
52
52
|
def use_application_secret?
|
|
@@ -83,12 +83,12 @@ module Doorkeeper
|
|
|
83
83
|
secret
|
|
84
84
|
end
|
|
85
85
|
|
|
86
|
-
def
|
|
87
|
-
/RS\d{3}/ =~
|
|
86
|
+
def rsa_signing?
|
|
87
|
+
/RS\d{3}/ =~ signing_method
|
|
88
88
|
end
|
|
89
89
|
|
|
90
|
-
def
|
|
91
|
-
/ES\d{3}/ =~
|
|
90
|
+
def ecdsa_signing?
|
|
91
|
+
/ES\d{3}/ =~ signing_method
|
|
92
92
|
end
|
|
93
93
|
|
|
94
94
|
def rsa_key
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: doorkeeper-jwt
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.4.
|
|
4
|
+
version: 0.4.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Chris Warren
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: exe
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date:
|
|
12
|
+
date: 2026-07-20 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: jwt
|
|
@@ -32,9 +32,6 @@ dependencies:
|
|
|
32
32
|
- - ">="
|
|
33
33
|
- !ruby/object:Gem::Version
|
|
34
34
|
version: '1.16'
|
|
35
|
-
- - "<"
|
|
36
|
-
- !ruby/object:Gem::Version
|
|
37
|
-
version: '3'
|
|
38
35
|
type: :development
|
|
39
36
|
prerelease: false
|
|
40
37
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -42,9 +39,20 @@ dependencies:
|
|
|
42
39
|
- - ">="
|
|
43
40
|
- !ruby/object:Gem::Version
|
|
44
41
|
version: '1.16'
|
|
45
|
-
|
|
42
|
+
- !ruby/object:Gem::Dependency
|
|
43
|
+
name: doorkeeper
|
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
|
45
|
+
requirements:
|
|
46
|
+
- - ">="
|
|
46
47
|
- !ruby/object:Gem::Version
|
|
47
|
-
version: '
|
|
48
|
+
version: '0'
|
|
49
|
+
type: :development
|
|
50
|
+
prerelease: false
|
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
52
|
+
requirements:
|
|
53
|
+
- - ">="
|
|
54
|
+
- !ruby/object:Gem::Version
|
|
55
|
+
version: '0'
|
|
48
56
|
- !ruby/object:Gem::Dependency
|
|
49
57
|
name: pry
|
|
50
58
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -95,6 +103,7 @@ extensions: []
|
|
|
95
103
|
extra_rdoc_files: []
|
|
96
104
|
files:
|
|
97
105
|
- ".github/dependabot.yml"
|
|
106
|
+
- ".github/workflows/changelog.yml"
|
|
98
107
|
- ".github/workflows/ci.yml"
|
|
99
108
|
- ".gitignore"
|
|
100
109
|
- ".hound.yml"
|
|
@@ -105,8 +114,6 @@ files:
|
|
|
105
114
|
- LICENSE.txt
|
|
106
115
|
- README.md
|
|
107
116
|
- Rakefile
|
|
108
|
-
- bin/console
|
|
109
|
-
- bin/setup
|
|
110
117
|
- doorkeeper-jwt.gemspec
|
|
111
118
|
- lib/doorkeeper/jwt.rb
|
|
112
119
|
- lib/doorkeeper/jwt/config.rb
|
|
@@ -114,7 +121,12 @@ files:
|
|
|
114
121
|
homepage: https://github.com/chriswarren/doorkeeper-jwt
|
|
115
122
|
licenses:
|
|
116
123
|
- MIT
|
|
117
|
-
metadata:
|
|
124
|
+
metadata:
|
|
125
|
+
homepage_uri: https://github.com/doorkeeper-gem/doorkeeper-jwt
|
|
126
|
+
changelog_uri: https://github.com/doorkeeper-gem/doorkeeper-jwt/blob/main/CHANGELOG.md
|
|
127
|
+
source_code_uri: https://github.com/doorkeeper-gem/doorkeeper-jwt
|
|
128
|
+
bug_tracker_uri: https://github.com/doorkeeper-gem/doorkeeper-jwt/issues
|
|
129
|
+
funding_uri: https://opencollective.com/doorkeeper-gem
|
|
118
130
|
post_install_message:
|
|
119
131
|
rdoc_options: []
|
|
120
132
|
require_paths:
|
|
@@ -130,7 +142,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
130
142
|
- !ruby/object:Gem::Version
|
|
131
143
|
version: '0'
|
|
132
144
|
requirements: []
|
|
133
|
-
rubygems_version: 3.
|
|
145
|
+
rubygems_version: 3.1.6
|
|
134
146
|
signing_key:
|
|
135
147
|
specification_version: 4
|
|
136
148
|
summary: JWT token generator for Doorkeeper
|
data/bin/console
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
# frozen_string_literal: true
|
|
3
|
-
|
|
4
|
-
require "bundler/setup"
|
|
5
|
-
require "doorkeeper-jwt"
|
|
6
|
-
|
|
7
|
-
# You can add fixtures and/or initialization code here to make experimenting
|
|
8
|
-
# with your gem easier. You can also use a different console, if you like.
|
|
9
|
-
|
|
10
|
-
# (If you use this, don't forget to add pry to your Gemfile!)
|
|
11
|
-
# require 'pry'
|
|
12
|
-
#
|
|
13
|
-
# Pry.start
|
|
14
|
-
|
|
15
|
-
require "irb"
|
|
16
|
-
|
|
17
|
-
IRB.start
|