@@ -343,34 +343,10 @@ void V8DealerFeature::validateOptions(std::shared_ptr<ProgramOptions> options) {
343
343
v8security.addToInternalAllowList (_startupDirectory, FSAccessType::READ);
344
344
345
345
ctx->normalizePath (_moduleDirectories, " javascript.module-directory" , false );
346
-
347
- // try to append the current version name to the startup directory,
348
- // so instead of "/path/to/js" we will get "/path/to/js/3.4.0"
349
- std::string const versionAppendix =
350
- std::regex_replace (rest::Version::getServerVersion (), std::regex (" -.*$" ),
351
- " " );
352
- std::string versionedPath =
353
- basics::FileUtils::buildFilename (_startupDirectory, versionAppendix);
354
-
355
- LOG_TOPIC (" 604da" , DEBUG, Logger::V8)
356
- << " checking for existence of version-specific startup-directory '"
357
- << versionedPath << " '" ;
358
- if (basics::FileUtils::isDirectory (versionedPath)) {
359
- // version-specific js path exists!
360
- _startupDirectory = versionedPath;
361
- }
362
-
363
- for (auto & it : _moduleDirectories) {
364
- versionedPath = basics::FileUtils::buildFilename (it, versionAppendix);
365
-
366
- LOG_TOPIC (" 8e21a" , DEBUG, Logger::V8)
367
- << " checking for existence of version-specific module-directory '"
368
- << versionedPath << " '" ;
369
- if (basics::FileUtils::isDirectory (versionedPath)) {
370
- // version-specific js path exists!
371
- it = versionedPath;
346
+ for (auto const & it : _moduleDirectories) {
347
+ if (!it.empty ()) {
348
+ v8security.addToInternalAllowList (it, FSAccessType::READ);
372
349
}
373
- v8security.addToInternalAllowList (it, FSAccessType::READ);
374
350
}
375
351
376
352
// check whether app-path was specified
@@ -409,26 +385,38 @@ void V8DealerFeature::start() {
409
385
// now check if we have a js directory inside the database directory, and if
410
386
// it looks good
411
387
auto & dbPathFeature = server ().getFeature <DatabasePathFeature>();
412
- const std::string dbJSPath =
388
+ std::string const dbJSPath =
413
389
FileUtils::buildFilename (dbPathFeature.directory (), " js" );
414
- const std::string checksumFile =
390
+ std::string const checksumFile =
415
391
FileUtils::buildFilename (dbJSPath, StaticStrings::checksumFileJs);
416
- const std::string serverPath = FileUtils::buildFilename (dbJSPath, " server" );
417
- const std::string commonPath = FileUtils::buildFilename (dbJSPath, " common" );
392
+ std::string const serverPath = FileUtils::buildFilename (dbJSPath, " server" );
393
+ std::string const commonPath = FileUtils::buildFilename (dbJSPath, " common" );
394
+ std::string const nodeModulesPath = FileUtils::buildFilename (dbJSPath, " node" , " node_modules" );
418
395
if (FileUtils::isDirectory (dbJSPath) && FileUtils::exists (checksumFile) &&
419
396
FileUtils::isDirectory (serverPath) && FileUtils::isDirectory (commonPath)) {
420
- // only load node modules from original startup path
421
- _nodeModulesDirectory = _startupDirectory;
422
397
// js directory inside database directory looks good. now use it!
423
398
_startupDirectory = dbJSPath;
399
+ // older versions didn't copy node_modules. so check if it exists inside the
400
+ // database directory or not.
401
+ if (FileUtils::isDirectory (nodeModulesPath)) {
402
+ _nodeModulesDirectory = nodeModulesPath;
403
+ } else {
404
+ _nodeModulesDirectory = _startupDirectory;
405
+ }
424
406
}
425
407
}
408
+
409
+ V8SecurityFeature& v8security = server ().getFeature <V8SecurityFeature>();
410
+ v8security.addToInternalAllowList (_startupDirectory, FSAccessType::READ);
411
+ if (!_nodeModulesDirectory.empty ()) {
412
+ v8security.addToInternalAllowList (_nodeModulesDirectory, FSAccessType::READ);
413
+ }
426
414
427
415
LOG_TOPIC (" 77c97" , DEBUG, Logger::V8)
428
416
<< " effective startup-directory: " << _startupDirectory
429
417
<< " , effective module-directories: " << _moduleDirectories
430
418
<< " , node-modules-directory: " << _nodeModulesDirectory;
431
-
419
+
432
420
_startupLoader.setDirectory (_startupDirectory);
433
421
434
422
// dump paths
@@ -557,9 +545,9 @@ void V8DealerFeature::copyInstallationFiles() {
557
545
558
546
_nodeModulesDirectory = _startupDirectory;
559
547
560
- const std::string checksumFile =
548
+ std::string const checksumFile =
561
549
FileUtils::buildFilename (_startupDirectory, StaticStrings::checksumFileJs);
562
- const std::string copyChecksumFile =
550
+ std::string const copyChecksumFile =
563
551
FileUtils::buildFilename (copyJSPath, StaticStrings::checksumFileJs);
564
552
565
553
bool overwriteCopy = false ;
@@ -569,7 +557,7 @@ void V8DealerFeature::copyInstallationFiles() {
569
557
} else {
570
558
try {
571
559
overwriteCopy =
572
- (FileUtils::slurp (copyChecksumFile) != FileUtils::slurp (checksumFile));
560
+ (StringUtils::trim ( FileUtils::slurp (copyChecksumFile)) != StringUtils::trim ( FileUtils::slurp (checksumFile) ));
573
561
} catch (basics::Exception const & e) {
574
562
LOG_TOPIC (" efa47" , ERR, Logger::V8) << " Error reading '" << StaticStrings::checksumFileJs
575
563
<< " ' from disk: " << e.what ();
@@ -578,7 +566,7 @@ void V8DealerFeature::copyInstallationFiles() {
578
566
}
579
567
580
568
if (overwriteCopy) {
581
- // basics security checks before removing an existing directory:
569
+ // basic security checks before removing an existing directory:
582
570
// check if for some reason we will be trying to remove the entire database
583
571
// directory...
584
572
if (FileUtils::exists (FileUtils::buildFilename (copyJSPath, " ENGINE" ))) {
@@ -587,7 +575,7 @@ void V8DealerFeature::copyInstallationFiles() {
587
575
FATAL_ERROR_EXIT ();
588
576
}
589
577
590
- LOG_TOPIC (" dd1c0" , DEBUG , Logger::V8)
578
+ LOG_TOPIC (" dd1c0" , INFO , Logger::V8)
591
579
<< " Copying JS installation files from '" << _startupDirectory
592
580
<< " ' to '" << copyJSPath << " '" ;
593
581
auto res = TRI_ERROR_NO_ERROR;
@@ -606,40 +594,46 @@ void V8DealerFeature::copyInstallationFiles() {
606
594
FATAL_ERROR_EXIT ();
607
595
}
608
596
609
- // intentionally do not copy js/node/node_modules...
597
+ // intentionally do not copy js/node/node_modules/estlint!
610
598
// we avoid copying this directory because it contains 5000+ files at the
611
- // moment, and copying them one by one is darn slow at least on Windows...
599
+ // moment, and copying them one by one is slow. In addition, eslint is not
600
+ // needed in release builds
612
601
std::string const versionAppendix =
613
602
std::regex_replace (rest::Version::getServerVersion (),
614
603
std::regex (" -.*$" ), " " );
615
- std::string const nodeModulesPath =
616
- FileUtils::buildFilename (" js" , " node" , " node_modules" );
617
- std::string const nodeModulesPathVersioned =
618
- basics::FileUtils::buildFilename ( " js " , versionAppendix, " node " ,
619
- " node_modules " ) ;
604
+ std::string const eslintPath =
605
+ FileUtils::buildFilename (" js" , " node" , " node_modules" , " eslint " );
606
+
607
+ // .bin directories could be harmful, and .map files are large and unnecessary
608
+ std::string const binDirectory = std::string (TRI_DIR_SEPARATOR_STR) + " .bin " + TRI_DIR_SEPARATOR_STR ;
620
609
621
- std::regex const binRegex ( " [/ \\\\ ] \\ .bin[/ \\\\ ] " , std::regex::ECMAScript) ;
610
+ size_t copied = 0 ;
622
611
623
- auto filter = [&nodeModulesPath, &nodeModulesPathVersioned, &binRegex](std::string const & filename) -> bool {
624
- if (std::regex_search (filename, binRegex)) {
612
+ auto filter = [&eslintPath, &binDirectory, &copied](std::string const & filename) -> bool {
613
+ if (filename.size () >= 4 && filename.compare (filename.size () - 4 , 4 , " .map" ) == 0 ) {
614
+ // filename ends with ".map". filter it out!
615
+ return true ;
616
+ }
617
+ if (filename.find (binDirectory) != std::string::npos) {
625
618
// don't copy files in .bin
626
619
return true ;
627
620
}
621
+
628
622
std::string normalized = filename;
629
623
FileUtils::normalizePath (normalized);
630
- if ((!nodeModulesPath.empty () &&
631
- normalized.size () >= nodeModulesPath.size () &&
632
- normalized.substr (normalized.size () - nodeModulesPath.size (), nodeModulesPath.size ()) == nodeModulesPath) ||
633
- (!nodeModulesPathVersioned.empty () &&
634
- normalized.size () >= nodeModulesPathVersioned.size () &&
635
- normalized.substr (normalized.size () - nodeModulesPathVersioned.size (), nodeModulesPathVersioned.size ()) == nodeModulesPathVersioned)) {
624
+ if ((normalized.size () >= eslintPath.size () &&
625
+ normalized.compare (normalized.size () - eslintPath.size (), eslintPath.size (), eslintPath) == 0 )) {
636
626
// filter it out!
637
627
return true ;
638
628
}
629
+
639
630
// let the file/directory pass through
631
+ ++copied;
640
632
return false ;
641
633
};
642
634
635
+ double start = TRI_microtime ();
636
+
643
637
std::string error;
644
638
if (!FileUtils::copyRecursive (_startupDirectory, copyJSPath, filter, error)) {
645
639
LOG_TOPIC (" 45261" , FATAL, Logger::V8) << " Error copying JS installation files to '"
@@ -662,8 +656,14 @@ void V8DealerFeature::copyInstallationFiles() {
662
656
<< copyJSPath << " ': " << error;
663
657
}
664
658
}
659
+
660
+ LOG_TOPIC (" 38e1e" , INFO, Logger::V8)
661
+ << " copying " << copied << " JS installation file(s) took " << Logger::FIXED (TRI_microtime () - start, 6 ) << " s" ;
665
662
}
663
+
664
+ // finally switch over the paths
666
665
_startupDirectory = copyJSPath;
666
+ _nodeModulesDirectory = basics::FileUtils::buildFilename (copyJSPath, " node" , " node_modules" );
667
667
}
668
668
669
669
V8Context* V8DealerFeature::addContext () {
0 commit comments