ops_team 1.13.0 → 1.16.0.pre.rc1
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/Gemfile +1 -0
- data/bin/benchmark +185 -0
- data/bin/ops +15 -3
- data/lib/action.rb +3 -3
- data/lib/action_list.rb +0 -2
- data/lib/builtin.rb +20 -1
- data/lib/builtins/background.rb +1 -3
- data/lib/builtins/background_log.rb +0 -3
- data/lib/builtins/common/up_down.rb +0 -7
- data/lib/builtins/countdown.rb +0 -3
- data/lib/builtins/down.rb +0 -5
- data/lib/builtins/env.rb +0 -3
- data/lib/builtins/envdiff.rb +1 -5
- data/lib/builtins/exec.rb +2 -5
- data/lib/builtins/help.rb +0 -4
- data/lib/builtins/helpers/dependency_handler.rb +0 -6
- data/lib/builtins/helpers/enumerator.rb +3 -0
- data/lib/builtins/init.rb +0 -3
- data/lib/builtins/up.rb +0 -6
- data/lib/builtins/version.rb +0 -3
- data/lib/dependencies/apk.rb +0 -2
- data/lib/dependencies/apt.rb +0 -3
- data/lib/dependencies/brew.rb +0 -2
- data/lib/dependencies/cask.rb +0 -2
- data/lib/dependencies/custom.rb +0 -2
- data/lib/dependencies/dir.rb +0 -2
- data/lib/dependencies/docker.rb +0 -2
- data/lib/dependencies/gem.rb +0 -3
- data/lib/dependencies/pip.rb +0 -3
- data/lib/dependencies/sshkey.rb +0 -2
- data/lib/dependency.rb +0 -3
- data/lib/environment.rb +0 -4
- data/lib/forward.rb +0 -2
- data/lib/forwards.rb +0 -2
- data/lib/hook_handler.rb +0 -2
- data/lib/ops.rb +9 -10
- data/lib/profiler.rb +47 -0
- data/lib/runner.rb +5 -7
- data/lib/secrets.rb +0 -4
- data/loader.rb +7 -1
- data/ops_team.gemspec +1 -1
- metadata +10 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e5aa70e4e711e46c9e7661013c62fc3f40db454caeee504c0ff3c49258ea3951
|
4
|
+
data.tar.gz: c1a491887c6629b419b3397aed7b0ad0e1b74a19bcfda45fc79fb15d481f517c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b92b2d6583d86f2a0fccf7d17d6d713aaf062eed7837836fb0904c7bafee5ded631a9d26b22c96eb429e629f54d7a9e06f5f2ace0411743e57005ec410086808
|
7
|
+
data.tar.gz: f8199c0e807ed8fa7e1d3bfba3928c51fa32dca844bdaa103d3d18afb35b8ef017ddae71a8371a3d5fbb1a3ec3b9bd475105754e6e5f0b7b439b90279171c28c
|
data/Gemfile
CHANGED
data/bin/benchmark
ADDED
@@ -0,0 +1,185 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'json'
|
5
|
+
require 'colorize'
|
6
|
+
|
7
|
+
COMMANDS = [
|
8
|
+
"version",
|
9
|
+
"env",
|
10
|
+
"help",
|
11
|
+
"exec echo hi",
|
12
|
+
"env OPS_AUTO_COMPLETE=true"
|
13
|
+
].freeze
|
14
|
+
|
15
|
+
class Runner
|
16
|
+
RUNS = 10
|
17
|
+
WARMUPS = 3
|
18
|
+
|
19
|
+
attr_reader :command, :version
|
20
|
+
|
21
|
+
def initialize(command, version)
|
22
|
+
@command = command
|
23
|
+
@version = version
|
24
|
+
end
|
25
|
+
|
26
|
+
def run
|
27
|
+
unless File.exist?(json_file)
|
28
|
+
system(
|
29
|
+
"hyperfine -m #{RUNS} \
|
30
|
+
--export-json #{json_file} \
|
31
|
+
--export-markdown #{markdown_file} \
|
32
|
+
--warmup #{WARMUPS} \
|
33
|
+
'#{@command}'"
|
34
|
+
)
|
35
|
+
end
|
36
|
+
|
37
|
+
results
|
38
|
+
end
|
39
|
+
|
40
|
+
def results
|
41
|
+
# for now, only ever one result, since we're not having hyperfine vary params
|
42
|
+
@results ||= JSON.parse(results_data)["results"].first
|
43
|
+
end
|
44
|
+
|
45
|
+
def method_missing(method, *_, &_)
|
46
|
+
results[method.to_s]
|
47
|
+
end
|
48
|
+
|
49
|
+
def respond_to_missing?(method, _ = false)
|
50
|
+
results&.keys&.include?(method.to_s)
|
51
|
+
end
|
52
|
+
|
53
|
+
def json_file
|
54
|
+
@json_file ||= "#{output_file}.json"
|
55
|
+
end
|
56
|
+
|
57
|
+
def markdown_file
|
58
|
+
@markdown_file ||= "#{output_file}.md"
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def output_file
|
64
|
+
"benchmark/#{@version}-#{@command.gsub(" ", "_").gsub("/", "-")}"
|
65
|
+
end
|
66
|
+
|
67
|
+
def results_data
|
68
|
+
File.read(json_file)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
class Benchmark
|
73
|
+
attr_reader :executable
|
74
|
+
|
75
|
+
def initialize(executable)
|
76
|
+
@executable = executable
|
77
|
+
end
|
78
|
+
|
79
|
+
def run
|
80
|
+
runners.map(&:run)
|
81
|
+
|
82
|
+
runners.map(&:mean)
|
83
|
+
end
|
84
|
+
|
85
|
+
def version
|
86
|
+
@version ||= `#{@executable} version`.chomp
|
87
|
+
end
|
88
|
+
|
89
|
+
def runners
|
90
|
+
@runners ||= COMMANDS.map do |cmd|
|
91
|
+
Runner.new("#{@executable} #{cmd}", version)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
class Benchmarker
|
97
|
+
CLR_THRESHOLD = 0.1
|
98
|
+
CLR_WIDTH = 14
|
99
|
+
COL_WIDTH = 24
|
100
|
+
CMD_WIDTH = 30
|
101
|
+
|
102
|
+
def initialize(*executables)
|
103
|
+
@executables = executables
|
104
|
+
end
|
105
|
+
|
106
|
+
def summary
|
107
|
+
result_pairs = results.first.zip(results.last)
|
108
|
+
|
109
|
+
output = header
|
110
|
+
COMMANDS.length.times do |index|
|
111
|
+
output << format(
|
112
|
+
"%#{CMD_WIDTH + CLR_WIDTH}s %#{COL_WIDTH}s %#{COL_WIDTH + CLR_WIDTH}s",
|
113
|
+
COMMANDS[index].white,
|
114
|
+
*result_strings(result_pairs[index])
|
115
|
+
)
|
116
|
+
end
|
117
|
+
output << summary_numbers
|
118
|
+
|
119
|
+
output.join("\n")
|
120
|
+
end
|
121
|
+
|
122
|
+
def benchmarks
|
123
|
+
@benchmarks ||= @executables.map do |executable|
|
124
|
+
Benchmark.new(executable)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def results
|
129
|
+
@results ||= benchmarks.map(&:run)
|
130
|
+
end
|
131
|
+
|
132
|
+
private
|
133
|
+
|
134
|
+
def result_pairs
|
135
|
+
@result_pairs ||= results.first.zip(results.last)
|
136
|
+
end
|
137
|
+
|
138
|
+
def header
|
139
|
+
[
|
140
|
+
format(
|
141
|
+
"%#{CMD_WIDTH}s %#{COL_WIDTH + CLR_WIDTH}s %#{COL_WIDTH + CLR_WIDTH}s",
|
142
|
+
"", *benchmarks.map { |b| b.executable.white }
|
143
|
+
),
|
144
|
+
format(
|
145
|
+
"%#{CMD_WIDTH}s %#{COL_WIDTH + CLR_WIDTH}s %#{COL_WIDTH + CLR_WIDTH}s",
|
146
|
+
"", *benchmarks.map { |b| b.version.white }
|
147
|
+
)
|
148
|
+
]
|
149
|
+
end
|
150
|
+
|
151
|
+
def result_strings(pair)
|
152
|
+
colour = :blue
|
153
|
+
if pair.last < (pair.first * (1 - CLR_THRESHOLD))
|
154
|
+
colour = :green
|
155
|
+
elsif pair.last < (pair.first * CLR_THRESHOLD)
|
156
|
+
colour = :red
|
157
|
+
end
|
158
|
+
|
159
|
+
outputs = pair.map { |number| format("%02.3f", number) }
|
160
|
+
|
161
|
+
outputs[1] = outputs.last.send(colour)
|
162
|
+
|
163
|
+
outputs
|
164
|
+
end
|
165
|
+
|
166
|
+
def summary_numbers
|
167
|
+
format(
|
168
|
+
"%#{CMD_WIDTH + CLR_WIDTH}s %#{COL_WIDTH}s %#{COL_WIDTH + CLR_WIDTH}s",
|
169
|
+
"Avg difference".white, "-", avg_diff_string.white
|
170
|
+
)
|
171
|
+
end
|
172
|
+
|
173
|
+
def avg_diff_string
|
174
|
+
format("%02.3f", avg_diff)
|
175
|
+
end
|
176
|
+
|
177
|
+
def avg_diff
|
178
|
+
result_pairs.each_with_object([]) do |pair, diff|
|
179
|
+
diff << pair.first - pair.last
|
180
|
+
end.sum / result_pairs.length
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
`rm -f benchmark/*.json benchmark/*.md` unless %w[--skip -s].include?(ARGV[0])
|
185
|
+
puts Benchmarker.new("ops", "bin/ops").summary
|
data/bin/ops
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
+
start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
5
|
+
|
6
|
+
require_relative '../lib/profiler'
|
4
7
|
require 'optparse'
|
5
8
|
|
6
9
|
def usage
|
@@ -12,6 +15,8 @@ def usage
|
|
12
15
|
end
|
13
16
|
|
14
17
|
options = {}
|
18
|
+
status = -1
|
19
|
+
|
15
20
|
while ARGV[0]&.match(/^-/)
|
16
21
|
opt = ARGV.shift
|
17
22
|
case opt
|
@@ -24,7 +29,14 @@ while ARGV[0]&.match(/^-/)
|
|
24
29
|
end
|
25
30
|
end
|
26
31
|
|
27
|
-
|
28
|
-
|
32
|
+
Profiler.measure("bin:require") do
|
33
|
+
require_relative "../loader"
|
34
|
+
end
|
35
|
+
|
36
|
+
Profiler.measure("bin:run") do
|
37
|
+
status = Ops.new(ARGV, config_file: options[:file]).run
|
38
|
+
end
|
29
39
|
|
30
|
-
|
40
|
+
Profiler.add_measurement("bin:all", Process.clock_gettime(Process::CLOCK_MONOTONIC) - start_time)
|
41
|
+
Output.error(Profiler.summary) if Profiler.summary
|
42
|
+
exit status
|
data/lib/action.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'secrets'
|
4
|
-
|
5
3
|
# represents one action to be performed in the shell
|
6
4
|
# can assemble a command line from a command and args
|
7
5
|
class Action
|
@@ -9,11 +7,13 @@ class Action
|
|
9
7
|
|
10
8
|
def initialize(name, config, args)
|
11
9
|
@name = name
|
12
|
-
@config = config
|
10
|
+
@config = config || {}
|
13
11
|
@args = args
|
14
12
|
end
|
15
13
|
|
16
14
|
def run
|
15
|
+
Output.error(Profiler.summary) if Profiler.summary
|
16
|
+
|
17
17
|
if perform_shell_expansion?
|
18
18
|
Kernel.exec(to_s)
|
19
19
|
else
|
data/lib/action_list.rb
CHANGED
data/lib/builtin.rb
CHANGED
@@ -6,16 +6,35 @@ class Builtin
|
|
6
6
|
attr_reader :args, :config
|
7
7
|
|
8
8
|
class << self
|
9
|
+
BUILTIN_DIR = "builtins"
|
10
|
+
|
9
11
|
def description
|
10
12
|
"no description"
|
11
13
|
end
|
12
14
|
|
13
15
|
def class_for(name:)
|
14
|
-
|
16
|
+
file = file_for(name: name)
|
17
|
+
unless File.exist?(file)
|
18
|
+
require 'require_all'
|
19
|
+
require_rel "builtins"
|
20
|
+
end
|
21
|
+
|
22
|
+
get_const(name: builtin_class_name_for(name: name))
|
15
23
|
end
|
16
24
|
|
17
25
|
private
|
18
26
|
|
27
|
+
def get_const(name:)
|
28
|
+
Builtins.const_get(name)
|
29
|
+
rescue NameError
|
30
|
+
# no such constant
|
31
|
+
nil
|
32
|
+
end
|
33
|
+
|
34
|
+
def file_for(name:)
|
35
|
+
File.join(File.dirname(__FILE__), BUILTIN_DIR, "#{name}.rb")
|
36
|
+
end
|
37
|
+
|
19
38
|
def builtin_class_name_for(name:)
|
20
39
|
name.capitalize.to_sym
|
21
40
|
end
|
data/lib/builtins/background.rb
CHANGED
data/lib/builtins/countdown.rb
CHANGED
data/lib/builtins/down.rb
CHANGED
data/lib/builtins/env.rb
CHANGED
data/lib/builtins/envdiff.rb
CHANGED
@@ -1,9 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'builtin'
|
4
|
-
|
5
3
|
module Builtins
|
6
|
-
class
|
4
|
+
class Envdiff < Builtin
|
7
5
|
class << self
|
8
6
|
def description
|
9
7
|
"compares keys present in config and secrets between different environments"
|
@@ -126,6 +124,4 @@ module Builtins
|
|
126
124
|
Options.get("envdiff.ignored_keys") || []
|
127
125
|
end
|
128
126
|
end
|
129
|
-
|
130
|
-
Envdiff = EnvDiff
|
131
127
|
end
|
data/lib/builtins/exec.rb
CHANGED
@@ -1,10 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'builtin'
|
4
|
-
require 'output'
|
5
|
-
require 'secrets'
|
6
|
-
require 'options'
|
7
|
-
|
8
3
|
module Builtins
|
9
4
|
class Exec < Builtin
|
10
5
|
class << self
|
@@ -17,9 +12,11 @@ module Builtins
|
|
17
12
|
Secrets.load if Options.get("exec.load_secrets")
|
18
13
|
|
19
14
|
if args.any?
|
15
|
+
Output.error(Profiler.summary) if Profiler.summary
|
20
16
|
Kernel.exec(args.join(" "))
|
21
17
|
else
|
22
18
|
Output.error("Usage: ops exec '<command>'")
|
19
|
+
|
23
20
|
false
|
24
21
|
end
|
25
22
|
end
|
data/lib/builtins/help.rb
CHANGED
data/lib/builtins/init.rb
CHANGED
data/lib/builtins/up.rb
CHANGED
data/lib/builtins/version.rb
CHANGED
data/lib/dependencies/apk.rb
CHANGED
data/lib/dependencies/apt.rb
CHANGED
data/lib/dependencies/brew.rb
CHANGED
data/lib/dependencies/cask.rb
CHANGED
data/lib/dependencies/custom.rb
CHANGED
data/lib/dependencies/dir.rb
CHANGED
data/lib/dependencies/docker.rb
CHANGED
data/lib/dependencies/gem.rb
CHANGED
data/lib/dependencies/pip.rb
CHANGED
data/lib/dependencies/sshkey.rb
CHANGED
data/lib/dependency.rb
CHANGED
data/lib/environment.rb
CHANGED
data/lib/forward.rb
CHANGED
data/lib/forwards.rb
CHANGED
data/lib/hook_handler.rb
CHANGED
data/lib/ops.rb
CHANGED
@@ -1,16 +1,13 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
|
5
|
-
require '
|
6
|
-
require "rubygems"
|
7
|
-
|
8
|
-
require 'output'
|
9
|
-
require 'options'
|
10
|
-
require 'version'
|
11
|
-
require 'runner'
|
4
|
+
Profiler.measure("ops:requires_external") do
|
5
|
+
require 'yaml'
|
6
|
+
require "rubygems"
|
7
|
+
end
|
12
8
|
|
13
|
-
|
9
|
+
Profiler.measure("ops:requires_internal") do
|
10
|
+
end
|
14
11
|
|
15
12
|
# executes commands based on local `ops.yml`
|
16
13
|
class Ops
|
@@ -45,7 +42,9 @@ class Ops
|
|
45
42
|
return exit(INVALID_SYNTAX_EXIT_CODE) unless syntax_valid?
|
46
43
|
return exit(MIN_VERSION_NOT_MET_EXIT_CODE) unless min_version_met?
|
47
44
|
|
48
|
-
runner
|
45
|
+
Profiler.measure("runner:run") do
|
46
|
+
runner.run
|
47
|
+
end
|
49
48
|
rescue Runner::UnknownActionError => e
|
50
49
|
Output.error(e.to_s)
|
51
50
|
Output.out(RECOMMEND_HELP_TEXT) unless print_did_you_mean
|
data/lib/profiler.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Profiler
|
4
|
+
INDENT = " "
|
5
|
+
|
6
|
+
@measurements = {}
|
7
|
+
|
8
|
+
class << self
|
9
|
+
attr_reader :measurements
|
10
|
+
|
11
|
+
def measure(tag)
|
12
|
+
start = time_now
|
13
|
+
result = yield
|
14
|
+
add_measurement(tag, time_now - start)
|
15
|
+
|
16
|
+
result
|
17
|
+
end
|
18
|
+
|
19
|
+
def add_measurement(tag, seconds)
|
20
|
+
return unless profiling?
|
21
|
+
|
22
|
+
@measurements[tag] ||= []
|
23
|
+
|
24
|
+
@measurements[tag] << seconds
|
25
|
+
end
|
26
|
+
|
27
|
+
def summary
|
28
|
+
return unless profiling?
|
29
|
+
|
30
|
+
@summary ||= measurements.reverse_each.each_with_object([]) do |(tag, values), output|
|
31
|
+
output << "#{tag}:\n"
|
32
|
+
values.sort.reverse.each do |value|
|
33
|
+
value_str = format("%.3f", value * 1000)
|
34
|
+
output << format("%<indent>s%9<value>sms\n", indent: INDENT, value: value_str)
|
35
|
+
end
|
36
|
+
end.join
|
37
|
+
end
|
38
|
+
|
39
|
+
def profiling?
|
40
|
+
!ENV["OPS_PROFILE"].nil?
|
41
|
+
end
|
42
|
+
|
43
|
+
def time_now
|
44
|
+
Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/lib/runner.rb
CHANGED
@@ -1,11 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
require 'action_list'
|
6
|
-
require 'action_suggester'
|
7
|
-
require 'forwards'
|
8
|
-
require 'environment'
|
3
|
+
module Builtins
|
4
|
+
end
|
9
5
|
|
10
6
|
class Runner
|
11
7
|
class UnknownActionError < StandardError; end
|
@@ -61,7 +57,9 @@ class Runner
|
|
61
57
|
end
|
62
58
|
|
63
59
|
def builtin
|
64
|
-
|
60
|
+
Profiler.measure("runner:require_builtin") do
|
61
|
+
@builtin ||= Builtin.class_for(name: @action_name)&.new(@args, @config)
|
62
|
+
end
|
65
63
|
rescue NameError
|
66
64
|
# this means there isn't a builtin with that name in that module
|
67
65
|
nil
|
data/lib/secrets.rb
CHANGED
data/loader.rb
CHANGED
@@ -1,4 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# for convenience, add "lib" to the load path
|
4
|
-
$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + "/lib"))
|
4
|
+
# $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + "/lib"))
|
5
|
+
|
6
|
+
require 'zeitwerk'
|
7
|
+
|
8
|
+
loader = Zeitwerk::Loader.new
|
9
|
+
loader.push_dir(File.expand_path("#{__dir__}/lib"))
|
10
|
+
loader.setup
|
data/ops_team.gemspec
CHANGED
metadata
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ops_team
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.16.0.pre.rc1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- nickthecook@gmail.com
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
date: 2021-10-25 00:00:00.000000000 Z
|
@@ -150,14 +150,15 @@ dependencies:
|
|
150
150
|
- - ">="
|
151
151
|
- !ruby/object:Gem::Version
|
152
152
|
version: 1.1.6
|
153
|
-
description:
|
154
|
-
email:
|
153
|
+
description:
|
154
|
+
email:
|
155
155
|
executables:
|
156
156
|
- ops
|
157
157
|
extensions: []
|
158
158
|
extra_rdoc_files: []
|
159
159
|
files:
|
160
160
|
- Gemfile
|
161
|
+
- bin/benchmark
|
161
162
|
- bin/ops
|
162
163
|
- bin/print_config
|
163
164
|
- bin/print_secrets
|
@@ -205,6 +206,7 @@ files:
|
|
205
206
|
- lib/ops.rb
|
206
207
|
- lib/options.rb
|
207
208
|
- lib/output.rb
|
209
|
+
- lib/profiler.rb
|
208
210
|
- lib/runner.rb
|
209
211
|
- lib/secrets.rb
|
210
212
|
- lib/version.rb
|
@@ -214,7 +216,7 @@ homepage: https://github.com/nickthecook/ops
|
|
214
216
|
licenses:
|
215
217
|
- GPL-3.0-only
|
216
218
|
metadata: {}
|
217
|
-
post_install_message:
|
219
|
+
post_install_message:
|
218
220
|
rdoc_options: []
|
219
221
|
require_paths:
|
220
222
|
- lib
|
@@ -225,12 +227,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
225
227
|
version: '2.5'
|
226
228
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
227
229
|
requirements:
|
228
|
-
- - "
|
230
|
+
- - ">"
|
229
231
|
- !ruby/object:Gem::Version
|
230
|
-
version:
|
232
|
+
version: 1.3.1
|
231
233
|
requirements: []
|
232
234
|
rubygems_version: 3.2.15
|
233
|
-
signing_key:
|
235
|
+
signing_key:
|
234
236
|
specification_version: 4
|
235
237
|
summary: ops_team handles basic automation for your project, driven by self-documenting
|
236
238
|
YAML config
|