nrser-rash 0.2.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.
Files changed (54) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +104 -0
  3. data/.gitmodules +4 -0
  4. data/.rspec +2 -0
  5. data/.travis.yml +4 -0
  6. data/.yardopts +7 -0
  7. data/Gemfile +10 -0
  8. data/README.md +4 -0
  9. data/Rakefile +6 -0
  10. data/bash/source-profile.sh +17 -0
  11. data/dev/bin/.gitkeep +0 -0
  12. data/dev/bin/console +33 -0
  13. data/dev/bin/rake +3 -0
  14. data/dev/bin/rash +16 -0
  15. data/dev/bin/rspec +3 -0
  16. data/dev/ref/autocomplete.rb +62 -0
  17. data/dev/scratch/apps.AppleScript +14 -0
  18. data/dev/scratch/blocks.rb +232 -0
  19. data/dev/scratch/decorating_methods.rb +18 -0
  20. data/dev/scratch/functions.sh +80 -0
  21. data/dev/scratch/if.sh +16 -0
  22. data/dev/scratch/inc.rb +3 -0
  23. data/dev/scratch/inheriting_env/main.rb +44 -0
  24. data/dev/scratch/inheriting_env/sub.rb +9 -0
  25. data/dev/scratch/load_main.rb +5 -0
  26. data/dev/scratch/load_module.rb +19 -0
  27. data/dev/scratch/lsregister-dump.txt +30165 -0
  28. data/dev/scratch/main.rb +4 -0
  29. data/dev/scratch/optparse.rb +43 -0
  30. data/dev/scratch/overridding-cd.sh +53 -0
  31. data/dev/scratch/path.sh +22 -0
  32. data/dev/scratch/pirating_methods.rb +62 -0
  33. data/dev/scratch/profile.sh +624 -0
  34. data/dev/scratch/return.sh +5 -0
  35. data/dev/scratch/source_rvm.sh +11 -0
  36. data/dev/scratch/stub-names/project/test +3 -0
  37. data/exe/rash +4 -0
  38. data/lib/nrser/rash/cli/call.rb +137 -0
  39. data/lib/nrser/rash/cli/help.rb +29 -0
  40. data/lib/nrser/rash/cli/list.rb +36 -0
  41. data/lib/nrser/rash/cli/run.rb +54 -0
  42. data/lib/nrser/rash/cli.rb +21 -0
  43. data/lib/nrser/rash/config.rb +172 -0
  44. data/lib/nrser/rash/core_ext/object.rb +55 -0
  45. data/lib/nrser/rash/formatters.rb +105 -0
  46. data/lib/nrser/rash/functions.rb +154 -0
  47. data/lib/nrser/rash/helpers.rb +53 -0
  48. data/lib/nrser/rash/testing.rb +305 -0
  49. data/lib/nrser/rash/util.rb +260 -0
  50. data/lib/nrser/rash/version.rb +17 -0
  51. data/lib/nrser/rash.rb +40 -0
  52. data/nrser-rash.gemspec +48 -0
  53. data/tmp/.gitkeep +0 -0
  54. metadata +248 -0
@@ -0,0 +1,260 @@
1
+ # Refinements
2
+ # =======================================================================
3
+
4
+ using NRSER
5
+ using NRSER::Types
6
+
7
+
8
+ # Definitions
9
+ # =======================================================================
10
+
11
+ module NRSER::Rash
12
+
13
+ # @!group Utility Class Methods
14
+ # ==========================================================================
15
+
16
+ def self.log_error(headline, error, message='')
17
+ logger.error "#{ headline }:\n" +
18
+ "#{ error } (#{ error.class })\n\t" +
19
+ error.backtrace.join("\n\t") + "\n#{ message}"
20
+ end
21
+
22
+
23
+ # substitute stuff into a shell command after escaping with
24
+ # `Shellwords.escape`.
25
+ #
26
+ # arguments after the first may be multiple values that will
27
+ # be treated like a positional list for substitution, or a single
28
+ # hash that will be treated like a key substitution.
29
+ #
30
+ # any substitution value that is an Array will be treated like a list of
31
+ # path segments and joined with `File.join`.
32
+ def self.sub command, *subs
33
+ quoted = if subs.length == 1 && subs[0].is_a?(Hash)
34
+ Hash[
35
+ subs[0].map do |key, sub|
36
+ sub = File.join(*sub) if sub.is_a? Array
37
+ # shellwords in 1.9.3 can't handle symbols
38
+ sub = sub.to_s if sub.is_a? Symbol
39
+ [key, Shellwords.escape(sub)]
40
+ end
41
+ ]
42
+ else
43
+ subs.map do |sub|
44
+ sub = File.join(*sub) if sub.is_a? Array
45
+ # shellwords in 1.9.3 can't handle symbols
46
+ sub = sub.to_s if sub.is_a? Symbol
47
+ Shellwords.escape sub
48
+ end
49
+ end
50
+ command % quoted
51
+ end
52
+
53
+ # shortcut for `Shellwords.escape`
54
+ def self.esc *args
55
+ Shellwords.escape *args
56
+ end
57
+
58
+ # execute a system command, using shellwords to escape substituted values.
59
+ #
60
+ # arguments after the first may be multiple values that will
61
+ # be treated like a positional list for substitution, or a single
62
+ # hash that will be treated like a key substitution.
63
+ #
64
+ # any substitution value that is an Array will be treated like a list of
65
+ # path segments and joined with `File.join`.
66
+ def self.sys command, *subs
67
+ cmd = sub command, *subs
68
+ output = `#{ cmd }`
69
+ if $?.exitstatus == 0
70
+ return output
71
+ else
72
+ raise SystemCallError.new(
73
+ "cmd `#{ cmd }` failed with status #{ $?.exitstatus }",
74
+ $?.exitstatus
75
+ )
76
+ end
77
+ end
78
+
79
+ # just runs a command and return true if it exited with status 0
80
+ def self.sys? command, *subs
81
+ cmd = sub command, *subs
82
+ `#{ cmd }`
83
+ $?.exitstatus == 0
84
+ end
85
+
86
+ # run and ignore exit code
87
+ def self.sys! command, *subs
88
+ cmd = sub command, *subs
89
+ `#{ cmd }`
90
+ end
91
+
92
+ def self.chdir path, &block
93
+ path = File.expand_path path
94
+ Dir.chdir path do
95
+ block.(path)
96
+ end
97
+ end
98
+
99
+ # finds direct submodules of `file_path` and requires them.
100
+ # assumes they are in a folder with the same name as the file, e.g.
101
+ #
102
+ # /rash/functions/chinese.rb
103
+ # /rash/functions/chinese/*.rb
104
+ #
105
+ # call it like:
106
+ #
107
+ # NRSER::Rash.require_submodules __FILE__
108
+ #
109
+ def self.require_submodules file_path, deep: false
110
+ file_path = file_path.to_pn
111
+ file_dir = file_path.dirname
112
+
113
+ mod_dir = file_dir / file_path.basename( '.rb' )
114
+
115
+ glob = if deep
116
+ mod_dir / '**' / '*.rb'
117
+ else
118
+ mod_dir / '*.rb'
119
+ end
120
+
121
+ logger.trace "Requiring submodules",
122
+ file_path: file_path,
123
+ file_dir: file_dir,
124
+ mod_dir: mod_dir,
125
+ glob: glob
126
+
127
+ Pathname.glob( glob ).each { |abs_path|
128
+ rel_path = abs_path.relative_path_from file_dir
129
+ req_path = rel_path.dirname / rel_path.basename( '.rb' )
130
+
131
+ logger.trace "Requiring file",
132
+ abs_path: abs_path,
133
+ rel_path: rel_path,
134
+ req_path: req_path
135
+
136
+ begin
137
+ require abs_path.to_s
138
+ rescue Exception => error
139
+ if NRSER::Rash.config( 'DEBUG', false )
140
+ raise error
141
+ else
142
+ logger.warn "Failed to load file #{ abs_path.to_s.inspect }", error
143
+ end
144
+ end
145
+ }
146
+ end
147
+
148
+ def self.stdin
149
+ return $stdin.read unless $stdin.tty?
150
+ end
151
+
152
+ # splits up string args that represent what i'm calling a "path to a
153
+ # reference" in Ruby. by example:
154
+ #
155
+ # NRSER::Rash.ref_path('NRSER::Rash::Functions.blah')
156
+ # # -> ['NRSER', 'Rash', 'Functions', 'blah']
157
+ def self.ref_path(*args)
158
+ args.map {|part|
159
+ part.split('::').map {|_| _.split('.')}
160
+ }.flatten
161
+ end
162
+
163
+ # find the common indent of each line of a string.
164
+ # ignores lines that are all whitespace (`/^\s*$/`), which takes care
165
+ # or newlines at the end of files, and prevents the method from
166
+ # not working due to whitespace weirdness that you can't see.
167
+ #
168
+ # note that inconsistent whitespace will still cause problems since
169
+ # there isn't anyway to guess the tabstop equating spaces and tabs.
170
+ def self.find_indent(string)
171
+ string.lines.reject {|line|
172
+ # don't consider blank lines
173
+ line =~ /^[\ \t]*$/
174
+ }.map {|line|
175
+ # get the indent off each non-blank line
176
+ line.match(/^([\ \t]*)/)[1]
177
+ }.sort.reduce {|first, indent|
178
+ return '' unless indent[0...(first.length)] == first
179
+ first
180
+ }
181
+ end
182
+
183
+ def self.dedent(string = NRSER::Rash.stdin)
184
+ indent = find_indent(string)
185
+ # short-circuit if there is no indent
186
+ return string if indent == ''
187
+ # process the lines
188
+ new_lines = string.lines.map do |line|
189
+ # does the line start with the indent?
190
+ if line[0...(indent.length)] == indent
191
+ # it does, so chop it off
192
+ line[(indent.length)..(line.length)]
193
+ elsif line =~ /^\s+$/
194
+ # it does not start with the indent. we're going to let this slide
195
+ # if it's only whitespace
196
+ line
197
+ else
198
+ # we shouldn't get here if `find_indent` is doing it's job
199
+ # i guess report an error and return the string?
200
+ logger.error "should not be so"
201
+ return string
202
+ end
203
+ end
204
+ new_lines.join
205
+ end
206
+
207
+ # @!endgroup Utility Class Methods
208
+
209
+
210
+ class Writer < IO
211
+ def initialize(options = {})
212
+ options = {:out => $stdout, :spacer => ' '}.merge options
213
+ @spacer = options[:spacer]
214
+ @level = 0
215
+ @new_line = true
216
+ @out = options[:out]
217
+ super options[:out].fileno
218
+ end
219
+
220
+ attr_accessor :out
221
+
222
+ def indent(&b)
223
+ @level += 1
224
+ if b
225
+ yield
226
+ dedent
227
+ end
228
+ end
229
+
230
+ def dedent
231
+ @level -= 1
232
+ end
233
+
234
+ def block(start = nil, finish = nil, &body)
235
+ [start].flatten.each {|line| puts line } if start
236
+ indent do
237
+ yield
238
+ end
239
+ [finish].flatten.each {|line| puts line} if finish
240
+ end
241
+
242
+ # add the indent, unless it's called with a newline (`puts` calls
243
+ # write twice for every line, with the second call being "\n")
244
+ def write(obj)
245
+ if @new_line && @level > 0
246
+ super indent_string
247
+ end
248
+ str = obj.to_s
249
+ @new_line = (str[-1] == "\n")
250
+ super str.lines.to_a.join(indent_string)
251
+ end
252
+
253
+ private
254
+
255
+ def indent_string
256
+ @spacer * @level
257
+ end
258
+ end # class Writer
259
+
260
+ end # module NRSER::Rash
@@ -0,0 +1,17 @@
1
+ require 'pathname'
2
+
3
+ module NRSER
4
+ module Rash
5
+ # The current version.
6
+ #
7
+ # @return [String]
8
+ #
9
+ VERSION = "0.2.0"
10
+
11
+ # Absolute, expanded path to the gem's root directory.
12
+ #
13
+ # @return [Pathname]
14
+ #
15
+ ROOT = ( Pathname.new(__FILE__ ).dirname / '..' / '..' ).expand_path
16
+ end
17
+ end
data/lib/nrser/rash.rb ADDED
@@ -0,0 +1,40 @@
1
+ # Requirements
2
+ # =======================================================================
3
+
4
+ # Stdlib
5
+ # -----------------------------------------------------------------------
6
+ require 'logger'
7
+ require 'set'
8
+ require 'shellwords'
9
+ require 'json'
10
+
11
+ # Deps
12
+ # -----------------------------------------------------------------------
13
+ require 'nrser'
14
+ require 'semantic_logger'
15
+
16
+ # Project / Package
17
+ # -----------------------------------------------------------------------
18
+ require_relative './rash/version'
19
+ require_relative './rash/cli'
20
+ require_relative './rash/core_ext/object'
21
+ require_relative './rash/config'
22
+ require_relative './rash/formatters'
23
+ require_relative './rash/functions'
24
+ require_relative './rash/helpers'
25
+ require_relative './rash/testing'
26
+ require_relative './rash/util'
27
+
28
+
29
+ # Definitions
30
+ # =======================================================================
31
+
32
+ module NRSER::Rash
33
+
34
+ # Mixins
35
+ # ============================================================================
36
+
37
+ # Add {.logger} and {#logger} methods
38
+ include SemanticLogger::Loggable
39
+
40
+ end # module NRSER::Rash
@@ -0,0 +1,48 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'nrser/rash/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "nrser-rash"
8
+ spec.version = NRSER::Rash::VERSION
9
+ spec.authors = ["nrser"]
10
+ spec.email = ["neil@ztkae.com"]
11
+
12
+ spec.summary = %q{bullshit}
13
+ # spec.description = %q{TODO: Write a longer description or delete this line.}
14
+ spec.homepage = "https://github.com/nrser/rash"
15
+
16
+ spec.required_ruby_version = '>= 2.3.0'
17
+
18
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
19
+ spec.bindir = "exe"
20
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
+ spec.require_paths = ["lib"]
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.10"
24
+ spec.add_development_dependency "rake", "~> 10.0"
25
+ spec.add_development_dependency "rspec"
26
+
27
+ # GitHub-Flavored Markdown (GFM) for use with `yard`
28
+ spec.add_development_dependency 'github-markup', '~> 1.6'
29
+
30
+ # Doc site generation with `yard`
31
+ spec.add_development_dependency 'yard', '~> 0.9.12'
32
+
33
+ # Provider for `commonmarker`, the new GFM lib
34
+ spec.add_development_dependency 'yard-commonmarker', '~> 0.3.0'
35
+
36
+ # Better console life
37
+ spec.add_development_dependency 'pry'
38
+
39
+ # Used for the wonky in-module testing thing. Yeah I know it ships with
40
+ # Ruby but there was some issue with that...
41
+ spec.add_dependency 'minitest', '~> 5.8', '>= 5.8.4'
42
+
43
+ # My guns
44
+ spec.add_dependency 'nrser', '0.2.0.pre.0'
45
+
46
+ # My favorite wrapper
47
+ spec.add_dependency "cmds", '~> 0.0', ">= 0.2.7"
48
+ end
data/tmp/.gitkeep ADDED
File without changes
metadata ADDED
@@ -0,0 +1,248 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nrser-rash
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - nrser
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2018-02-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.10'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.10'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: github-markup
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.6'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.6'
69
+ - !ruby/object:Gem::Dependency
70
+ name: yard
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 0.9.12
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 0.9.12
83
+ - !ruby/object:Gem::Dependency
84
+ name: yard-commonmarker
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 0.3.0
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 0.3.0
97
+ - !ruby/object:Gem::Dependency
98
+ name: pry
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: minitest
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '5.8'
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ version: 5.8.4
121
+ type: :runtime
122
+ prerelease: false
123
+ version_requirements: !ruby/object:Gem::Requirement
124
+ requirements:
125
+ - - "~>"
126
+ - !ruby/object:Gem::Version
127
+ version: '5.8'
128
+ - - ">="
129
+ - !ruby/object:Gem::Version
130
+ version: 5.8.4
131
+ - !ruby/object:Gem::Dependency
132
+ name: nrser
133
+ requirement: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - '='
136
+ - !ruby/object:Gem::Version
137
+ version: 0.2.0.pre.0
138
+ type: :runtime
139
+ prerelease: false
140
+ version_requirements: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - '='
143
+ - !ruby/object:Gem::Version
144
+ version: 0.2.0.pre.0
145
+ - !ruby/object:Gem::Dependency
146
+ name: cmds
147
+ requirement: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - "~>"
150
+ - !ruby/object:Gem::Version
151
+ version: '0.0'
152
+ - - ">="
153
+ - !ruby/object:Gem::Version
154
+ version: 0.2.7
155
+ type: :runtime
156
+ prerelease: false
157
+ version_requirements: !ruby/object:Gem::Requirement
158
+ requirements:
159
+ - - "~>"
160
+ - !ruby/object:Gem::Version
161
+ version: '0.0'
162
+ - - ">="
163
+ - !ruby/object:Gem::Version
164
+ version: 0.2.7
165
+ description:
166
+ email:
167
+ - neil@ztkae.com
168
+ executables:
169
+ - rash
170
+ extensions: []
171
+ extra_rdoc_files: []
172
+ files:
173
+ - ".gitignore"
174
+ - ".gitmodules"
175
+ - ".rspec"
176
+ - ".travis.yml"
177
+ - ".yardopts"
178
+ - Gemfile
179
+ - README.md
180
+ - Rakefile
181
+ - bash/source-profile.sh
182
+ - dev/bin/.gitkeep
183
+ - dev/bin/console
184
+ - dev/bin/rake
185
+ - dev/bin/rash
186
+ - dev/bin/rspec
187
+ - dev/ref/autocomplete.rb
188
+ - dev/scratch/apps.AppleScript
189
+ - dev/scratch/blocks.rb
190
+ - dev/scratch/decorating_methods.rb
191
+ - dev/scratch/functions.sh
192
+ - dev/scratch/if.sh
193
+ - dev/scratch/inc.rb
194
+ - dev/scratch/inheriting_env/main.rb
195
+ - dev/scratch/inheriting_env/sub.rb
196
+ - dev/scratch/load_main.rb
197
+ - dev/scratch/load_module.rb
198
+ - dev/scratch/lsregister-dump.txt
199
+ - dev/scratch/main.rb
200
+ - dev/scratch/optparse.rb
201
+ - dev/scratch/overridding-cd.sh
202
+ - dev/scratch/path.sh
203
+ - dev/scratch/pirating_methods.rb
204
+ - dev/scratch/profile.sh
205
+ - dev/scratch/return.sh
206
+ - dev/scratch/source_rvm.sh
207
+ - dev/scratch/stub-names/project/test
208
+ - exe/rash
209
+ - lib/nrser/rash.rb
210
+ - lib/nrser/rash/cli.rb
211
+ - lib/nrser/rash/cli/call.rb
212
+ - lib/nrser/rash/cli/help.rb
213
+ - lib/nrser/rash/cli/list.rb
214
+ - lib/nrser/rash/cli/run.rb
215
+ - lib/nrser/rash/config.rb
216
+ - lib/nrser/rash/core_ext/object.rb
217
+ - lib/nrser/rash/formatters.rb
218
+ - lib/nrser/rash/functions.rb
219
+ - lib/nrser/rash/helpers.rb
220
+ - lib/nrser/rash/testing.rb
221
+ - lib/nrser/rash/util.rb
222
+ - lib/nrser/rash/version.rb
223
+ - nrser-rash.gemspec
224
+ - tmp/.gitkeep
225
+ homepage: https://github.com/nrser/rash
226
+ licenses: []
227
+ metadata: {}
228
+ post_install_message:
229
+ rdoc_options: []
230
+ require_paths:
231
+ - lib
232
+ required_ruby_version: !ruby/object:Gem::Requirement
233
+ requirements:
234
+ - - ">="
235
+ - !ruby/object:Gem::Version
236
+ version: 2.3.0
237
+ required_rubygems_version: !ruby/object:Gem::Requirement
238
+ requirements:
239
+ - - ">="
240
+ - !ruby/object:Gem::Version
241
+ version: '0'
242
+ requirements: []
243
+ rubyforge_project:
244
+ rubygems_version: 2.5.2
245
+ signing_key:
246
+ specification_version: 4
247
+ summary: bullshit
248
+ test_files: []