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
@@ -0,0 +1,62 @@
|
|
1
|
+
<!doctype html>
|
2
|
+
|
3
|
+
<html lang="en">
|
4
|
+
<head>
|
5
|
+
<meta charset="utf-8">
|
6
|
+
|
7
|
+
<title>Cutting Edge</title>
|
8
|
+
<meta name="description" content="Cutting Edge">
|
9
|
+
<meta name="author" content="Repotag">
|
10
|
+
|
11
|
+
<link rel="stylesheet" href="/stylesheets/primer.css">
|
12
|
+
|
13
|
+
</head>
|
14
|
+
|
15
|
+
<body>
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
<div class="container-lg">
|
20
|
+
|
21
|
+
<%= erb :_header %>
|
22
|
+
|
23
|
+
<br/>
|
24
|
+
<div class="pagehead">
|
25
|
+
<h1>Monitored Projects</h1>
|
26
|
+
</div>
|
27
|
+
<br/>
|
28
|
+
|
29
|
+
<%= erb :_overview %>
|
30
|
+
|
31
|
+
|
32
|
+
<br/>
|
33
|
+
<% if @hidden_repos_exist %>
|
34
|
+
<div id="hidden-repos">
|
35
|
+
<details class="details-reset mt-3">
|
36
|
+
<summary class="btn-link link-gray">List hidden repositories <span class="dropdown-caret"></summary>
|
37
|
+
<div class="p-3 mt-2">
|
38
|
+
<form id='token-form'>
|
39
|
+
<div class="form-group" id="token-form-group">
|
40
|
+
<div class="input-group">
|
41
|
+
<input class="form-control input-contrast" name="token" type="text" placeholder="Enter your CuttingEdge token here">
|
42
|
+
<span class="input-group-button">
|
43
|
+
<button class="btn" id="token-submit" type="submit" aria-label="Submit">
|
44
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="15" height="15"><path fill-rule="evenodd" d="M1.5 8a6.5 6.5 0 1113 0 6.5 6.5 0 01-13 0zM0 8a8 8 0 1116 0A8 8 0 010 8zm11.78-1.72a.75.75 0 00-1.06-1.06L6.75 9.19 5.28 7.72a.75.75 0 00-1.06 1.06l2 2a.75.75 0 001.06 0l4.5-4.5z"></path></svg>
|
45
|
+
</button>
|
46
|
+
</span>
|
47
|
+
</div>
|
48
|
+
<p class="note error" id="token-input-validation"></p>
|
49
|
+
</div>
|
50
|
+
</form>
|
51
|
+
</div>
|
52
|
+
</details>
|
53
|
+
</div>
|
54
|
+
<% end %>
|
55
|
+
|
56
|
+
<%= erb :_footer %>
|
57
|
+
</div>
|
58
|
+
|
59
|
+
<script src="/javascript/cuttingedge.js"></script>
|
60
|
+
<script async defer src="https://buttons.github.io/buttons.js"></script>
|
61
|
+
</body>
|
62
|
+
</html>
|
@@ -0,0 +1,101 @@
|
|
1
|
+
<!doctype html>
|
2
|
+
|
3
|
+
<html lang="en">
|
4
|
+
<head>
|
5
|
+
<meta charset="utf-8">
|
6
|
+
|
7
|
+
<title>Dependency Overview</title>
|
8
|
+
<meta name="description" content="Cutting Edge">
|
9
|
+
<meta name="author" content="Repotag">
|
10
|
+
|
11
|
+
<link rel="stylesheet" href="/stylesheets/primer.css">
|
12
|
+
|
13
|
+
</head>
|
14
|
+
|
15
|
+
<body>
|
16
|
+
|
17
|
+
|
18
|
+
<div class="container-lg">
|
19
|
+
|
20
|
+
<%= erb :_header %>
|
21
|
+
|
22
|
+
<br/>
|
23
|
+
|
24
|
+
<div class="pagehead">
|
25
|
+
<h1 class="text-gray"><a href="<%= @project_url %>" class="link-gray"><%= @name %></a> (<image height="24" src="<%= "/images/languages/#{@language}.svg" %>"></image> <%= @language %>)</h1>
|
26
|
+
</div>
|
27
|
+
|
28
|
+
<div class="TableObject">
|
29
|
+
<div class="TableObject-item TableObject-item--primary">
|
30
|
+
<svg height="20" width="200"><image xlink:href="<%= @svg %>" /></svg>
|
31
|
+
</div>
|
32
|
+
<div class="TableObject-item">
|
33
|
+
<div>
|
34
|
+
<details class="dropdown details-reset details-overlay d-inline-block" id="embed">
|
35
|
+
<summary class="btn btn-sm" aria-haspopup="true">
|
36
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -2 16 16" width="16" height="16"><path fill-rule="evenodd" d="M2 13h4v1H2v-1zm5-6H2v1h5V7zm2 3V8l-3 3 3 3v-2h5v-2H9zM4.5 9H2v1h2.5V9zM2 12h2.5v-1H2v1zm9 1h1v2c-.02.28-.11.52-.3.7-.19.18-.42.28-.7.3H1c-.55 0-1-.45-1-1V4c0-.55.45-1 1-1h3c0-1.11.89-2 2-2 1.11 0 2 .89 2 2h3c.55 0 1 .45 1 1v5h-1V6H1v9h10v-2zM2 5h8c0-.55-.45-1-1-1H8c-.55 0-1-.45-1-1s-.45-1-1-1-1 .45-1 1-.45 1-1 1H3c-.55 0-1 .45-1 1z"></path></svg>
|
37
|
+
|
38
|
+
<span>Embed</span>
|
39
|
+
<div class="dropdown-caret"></div>
|
40
|
+
</summary>
|
41
|
+
|
42
|
+
<ul class="dropdown-menu dropdown-menu-sw">
|
43
|
+
<li><a class="dropdown-item clipboard" href="#" data-clipboard-text="<%= @md %>" onclick="getElementById('embed').removeAttribute('open')">Markdown link</a></li>
|
44
|
+
<li><a class="dropdown-item clipboard" href="#" data-clipboard-text="<%= @svg %>" onclick="getElementById('embed').removeAttribute('open')">Image Link</a></li>
|
45
|
+
</ul>
|
46
|
+
</details>
|
47
|
+
</div>
|
48
|
+
</div>
|
49
|
+
</div>
|
50
|
+
|
51
|
+
<br/>
|
52
|
+
|
53
|
+
|
54
|
+
<% if @specs && @specs[:locations] %>
|
55
|
+
<% @specs[:locations].each do |filename, spec| %>
|
56
|
+
|
57
|
+
<h3><%= filename %></h3>
|
58
|
+
<br/>
|
59
|
+
<div class="Box flex-auto">
|
60
|
+
<div class="Box-header Box-header--gray d-flex">
|
61
|
+
<div class="flex-auto col-md-2" role="gridcell"><b>Name</b></div>
|
62
|
+
<div class="flex-auto col-md-2" role="gridcell"><b>Required</b></div>
|
63
|
+
<div class="flex-auto col-md-2" role="gridcell"><b>Latest</b></div>
|
64
|
+
<div class="flex-auto col-md-2" role="gridcell"><b>Status</b></div>
|
65
|
+
</div>
|
66
|
+
<% spec.each do |type, dependencies| %>
|
67
|
+
<% next if dependencies.empty? %>
|
68
|
+
<% dependencies.each do |dependency| %>
|
69
|
+
<div class="Box-row Box-row--hover-gray d-flex" role="row">
|
70
|
+
<div class="flex-auto col-md-2" role="gridcell"><a href="<%= dependency[:url] %>"><%= dependency[:name] %></a></div>
|
71
|
+
<div class="flex-auto col-md-2" role="gridcell"><%= dependency[:required] %></div>
|
72
|
+
<div class="flex-auto col-md-2" role="gridcell"><%= dependency[:latest] %></div>
|
73
|
+
<div class="flex-auto col-md-2" role="gridcell"><span class="Label Label--<%= @colors.fetch(type, 'gray') %>"><%= type.to_s.split('_').collect(&:capitalize).join(' ') %></span></div>
|
74
|
+
</div>
|
75
|
+
<% end %>
|
76
|
+
<% end %>
|
77
|
+
</div>
|
78
|
+
<br/>
|
79
|
+
<% end %>
|
80
|
+
<% else %>
|
81
|
+
<div class="Box border-dashed p-2 text text-gray text-center f-4">
|
82
|
+
Nothing to see here at the moment.
|
83
|
+
</div>
|
84
|
+
<% end %>
|
85
|
+
<%= erb :_footer %>
|
86
|
+
</div>
|
87
|
+
|
88
|
+
|
89
|
+
<script src="/javascript/clipboard.min.js"></script>
|
90
|
+
<script>
|
91
|
+
new ClipboardJS('.clipboard');
|
92
|
+
function closeDropdown() {
|
93
|
+
|
94
|
+
}
|
95
|
+
</script>
|
96
|
+
<script async defer src="https://buttons.github.io/buttons.js"></script>
|
97
|
+
|
98
|
+
|
99
|
+
</body>
|
100
|
+
</html>
|
101
|
+
|
@@ -0,0 +1,163 @@
|
|
1
|
+
<!doctype html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta name="viewport" content="width=device-width">
|
5
|
+
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
6
|
+
<title>CuttingEdge Dependency Title</title>
|
7
|
+
<style>
|
8
|
+
/* -------------------------------------
|
9
|
+
This template is thanks to: https://github.com/leemunroe/responsive-html-email-template (MIT License)
|
10
|
+
------------------------------------- */
|
11
|
+
|
12
|
+
/* -------------------------------------
|
13
|
+
INLINED WITH htmlemail.io/inline
|
14
|
+
------------------------------------- */
|
15
|
+
/* -------------------------------------
|
16
|
+
RESPONSIVE AND MOBILE FRIENDLY STYLES
|
17
|
+
------------------------------------- */
|
18
|
+
|
19
|
+
@media only screen and (max-width: 620px) {
|
20
|
+
table[class=body] h1 {
|
21
|
+
font-size: 28px !important;
|
22
|
+
margin-bottom: 10px !important;
|
23
|
+
}
|
24
|
+
table[class=body] p,
|
25
|
+
table[class=body] ul,
|
26
|
+
table[class=body] ol,
|
27
|
+
table[class=body] td,
|
28
|
+
table[class=body] span,
|
29
|
+
table[class=body] a {
|
30
|
+
font-size: 16px !important;
|
31
|
+
}
|
32
|
+
table[class=body] .wrapper,
|
33
|
+
table[class=body] .article {
|
34
|
+
padding: 10px !important;
|
35
|
+
}
|
36
|
+
table[class=body] .content {
|
37
|
+
padding: 0 !important;
|
38
|
+
}
|
39
|
+
table[class=body] .container {
|
40
|
+
padding: 0 !important;
|
41
|
+
width: 100% !important;
|
42
|
+
}
|
43
|
+
table[class=body] .main {
|
44
|
+
border-left-width: 0 !important;
|
45
|
+
border-radius: 0 !important;
|
46
|
+
border-right-width: 0 !important;
|
47
|
+
}
|
48
|
+
table[class=body] .btn table {
|
49
|
+
width: 100% !important;
|
50
|
+
}
|
51
|
+
table[class=body] .btn a {
|
52
|
+
width: 100% !important;
|
53
|
+
}
|
54
|
+
table[class=body] .img-responsive {
|
55
|
+
height: auto !important;
|
56
|
+
max-width: 100% !important;
|
57
|
+
width: auto !important;
|
58
|
+
}
|
59
|
+
}
|
60
|
+
|
61
|
+
/* -------------------------------------
|
62
|
+
PRESERVE THESE STYLES IN THE HEAD
|
63
|
+
------------------------------------- */
|
64
|
+
@media all {
|
65
|
+
.ExternalClass {
|
66
|
+
width: 100%;
|
67
|
+
}
|
68
|
+
.ExternalClass,
|
69
|
+
.ExternalClass p,
|
70
|
+
.ExternalClass span,
|
71
|
+
.ExternalClass font,
|
72
|
+
.ExternalClass td,
|
73
|
+
.ExternalClass div {
|
74
|
+
line-height: 100%;
|
75
|
+
}
|
76
|
+
.apple-link a {
|
77
|
+
color: inherit !important;
|
78
|
+
font-family: inherit !important;
|
79
|
+
font-size: inherit !important;
|
80
|
+
font-weight: inherit !important;
|
81
|
+
line-height: inherit !important;
|
82
|
+
text-decoration: none !important;
|
83
|
+
}
|
84
|
+
#MessageViewBody a {
|
85
|
+
color: inherit;
|
86
|
+
text-decoration: none;
|
87
|
+
font-size: inherit;
|
88
|
+
font-family: inherit;
|
89
|
+
font-weight: inherit;
|
90
|
+
line-height: inherit;
|
91
|
+
}
|
92
|
+
|
93
|
+
.btn-primary table td:hover {
|
94
|
+
background-color: #34495e !important;
|
95
|
+
}
|
96
|
+
.btn-primary a:hover {
|
97
|
+
background-color: #34495e !important;
|
98
|
+
border-color: #34495e !important;
|
99
|
+
}
|
100
|
+
}
|
101
|
+
</style>
|
102
|
+
</head>
|
103
|
+
<body class="" style="background-color: #f6f6f6; font-family: sans-serif; -webkit-font-smoothing: antialiased; font-size: 14px; line-height: 1.4; margin: 0; padding: 0; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%;">
|
104
|
+
<span class="preheader" style="color: transparent; display: none; height: 0; max-height: 0; max-width: 0; opacity: 0; overflow: hidden; mso-hide: all; visibility: hidden; width: 0;">This is preheader text. Some clients will show this text as a preview.</span>
|
105
|
+
<table border="0" cellpadding="0" cellspacing="0" class="body" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; background-color: #f6f6f6;">
|
106
|
+
<tr>
|
107
|
+
<td style="font-family: sans-serif; font-size: 14px; vertical-align: top;"> </td>
|
108
|
+
<td class="container" style="font-family: sans-serif; font-size: 14px; vertical-align: top; display: block; Margin: 0 auto; max-width: 580px; padding: 10px; width: 580px;">
|
109
|
+
<div class="content" style="box-sizing: border-box; display: block; Margin: 0 auto; max-width: 580px; padding: 10px;">
|
110
|
+
|
111
|
+
<!-- START CENTERED WHITE CONTAINER -->
|
112
|
+
<table class="main" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; background: #ffffff; border-radius: 3px;">
|
113
|
+
|
114
|
+
<!-- START MAIN CONTENT AREA -->
|
115
|
+
<tr>
|
116
|
+
<td class="wrapper" style="font-family: sans-serif; font-size: 14px; vertical-align: top; box-sizing: border-box; padding: 20px;">
|
117
|
+
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%;">
|
118
|
+
<tr>
|
119
|
+
<td style="font-family: sans-serif; font-size: 14px; vertical-align: top;">
|
120
|
+
<p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; Margin-bottom: 15px;">
|
121
|
+
Hi there,
|
122
|
+
</p>
|
123
|
+
<p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; Margin-bottom: 15px;">
|
124
|
+
This is <a href="<%= url %>">CuttingEdge</a> informing you that the dependency status for <a href="<%= "#{url}/#{project}/info" %>"><%= project %></a> has changed.
|
125
|
+
</p>
|
126
|
+
<% specs[:locations].each do |filename, spec| %>
|
127
|
+
<p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; Margin-bottom: 15px;">
|
128
|
+
In <b><%= filename %></b>:
|
129
|
+
<% spec.each do |type, dependencies|
|
130
|
+
next if dependencies.empty?
|
131
|
+
%>
|
132
|
+
<ul>
|
133
|
+
<b><%= type.to_s.split('_').collect(&:capitalize).join(' ') %></b>:
|
134
|
+
<ul>
|
135
|
+
<% dependencies.each do |dependency| %>
|
136
|
+
<li><%= dependency[:name] %> <%= dependency[:required] %> (latest: <%= dependency[:latest] %>)</li>
|
137
|
+
<% end %>
|
138
|
+
</ul>
|
139
|
+
</ul>
|
140
|
+
<% end %>
|
141
|
+
</p>
|
142
|
+
<% end %>
|
143
|
+
<p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; Margin-bottom: 15px;">
|
144
|
+
Have a nice day!
|
145
|
+
</p>
|
146
|
+
</td>
|
147
|
+
</tr>
|
148
|
+
</table>
|
149
|
+
</td>
|
150
|
+
</tr>
|
151
|
+
|
152
|
+
<!-- END MAIN CONTENT AREA -->
|
153
|
+
</table>
|
154
|
+
|
155
|
+
|
156
|
+
<!-- END CENTERED WHITE CONTAINER -->
|
157
|
+
</div>
|
158
|
+
</td>
|
159
|
+
<td style="font-family: sans-serif; font-size: 14px; vertical-align: top;"> </td>
|
160
|
+
</tr>
|
161
|
+
</table>
|
162
|
+
</body>
|
163
|
+
</html>
|
@@ -1,22 +1,44 @@
|
|
1
|
-
require File.expand_path('../../badge.rb', __FILE__)
|
2
1
|
require File.expand_path('../helpers.rb', __FILE__)
|
3
2
|
|
3
|
+
module CuttingEdge
|
4
|
+
BADGE_TEMPLATE = File.read(File.expand_path('../../templates/badge.svg.erb', __FILE__)) unless defined?(BADGE_TEMPLATE)
|
5
|
+
BADGE_OK = File.read(File.expand_path('../../public/images/ok.svg', __FILE__)) unless defined?(BADGE_OK)
|
6
|
+
BADGE_ERROR = File.read(File.expand_path('../../public/images/error.svg', __FILE__)) unless defined?(BADGE_ERROR)
|
7
|
+
BADGE_BASE_WIDTH = 25 unless defined?(BADGE_BASE_WIDTH)
|
8
|
+
BADGE_CELL_WIDTH = 25 unless defined?(BADGE_CELL_WIDTH)
|
9
|
+
BADGE_COLORS = {
|
10
|
+
ok: '#4c1',
|
11
|
+
outdated_patch: '#dfb317',
|
12
|
+
outdated_minor: '#fe7d37',
|
13
|
+
outdated_major: '#e05d44',
|
14
|
+
unknown: '#9f9f9f'
|
15
|
+
} unless defined?(BADGE_COLORS)
|
16
|
+
BADGE_LAYOUT = [:ok, :outdated_patch, :outdated_minor, :outdated_major, :unknown] unless defined?(BADGE_LAYOUT)
|
17
|
+
end
|
18
|
+
|
4
19
|
class BadgeWorker < GenericWorker
|
5
20
|
|
6
21
|
def perform(identifier)
|
7
22
|
log_info 'Running Worker!'
|
8
23
|
dependencies = get_from_store(identifier)
|
9
|
-
if dependencies
|
10
|
-
|
11
|
-
|
24
|
+
if dependencies && !dependencies.empty? && !(dependencies[:outdated] == :unknown)
|
25
|
+
result = if dependencies[:outdated] == :up_to_date
|
26
|
+
CuttingEdge::BADGE_OK
|
27
|
+
else
|
28
|
+
dependencies = ::CuttingEdge::BADGE_LAYOUT.map { |k| [k, dependencies[k]] }.to_h.
|
29
|
+
delete_if {|_, number| number == 0}
|
30
|
+
ERB.new(CuttingEdge::BADGE_TEMPLATE).result_with_hash(
|
31
|
+
base_width: CuttingEdge::BADGE_BASE_WIDTH,
|
32
|
+
cell_width: CuttingEdge::BADGE_CELL_WIDTH,
|
33
|
+
colors: CuttingEdge::BADGE_COLORS,
|
34
|
+
dependencies: dependencies
|
35
|
+
)
|
36
|
+
end
|
37
|
+
else
|
38
|
+
result = CuttingEdge::BADGE_ERROR
|
12
39
|
end
|
40
|
+
|
41
|
+
add_to_store("svg-#{identifier}", result)
|
13
42
|
GC.start
|
14
43
|
end
|
15
|
-
|
16
|
-
private
|
17
|
-
|
18
|
-
def generate_status(status)
|
19
|
-
# status is more specific than Badge.build_badge currently expects, so make it a bit less so
|
20
|
-
status == :up_to_date ? status : :out_of_date
|
21
|
-
end
|
22
44
|
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'http'
|
3
|
-
require 'moneta'
|
4
3
|
require File.expand_path('../../versions.rb', __FILE__)
|
5
4
|
require File.expand_path('../../langs.rb', __FILE__)
|
6
5
|
require File.expand_path('../helpers.rb', __FILE__)
|
@@ -10,18 +9,30 @@ class DependencyWorker < GenericWorker
|
|
10
9
|
|
11
10
|
# Order is significant for purposes of calculating results[:outdated]
|
12
11
|
STATUS_TYPES = [:outdated_major, :outdated_minor, :outdated_patch, :ok, :no_requirement, :unknown]
|
13
|
-
OUTDATED_TYPES = STATUS_TYPES[0..-
|
12
|
+
OUTDATED_TYPES = STATUS_TYPES[0..-4] # Which types indicate an outdated dependency. Used to calculate the total number of out-of-date dependencies.
|
14
13
|
|
15
|
-
def perform(identifier, lang, locations, dependency_types)
|
14
|
+
def perform(identifier, lang, locations, dependency_types, to_addr, auth_token = nil)
|
16
15
|
log_info 'Running Worker!'
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
16
|
+
@lang = get_lang(lang)
|
17
|
+
@provider = get_provider(identifier)
|
18
|
+
@auth_token = auth_token
|
19
|
+
old_dependencies = get_from_store(identifier)
|
20
|
+
begin
|
21
|
+
dependencies = {:locations => {}}
|
22
|
+
locations.each do |name, url|
|
23
|
+
contents = http_get(url)
|
24
|
+
dependencies[:locations][name] = get_results(@lang.parse_file(name, contents), dependency_types)
|
25
|
+
end
|
26
|
+
dependencies.merge!(generate_stats(dependencies[:locations]))
|
27
|
+
@nothing_changed = dependencies == old_dependencies
|
28
|
+
add_to_store(identifier, dependencies) unless @nothing_changed
|
29
|
+
ensure
|
30
|
+
unless @nothing_changed
|
31
|
+
badge_worker(identifier)
|
32
|
+
mail_worker(identifier, to_addr) if to_addr
|
33
|
+
end
|
34
|
+
GC.start
|
21
35
|
end
|
22
|
-
dependencies.merge!(generate_stats(dependencies))
|
23
|
-
add_to_store(identifier, dependencies)
|
24
|
-
GC.start
|
25
36
|
end
|
26
37
|
|
27
38
|
private
|
@@ -53,7 +64,7 @@ class DependencyWorker < GenericWorker
|
|
53
64
|
STATUS_TYPES.each do |type|
|
54
65
|
num = stats(type, locations)
|
55
66
|
results[type] = num
|
56
|
-
if
|
67
|
+
if outdated_type?(type)
|
57
68
|
results[:outdated_total] = results[:outdated_total].to_i + num
|
58
69
|
results[:outdated] = type unless results[:outdated] || num == 0
|
59
70
|
end
|
@@ -62,7 +73,8 @@ class DependencyWorker < GenericWorker
|
|
62
73
|
results[:outdated] = :up_to_date unless results[:outdated]
|
63
74
|
results
|
64
75
|
end
|
65
|
-
|
76
|
+
|
77
|
+
# Add up the number of dependencies of type `stat` (e.g. :ok) in the different locations where dependencies are stored.
|
66
78
|
def stats(stat, locations)
|
67
79
|
sum = 0
|
68
80
|
locations.each do |name, dependencies|
|
@@ -76,25 +88,33 @@ class DependencyWorker < GenericWorker
|
|
76
88
|
:name => name,
|
77
89
|
:required => requirement,
|
78
90
|
:latest => latest,
|
79
|
-
:type => type
|
91
|
+
:type => type,
|
92
|
+
:url => requirement == 'unknown' ? nil : @lang.website(name)
|
80
93
|
}
|
81
94
|
end
|
82
95
|
|
83
96
|
def get_lang(lang)
|
84
97
|
Object.const_get("#{lang.capitalize}Lang")
|
85
98
|
end
|
99
|
+
|
100
|
+
def get_provider(identifier)
|
101
|
+
::CuttingEdge.const_get("#{identifier.split('/').first.capitalize}Repository")
|
102
|
+
end
|
86
103
|
|
87
104
|
def http_get(url)
|
88
105
|
begin
|
89
|
-
response = HTTP.get(url)
|
106
|
+
response = HTTP.headers(@provider.headers(@auth_token)).get(url)
|
90
107
|
response.status == 200 ? response.to_s : nil
|
91
108
|
rescue HTTP::TimeoutError => e
|
92
|
-
log_info("Encountered error when fetching latest version of #{
|
109
|
+
log_info("Encountered error when fetching latest version of #{url}: #{e.class} #{e.message}")
|
93
110
|
end
|
94
111
|
end
|
95
112
|
|
96
113
|
def is_outdated?(dependency, latest_version)
|
97
114
|
!dependency.requirement.satisfied_by?(latest_version)
|
98
115
|
end
|
99
|
-
|
116
|
+
|
117
|
+
def outdated_type?(type)
|
118
|
+
OUTDATED_TYPES.include?(type)
|
119
|
+
end
|
100
120
|
end
|