nrser-rash 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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: []