scout-camp 0.1.13 → 0.1.14

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 (49) hide show
  1. checksums.yaml +4 -4
  2. data/.vimproject +52 -11
  3. data/Rakefile +5 -0
  4. data/VERSION +1 -1
  5. data/bin/scout-camp +46 -0
  6. data/doc/terraform.md +188 -0
  7. data/lib/scout/aws/s3.rb +6 -4
  8. data/lib/scout/offsite/resource.rb +110 -5
  9. data/lib/scout/offsite/step.rb +21 -14
  10. data/lib/scout/offsite/sync.rb +38 -10
  11. data/lib/scout/offsite.rb +1 -0
  12. data/lib/scout/render/engine.rb +119 -0
  13. data/lib/scout/render/helpers.rb +92 -0
  14. data/lib/scout/render/resource.rb +54 -0
  15. data/lib/scout/render.rb +3 -0
  16. data/lib/scout/sinatra/auth.rb +158 -0
  17. data/lib/scout/sinatra/base/assets.rb +245 -0
  18. data/lib/scout/sinatra/base/favicon.rb +43 -0
  19. data/lib/scout/sinatra/base/headers.rb +77 -0
  20. data/lib/scout/sinatra/base/helpers.rb +14 -0
  21. data/lib/scout/sinatra/base/parameters.rb +147 -0
  22. data/lib/scout/sinatra/base/post_processing.rb +18 -0
  23. data/lib/scout/sinatra/base/session.rb +72 -0
  24. data/lib/scout/sinatra/base.rb +253 -0
  25. data/lib/scout/sinatra/entity.rb +259 -0
  26. data/lib/scout/sinatra/finder.rb +9 -0
  27. data/lib/scout/sinatra/fragment.rb +275 -0
  28. data/lib/scout/sinatra/htmx.rb +68 -0
  29. data/lib/scout/sinatra/knowledge_base.rb +14 -0
  30. data/lib/scout/sinatra/tool.rb +11 -0
  31. data/lib/scout/sinatra/workflow.rb +129 -0
  32. data/lib/scout-camp.rb +1 -1
  33. data/scout-camp.gemspec +39 -3
  34. data/scout_commands/find +83 -0
  35. data/scout_commands/glob +90 -0
  36. data/share/aws/lambda_function.rb +53 -30
  37. data/share/terraform/aws/efs_host/data.tf +1 -2
  38. data/share/terraform/aws/efs_host/main.tf +1 -1
  39. data/share/terraform/aws/efs_host/variables.tf +5 -1
  40. data/test/scout/render/test_engine.rb +88 -0
  41. data/test/scout/render/test_resource.rb +29 -0
  42. data/test/scout/sinatra/base/test_headers.rb +125 -0
  43. data/test/scout/sinatra/base/test_parameters.rb +88 -0
  44. data/test/scout/sinatra/test_base.rb +27 -0
  45. data/test/scout/sinatra/test_entity.rb +44 -0
  46. data/test/scout/sinatra/test_render.rb +44 -0
  47. data/test/scout/sinatra/test_workflow.rb +157 -0
  48. data/test/test_helper.rb +26 -0
  49. metadata +103 -2
@@ -0,0 +1,275 @@
1
+ require_relative 'render/parameters'
2
+
3
+ module ScoutRenderHelpers
4
+ def fragment(link = nil, &block)
5
+ fragment_code, link = [link.to_s, nil] if link and not link.to_s[0] == '<'
6
+ text = fragment_code if fragment_code
7
+
8
+ if block_given?
9
+ if defined? @step and (_cache_type == :asynchronous or _cache_type == :async)
10
+
11
+ fragment_code ||= (rand * 100000).to_i.to_s
12
+ fragment_file = @step.file(fragment_code)
13
+ pid_file = fragment_file + '.pid'
14
+
15
+ pid = @step.child{
16
+ begin
17
+ class << @step
18
+ def status=(message)
19
+ nil
20
+ end
21
+ end
22
+ Log.low("Fragment started: #{ fragment_file } - #{Process.pid}")
23
+ res = block.call fragment_file
24
+ Log.low("Fragment writing: #{ fragment_file } - #{Process.pid}")
25
+ Open.write(fragment_file, res) unless res.nil?
26
+ Log.low("Fragment done: #{ fragment_file } - #{Process.pid}")
27
+ rescue Exception
28
+ Open.write(fragment_file + '.error', [$!.class.to_s, $!.message] * ": ")
29
+ Open.write(fragment_file + '.backtrace', $!.backtrace * "\n") if $!.backtrace
30
+ Log.error("Error in fragment: #{ fragment_file }")
31
+ Log.exception $!
32
+ Open.rm pid_file if Open.exists? pid_file
33
+ Kernel.exit! -1
34
+ ensure
35
+ Open.rm pid_file if Open.exists? pid_file
36
+ end
37
+ Kernel.exit! 0
38
+ }
39
+ Open.write(pid_file, pid.to_s)
40
+
41
+ url = fullpath
42
+ url = remove_GET_param(url, "_update")
43
+ url = remove_GET_param(url, "_")
44
+
45
+ fragment_url = add_GET_param(url, "_fragment", fragment_code)
46
+ if link.nil?
47
+ html_tag('a', "", :href => fragment_url, :class => 'fragment', "data-text" => text)
48
+ else
49
+ if FalseClass === link
50
+ return fragment_code
51
+ elsif TrueClass === link
52
+ return fragment_url
53
+ elsif link =~ / href=/
54
+ link = link.sub(/ href=('|")/," href='#{fragment_url}'")
55
+ else
56
+ link = link.sub(/<a /,"<a href='#{fragment_url}' ")
57
+ end
58
+
59
+ if text
60
+ link.sub(/<a /,"<a data-text='#{text}' ")
61
+ else
62
+ link
63
+ end
64
+ end
65
+ else
66
+ block.call
67
+ end
68
+ else
69
+ if link =~ / class=/
70
+ link = link.sub(/ class=('|")/,' class=\1fragment ')
71
+ else
72
+ link = link.sub(/<a /,'<a class="fragment" ')
73
+ end
74
+
75
+ if text
76
+ link.sub(/<a /,"<a data-text='#{text}' ")
77
+ else
78
+ link
79
+ end
80
+ end
81
+ end
82
+ end
83
+
84
+ module SinatraScoutFragment
85
+ def self.registered(app)
86
+ app.helpers do
87
+ # keep a small param consumer (safe)
88
+ def process_fragment(fragment_code)
89
+ fragment_file = @step.file(fragment_code)
90
+ if Open.exists?(fragment_file)
91
+ case _format.to_s
92
+ when "query-entity"
93
+ tsv, table_options = load_tsv(fragment_file, true)
94
+ begin
95
+ res = tsv[@entity].to_json
96
+ content_type "application/json"
97
+ rescue
98
+ res = nil.to_json
99
+ end
100
+ halt 200, res
101
+ when "query-entity-field"
102
+ tsv, table_options = load_tsv(fragment_file, true)
103
+ begin
104
+ res = tsv[@entity]
105
+ res = [res] if tsv.type == :single or tsv.type == :flat
106
+ rescue
107
+ res = nil.to_json
108
+ end
109
+
110
+ fields = tsv.fields
111
+ content_type "application/json"
112
+ hash = {}
113
+ fields.each_with_index do |f,i|
114
+ hash[f] = res.nil? ? nil : res[i]
115
+ end
116
+
117
+ halt 200, hash.to_json
118
+ when "table"
119
+ html_halt tsv2html(fragment_file)
120
+ when "json"
121
+ content_type "application/json"
122
+ halt 200, tsv_process(load_tsv(fragment_file).first).to_json
123
+ when "tsv"
124
+ content_type "text/tab-separated-values"
125
+ halt 200, tsv_process(load_tsv(fragment_file).first).to_s
126
+ when "values"
127
+ tsv = tsv_process(load_tsv(fragment_file).first)
128
+ list = tsv.values.flatten
129
+ content_type "application/json"
130
+ halt 200, list.compact.to_json
131
+ when "entities"
132
+ raw_tsv, tsv_options = load_tsv(fragment_file)
133
+ tsv = tsv_process(raw_tsv)
134
+
135
+ list = tsv.values.flatten
136
+ list = tsv.prepare_entity(list, tsv.fields.first, tsv.entity_options)
137
+ type = list.annotation_types.last
138
+ list_id = "List of #{type} in table #{ @fragment }"
139
+ list_id << " (#{ @filter })" if @filter
140
+ Entity::List.save_list(type.to_s, list_id, list, user)
141
+ url = Entity::REST.entity_list_url(list_id, type)
142
+ url = url + '?_layout=false' unless @layout
143
+ url = escape_url(url)
144
+ redirect to(url)
145
+ when "map"
146
+ raw_tsv, tsv_options = load_tsv(fragment_file)
147
+ raw_tsv.unnamed = true
148
+ tsv = tsv_process(raw_tsv)
149
+
150
+ field = tsv.key_field
151
+ column = tsv.fields.first
152
+
153
+ if tsv.entity_templates[field]
154
+ type = tsv.entity_templates[field].annotation_types.first
155
+ else
156
+ type = [Entity.formats[field]].compact.first || field
157
+ end
158
+
159
+ map_id = "Map #{type}-#{column} in #{ @fragment }"
160
+ map_id << " (#{ @filter.gsub(';','|') })" if @filter
161
+ Entity::Map.save_map(type.to_s, column, map_id, tsv, user)
162
+ url = Entity::REST.entity_map_url(map_id, type, column)
163
+ url = url + '?_layout=false' unless @layout
164
+ url = escape_url(url)
165
+ redirect to(url)
166
+ when "excel"
167
+ require 'rbbt/tsv/excel'
168
+ tsv, tsv_options = load_tsv(fragment_file)
169
+ tsv = tsv_process(tsv)
170
+ data = nil
171
+ excel_file = TmpFile.tmp_file
172
+ tsv.excel(excel_file, :sort_by => @excel_sort_by, :sort_by_cast => @excel_sort_by_cast, :name => true, :remove_links => true)
173
+ name = tsv_options[:table_id]
174
+ name ||= "rbbt-table"
175
+ name = name.sub(/\s/,'_')
176
+ name = name.sub('.tsv','')
177
+ send_file excel_file, :type => 'application/vnd.ms-excel', :filename => "#{name}.xls"
178
+ when "heatmap"
179
+ require 'rbbt/util/R'
180
+ tsv, tsv_options = load_tsv(fragment_file)
181
+ content_type "text/html"
182
+ data = nil
183
+ png_file = TmpFile.tmp_file + '.png'
184
+ width = tsv.fields.length * 10 + 500
185
+ height = tsv.size * 10 + 500
186
+ width = 10000 if width > 10000
187
+ height = 10000 if height > 10000
188
+ tsv.R <<-EOF
189
+ rbbt.pheatmap(file='#{png_file}', data, width=#{width}, height=#{height})
190
+ data = NULL
191
+ EOF
192
+ send_file png_file, :type => 'image/png', :filename => fragment_file + ".heatmap.png"
193
+ when 'binary'
194
+ send_file fragment_file, :type => 'application/octet-stream'
195
+ else
196
+ require 'mimemagic'
197
+ mime = nil
198
+ Open.open(fragment_file) do |io|
199
+ begin
200
+ mime = MimeMagic.by_path(fragment_file)
201
+ if mime.nil?
202
+ io.rewind
203
+ mime = MimeMagic.by_magic(io)
204
+ end
205
+ if mime.nil?
206
+ io.rewind if IO === io
207
+ mime = "text/tab-separated-values" if io.gets =~ /^#/ and io.gets.include? "\t"
208
+ end
209
+ rescue Exception
210
+ Log.exception $!
211
+ end
212
+ end
213
+
214
+ if mime.nil?
215
+ txt = Open.read(fragment_file)
216
+
217
+ if txt =~ /<([^> ]+)[^>]*>.*?<\/\1>/m
218
+ mime = "text/html"
219
+ else
220
+ begin
221
+ JSON.parse(txt)
222
+ mime = "application/json"
223
+ rescue
224
+ end
225
+ end
226
+ else
227
+ txt = nil
228
+ end
229
+
230
+ if mime
231
+ content_type mime
232
+ else
233
+ content_type "text/plain"
234
+ end
235
+
236
+ if mime && mime.to_s.include?("text/html")
237
+ html_halt txt || Open.read(fragment_file)
238
+ else
239
+ if File.exist?(fragment_file)
240
+ send_file fragment_file
241
+ else
242
+ halt 200, Open.read(fragment_file)
243
+ end
244
+ end
245
+ end
246
+ elsif Open.exists?(fragment_file + '.error')
247
+ klass, _sep, message = Open.read(fragment_file + '.error').partition(": ")
248
+ backtrace = Open.read(fragment_file + '.backtrace').split("\n")
249
+ exception = Kernel.const_get(klass).new message || "no message"
250
+ exception.set_backtrace backtrace
251
+ raise exception
252
+ #halt 500, html_tag(:span, File.read(fragment_file + '.error'), :class => "message") +
253
+ # html_tag(:ul, File.read(fragment_file + '.backtrace').split("\n").collect{|l| html_tag(:li, l)} * "\n", :class => "backtrace")
254
+ elsif Open.exists?(fragment_file + '.pid')
255
+ pid = Open.read(fragment_file + '.pid')
256
+ if Misc.pid_exists?(pid.to_i)
257
+ halt 202, "Fragment not completed"
258
+ else
259
+ halt 500, "Fragment aborted"
260
+ end
261
+ else
262
+ halt 500, "Fragment not completed and no pid file"
263
+ end
264
+ end
265
+ end
266
+ end
267
+ end
268
+
269
+ SinatraScoutParameters.register_common_parameter(:_fragment, :string)
270
+
271
+ SinatraScoutPostProcessing.register_post_processing do |step|
272
+ if _fragment
273
+ process_fragment(_fragment)
274
+ end
275
+ end
@@ -0,0 +1,68 @@
1
+
2
+ module SinatraScoutHTMX
3
+
4
+ def self.registered(app)
5
+ app.before do
6
+ headers "X-Frame-Options" => "DENY"
7
+ end
8
+
9
+ app.after do
10
+ triggers = []
11
+
12
+ status = case response.status
13
+ when 200
14
+ ['done', 'complete']
15
+ when 500
16
+ ['error', 'complete']
17
+ when 202
18
+ ['running']
19
+ else
20
+ []
21
+ end
22
+
23
+ if defined?(entity_type) && entity_type
24
+ entity = (splat*"/").gsub(/\s/,'_')
25
+ triggers << 'entity'
26
+ triggers << entity_type
27
+ triggers << entity
28
+ triggers << [entity_type, entity]*'_'
29
+ end
30
+
31
+ if defined?(entity_property) && entity_property
32
+ triggers << 'entity_property'
33
+ triggers << [entity_type, entity_property]*'_'
34
+ triggers << [entity, entity_property]*'_'
35
+ triggers << [entity_type, entity, entity_property]*'_'
36
+ triggers << entity_property
37
+ end
38
+
39
+ if defined?(entity_action) && entity_action
40
+ triggers << 'entity_action'
41
+ triggers << [entity_type, entity_action]*'_'
42
+ triggers << [entity, entity_action]*'_'
43
+ triggers << [entity_type, entity, entity_action]*'_'
44
+ triggers << entity_action
45
+ end
46
+
47
+ if defined?(task_name) && task_name
48
+ triggers << 'task'
49
+ triggers << task_name
50
+ triggers << [workflow, task_name]*"_"
51
+ end
52
+
53
+ if defined?(preferences_changed) && preferences_changed.any?
54
+ triggers << ['preference']
55
+ preferences_changed.each do |preference|
56
+ triggers << [preference]
57
+ triggers << ['preference_' + preference]
58
+ end
59
+ end
60
+
61
+ triggers += triggers.collect{|t| status.collect{|s| [t, s]*"_" }}.flatten
62
+
63
+ triggers << status
64
+
65
+ headers['HX-Trigger'] = triggers * ", "
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,14 @@
1
+ require 'scout/knowledge_base'
2
+
3
+ module SinatraScoutKnowledgeBase
4
+ def self.registered(app)
5
+ # helpers for REST-style responses & params
6
+ app.set :knowledge_base, KnowledgeBase.load(:default)
7
+
8
+ app.helpers do
9
+ def knowledge_base
10
+ settings.knowledge_base
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,11 @@
1
+ module SinatraScoutTool
2
+ def self.registered(app)
3
+ app.helpers do
4
+ def tool(name, params = {})
5
+ record_js "/js/tool/#{name}.js" if ScoutRender.exists?("public/js/tool/#{name}.js")
6
+ record_css "/css/tool/#{name}.css" if ScoutRender.exists?("public/css/#{name}.css")
7
+ render_partial("tool/#{name}", params)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,129 @@
1
+ require 'sinatra'
2
+ require_relative 'base'
3
+ require_relative 'knowledge_base'
4
+
5
+ module SinatraScoutWorkflow
6
+ def self.registered(app)
7
+ app.register SinatraScoutKnowledgeBase
8
+
9
+ app.set :registered_workflows, {}
10
+
11
+ # helpers for REST-style responses & params
12
+ app.helpers do
13
+ # prepare task inputs: read keys from provided task_info[:inputs]
14
+ def consume_task_parameters_for(workflow, task, params_hash)
15
+ task_info = workflow.task_info(task.to_sym)
16
+ inputs = {}
17
+ task_info[:inputs].each do |k|
18
+ v = params_hash[k.to_s]
19
+ inputs[k.to_sym] = v unless v.nil?
20
+ # accept file parts named "#{k}__param_file" (Rack file upload hash)
21
+ if params_hash["#{k}__param_file"]
22
+ inputs["#{k}__param_file"] = params_hash["#{k}__param_file"]
23
+ end
24
+ end
25
+ inputs
26
+ end
27
+
28
+ def workflow_render(workflow, template, params = {})
29
+ params[:workflow] = workflow
30
+ case template
31
+ when :tasks
32
+ render_template('tasks', params)
33
+ when Symbol, String
34
+ render_template("#{workflow}/#{template}", params.merge(task: template))
35
+ when Step
36
+ job = template
37
+ task_name = job.task_name
38
+ render_template("#{workflow}/#{task_name}", params.merge(task: task_name, job: job))
39
+ end
40
+ end
41
+
42
+ def workflow_template(workflow, task, type = :job)
43
+ workflow_name = Workflow === workflow ? workflow.name : workflow.to_s
44
+ file = File.join(workflow_name, task.to_s, type.to_s)
45
+ return file if ScoutRender.exists?(file)
46
+
47
+ workflow_name = Workflow === workflow ? workflow.name : workflow.to_s
48
+ file = File.join(workflow_name, task.to_s)
49
+ return file if ScoutRender.exists?(file)
50
+
51
+ file = File.join(workflow_name, type.to_s)
52
+ return file if ScoutRender.exists?(file)
53
+
54
+ file = File.join(type.to_s)
55
+ return file if ScoutRender.exists?(file)
56
+
57
+ raise TemplateNotFoundException, "Workflow template not fond for workflow #{workflow_name} task #{task} type #{type}"
58
+ end
59
+
60
+ def render_job(workflow, job, params = {})
61
+ task = job.task_name
62
+ template = workflow_template(workflow, task)
63
+ render_template(template, params.merge(job: job, task: task, workflow: workflow))
64
+ end
65
+
66
+ def job_url(job)
67
+ workflow = job.workflow
68
+ task = job.task_name
69
+ name = job.name
70
+ workflow_name = Workflow === workflow ? workflow.name : workflow.to_s
71
+
72
+ '/' + [workflow_name, task, name] * "/"
73
+ end
74
+
75
+ def workflow_name
76
+ return nil unless task_name
77
+ return fullpath.split("/")[1]
78
+ end
79
+
80
+ def workflow
81
+ return nil unless workflow_name
82
+ Kernel.const_get workflow_name
83
+ end
84
+
85
+ def job_name
86
+ splat * "/"
87
+ end
88
+
89
+ def job
90
+ return nil unless task_name
91
+ return nil unless job_name
92
+ job = workflow.load_job task_name, job_name
93
+ end
94
+ end
95
+
96
+ # expose method to register a workflow at runtime
97
+ app.define_singleton_method(:add_workflow) do |workflow, opts = {}|
98
+ name = workflow.to_s.split('::').last
99
+ settings.registered_workflows[name] = workflow
100
+ settings.knowledge_base = workflow.knowledge_base if workflow.knowledge_base
101
+ ScoutRender.prepend_path name, workflow.libdir
102
+
103
+ # GET /<workflow> - exports
104
+ app.get "/#{name}/:task_name/*" do
105
+ job = workflow.load_job task_name, job_name
106
+
107
+ case _format
108
+ when :info
109
+ serve_step_info job
110
+ when :json
111
+ serve_step_json job
112
+ when :raw
113
+ serve_step_raw job
114
+ else
115
+ serve_step job, _layout, params do
116
+ begin
117
+ render_job workflow, job, params
118
+ rescue TemplateNotFoundException
119
+ halt 200, "Job #{job.short_path} done"
120
+ end
121
+ end
122
+ end
123
+ end
124
+ end
125
+
126
+ app.register_common_parameter(:task_name, :symbol)
127
+ end
128
+ end
129
+
data/lib/scout-camp.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  require 'scout'
2
2
  require 'scout/path'
3
3
  require 'scout/resource'
4
- Path.add_path :scout_camp, File.join(Path.caller_lib_dir(__FILE__), "{TOPLEVEL}/{SUBPATH}")
4
+ Path.add_path :scout_camp_lib, File.join(Path.caller_lib_dir(__FILE__), "{TOPLEVEL}/{SUBPATH}")
5
5
  require 'scout/terraform_dsl'
6
6
  require 'scout/offsite'
7
7
  require 'scout/aws/s3'
data/scout-camp.gemspec CHANGED
@@ -2,11 +2,11 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Juwelier::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: scout-camp 0.1.13 ruby lib
5
+ # stub: scout-camp 0.1.14 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "scout-camp".freeze
9
- s.version = "0.1.13".freeze
9
+ s.version = "0.1.14".freeze
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib".freeze]
@@ -26,6 +26,7 @@ Gem::Specification.new do |s|
26
26
  "Rakefile",
27
27
  "VERSION",
28
28
  "bin/scout-camp",
29
+ "doc/terraform.md",
29
30
  "lib/scout-camp.rb",
30
31
  "lib/scout/aws/s3.rb",
31
32
  "lib/scout/offsite.rb",
@@ -34,10 +35,32 @@ Gem::Specification.new do |s|
34
35
  "lib/scout/offsite/ssh.rb",
35
36
  "lib/scout/offsite/step.rb",
36
37
  "lib/scout/offsite/sync.rb",
38
+ "lib/scout/render.rb",
39
+ "lib/scout/render/engine.rb",
40
+ "lib/scout/render/helpers.rb",
41
+ "lib/scout/render/resource.rb",
42
+ "lib/scout/sinatra/auth.rb",
43
+ "lib/scout/sinatra/base.rb",
44
+ "lib/scout/sinatra/base/assets.rb",
45
+ "lib/scout/sinatra/base/favicon.rb",
46
+ "lib/scout/sinatra/base/headers.rb",
47
+ "lib/scout/sinatra/base/helpers.rb",
48
+ "lib/scout/sinatra/base/parameters.rb",
49
+ "lib/scout/sinatra/base/post_processing.rb",
50
+ "lib/scout/sinatra/base/session.rb",
51
+ "lib/scout/sinatra/entity.rb",
52
+ "lib/scout/sinatra/finder.rb",
53
+ "lib/scout/sinatra/fragment.rb",
54
+ "lib/scout/sinatra/htmx.rb",
55
+ "lib/scout/sinatra/knowledge_base.rb",
56
+ "lib/scout/sinatra/tool.rb",
57
+ "lib/scout/sinatra/workflow.rb",
37
58
  "lib/scout/terraform_dsl.rb",
38
59
  "lib/scout/terraform_dsl/deployment.rb",
39
60
  "lib/scout/terraform_dsl/util.rb",
40
61
  "scout-camp.gemspec",
62
+ "scout_commands/find",
63
+ "scout_commands/glob",
41
64
  "scout_commands/offsite",
42
65
  "scout_commands/sync",
43
66
  "scout_commands/terraform/add/lambda",
@@ -111,16 +134,29 @@ Gem::Specification.new do |s|
111
134
  "test/scout/offsite/test_ssh.rb",
112
135
  "test/scout/offsite/test_step.rb",
113
136
  "test/scout/offsite/test_sync.rb",
137
+ "test/scout/render/test_engine.rb",
138
+ "test/scout/render/test_resource.rb",
139
+ "test/scout/sinatra/base/test_headers.rb",
140
+ "test/scout/sinatra/base/test_parameters.rb",
141
+ "test/scout/sinatra/test_base.rb",
142
+ "test/scout/sinatra/test_entity.rb",
143
+ "test/scout/sinatra/test_render.rb",
144
+ "test/scout/sinatra/test_workflow.rb",
114
145
  "test/scout/test_terraform_dsl.rb",
115
146
  "test/test_helper.rb"
116
147
  ]
117
148
  s.homepage = "http://github.com/mikisvaz/scout-camp".freeze
118
149
  s.licenses = ["MIT".freeze]
119
- s.rubygems_version = "3.6.7".freeze
150
+ s.rubygems_version = "3.7.0.dev".freeze
120
151
  s.summary = "Deploy you scouts".freeze
121
152
 
122
153
  s.specification_version = 4
123
154
 
124
155
  s.add_runtime_dependency(%q<scout-essentials>.freeze, [">= 0".freeze])
156
+ s.add_runtime_dependency(%q<aws-sdk-s3>.freeze, [">= 0".freeze])
157
+ s.add_runtime_dependency(%q<sinatra>.freeze, [">= 0".freeze])
158
+ s.add_runtime_dependency(%q<omniauth>.freeze, [">= 0".freeze])
159
+ s.add_runtime_dependency(%q<mimemagic>.freeze, [">= 0".freeze])
160
+ s.add_runtime_dependency(%q<omniauth-google-oauth2>.freeze, [">= 0".freeze])
125
161
  end
126
162
 
@@ -0,0 +1,83 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'scout-camp'
4
+
5
+ $0 = "scout #{$previous_commands.any? ? $previous_commands*" " + " " : "" }#{ File.basename(__FILE__) }" if $previous_commands
6
+
7
+ options = SOPT.setup <<EOF
8
+
9
+ Find files
10
+
11
+ $ #{$0} [<options>] (<resource> <path>|<path>)
12
+
13
+ -h--help Print this help
14
+ -r--requires* Files to require; 'all' for all in Scout.etc.requires
15
+ -lw--load_workflow* Files to require; 'all' for all in Scout.etc.requires
16
+ -w--where* Where to look for the path
17
+ EOF
18
+ if options[:help]
19
+ if defined? scout_usage
20
+ scout_usage
21
+ else
22
+ puts SOPT.doc
23
+ end
24
+ exit 0
25
+ end
26
+
27
+ resource, path = ARGV
28
+ path, resource = resource, nil if path.nil?
29
+
30
+ raise MissingParameterException.new(:path) if path.nil?
31
+
32
+ case options[:workflows]
33
+ when nil, false, "false", "none"
34
+ when "all"
35
+ Scout.etc.workflows.list.each do |workflow|
36
+ Workflow.require_workflow file
37
+ end if Scout.etc.workflows.exists?
38
+ else
39
+ options[:workflows].split(/[ ,;|]/).each do |workflow|
40
+ Workflow.require_workflow workflow
41
+ end
42
+ end
43
+
44
+ case options[:requires]
45
+ when nil, false, "false", "none"
46
+ when "all"
47
+ Scout.etc.requires.list.each do |file|
48
+ require file
49
+ end if Scout.etc.requires.exists?
50
+ else
51
+ options[:requires].split(/[ ,;|]/).each do |file|
52
+ require file
53
+ end
54
+ end
55
+
56
+ location = nil
57
+ where = options[:where]
58
+ all = options[:all]
59
+
60
+ begin
61
+ resource = Workflow.require_workflow resource
62
+ rescue
63
+ begin
64
+ resource = Kernel.const_get(resource)
65
+ rescue
66
+ raise "Resource not found: #{ resource }"
67
+ end
68
+ end if resource
69
+
70
+ path = (resource || Scout)[path.dup]
71
+
72
+ if where.nil? || where == 'all' || path.path_maps.include?(where.to_sym)
73
+ location = path.find(where)
74
+
75
+ if Array === location
76
+ puts location * "\n"
77
+ else
78
+ location = nil if ! Open.exists?(location)
79
+ puts location
80
+ end
81
+ else
82
+ puts SSHLine.command(where, $0, ARGV, options.merge("where" => :all, add_option_dashes: true))
83
+ end