logfmt 0.0.10 → 0.1.0.beta.1
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/CHANGELOG.md +5 -0
- data/Gemfile +2 -1
- data/README.md +145 -1
- data/Rakefile +30 -1
- data/lib/logfmt/logger.rb +74 -0
- data/lib/logfmt/version.rb +1 -1
- data/lib/logfmt.rb +1 -0
- data/logfmt.gemspec +40 -0
- metadata +9 -11
- data/bin/bundle +0 -114
- data/bin/console +0 -8
- data/bin/rake +0 -29
- data/bin/rspec +0 -29
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d8f2e9e3f3d271e1cad7120cb1fedc6a839050004a51ccd72a9e0ef019b242e6
|
4
|
+
data.tar.gz: 01035abc746fce52ac36c672bec2640a3c4d436f300b244d13b4e936b655030b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bb92737ee195acf40cfae4ae48b73895165568690984448e75d9bd4c3a3131f570721ebf0182778c959dc312182f6ebc9bcc0a6a26a877f09e24faa16f2377ff
|
7
|
+
data.tar.gz: 3df2ec4510aad12b18cbe6d1f2da2ffc7b8e3114bb3c66a4b74ae9d04965a5ba766a90db1b7510104295e0c133d36b2bff7190ac80bbbdfac85d770a4b1bb98d
|
data/CHANGELOG.md
CHANGED
@@ -5,6 +5,11 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
|
|
5
5
|
|
6
6
|
## \[Unreleased\]
|
7
7
|
|
8
|
+
## [0.1.0.beta.1] 2022-10-21
|
9
|
+
### Added
|
10
|
+
- Add `Logfmt::Logger` and `Logfmt::TaggedLogger`.
|
11
|
+
The later is distributed as its own gem, `logfmt-tagged_logger`, but lives in this repo.
|
12
|
+
|
8
13
|
## [0.0.10] 2022-04-30
|
9
14
|
### Changed
|
10
15
|
- Autoload the `Logfmt::Parser` when it's used, in preparation for the coming `Logfmt::Logger` and friends.
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,58 @@
|
|
1
1
|
# Logfmt
|
2
2
|
|
3
|
-
|
3
|
+
Write and parse structured log lines in the [logfmt style][logfmt-blog].
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem "logfmt"
|
11
|
+
```
|
12
|
+
|
13
|
+
And then install:
|
14
|
+
|
15
|
+
```bash
|
16
|
+
$ bundle
|
17
|
+
```
|
18
|
+
|
19
|
+
Or install it yourself:
|
20
|
+
|
21
|
+
```bash
|
22
|
+
$ gem install logfmt
|
23
|
+
```
|
24
|
+
|
25
|
+
### Versioning
|
26
|
+
|
27
|
+
This project adheres to [Semantic Versioning][semver].
|
28
|
+
|
29
|
+
## Usage
|
30
|
+
|
31
|
+
`Logfmt` is composed to two parts: writing structured log lines in the `logfmt` style, and parsing `logfmt`-style log lines.
|
32
|
+
|
33
|
+
While writing and parsing `logfmt` are related, we've found that it's common to only need to do one or there other in a single application.
|
34
|
+
To support that usage, `Logfmt` leverages Ruby's `autoload` to lazily load the `Logfmt::Parser` or `Logfmt::Logger` (and associated code) into memory.
|
35
|
+
In the general case that looks something like:
|
36
|
+
|
37
|
+
```ruby
|
38
|
+
require "logfmt"
|
39
|
+
|
40
|
+
Logfmt # This constant was already loaded, but neither Logfmt::Parser
|
41
|
+
# nor Logfmt::Logger constants are loaded. Yet.
|
42
|
+
|
43
|
+
Logfmt.parse("…")
|
44
|
+
# OR
|
45
|
+
Logfmt::Parser.parse("…")
|
46
|
+
|
47
|
+
# Either of the above will load the Logfmt::Parser constant.
|
48
|
+
# Similarly you can autoload the Logfmt::Logger via
|
49
|
+
|
50
|
+
Logfmt::Logger.new
|
51
|
+
```
|
52
|
+
|
53
|
+
If you want to eagerly load the logger or parser, you can do that by requiring them directly
|
54
|
+
|
55
|
+
### Parsing log lines
|
4
56
|
|
5
57
|
```ruby
|
6
58
|
require "logfmt/parser"
|
@@ -8,3 +60,95 @@ require "logfmt/parser"
|
|
8
60
|
Logfmt::Parser.parse('foo=bar a=14 baz="hello kitty" cool%story=bro f %^asdf')
|
9
61
|
#=> {"foo"=>"bar", "a"=>14, "baz"=>"hello kitty", "cool%story"=>"bro", "f"=>true, "%^asdf"=>true}
|
10
62
|
```
|
63
|
+
|
64
|
+
### Writing log lines
|
65
|
+
|
66
|
+
The `Logfmt::Logger` is built on the stdlib `::Logger` and adheres to its API.
|
67
|
+
The primary difference is that `Logfmt::Logger` defaults to a `logfmt`-style formatter.
|
68
|
+
Specifically, a `Logfmt::Logger::KeyValueFormatter`, which results in log lines something like this:
|
69
|
+
|
70
|
+
```ruby
|
71
|
+
require "logfmt/logger"
|
72
|
+
|
73
|
+
logger = Logfmt::Logger.new($stdout)
|
74
|
+
|
75
|
+
logger.info(foo: "bar", a: 14, "baz" => "hello kitty", "cool%story" => "bro", f: true, "%^asdf" => true)
|
76
|
+
#=> time=2022-04-20T23:30:54.647403Z severity=INFO foo=bar a=14 baz="hello kitty" cool%story=bro f %^asdf
|
77
|
+
|
78
|
+
logger.debug("MADE IT HERE!")
|
79
|
+
#=> time=2022-04-20T23:33:44.912595Z severity=DEBUG msg="MADE IT HERE!"
|
80
|
+
```
|
81
|
+
|
82
|
+
#### Tagged log lines
|
83
|
+
|
84
|
+
The `logfmt-tagged_logger` gem adds support for Rails-style [tagged logging][tagged-logger].
|
85
|
+
This gem adds a `Logfmt::TaggedLogger` which is built on `ActiveSupport::TaggedLogger`, but emits the tags in logfmt-style, as key/value pairs.
|
86
|
+
For example
|
87
|
+
|
88
|
+
```ruby
|
89
|
+
logger = Logfmt::TaggedLogger.new($stdout)
|
90
|
+
|
91
|
+
logger.tagged(source: "api") do
|
92
|
+
logger.info(foo: "bar")
|
93
|
+
end
|
94
|
+
|
95
|
+
#=> time=2022-04-20T23:33:44.912595Z severity=info source=api foo=bar"
|
96
|
+
```
|
97
|
+
|
98
|
+
You can also pass "bare" tags and they'll be collected and emitted under the `tags` key.
|
99
|
+
|
100
|
+
```ruby
|
101
|
+
logger = Logfmt::TaggedLogger.new($stdout)
|
102
|
+
|
103
|
+
logger.tagged("API", "1.2.3.4") do
|
104
|
+
logger.info(foo: "bar")
|
105
|
+
end
|
106
|
+
|
107
|
+
#=> time=2022-04-20T23:33:44.912595Z severity=info tags="[API] [1.2.3.4]" foo=bar"
|
108
|
+
```
|
109
|
+
|
110
|
+
It's likely more helpful and useful to use meaningful key/values for your tags, rather than bare tags.
|
111
|
+
|
112
|
+
#### Expected key/value transformations
|
113
|
+
|
114
|
+
When writing a log line with the `Logfmt::Logger::KeyValueFormatter` the keys and/or values will be transformed thusly:
|
115
|
+
|
116
|
+
* "Bare messages" (those with no key given when invoking the logger) will be wrapped in the `msg` key.
|
117
|
+
|
118
|
+
```ruby
|
119
|
+
logger.info("here")
|
120
|
+
#=> time=2022-04-20T23:33:49.912997Z severity=INFO msg=here
|
121
|
+
```
|
122
|
+
|
123
|
+
* Values, including bare messages, containing white space or control characters (spaces, tabs, newlines, emoji, etc…) will be wrapped in double quotes (`""`) and fully escaped.
|
124
|
+
|
125
|
+
```ruby
|
126
|
+
logger.info("👻 Boo!")
|
127
|
+
#=> time=2022-04-20T23:33:35.912595Z severity=INFO msg="\u{1F47B} Boo!"
|
128
|
+
|
129
|
+
logger.info(number: 42, with_quotes: %{These "are" 'quotes', OK?})
|
130
|
+
#=> time=2022-04-20T23:33:36.412183Z severity=INFO number=42 with_quotes="These \"are\" 'quotes', OK?"
|
131
|
+
```
|
132
|
+
|
133
|
+
* Floating point values are truncated to three digits.
|
134
|
+
|
135
|
+
* Time values are formatted as ISO8601 strings, with six digits sub-second precision.
|
136
|
+
|
137
|
+
* A value that is an Array is wrapped in square brackets, and then the above rules applied to each Array value.
|
138
|
+
This works well for arrays of simple values - like numbers, symbols, or simple strings.
|
139
|
+
But complex data structures will result in human mind-breaking escape sequences.
|
140
|
+
So don't do that.
|
141
|
+
Keep values simple.
|
142
|
+
|
143
|
+
```ruby
|
144
|
+
logger.info(an_array: [1, "two", :three])
|
145
|
+
#=> time=2022-04-20T23:33:36.412183Z severity=INFO an_array="[1, two, three]"
|
146
|
+
```
|
147
|
+
|
148
|
+
**NOTE**: it is **not** expected that log lines generated by `Logfmt` can be round-tripped by parsing the log line with `Logfmt`.
|
149
|
+
Specifically, this applies to Unicode and some control characters, as well as bare messages which will be wrapped in the `msg` key when writing.
|
150
|
+
Additionally, symbol keys will be parsed back into string keys.
|
151
|
+
|
152
|
+
[logfmt-blog]: https://brandur.org/logfmt "Structured log lines with key/value pairs"
|
153
|
+
[semver]: https://semver.org/spec/v2.0.0.html "Semantic Versioning 2.0.0"
|
154
|
+
[tagged-logger]: https://guides.rubyonrails.org/debugging_rails_applications.html#tagged-logging "Tagged Logging"
|
data/Rakefile
CHANGED
@@ -1,8 +1,37 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "bundler/
|
3
|
+
require "bundler/gem_helper"
|
4
4
|
require "rspec/core/rake_task"
|
5
5
|
|
6
|
+
desc "Run all specs"
|
6
7
|
RSpec::Core::RakeTask.new(:spec)
|
7
8
|
|
9
|
+
namespace "logfmt" do
|
10
|
+
Bundler::GemHelper.install_tasks name: "logfmt"
|
11
|
+
end
|
12
|
+
|
13
|
+
# Inspired by how dotenv/dotenv-rails handles mulitple Gems in a single repo
|
14
|
+
class LogFmtTaggedLoggerGemHelper < Bundler::GemHelper
|
15
|
+
def guard_already_tagged
|
16
|
+
# noop
|
17
|
+
end
|
18
|
+
|
19
|
+
def tag_version
|
20
|
+
# noop
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
namespace "logfmt-tagged_logger" do
|
25
|
+
LogFmtTaggedLoggerGemHelper.install_tasks name: "logfmt-tagged_logger"
|
26
|
+
end
|
27
|
+
|
28
|
+
desc "Build logfmt and logfmt-tagged_logger into the pkg directory"
|
29
|
+
task build: ["logfmt:build", "logfmt-tagged_logger:build"]
|
30
|
+
|
31
|
+
desc "Build and install logfmt and logfmt-tagged_logger into system gems"
|
32
|
+
task install: ["logfmt:install", "logfmt-tagged_logger:install"]
|
33
|
+
|
34
|
+
desc "Create tag, build, and push logfmt and logfmt-tagged_logger to rubygems.org"
|
35
|
+
task release: ["logfmt:release", "logfmt-tagged_logger:release"]
|
36
|
+
|
8
37
|
task default: :spec
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../logfmt"
|
4
|
+
require "logger"
|
5
|
+
require "time"
|
6
|
+
|
7
|
+
module Logfmt
|
8
|
+
class Logger < ::Logger
|
9
|
+
def initialize(*args, **kwargs)
|
10
|
+
super
|
11
|
+
@formatter ||= KeyValueFormatter.new
|
12
|
+
end
|
13
|
+
|
14
|
+
class KeyValueFormatter < ::Logger::Formatter
|
15
|
+
def call(severity, timestamp, progname, msg)
|
16
|
+
%(time=#{format_datetime(timestamp)} severity=#{severity.ljust(5)}#{format_progname(progname)} #{format_message(msg)}\n)
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def format_datetime(time)
|
22
|
+
time.utc.iso8601(6)
|
23
|
+
end
|
24
|
+
|
25
|
+
def format_message(msg)
|
26
|
+
return unless msg
|
27
|
+
|
28
|
+
if msg.respond_to?(:to_hash)
|
29
|
+
pairs = msg.to_hash.map { |k, v| format_pair(k, v) }
|
30
|
+
pairs.compact.join(" ")
|
31
|
+
else
|
32
|
+
format_pair("msg", msg)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def format_pair(key, value)
|
37
|
+
return nil if value.nil?
|
38
|
+
|
39
|
+
# Return a bare key when the value is a `TrueClass`
|
40
|
+
return key if value == true
|
41
|
+
|
42
|
+
"#{key}=#{format_value(value)}"
|
43
|
+
end
|
44
|
+
|
45
|
+
def format_progname(progname)
|
46
|
+
return nil unless progname
|
47
|
+
|
48
|
+
# Format this pair like any other to ensure quoting, escaping, etc…,
|
49
|
+
# But we also need a leading space so we can interpolate the resulting
|
50
|
+
# key/value pair into our log line.
|
51
|
+
" #{format_pair(" progname", progname)}"
|
52
|
+
end
|
53
|
+
|
54
|
+
def format_value(value)
|
55
|
+
if value.is_a?(Float)
|
56
|
+
format("%.3f", value)
|
57
|
+
elsif value.is_a?(Time)
|
58
|
+
format_datetime(value)
|
59
|
+
elsif value.respond_to?(:to_ary)
|
60
|
+
format_value(
|
61
|
+
"[#{Array(value).map { |v| format_value(v) }.join(", ")}]"
|
62
|
+
)
|
63
|
+
else
|
64
|
+
# Interpolating due to a weird/subtle behaviour possible in #to_s.
|
65
|
+
# Namely, it's possible it doesn't actually return a String:
|
66
|
+
# https://github.com/ruby/spec/blob/3affe1e54fcd11918a242ad5d4a7ba895ee30c4c/language/string_spec.rb#L130-L141
|
67
|
+
value = "#{value}" # rubocop:disable Style/RedundantInterpolation
|
68
|
+
value = value.dump if value.match?(/[[:space:]]|[[:cntrl:]]/) # wrap in quotes and escape control characters
|
69
|
+
value
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
data/lib/logfmt/version.rb
CHANGED
data/lib/logfmt.rb
CHANGED
data/logfmt.gemspec
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "lib/logfmt/version"
|
4
|
+
require "English"
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "logfmt"
|
8
|
+
spec.version = Logfmt::VERSION
|
9
|
+
spec.authors = ["Timothée Peignier"]
|
10
|
+
spec.email = ["timothee.peignier@tryphon.org"]
|
11
|
+
|
12
|
+
spec.summary = "Write and parse logfmt messages."
|
13
|
+
spec.description = "Write and parse log lines in the logfmt style."
|
14
|
+
spec.homepage = "https://github.com/cyberdelia/logfmt-ruby"
|
15
|
+
spec.license = "MIT"
|
16
|
+
spec.required_ruby_version = ">= 2.5.0"
|
17
|
+
|
18
|
+
spec.metadata = {
|
19
|
+
"bug_tracker_uri" => "#{spec.homepage}/issues",
|
20
|
+
"changelog_uri" => "#{spec.homepage}/blog/master/CHANGELOG.md",
|
21
|
+
"documentation_uri" => spec.homepage,
|
22
|
+
"source_code_uri" => spec.homepage
|
23
|
+
}
|
24
|
+
|
25
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
26
|
+
`git ls-files`.split($OUTPUT_RECORD_SEPARATOR)
|
27
|
+
.reject { |f|
|
28
|
+
(f == __FILE__) ||
|
29
|
+
f.match?(%r{\A(?:(?:bin|spec|features)/|\.(?:git|github))}) ||
|
30
|
+
f.match?(/tagged_logger/)
|
31
|
+
}
|
32
|
+
end
|
33
|
+
spec.bindir = "bin"
|
34
|
+
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
35
|
+
spec.require_paths = ["lib"]
|
36
|
+
|
37
|
+
spec.add_development_dependency "pry-byebug", "~> 3.9"
|
38
|
+
spec.add_development_dependency "rake", "~> 13.0"
|
39
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
40
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: logfmt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.1.0.beta.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Timothée Peignier
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-10-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: pry-byebug
|
@@ -52,7 +52,7 @@ dependencies:
|
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '3.0'
|
55
|
-
description:
|
55
|
+
description: Write and parse log lines in the logfmt style.
|
56
56
|
email:
|
57
57
|
- timothee.peignier@tryphon.org
|
58
58
|
executables: []
|
@@ -65,13 +65,11 @@ files:
|
|
65
65
|
- README.md
|
66
66
|
- Rakefile
|
67
67
|
- bench.rb
|
68
|
-
- bin/bundle
|
69
|
-
- bin/console
|
70
|
-
- bin/rake
|
71
|
-
- bin/rspec
|
72
68
|
- lib/logfmt.rb
|
69
|
+
- lib/logfmt/logger.rb
|
73
70
|
- lib/logfmt/parser.rb
|
74
71
|
- lib/logfmt/version.rb
|
72
|
+
- logfmt.gemspec
|
75
73
|
homepage: https://github.com/cyberdelia/logfmt-ruby
|
76
74
|
licenses:
|
77
75
|
- MIT
|
@@ -88,15 +86,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
88
86
|
requirements:
|
89
87
|
- - ">="
|
90
88
|
- !ruby/object:Gem::Version
|
91
|
-
version: 2.
|
89
|
+
version: 2.5.0
|
92
90
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
93
91
|
requirements:
|
94
|
-
- - "
|
92
|
+
- - ">"
|
95
93
|
- !ruby/object:Gem::Version
|
96
|
-
version:
|
94
|
+
version: 1.3.1
|
97
95
|
requirements: []
|
98
96
|
rubygems_version: 3.3.7
|
99
97
|
signing_key:
|
100
98
|
specification_version: 4
|
101
|
-
summary:
|
99
|
+
summary: Write and parse logfmt messages.
|
102
100
|
test_files: []
|
data/bin/bundle
DELETED
@@ -1,114 +0,0 @@
|
|
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
|
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_requirement
|
64
|
-
@bundler_requirement ||=
|
65
|
-
env_var_version || cli_arg_version ||
|
66
|
-
bundler_requirement_for(lockfile_version)
|
67
|
-
end
|
68
|
-
|
69
|
-
def bundler_requirement_for(version)
|
70
|
-
return "#{Gem::Requirement.default}.a" unless version
|
71
|
-
|
72
|
-
bundler_gem_version = Gem::Version.new(version)
|
73
|
-
|
74
|
-
requirement = bundler_gem_version.approximate_recommendation
|
75
|
-
|
76
|
-
return requirement unless Gem.rubygems_version < Gem::Version.new("2.7.0")
|
77
|
-
|
78
|
-
requirement += ".a" if bundler_gem_version.prerelease?
|
79
|
-
|
80
|
-
requirement
|
81
|
-
end
|
82
|
-
|
83
|
-
def load_bundler!
|
84
|
-
ENV["BUNDLE_GEMFILE"] ||= gemfile
|
85
|
-
|
86
|
-
activate_bundler
|
87
|
-
end
|
88
|
-
|
89
|
-
def activate_bundler
|
90
|
-
gem_error = activation_error_handling do
|
91
|
-
gem "bundler", bundler_requirement
|
92
|
-
end
|
93
|
-
return if gem_error.nil?
|
94
|
-
require_error = activation_error_handling do
|
95
|
-
require "bundler/version"
|
96
|
-
end
|
97
|
-
return if require_error.nil? && Gem::Requirement.new(bundler_requirement).satisfied_by?(Gem::Version.new(Bundler::VERSION))
|
98
|
-
warn "Activating bundler (#{bundler_requirement}) failed:\n#{gem_error.message}\n\nTo install the version of bundler this project requires, run `gem install bundler -v '#{bundler_requirement}'`"
|
99
|
-
exit 42
|
100
|
-
end
|
101
|
-
|
102
|
-
def activation_error_handling
|
103
|
-
yield
|
104
|
-
nil
|
105
|
-
rescue StandardError, LoadError => e
|
106
|
-
e
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
m.load_bundler!
|
111
|
-
|
112
|
-
if m.invoked_as_script?
|
113
|
-
load Gem.bin_path("bundler", "bundle")
|
114
|
-
end
|
data/bin/console
DELETED
data/bin/rake
DELETED
@@ -1,29 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
#
|
5
|
-
# This file was generated by Bundler.
|
6
|
-
#
|
7
|
-
# The application 'rake' is installed as part of a gem, and
|
8
|
-
# this file is here to facilitate running it.
|
9
|
-
#
|
10
|
-
|
11
|
-
require "pathname"
|
12
|
-
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
13
|
-
Pathname.new(__FILE__).realpath)
|
14
|
-
|
15
|
-
bundle_binstub = File.expand_path("../bundle", __FILE__)
|
16
|
-
|
17
|
-
if File.file?(bundle_binstub)
|
18
|
-
if File.read(bundle_binstub, 300) =~ /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
|
-
|
26
|
-
require "rubygems"
|
27
|
-
require "bundler/setup"
|
28
|
-
|
29
|
-
load Gem.bin_path("rake", "rake")
|
data/bin/rspec
DELETED
@@ -1,29 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
#
|
5
|
-
# This file was generated by Bundler.
|
6
|
-
#
|
7
|
-
# The application 'rspec' is installed as part of a gem, and
|
8
|
-
# this file is here to facilitate running it.
|
9
|
-
#
|
10
|
-
|
11
|
-
require "pathname"
|
12
|
-
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
13
|
-
Pathname.new(__FILE__).realpath)
|
14
|
-
|
15
|
-
bundle_binstub = File.expand_path("../bundle", __FILE__)
|
16
|
-
|
17
|
-
if File.file?(bundle_binstub)
|
18
|
-
if File.read(bundle_binstub, 300) =~ /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
|
-
|
26
|
-
require "rubygems"
|
27
|
-
require "bundler/setup"
|
28
|
-
|
29
|
-
load Gem.bin_path("rspec-core", "rspec")
|