passenger 5.2.2 → 5.2.3
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of passenger might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG +13 -0
- data/README.md +8 -1
- data/dev/configkit-schemas/index.json +3 -3
- data/src/agent/Core/AdminPanelConnector.h +3 -5
- data/src/agent/Core/ApplicationPool/Group/SpawningAndRestarting.cpp +1 -0
- data/src/agent/Core/ApplicationPool/Options.h +1 -0
- data/src/agent/Core/Config.h +1 -1
- data/src/agent/Core/Controller/Config.h +1 -1
- data/src/agent/Core/SpawningKit/Spawner.h +9 -2
- data/src/agent/Shared/Fundamentals/AbortHandler.cpp +11 -2
- data/src/agent/Watchdog/Config.h +1 -1
- data/src/cxx_supportlib/Constants.h +1 -1
- data/src/cxx_supportlib/LoggingKit/Context.h +3 -2
- data/src/cxx_supportlib/LoggingKit/Implementation.cpp +17 -4
- data/src/helper-scripts/wsgi-loader.py +5 -2
- data/src/ruby_supportlib/phusion_passenger.rb +4 -3
- data/src/ruby_supportlib/phusion_passenger/platform_info/crypto.rb +1 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 01036c04dda75ab9ff7ebcf52f55b8675d162add
|
4
|
+
data.tar.gz: b72cbc20345165976f230aa36372e526b5a1c0f3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c81cc451477301effa27488540bc7fd23613ee0e845ac1997b4893080fc5b73b6922a290878ca268c0cfb9ea76fb48334eca5a46f05cfb55e4369e22ac51d93c
|
7
|
+
data.tar.gz: 0e2177accbbd4ebd0b8fd81685bd37eba224b64fa2a45cda1a3d130b3c988fd9695c2c160ed744fb1aac31152d468ddf9a39ef227909b0114065d99e20141714
|
data/CHANGELOG
CHANGED
@@ -1,9 +1,22 @@
|
|
1
|
+
Release 5.2.3
|
2
|
+
-------------
|
3
|
+
|
4
|
+
* Fuse Panel support: fixes a few bugs with handling small log files and with apps that don't output any messages.
|
5
|
+
* Python app support: fixes a Python 3 compatibility issue w.r.t. writing data over the socket.
|
6
|
+
* macOS support: fixes a crash in the `passenger-config compile-nginx-engine` command which only occurs on macOS >= 10.13. This crash was caused by a missing `require` call in our code, and affects users who compile Passenger from source, e.g. users of the Passenger Enterprise Homebrew formula.
|
7
|
+
* Fixes a small memory corruption issue (dangling pointer) in the ApplicationPool subsystem.
|
8
|
+
* Improves support for the $TMPDIR environment variable by removing leftover hardcoded references to /tmp. Closes GH-2052.
|
9
|
+
* Updated PCRE version to 8.42 (was: 8.41) across the board.
|
10
|
+
|
11
|
+
|
1
12
|
Release 5.2.2
|
2
13
|
-------------
|
3
14
|
|
4
15
|
* Adds an option for dumping the web server config manifest to a given file: `PassengerDumpConfigManifest` (Apache) / `passenger_dump_config_manifest` (Nginx). This option is mostly useful for Passenger developers.
|
5
16
|
* [Nginx] Fixes support for configurations that have two `passenger_base_uri` options in a single virtual host, without corresponding `passenger_app_group_name` and `passenger_app_root` directives. Closes GH-2043.
|
6
17
|
* [Enterprise] Improved support for RAM-based pricing on Heroku (now using officially recommended memory limit reporting via CGROUP).
|
18
|
+
* (added in CHANGELOG after release) Four new options to connect to the new Fuse Panel: admin_panel_url, admin_panel_auth_type, admin_panel_username, admin_panel_password
|
19
|
+
* (added in CHANGELOG after release) Updated OpenSSL version used in precompiled binaries (used for e.g. gem installs) to 1.0.2o (was: 1.0.2m).
|
7
20
|
|
8
21
|
|
9
22
|
Release 5.2.1
|
data/README.md
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
[![Gem Version](https://badge.fury.io/rb/passenger.svg)](https://badge.fury.io/rb/passenger)
|
1
2
|
# <img src="images/passenger_logo.svg" alt="passenger logo" style="margin-bottom: -.2em; width: 1.4em"> Phusion Passenger
|
2
3
|
<h3>Supercharge your Ruby, Node.js and Python apps</h3>
|
3
4
|
|
@@ -5,12 +6,18 @@
|
|
5
6
|
|
6
7
|
<a href="https://fpdl.vimeocdn.com/vimeo-prod-skyfire-std-us/01/4984/8/224923750/789267447.mp4?token=1520274300-0xc6893cd7e4a119105d32dd731bf4a34928c2c1c8"><img src="https://github.com/phusion/passenger/blob/stable-5.2/images/justin.png" height="400"></a><br><em>Phusion Passenger - the smart app server</em>
|
7
8
|
|
8
|
-
What makes
|
9
|
+
<p>What makes Passenger so fast and reliable is its <strong>C++</strong> core, its <strong>zero-copy</strong> architecture, its <strong>watchdog</strong> system and its <strong>hybrid</strong> evented, multi-threaded and multi-process design.</p>
|
10
|
+
|
11
|
+
## Fuse Panel - GUI for Passenger
|
12
|
+
The <strong>smarter</strong> and <strong>simpler command center</strong> for your applications. <strong><a href="https://www.phusionpassenger.com/fuse-panel" target="_blank">Fuse Panel</a></strong> monitors your apps in near real-time, offers insights in your logs and enables analyzing and troubleshooting issues. New and exclusively available in the Fuse Panel is much-requested feature <strong>per-application log viewing and splitting</strong>.
|
13
|
+
|
14
|
+
Regardless of if you’re running Passenger open source or you’re one of our enterprise customers, the Fuse Panel is available for free while in beta. <a href="https://www.phusionpassenger.com/fuse-panel" target="_blank">Give it a try</a>.
|
9
15
|
|
10
16
|
<img src="https://github.com/phusion/passenger/blob/stable-5.2/images/spark.png" align="left" width="300">
|
11
17
|
|
12
18
|
### Learn more:
|
13
19
|
- [Website](https://www.phusionpassenger.com/)
|
20
|
+
- [Fuse Panel](https://www.phusionpassenger.com/fuse-panel)
|
14
21
|
- [Documentation & Support](https://www.phusionpassenger.com/support)
|
15
22
|
- [Twitter](https://twitter.com/phusion_nl)
|
16
23
|
- [Blog](http://blog.phusion.nl/)
|
@@ -289,7 +289,7 @@
|
|
289
289
|
"type" : "unsigned integer"
|
290
290
|
},
|
291
291
|
"server_software" : {
|
292
|
-
"default_value" : "Phusion_Passenger/5.2.
|
292
|
+
"default_value" : "Phusion_Passenger/5.2.3",
|
293
293
|
"has_default_value" : "static",
|
294
294
|
"type" : "string"
|
295
295
|
},
|
@@ -794,7 +794,7 @@
|
|
794
794
|
"type" : "string"
|
795
795
|
},
|
796
796
|
"server_software" : {
|
797
|
-
"default_value" : "Phusion_Passenger/5.2.
|
797
|
+
"default_value" : "Phusion_Passenger/5.2.3",
|
798
798
|
"has_default_value" : "static",
|
799
799
|
"type" : "string"
|
800
800
|
},
|
@@ -1519,7 +1519,7 @@
|
|
1519
1519
|
"type" : "string"
|
1520
1520
|
},
|
1521
1521
|
"server_software" : {
|
1522
|
-
"default_value" : "Phusion_Passenger/5.2.
|
1522
|
+
"default_value" : "Phusion_Passenger/5.2.3",
|
1523
1523
|
"has_default_value" : "static",
|
1524
1524
|
"type" : "string"
|
1525
1525
|
},
|
@@ -466,6 +466,7 @@ private:
|
|
466
466
|
dup2(pipe.second, STDOUT_FILENO);
|
467
467
|
pipe.first.close();
|
468
468
|
pipe.second.close();
|
469
|
+
closeAllFileDescriptors(2, true);
|
469
470
|
|
470
471
|
execvp(execArgs[0], (char * const *) &execArgs[0]);
|
471
472
|
|
@@ -486,12 +487,9 @@ private:
|
|
486
487
|
} else {
|
487
488
|
pipe.second.close();
|
488
489
|
string out = readAll(pipe.first);
|
490
|
+
LoggingKit::context->saveMonitoredFileLog(key, f.c_str(), f.size(),
|
491
|
+
out.data(), out.size());
|
489
492
|
pipe.first.close();
|
490
|
-
istringstream iss(out);
|
491
|
-
string line;
|
492
|
-
while (getline(iss, line)) {
|
493
|
-
LoggingKit::context->updateLog(key, f.c_str(), f.size(), line.c_str(), line.size());
|
494
|
-
}
|
495
493
|
syscalls::waitpid(pid, NULL, 0);
|
496
494
|
}
|
497
495
|
}
|
@@ -310,6 +310,7 @@ Group::restart(const Options &options, RestartMethod method) {
|
|
310
310
|
m_spawning = false;
|
311
311
|
m_restarting = true;
|
312
312
|
uuid = generateUuid(pool);
|
313
|
+
this->options.groupUuid = uuid;
|
313
314
|
detachAll(actions);
|
314
315
|
getPool()->interruptableThreads.create_thread(
|
315
316
|
boost::bind(&Group::finalizeRestart, this, shared_from_this(),
|
@@ -116,6 +116,7 @@ private:
|
|
116
116
|
result.push_back(&options.ustRouterUsername);
|
117
117
|
result.push_back(&options.ustRouterPassword);
|
118
118
|
result.push_back(&options.apiKey);
|
119
|
+
result.push_back(&options.groupUuid);
|
119
120
|
result.push_back(&options.hostName);
|
120
121
|
result.push_back(&options.uri);
|
121
122
|
result.push_back(&options.unionStationKey);
|
data/src/agent/Core/Config.h
CHANGED
@@ -153,7 +153,7 @@ using namespace std;
|
|
153
153
|
* security_update_checker_interval unsigned integer - default(86400)
|
154
154
|
* security_update_checker_proxy_url string - -
|
155
155
|
* security_update_checker_url string - default("https://securitycheck.phusionpassenger.com/v1/check.json")
|
156
|
-
* server_software string - default("Phusion_Passenger/5.2.
|
156
|
+
* server_software string - default("Phusion_Passenger/5.2.3")
|
157
157
|
* show_version_in_header boolean - default(true)
|
158
158
|
* single_app_mode_app_root string - default,read_only
|
159
159
|
* single_app_mode_app_type string - read_only
|
@@ -111,7 +111,7 @@ parseControllerBenchmarkMode(const StaticString &mode) {
|
|
111
111
|
* multi_app boolean - default(true),read_only
|
112
112
|
* request_freelist_limit unsigned integer - default(1024)
|
113
113
|
* response_buffer_high_watermark unsigned integer - default(134217728)
|
114
|
-
* server_software string - default("Phusion_Passenger/5.2.
|
114
|
+
* server_software string - default("Phusion_Passenger/5.2.3")
|
115
115
|
* show_version_in_header boolean - default(true)
|
116
116
|
* start_reading_after_accept boolean - default(true)
|
117
117
|
* stat_throttle_rate unsigned integer - default(10)
|
@@ -129,12 +129,19 @@ protected:
|
|
129
129
|
|
130
130
|
public:
|
131
131
|
DebugDir(uid_t uid, gid_t gid) {
|
132
|
-
char buf[PATH_MAX]
|
132
|
+
char buf[PATH_MAX];
|
133
|
+
char *pos = buf;
|
134
|
+
const char *end = buf + PATH_MAX;
|
135
|
+
|
136
|
+
pos = appendData(pos, end, getSystemTempDir());
|
137
|
+
pos = appendData(pos, end, "/passenger.spawn-debug.XXXXXXXXXX");
|
138
|
+
*pos = '\0';
|
139
|
+
|
133
140
|
const char *result = mkdtemp(buf);
|
134
141
|
if (result == NULL) {
|
135
142
|
int e = errno;
|
136
143
|
throw SystemException("Cannot create a temporary directory "
|
137
|
-
"in the format of '
|
144
|
+
"in the format of '" + StaticString(buf) + "'", e);
|
138
145
|
} else {
|
139
146
|
path = result;
|
140
147
|
boost::this_thread::disable_interruption di;
|
@@ -75,6 +75,7 @@ struct AbortHandlerContext {
|
|
75
75
|
const AbortHandlerConfig *config;
|
76
76
|
char *installSpec;
|
77
77
|
char *rubyLibDir;
|
78
|
+
char *tmpDir;
|
78
79
|
char *crashWatchCommand;
|
79
80
|
char *backtraceSanitizerCommand;
|
80
81
|
bool backtraceSanitizerPassProgramInfo;
|
@@ -642,7 +643,8 @@ createCrashLogFile(char *filename, size_t bufSize, time_t t) {
|
|
642
643
|
int fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600);
|
643
644
|
if (fd == -1) {
|
644
645
|
pos = filename;
|
645
|
-
pos = ASSU::appendData(pos, end,
|
646
|
+
pos = ASSU::appendData(pos, end, ctx->tmpDir);
|
647
|
+
pos = ASSU::appendData(pos, end, "/passenger-crash-log.");
|
646
648
|
pos = ASSU::appendInteger<time_t, 10>(pos, end, t);
|
647
649
|
*pos = '\0';
|
648
650
|
fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600);
|
@@ -977,6 +979,7 @@ abortHandlerConfigChanged() {
|
|
977
979
|
const AbortHandlerConfig *config = ctx->config;
|
978
980
|
char *oldInstallSpec = ctx->installSpec;
|
979
981
|
char *oldRubyLibDir = ctx->rubyLibDir;
|
982
|
+
char *oldTmpDir = ctx->tmpDir;
|
980
983
|
char *oldCrashWatchCommand = ctx->crashWatchCommand;
|
981
984
|
char *oldBacktraceSanitizerCommand = ctx->backtraceSanitizerCommand;
|
982
985
|
|
@@ -986,11 +989,14 @@ abortHandlerConfigChanged() {
|
|
986
989
|
|
987
990
|
ctx->installSpec = strdup(locator->getInstallSpec().c_str());
|
988
991
|
ctx->rubyLibDir = strdup(locator->getRubyLibDir().c_str());
|
992
|
+
ctx->tmpDir = strdup(getSystemTempDir());
|
989
993
|
|
990
994
|
path = locator->getHelperScriptsDir() + "/crash-watch.rb";
|
991
995
|
ctx->crashWatchCommand = strdup(path.c_str());
|
992
996
|
|
993
|
-
if (ctx->installSpec == NULL || ctx->rubyLibDir == NULL
|
997
|
+
if (ctx->installSpec == NULL || ctx->rubyLibDir == NULL
|
998
|
+
|| ctx->tmpDir == NULL || ctx->crashWatchCommand == NULL)
|
999
|
+
{
|
994
1000
|
fprintf(stderr, "Cannot allocate memory for abort handler!\n");
|
995
1001
|
fflush(stderr);
|
996
1002
|
abort();
|
@@ -1013,12 +1019,14 @@ abortHandlerConfigChanged() {
|
|
1013
1019
|
} else {
|
1014
1020
|
ctx->installSpec = NULL;
|
1015
1021
|
ctx->rubyLibDir = NULL;
|
1022
|
+
ctx->tmpDir = NULL;
|
1016
1023
|
ctx->crashWatchCommand = NULL;
|
1017
1024
|
useCxxFiltAsBacktraceSanitizer();
|
1018
1025
|
}
|
1019
1026
|
|
1020
1027
|
free(oldInstallSpec);
|
1021
1028
|
free(oldRubyLibDir);
|
1029
|
+
free(oldTmpDir);
|
1022
1030
|
free(oldCrashWatchCommand);
|
1023
1031
|
free(oldBacktraceSanitizerCommand);
|
1024
1032
|
}
|
@@ -1027,6 +1035,7 @@ void
|
|
1027
1035
|
shutdownAbortHandler() {
|
1028
1036
|
free(ctx->installSpec);
|
1029
1037
|
free(ctx->rubyLibDir);
|
1038
|
+
free(ctx->tmpDir);
|
1030
1039
|
free(ctx->crashWatchCommand);
|
1031
1040
|
free(ctx->backtraceSanitizerCommand);
|
1032
1041
|
free(ctx->alternativeStack);
|
data/src/agent/Watchdog/Config.h
CHANGED
@@ -145,7 +145,7 @@ using namespace std;
|
|
145
145
|
* security_update_checker_interval unsigned integer - default(86400)
|
146
146
|
* security_update_checker_proxy_url string - -
|
147
147
|
* security_update_checker_url string - default("https://securitycheck.phusionpassenger.com/v1/check.json")
|
148
|
-
* server_software string - default("Phusion_Passenger/5.2.
|
148
|
+
* server_software string - default("Phusion_Passenger/5.2.3")
|
149
149
|
* setsid boolean - default(false)
|
150
150
|
* show_version_in_header boolean - default(true)
|
151
151
|
* single_app_mode_app_root string - default,read_only
|
@@ -81,7 +81,7 @@
|
|
81
81
|
#define PASSENGER_API_VERSION_MAJOR 0
|
82
82
|
#define PASSENGER_API_VERSION_MINOR 3
|
83
83
|
#define PASSENGER_DEFAULT_USER "nobody"
|
84
|
-
#define PASSENGER_VERSION "5.2.
|
84
|
+
#define PASSENGER_VERSION "5.2.3"
|
85
85
|
#define POOL_HELPER_THREAD_STACK_SIZE 262144
|
86
86
|
#define PROCESS_SHUTDOWN_TIMEOUT 60
|
87
87
|
#define PROCESS_SHUTDOWN_TIMEOUT_DISPLAY "1 minute"
|
@@ -107,8 +107,9 @@ public:
|
|
107
107
|
|
108
108
|
// specifically for logging output from application processes
|
109
109
|
void saveNewLog(const HashedStaticString &groupName, const char *sourceStr, unsigned int sourceStrLen, const char *message, unsigned int messageLen);
|
110
|
-
|
111
|
-
|
110
|
+
void saveMonitoredFileLog(const HashedStaticString &groupName,
|
111
|
+
const char *sourceStr, unsigned int sourceStrLen,
|
112
|
+
const char *content, unsigned int contentLen);
|
112
113
|
// snapshot logStore to a JSON structure for external relay
|
113
114
|
Json::Value convertLog();
|
114
115
|
|
@@ -332,7 +332,13 @@ Context::saveNewLog(const HashedStaticString &groupName, const char *sourceStr,
|
|
332
332
|
}
|
333
333
|
|
334
334
|
void
|
335
|
-
Context::
|
335
|
+
Context::saveMonitoredFileLog(const HashedStaticString &groupName,
|
336
|
+
const char *sourceStr, unsigned int sourceStrLen,
|
337
|
+
const char *content, unsigned int contentLen)
|
338
|
+
{
|
339
|
+
vector<StaticString> lines;
|
340
|
+
split(StaticString(content, contentLen), '\n', lines);
|
341
|
+
|
336
342
|
boost::lock_guard<boost::mutex> l(syncher); //lock
|
337
343
|
|
338
344
|
LogStore::Cell *c = logStore.lookupCell(groupName);
|
@@ -344,11 +350,15 @@ Context::updateLog(const HashedStaticString &groupName, const char *sourceStr, u
|
|
344
350
|
AppGroupLog &rec = c->value;
|
345
351
|
|
346
352
|
HashedStaticString source(sourceStr, sourceStrLen);
|
347
|
-
|
353
|
+
SimpleLogMap::Cell *c2 = rec.watchFileLog.lookupCell(source);
|
354
|
+
if (c2 == NULL) {
|
348
355
|
SimpleLogBuffer logBuffer(LOG_MONITORING_MAX_LINES);
|
349
|
-
rec.watchFileLog.insert(source, logBuffer);
|
356
|
+
c2 = rec.watchFileLog.insert(source, logBuffer);
|
357
|
+
}
|
358
|
+
c2->value.clear();
|
359
|
+
foreach (StaticString line, lines) {
|
360
|
+
c2->value.push_back(string(line.data(), line.size()));
|
350
361
|
}
|
351
|
-
rec.watchFileLog.lookupCell(source)->value.push_back(string(message, messageLen));
|
352
362
|
//unlock
|
353
363
|
}
|
354
364
|
|
@@ -363,6 +373,9 @@ Context::convertLog(){
|
|
363
373
|
reply[appGroupIter.getKey()] = Json::objectValue;
|
364
374
|
|
365
375
|
Json::Value &processLog = reply[appGroupIter.getKey()]["Application process log (combined)"];
|
376
|
+
if (processLog.isNull()) {
|
377
|
+
processLog = Json::arrayValue;
|
378
|
+
}
|
366
379
|
foreach (TimestampedLog logLine, appGroupIter->value.pidLog) {
|
367
380
|
Json::Value logLineJson = Json::objectValue;
|
368
381
|
logLineJson["source_id"] = logLine.sourceId;
|
@@ -126,7 +126,10 @@ if sys.version_info[0] >= 3:
|
|
126
126
|
return b.decode('latin-1')
|
127
127
|
|
128
128
|
def str_to_bytes(s):
|
129
|
-
|
129
|
+
if isinstance(s, bytes):
|
130
|
+
return s
|
131
|
+
else:
|
132
|
+
return s.encode('latin-1')
|
130
133
|
else:
|
131
134
|
def reraise_exception(exc_info):
|
132
135
|
exec("raise exc_info[0], exc_info[1], exc_info[2]")
|
@@ -261,7 +264,7 @@ class RequestHandler:
|
|
261
264
|
output_stream.sendall(str_to_bytes('%s: %s\r\n' % header))
|
262
265
|
output_stream.sendall(b'\r\n')
|
263
266
|
if not is_head:
|
264
|
-
output_stream.sendall(data)
|
267
|
+
output_stream.sendall(str_to_bytes(data))
|
265
268
|
except IOError:
|
266
269
|
# Mark this exception as coming from the Phusion Passenger
|
267
270
|
# socket and not some other socket.
|
@@ -31,7 +31,7 @@ module PhusionPassenger
|
|
31
31
|
|
32
32
|
PACKAGE_NAME = 'passenger'
|
33
33
|
# Run 'rake src/cxx_supportlib/Constants.h configkit_schemas_inline_comments' after changing this number.
|
34
|
-
VERSION_STRING = '5.2.
|
34
|
+
VERSION_STRING = '5.2.3'
|
35
35
|
|
36
36
|
PREFERRED_NGINX_VERSION = '1.12.2'
|
37
37
|
NGINX_SHA256_CHECKSUM = '305f379da1d5fb5aefa79e45c829852ca6983c7cd2a79328f8e084a324cf0416'
|
@@ -41,8 +41,9 @@ module PhusionPassenger
|
|
41
41
|
PACKAGING_PREFERRED_NGINX_VERSION = '1.12.2'
|
42
42
|
PACKAGING_NGINX_SHA256_CHECKSUM = '305f379da1d5fb5aefa79e45c829852ca6983c7cd2a79328f8e084a324cf0416'
|
43
43
|
|
44
|
-
|
45
|
-
|
44
|
+
# sha256sum of the .tar.gz
|
45
|
+
PREFERRED_PCRE_VERSION = '8.42'
|
46
|
+
PCRE_SHA256_CHECKSUM = '69acbc2fbdefb955d42a4c606dfde800c2885711d2979e356c0636efde9ec3b5'
|
46
47
|
|
47
48
|
STANDALONE_INTERFACE_VERSION = 1
|
48
49
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: passenger
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.2.
|
4
|
+
version: 5.2.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Phusion - http://www.phusion.nl/
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-04-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|