captive-stack-detector 0.4.0 → 0.5.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ece3c2210380284f962da264f7e16f96a649ddfdb55c110baf0f1065a6c0d5b9
4
- data.tar.gz: 29e1ffa94c58e29b44a2e868195e76593592204cb2449e1e46b19c6fc6069b03
3
+ metadata.gz: db3c27a80a53adecc0eaacc45336dad897fa31334c9f6da5b36422fc012e8a94
4
+ data.tar.gz: a7407996c89d2facb523558b4091d07474b8f1c45caa028e33f3e5ffa35a540c
5
5
  SHA512:
6
- metadata.gz: 976889c3c993bc6548ecdf0bf61074ca7113fa3457243d0c06e75bf74172d136a0b5f6f6d62377cb3a438f50ca9a0bcc14febc79f892c47ec1439a832fffef99
7
- data.tar.gz: 214e33cbfeff3724630a54868902d4e10cc9681ec3a8454c89eb15386ad359757a33ef2d505d8e749610e90854bd737406e02be4166ef2346e4d15370d9d0d4e
6
+ metadata.gz: bf3a1c1030044bbf76c1e905a07a33edf81ec4b540aec91d443da4012242ccde8d79769acc5d69b843401ddc52556c387a6afd8087de95f22361d440971df994
7
+ data.tar.gz: 33e5ea4a5de2c91e463cb2afcb7885e1518450f698f7caf315f2c38b97b74752e134e3211e9e7ce45e35001763fd464ea878c0dd173ddf7f24cc9833392150e6
@@ -28,12 +28,17 @@ module CaptiveStackDetector
28
28
  full = File.join(@path, filename)
29
29
  File.read(full, encoding: "utf-8") if File.exist?(full)
30
30
  end
31
+
32
+ def list(dir)
33
+ Dir.glob("#{dir}/**/*", base: @path).select { |entry| File.file?(File.join(@path, entry)) }.sort
34
+ end
31
35
  end
32
36
 
33
37
  class GithubFileReader
34
38
  extend Forwardable
35
39
 
36
40
  def_delegators :@parser, :ruby_version, :node_version, :env_vars
41
+ def_delegators :@client, :list
37
42
 
38
43
  def initialize(token, repo)
39
44
  @client = GithubApiClient.new(token, repo)
@@ -17,6 +17,7 @@ module CaptiveStackDetector
17
17
  def subtype = ASSET_GEMS.any? { |g| gem?(g) } ? "app" : "api"
18
18
  def database = gem?("pg") ? "postgres" : nil
19
19
  def queue = REDIS_GEMS.any? { |g| gem?(g) } ? "redis" : nil
20
+ def solid_queue? = gem?("solid_queue")
20
21
 
21
22
  def worker_command(procfile)
22
23
  if procfile
@@ -4,6 +4,7 @@ require "net/http"
4
4
  require "uri"
5
5
  require "base64"
6
6
  require "json"
7
+ require_relative "github_tree"
7
8
 
8
9
  module CaptiveStackDetector
9
10
  class GithubApiClient
@@ -13,17 +14,30 @@ module CaptiveStackDetector
13
14
  end
14
15
 
15
16
  def fetch(filename)
16
- uri = URI("https://api.github.com/repos/#{@repo}/contents/#{filename}")
17
- req = Net::HTTP::Get.new(uri)
18
- req["Authorization"] = "Bearer #{@token}"
19
- req["Accept"] = "application/vnd.github+json"
17
+ body = get("contents/#{filename}")
18
+ return nil unless body
20
19
 
21
- res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |h| h.request(req) }
22
- return nil unless res.is_a?(Net::HTTPSuccess)
23
-
24
- Base64.decode64(JSON.parse(res.body)["content"]).force_encoding("utf-8")
20
+ Base64.decode64(JSON.parse(body)["content"]).force_encoding("utf-8")
25
21
  rescue StandardError
26
22
  nil
27
23
  end
24
+
25
+ def list(dir)
26
+ body = get("git/trees/HEAD?recursive=1")
27
+ return [] unless body
28
+
29
+ GithubTree.new(body).files_in(dir)
30
+ rescue StandardError
31
+ []
32
+ end
33
+
34
+ private
35
+
36
+ def get(path)
37
+ uri = URI("https://api.github.com/repos/#{@repo}/#{path}")
38
+ req = Net::HTTP::Get.new(uri, "Authorization" => "Bearer #{@token}", "Accept" => "application/vnd.github+json")
39
+ res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }
40
+ res.body if res.is_a?(Net::HTTPSuccess)
41
+ end
28
42
  end
29
43
  end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+
5
+ module CaptiveStackDetector
6
+ class GithubTree
7
+ def initialize(body)
8
+ @entries = JSON.parse(body)["tree"]
9
+ end
10
+
11
+ def files_in(dir)
12
+ prefix = "#{dir}/"
13
+ @entries.filter_map { |entry| entry["path"] if entry["type"] == "blob" && entry["path"].start_with?(prefix) }
14
+ end
15
+ end
16
+ end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require_relative "../captive_stack_detector"
4
4
  require_relative "system_package_detector"
5
+ require_relative "solid_queue_worker"
5
6
 
6
7
  module CaptiveStackDetector
7
8
  class RailsStackDetector
@@ -27,7 +28,7 @@ module CaptiveStackDetector
27
28
  private
28
29
 
29
30
  def build_worker
30
- command = @analyzer.worker_command(@reader.read("Procfile"))
31
+ command = @analyzer.worker_command(@reader.read("Procfile")) || SolidQueueWorker.new(@reader, @analyzer).command
31
32
  command ? Worker.new(command: command) : nil
32
33
  end
33
34
 
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "yaml"
4
+
5
+ module CaptiveStackDetector
6
+ class RecurringSchedule
7
+ def initialize(yml)
8
+ @yml = yml
9
+ end
10
+
11
+ def task_names
12
+ environments.values.grep(Hash).flat_map(&:keys)
13
+ end
14
+
15
+ private
16
+
17
+ def environments
18
+ parsed = YAML.safe_load(@yml.to_s)
19
+ parsed.is_a?(Hash) ? parsed : {}
20
+ rescue Psych::Exception
21
+ {}
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CaptiveStackDetector
4
+ class SolidQueueUsage
5
+ DEFAULT_RECURRING_TASK = "clear_solid_queue_finished_jobs"
6
+ DEFAULT_JOB_FILE = "application_job.rb"
7
+
8
+ def initialize(recurring_task_names:, job_files:)
9
+ @recurring_task_names = recurring_task_names
10
+ @job_files = job_files
11
+ end
12
+
13
+ def used? = recurring_task? || application_job?
14
+
15
+ private
16
+
17
+ def recurring_task? = @recurring_task_names.any? { |task| task != DEFAULT_RECURRING_TASK }
18
+
19
+ def application_job?
20
+ @job_files.any? { |file| file.end_with?(".rb") && File.basename(file) != DEFAULT_JOB_FILE }
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "solid_queue_usage"
4
+ require_relative "recurring_schedule"
5
+
6
+ module CaptiveStackDetector
7
+ class SolidQueueWorker
8
+ COMMAND = "bin/jobs"
9
+
10
+ def initialize(reader, analyzer)
11
+ @reader = reader
12
+ @analyzer = analyzer
13
+ end
14
+
15
+ def command
16
+ COMMAND if @analyzer.solid_queue? && usage.used?
17
+ end
18
+
19
+ private
20
+
21
+ def usage
22
+ SolidQueueUsage.new(
23
+ recurring_task_names: RecurringSchedule.new(@reader.read("config/recurring.yml")).task_names,
24
+ job_files: @reader.list("app/jobs"),
25
+ )
26
+ end
27
+ end
28
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CaptiveStackDetector
4
- VERSION = "0.4.0"
4
+ VERSION = "0.5.0"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: captive-stack-detector
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Captive Studio
@@ -26,11 +26,15 @@ files:
26
26
  - lib/captive_stack_detector/gem_package_map.rb
27
27
  - lib/captive_stack_detector/gemfile_analyzer.rb
28
28
  - lib/captive_stack_detector/github_api_client.rb
29
+ - lib/captive_stack_detector/github_tree.rb
29
30
  - lib/captive_stack_detector/js_stack_detector.rb
30
31
  - lib/captive_stack_detector/node_version_detector.rb
31
32
  - lib/captive_stack_detector/package_json_analyzer.rb
32
33
  - lib/captive_stack_detector/rails_stack_detector.rb
34
+ - lib/captive_stack_detector/recurring_schedule.rb
33
35
  - lib/captive_stack_detector/ruby_version_detector.rb
36
+ - lib/captive_stack_detector/solid_queue_usage.rb
37
+ - lib/captive_stack_detector/solid_queue_worker.rb
34
38
  - lib/captive_stack_detector/ssr_framework_detector.rb
35
39
  - lib/captive_stack_detector/system_package_detector.rb
36
40
  - lib/captive_stack_detector/types.rb