cutting_edge 0.0.1 → 0.1
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 +7 -2
- data/Gemfile.lock +130 -0
- data/LICENSE +68 -81
- data/Procfile +1 -0
- data/README.md +272 -74
- data/Rakefile +0 -5
- data/bin/cutting_edge +60 -45
- data/config.rb +55 -0
- data/cutting_edge.gemspec +33 -4
- data/heroku.config.rb +20 -0
- data/lib/cutting_edge.rb +1 -1
- data/lib/cutting_edge/app.rb +95 -19
- data/lib/cutting_edge/langs.rb +7 -1
- data/lib/cutting_edge/langs/python.rb +5 -1
- data/lib/cutting_edge/langs/ruby.rb +5 -1
- data/lib/cutting_edge/langs/rust.rb +5 -1
- data/lib/cutting_edge/public/images/error.svg +24 -0
- data/lib/cutting_edge/public/images/languages/python.svg +1 -0
- data/lib/cutting_edge/public/images/languages/ruby.svg +1 -0
- data/lib/cutting_edge/public/images/languages/rust.svg +1 -0
- data/lib/cutting_edge/public/images/ok.svg +24 -0
- data/lib/cutting_edge/public/javascript/clipboard.min.js +7 -0
- data/lib/cutting_edge/public/javascript/cuttingedge.js +53 -0
- data/lib/cutting_edge/public/stylesheets/primer.css +22 -0
- data/lib/cutting_edge/repo.rb +124 -18
- data/lib/cutting_edge/templates/_footer.html.erb +3 -0
- data/lib/cutting_edge/templates/_header.html.erb +8 -0
- data/lib/cutting_edge/templates/_overview.html.erb +9 -0
- data/lib/cutting_edge/templates/badge.svg.erb +39 -0
- data/lib/cutting_edge/templates/index.html.erb +62 -0
- data/lib/cutting_edge/templates/info.html.erb +101 -0
- data/lib/cutting_edge/templates/mail.html.erb +163 -0
- data/lib/cutting_edge/workers/badge.rb +33 -11
- data/lib/cutting_edge/workers/dependency.rb +36 -16
- data/lib/cutting_edge/workers/helpers.rb +8 -0
- data/lib/cutting_edge/workers/mail.rb +38 -0
- data/projects.yml +25 -0
- data/spec/app_spec.rb +115 -0
- data/spec/badge_worker_spec.rb +77 -0
- data/spec/dependency_worker_spec.rb +132 -0
- data/spec/email_worker_spec.rb +43 -0
- data/spec/fixtures.rb +180 -0
- data/spec/fixtures/projects.yml +27 -0
- data/spec/langs/python_spec.rb +47 -5
- data/spec/langs/ruby_spec.rb +105 -0
- data/spec/langs/rust_spec.rb +31 -0
- data/spec/repo_spec.rb +52 -0
- data/spec/spec_helper.rb +9 -1
- metadata +43 -15
- data/lib/cutting_edge/badge.rb +0 -46
data/Rakefile
CHANGED
data/bin/cutting_edge
CHANGED
@@ -1,72 +1,87 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
require File.expand_path('../../lib/cutting_edge/app.rb', __FILE__)
|
4
3
|
require 'yaml'
|
5
4
|
require 'rufus-scheduler'
|
5
|
+
require 'optparse'
|
6
|
+
require 'semantic_logger'
|
6
7
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
gollum:
|
11
|
-
api_token: secret
|
12
|
-
gollum-lib:
|
13
|
-
api_token: secret
|
14
|
-
locations: [gemspec.rb]
|
15
|
-
dependency_types: [runtime, development]
|
16
|
-
singingwolfboy:
|
17
|
-
flask-dance:
|
18
|
-
language: python
|
19
|
-
rust-lang:
|
20
|
-
crates.io:
|
21
|
-
language: rust
|
22
|
-
api_token: secret
|
23
|
-
gitlab:
|
24
|
-
cthowl01:
|
25
|
-
team-chess-ruby:
|
26
|
-
api_token: secret
|
27
|
-
YAML
|
8
|
+
module CuttingEdge
|
9
|
+
REFRESH_SCHEDULE = '1h'
|
10
|
+
end
|
28
11
|
|
29
12
|
options = {
|
30
13
|
:port => 4567,
|
31
|
-
:bind => '0.0.0.0'
|
14
|
+
:bind => '0.0.0.0'
|
32
15
|
}
|
33
16
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
17
|
+
opts = OptionParser.new do |opts|
|
18
|
+
opts.banner = 'CuttingEdge is a dependency monitoring application.
|
19
|
+
|
20
|
+
Usage:
|
21
|
+
cutting_edge [options] [projects]
|
22
|
+
|
23
|
+
Arguments:
|
24
|
+
[projects] Path to the YAML file which defines the projects to be monitored. If not specified, projects.yml in the current working directory is used.
|
25
|
+
'
|
26
|
+
opts.separator ''
|
27
|
+
|
28
|
+
opts.on('-h', '--host [HOST]', 'Specify the hostname or IP address to listen on. Default: \'0.0.0.0\'.') do |host|
|
29
|
+
options[:bind] = host
|
30
|
+
end
|
31
|
+
|
32
|
+
opts.on('-p', '--port [PORT]', 'Specify the port to bind to. Default: \'4567\'.') do |port|
|
33
|
+
begin
|
34
|
+
# don't use 'port.to_i' here... it doesn't raise errors which might result in a nice confusion later on
|
35
|
+
options[:port] = Integer(port)
|
36
|
+
rescue ArgumentError
|
37
|
+
puts "Error: '#{port}' is not a valid port number."
|
38
|
+
exit 1
|
44
39
|
end
|
45
40
|
end
|
41
|
+
|
42
|
+
opts.on('-c', '--config [FILE]', 'Specify path to a .rb configuration file. Default: config.rb') do |file|
|
43
|
+
options[:config] = file || 'config.rb'
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
begin
|
48
|
+
opts.parse!
|
49
|
+
rescue OptionParser::InvalidOption => e
|
50
|
+
puts "cutting_edge: #{e.message}"
|
51
|
+
puts 'cutting_edge: try \'cutting_edge --help\' for more information'
|
52
|
+
exit
|
53
|
+
end
|
54
|
+
|
55
|
+
if cfg = options[:config]
|
56
|
+
# If the path begins with a '/' it will be considered an absolute path,
|
57
|
+
# otherwise it will be relative to the CWD
|
58
|
+
cfg = File.join(Dir.getwd, cfg) unless cfg.slice(0) == File::SEPARATOR
|
59
|
+
require cfg
|
46
60
|
end
|
47
61
|
|
62
|
+
# Only require the app after loading the optional config file, to give user the chance to define constants.
|
63
|
+
require File.expand_path('../../lib/cutting_edge/app.rb', __FILE__)
|
64
|
+
|
65
|
+
include CuttingEdgeHelpers
|
66
|
+
repositories = load_repositories(ARGV[0] || 'projects.yml')
|
67
|
+
repositories.merge!(CuttingEdge::REPOSITORIES) if defined?(CuttingEdge::REPOSITORIES)
|
68
|
+
|
69
|
+
CuttingEdge::STORE = Moneta.new(:Memory) unless defined?(CuttingEdge::STORE)
|
70
|
+
CuttingEdge::App.set(:store, CuttingEdge::STORE)
|
71
|
+
|
48
72
|
# Need to initialize the log like this once, because otherwise it only becomes available after the Sinatra app has received a request...
|
49
73
|
::SemanticLogger.add_appender(file_name: "#{CuttingEdge::App.environment}.log")
|
50
74
|
|
51
75
|
CuttingEdge::App.set(:repositories, repositories)
|
52
|
-
CuttingEdge::App.set(:store, store)
|
53
76
|
CuttingEdge::App.set(:enable_logging, true)
|
54
77
|
|
55
|
-
puts
|
78
|
+
puts 'Scheduling Jobs...'
|
56
79
|
scheduler = Rufus::Scheduler.new
|
57
|
-
scheduler.every(
|
80
|
+
scheduler.every(CuttingEdge::REFRESH_SCHEDULE) do
|
58
81
|
worker_fetch_all(repositories.values)
|
59
82
|
end
|
60
|
-
scheduler.every('1h5m') do
|
61
|
-
worker_all_badges(repositories.values)
|
62
|
-
end
|
63
83
|
|
64
|
-
puts
|
65
|
-
include CuttingEdgeHelpers
|
84
|
+
puts 'Running Workers a first time...'
|
66
85
|
worker_fetch_all(repositories.values)
|
67
86
|
|
68
|
-
sleep 5
|
69
|
-
worker_all_badges(repositories.values)
|
70
|
-
|
71
|
-
puts "Starting Sinatra..."
|
72
87
|
CuttingEdge::App.run!(options)
|
data/config.rb
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
# Example config.rb for CuttingEdge
|
2
|
+
# All the settings below are purely optional: they all have sane defaults.
|
3
|
+
|
4
|
+
# Configure mail server settings (outside the CuttingEdge module)
|
5
|
+
require 'mail'
|
6
|
+
Mail.defaults do
|
7
|
+
delivery_method :smtp, address: 'localhost', port: 25
|
8
|
+
end
|
9
|
+
|
10
|
+
module CuttingEdge
|
11
|
+
REFRESH_SCHEDULE = '1h' # How often to run workers to check for changes to dependency status. Examples of valid values: '10d', '10m', etc.
|
12
|
+
SERVER_HOST = 'mydependencymonitoring.com' # At what domain is this CuttingEdge instance running? Defaults to 'localhost'
|
13
|
+
SERVER_URL = "https://#{SERVER_HOST}:4567" # The URL used to refer to this CuttingEdge instance, for instance in e-mails. Defaults to 'http://#{SERVER_HOST}'
|
14
|
+
|
15
|
+
MAIL_TO = 'mydeps@mymail.com' # Default address to send email to. If set to false (=default!), don't send any e-mails except for repositories that have their 'email:' attribute set in projects.yml
|
16
|
+
MAIL_FROM = "cutting_edge@#{SERVER_HOST}" # From Address used for sending e-mails. Default: "cutting_edge@#{SERVER_HOST}"
|
17
|
+
MAIL_TEMPLATE = <<EOF
|
18
|
+
Define your own ERB template for e-mail updates from CuttingEdge here!
|
19
|
+
Of course, you can also File.read it from a separate template file.
|
20
|
+
See lib/cutting_edge/templates/mail.html.erb for the default template, and the available variables.
|
21
|
+
EOF
|
22
|
+
|
23
|
+
SECRET_TOKEN = 'mysecrettoken' # Global administrative secret
|
24
|
+
|
25
|
+
LAST_VERSION_TIMEOUT = 5 # Number of seconds after which to fail when trying to determine the latest version for a dependency.
|
26
|
+
|
27
|
+
BADGE_COLORS = {
|
28
|
+
ok: 'blue',
|
29
|
+
outdated_patch: '#dfb317',
|
30
|
+
outdated_minor: '#fe7d37',
|
31
|
+
outdated_major: '#e05d44',
|
32
|
+
unknown: '#9f9f9f'
|
33
|
+
} # Redefine the colors used in SVG badges
|
34
|
+
|
35
|
+
# The following will allow you to define projects on your own GitLab or Gitea server in projects.yml
|
36
|
+
# This will allow you to use the 'mygitlab' and 'mygitea' keys, respectively, in projects.yml
|
37
|
+
require './lib/cutting_edge/repo.rb'
|
38
|
+
define_gitlab_server('mygitlab', 'https://mygitlab.com')
|
39
|
+
define_gitea_server('mygitea', 'https://mygitea.com')
|
40
|
+
# Now you may use your own server instance in projects.yml like so:
|
41
|
+
# mygitlab:
|
42
|
+
# orgname:
|
43
|
+
# projectname:
|
44
|
+
# language: rust
|
45
|
+
# ruby_project:
|
46
|
+
# language ruby
|
47
|
+
|
48
|
+
# You may also define additional repositories programatically as follows.
|
49
|
+
# These will be added to the repositories defined in projects.yml.
|
50
|
+
# This may be useful, for instance, if you want to use environment variables to keep information secret.
|
51
|
+
# Note: you need to require './lib/cutting_edge/repo.rb' first
|
52
|
+
REPOSITORIES = {
|
53
|
+
"gitlab/#{ENV['PRIVATE_REPO1_ORG']}/#{ENV['PRIVATE_REPO1_NAME']}" => GitlabRepository.new(org: ENV['PRIVATE_REPO1_ORG'], name: ENV['PRIVATE_REPO1_NAME'], lang: 'python', auth_token: ENV['PRIVATE_REPO1_TOKEN'], hide: true)
|
54
|
+
}
|
55
|
+
end
|
data/cutting_edge.gemspec
CHANGED
@@ -5,8 +5,8 @@ Gem::Specification.new do |s|
|
|
5
5
|
s.required_ruby_version = '>= 2.4'
|
6
6
|
|
7
7
|
s.name = 'cutting_edge'
|
8
|
-
s.version = '0.
|
9
|
-
s.date = '2020-02
|
8
|
+
s.version = '0.1'
|
9
|
+
s.date = '2020-11-02'
|
10
10
|
s.license = 'GPL-3.0-only'
|
11
11
|
|
12
12
|
s.summary = 'Self-hosted dependency monitoring, including shiny badges.'
|
@@ -25,32 +25,61 @@ Gem::Specification.new do |s|
|
|
25
25
|
s.add_dependency 'sucker_punch', '~> 2.1'
|
26
26
|
s.add_dependency 'sinatra', '~> 2.0'
|
27
27
|
s.add_dependency 'moneta', '~> 1.2'
|
28
|
-
s.add_dependency 'victor', '~> 0.2.8'
|
29
28
|
s.add_dependency 'rufus-scheduler', '~> 3.6'
|
30
29
|
s.add_dependency 'sinatra-logger', '~> 0.3'
|
31
30
|
s.add_dependency 'toml-rb', '~> 2.0'
|
31
|
+
s.add_dependency 'mail', '~> 2.7'
|
32
|
+
|
32
33
|
# = MANIFEST =
|
33
34
|
s.files = %w[
|
34
35
|
Gemfile
|
36
|
+
Gemfile.lock
|
35
37
|
LICENSE
|
38
|
+
Procfile
|
36
39
|
README.md
|
37
40
|
Rakefile
|
38
41
|
bin/cutting_edge
|
42
|
+
config.rb
|
39
43
|
cutting_edge.gemspec
|
44
|
+
heroku.config.rb
|
40
45
|
lib/cutting_edge.rb
|
41
46
|
lib/cutting_edge/app.rb
|
42
|
-
lib/cutting_edge/badge.rb
|
43
47
|
lib/cutting_edge/langs.rb
|
44
48
|
lib/cutting_edge/langs/python.rb
|
45
49
|
lib/cutting_edge/langs/ruby.rb
|
46
50
|
lib/cutting_edge/langs/rust.rb
|
51
|
+
lib/cutting_edge/public/images/error.svg
|
52
|
+
lib/cutting_edge/public/images/languages/python.svg
|
53
|
+
lib/cutting_edge/public/images/languages/ruby.svg
|
54
|
+
lib/cutting_edge/public/images/languages/rust.svg
|
55
|
+
lib/cutting_edge/public/images/ok.svg
|
56
|
+
lib/cutting_edge/public/javascript/clipboard.min.js
|
57
|
+
lib/cutting_edge/public/javascript/cuttingedge.js
|
58
|
+
lib/cutting_edge/public/stylesheets/primer.css
|
47
59
|
lib/cutting_edge/repo.rb
|
60
|
+
lib/cutting_edge/templates/_footer.html.erb
|
61
|
+
lib/cutting_edge/templates/_header.html.erb
|
62
|
+
lib/cutting_edge/templates/_overview.html.erb
|
63
|
+
lib/cutting_edge/templates/badge.svg.erb
|
64
|
+
lib/cutting_edge/templates/index.html.erb
|
65
|
+
lib/cutting_edge/templates/info.html.erb
|
66
|
+
lib/cutting_edge/templates/mail.html.erb
|
48
67
|
lib/cutting_edge/versions.rb
|
49
68
|
lib/cutting_edge/workers/badge.rb
|
50
69
|
lib/cutting_edge/workers/dependency.rb
|
51
70
|
lib/cutting_edge/workers/helpers.rb
|
71
|
+
lib/cutting_edge/workers/mail.rb
|
72
|
+
projects.yml
|
73
|
+
spec/app_spec.rb
|
74
|
+
spec/badge_worker_spec.rb
|
75
|
+
spec/dependency_worker_spec.rb
|
76
|
+
spec/email_worker_spec.rb
|
77
|
+
spec/fixtures.rb
|
78
|
+
spec/fixtures/projects.yml
|
52
79
|
spec/langs/python_spec.rb
|
80
|
+
spec/langs/ruby_spec.rb
|
53
81
|
spec/langs/rust_spec.rb
|
82
|
+
spec/repo_spec.rb
|
54
83
|
spec/spec_helper.rb
|
55
84
|
]
|
56
85
|
# = MANIFEST =
|
data/heroku.config.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
# Default settings required for Heroku deployment
|
2
|
+
|
3
|
+
module CuttingEdge
|
4
|
+
SERVER_HOST = "#{ENV['HEROKU_APP_NAME']}.herokuapp.com" # At what domain is this CuttingEdge instance running?
|
5
|
+
SERVER_URL = "https://#{SERVER_HOST}"
|
6
|
+
MAIL_TO = ENV['CUTTING_EDGE_MAIL_TO'] if ENV['CUTTING_EDGE_MAIL_TO']
|
7
|
+
|
8
|
+
# Your additional configuration goes here.
|
9
|
+
# If you are going to host the repository containing this file publically (e.g. on GitHub), please read:
|
10
|
+
# https://github.com/repotag/cutting_edge/blob/master/README.md#Defining-repositories-in-configrb
|
11
|
+
end
|
12
|
+
|
13
|
+
# Needed to write to Heroku logs.
|
14
|
+
::SemanticLogger.add_appender(io: $stderr)
|
15
|
+
|
16
|
+
# Configure mail server settings
|
17
|
+
require 'mail'
|
18
|
+
Mail.defaults do
|
19
|
+
delivery_method :smtp, address: ENV['MAILGUN_SMTP_SERVER'], port: ENV['MAILGUN_SMTP_PORT'], user_name: ENV['MAILGUN_SMTP_LOGIN'], password: ENV['MAILGUN_SMTP_PASSWORD'], domain: CuttingEdge::SERVER_HOST
|
20
|
+
end
|
data/lib/cutting_edge.rb
CHANGED
data/lib/cutting_edge/app.rb
CHANGED
@@ -9,18 +9,10 @@ require File.expand_path('../../cutting_edge.rb', __FILE__)
|
|
9
9
|
require File.expand_path('../repo.rb', __FILE__)
|
10
10
|
require File.expand_path('../workers/dependency.rb', __FILE__)
|
11
11
|
require File.expand_path('../workers/badge.rb', __FILE__)
|
12
|
+
require File.expand_path('../workers/mail.rb', __FILE__)
|
12
13
|
|
13
14
|
module CuttingEdgeHelpers
|
14
|
-
|
15
|
-
repositories.each do |repo|
|
16
|
-
worker_generate_badge(repo)
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
def worker_generate_badge(repo)
|
21
|
-
BadgeWorker.perform_async(repo.identifier)
|
22
|
-
end
|
23
|
-
|
15
|
+
|
24
16
|
def worker_fetch_all(repositories)
|
25
17
|
repositories.each do |repo|
|
26
18
|
worker_fetch(repo)
|
@@ -28,38 +20,110 @@ module CuttingEdgeHelpers
|
|
28
20
|
end
|
29
21
|
|
30
22
|
def worker_fetch(repo)
|
31
|
-
DependencyWorker.perform_async(repo.identifier, repo.lang, repo.locations, repo.dependency_types)
|
23
|
+
DependencyWorker.perform_async(repo.identifier, repo.lang, repo.locations, repo.dependency_types, repo.contact_email, repo.auth_token)
|
24
|
+
end
|
25
|
+
|
26
|
+
def load_repositories(path)
|
27
|
+
repositories = {}
|
28
|
+
begin
|
29
|
+
YAML.load(File.read(path)).each do |source, orgs|
|
30
|
+
orgs.each do |org, value|
|
31
|
+
value.each do |name, settings|
|
32
|
+
cfg = settings.is_a?(Hash) ? settings : {}
|
33
|
+
repo = Object.const_get("CuttingEdge::#{source.capitalize}Repository").new(org: org, name: name, lang: cfg.fetch('language', nil), locations: cfg.fetch('locations', nil), branch: cfg.fetch('branch', nil), email: cfg.fetch('email', CuttingEdge::MAIL_TO), auth_token: cfg.fetch('auth_token', nil), hide: cfg.fetch('hide', false))
|
34
|
+
repo.dependency_types = cfg['dependency_types'].map {|dep| dep.to_sym} if cfg['dependency_types'].is_a?(Array)
|
35
|
+
repositories["#{source}/#{org}/#{name}"] = repo
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
rescue SyntaxError, Errno::ENOENT => e
|
40
|
+
puts "Error: #{path} does not contain a valid YAML project definition."
|
41
|
+
if ENV['RACK_ENV'] == 'test'
|
42
|
+
return nil
|
43
|
+
else
|
44
|
+
exit 1
|
45
|
+
end
|
46
|
+
end
|
47
|
+
repositories
|
32
48
|
end
|
33
49
|
end
|
34
50
|
|
35
|
-
|
36
51
|
module CuttingEdge
|
37
|
-
LAST_VERSION_TIMEOUT = 5
|
38
52
|
|
53
|
+
LAST_VERSION_TIMEOUT = 5
|
54
|
+
SERVER_HOST = 'localhost' unless defined?(SERVER_HOST)
|
55
|
+
SERVER_URL = "http://#{SERVER_HOST}" unless defined?(SERVER_URL)
|
56
|
+
MAIL_TO = false unless defined?(MAIL_TO) # Default address to send email to. If set to false, don't send any e-mails except for repositories that have their 'email' attribute set.
|
57
|
+
MAIL_FROM = "cutting_edge@#{SERVER_HOST}" unless defined?(MAIL_FROM)
|
58
|
+
|
39
59
|
class App < Sinatra::Base
|
40
60
|
include CuttingEdgeHelpers
|
41
61
|
|
62
|
+
set :views, ::File.join(::File.dirname(__FILE__), 'templates')
|
63
|
+
Tilt.register Tilt::ERBTemplate, 'html.erb'
|
64
|
+
set :public_folder, ::File.join(::File.dirname(__FILE__), 'public')
|
42
65
|
logger filename: "#{settings.environment}.log", level: :trace
|
43
66
|
|
44
67
|
before do
|
45
68
|
@store = settings.store
|
46
69
|
end
|
47
70
|
|
48
|
-
get
|
71
|
+
get '/' do
|
72
|
+
hidden_repos, public_repos = CuttingEdge::App.repositories.partition{|_, repo| repo.hidden?}.map(&:to_h)
|
73
|
+
@hidden_repos_exist = !hidden_repos.empty?
|
74
|
+
@repos = public_repos
|
75
|
+
erb :index
|
76
|
+
end
|
77
|
+
|
78
|
+
post '/hidden_repos' do
|
79
|
+
payload = JSON.parse(request.body.read)
|
80
|
+
if valid_token?(payload['token'])
|
81
|
+
@repos = CuttingEdge::App.repositories.select{|_, repo| repo.hidden?}
|
82
|
+
partial = Tilt::ERBTemplate.new(::File.join(CuttingEdge::App.views, '_overview.html.erb'))
|
83
|
+
{partial: partial.render(self)}.to_json
|
84
|
+
else
|
85
|
+
status 401
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
get %r{/(.+)/(.+)/(.+)/info/json} do |source, org, name|
|
49
91
|
repo_defined?(source, org, name)
|
92
|
+
validate_repo_token(params[:token]) if @repo.hidden?
|
50
93
|
content_type :json
|
51
|
-
@store[@repo.identifier]
|
94
|
+
data = @store[@repo.identifier]
|
95
|
+
if data
|
96
|
+
data.merge({:language => @repo.lang}).to_json
|
97
|
+
else
|
98
|
+
status 500
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
get %r{/(.+)/(.+)/(.+)/info} do |source, org, name|
|
103
|
+
repo_defined?(source, org, name)
|
104
|
+
validate_repo_token(params[:token]) if @repo.hidden?
|
105
|
+
@name = name
|
106
|
+
@svg = url("/#{source}/#{org}/#{name}/svg")
|
107
|
+
@svg = "#{@svg}?token=#{@repo.hidden_token}" if @repo.hidden?
|
108
|
+
@md = "[](#{url("/#{source}/#{org}/#{name}/info")})"
|
109
|
+
@colors = {ok: 'green', outdated_patch: 'yellow', outdated_minor: 'orange', outdated_major: 'red', unknown: 'gray'}
|
110
|
+
@specs = @store[@repo.identifier]
|
111
|
+
@project_url = @repo.url_for_project
|
112
|
+
@language = @repo.lang
|
113
|
+
erb :info
|
52
114
|
end
|
53
115
|
|
54
116
|
get %r{/(.+)/(.+)/(.+)/svg} do |source, org, name|
|
55
117
|
repo_defined?(source, org, name)
|
118
|
+
validate_repo_token(params[:token]) if @repo.hidden?
|
119
|
+
cache_control no_cache: true
|
56
120
|
content_type 'image/svg+xml'
|
57
121
|
@store["svg-#{@repo.identifier}"]
|
58
122
|
end
|
59
123
|
|
60
124
|
post %r{/(.+)/(.+)/(.+)/refresh} do |source, org, name|
|
61
125
|
repo_defined?(source, org, name)
|
62
|
-
if
|
126
|
+
if valid_token?(params[:token])
|
63
127
|
worker_fetch(@repo)
|
64
128
|
status 200
|
65
129
|
else
|
@@ -68,10 +132,22 @@ module CuttingEdge
|
|
68
132
|
end
|
69
133
|
|
70
134
|
private
|
71
|
-
|
135
|
+
|
136
|
+
def not_found
|
137
|
+
halt 404, '404 Not Found'
|
138
|
+
end
|
139
|
+
|
140
|
+
def valid_token?(token)
|
141
|
+
defined?(::CuttingEdge::SECRET_TOKEN) && token == ::CuttingEdge::SECRET_TOKEN
|
142
|
+
end
|
143
|
+
|
144
|
+
def validate_repo_token(token)
|
145
|
+
not_found unless token == @repo.hidden_token
|
146
|
+
end
|
147
|
+
|
72
148
|
def repo_defined?(source, org, name)
|
73
|
-
|
149
|
+
not_found unless @repo = settings.repositories["#{source}/#{org}/#{name}"]
|
74
150
|
end
|
75
|
-
|
151
|
+
|
76
152
|
end
|
77
153
|
end
|