11#include " compile_cache.h"
2+ #include < sys/stat.h> // S_ISDIR
23#include < string>
34#include " debug_utils-inl.h"
45#include " env-inl.h"
@@ -250,7 +251,8 @@ CompileCacheEntry* CompileCacheHandler::GetOrInsert(Local<String> code,
250251 // If the portable cache is enabled and it seems possible to compute the
251252 // relative position from an absolute path, we use the relative position
252253 // in the cache key.
253- if (portable_ == EnableOption::PORTABLE && IsAbsoluteFilePath (file_path)) {
254+ if (HasOption (portable_, EnableOption::PORTABLE ) &&
255+ IsAbsoluteFilePath (file_path)) {
254256 // Normalize the path to ensure it is consistent.
255257 std::string normalized_file_path = NormalizeFileURLOrPath (env, file_path);
256258 if (normalized_file_path.empty ()) {
@@ -325,6 +327,10 @@ void CompileCacheHandler::MaybeSaveImpl(CompileCacheEntry* entry,
325327 Debug (" keeping the in-memory entry\n " );
326328 return ;
327329 }
330+ if (read_only_) {
331+ Debug (" read-only, not serializing\n " );
332+ return ;
333+ }
328334 Debug (" %s the in-memory entry\n " ,
329335 entry->cache == nullptr ? " initializing" : " refreshing" );
330336
@@ -349,6 +355,9 @@ void CompileCacheHandler::MaybeSave(CompileCacheEntry* entry,
349355
350356void CompileCacheHandler::MaybeSave (CompileCacheEntry* entry,
351357 std::string_view transpiled) {
358+ if (read_only_) {
359+ return ;
360+ }
352361 CHECK (entry->type == CachedCodeType::kStrippedTypeScript );
353362 Debug (" [compile cache] saving transpilation cache for %s %s\n " ,
354363 entry->type_name (),
@@ -381,6 +390,10 @@ void CompileCacheHandler::MaybeSave(CompileCacheEntry* entry,
381390 */
382391void CompileCacheHandler::Persist () {
383392 DCHECK (!compile_cache_dir_.empty ());
393+ if (read_only_) {
394+ Debug (" [compile cache] read-only, skipping persistence\n " );
395+ return ;
396+ }
384397
385398 // TODO(joyeecheung): do this using a separate event loop to utilize the
386399 // libuv thread pool and do the file system operations concurrently.
@@ -546,7 +559,9 @@ CompileCacheEnableResult CompileCacheHandler::Enable(Environment* env,
546559 cache_tag,
547560 cache_dir_with_tag);
548561
549- if (!env->permission ()->is_granted (
562+ const bool read_only = HasOption (option, EnableOption::READ_ONLY );
563+ if (!read_only &&
564+ !env->permission ()->is_granted (
550565 env,
551566 permission::PermissionScope::kFileSystemWrite ,
552567 cache_dir_with_tag)) [[unlikely]] {
@@ -566,25 +581,45 @@ CompileCacheEnableResult CompileCacheHandler::Enable(Environment* env,
566581 return result;
567582 }
568583
569- fs::FSReqWrapSync req_wrap;
570- int err = fs::MKDirpSync (
571- nullptr , &(req_wrap.req ), cache_dir_with_tag, 0777 , nullptr );
572- if (is_debug_) {
573- Debug (" [compile cache] creating cache directory %s...%s\n " ,
584+ if (read_only) {
585+ // A read-only cache is used as found and never created: without the
586+ // directory there is nothing to read.
587+ uv_fs_t stat_req;
588+ int err =
589+ uv_fs_stat (nullptr , &stat_req, cache_dir_with_tag.c_str (), nullptr );
590+ bool is_dir = err == 0 && S_ISDIR (stat_req.statbuf .st_mode );
591+ uv_fs_req_cleanup (&stat_req);
592+ Debug (" [compile cache] read-only cache directory %s...%s\n " ,
574593 cache_dir_with_tag,
575- err < 0 ? uv_strerror (err) : " success" );
576- }
577- if (err != 0 && err != UV_EEXIST ) {
578- result.message =
579- " Cannot create cache directory: " + std::string (uv_strerror (err));
580- result.status = CompileCacheEnableStatus::FAILED ;
581- return result;
594+ is_dir ? " found" : " not found" );
595+ if (!is_dir) {
596+ result.message =
597+ " Cache directory does not exist (read-only): " + cache_dir_with_tag;
598+ result.status = CompileCacheEnableStatus::FAILED ;
599+ return result;
600+ }
601+ } else {
602+ fs::FSReqWrapSync req_wrap;
603+ int err = fs::MKDirpSync (
604+ nullptr , &(req_wrap.req ), cache_dir_with_tag, 0777 , nullptr );
605+ if (is_debug_) {
606+ Debug (" [compile cache] creating cache directory %s...%s\n " ,
607+ cache_dir_with_tag,
608+ err < 0 ? uv_strerror (err) : " success" );
609+ }
610+ if (err != 0 && err != UV_EEXIST ) {
611+ result.message =
612+ " Cannot create cache directory: " + std::string (uv_strerror (err));
613+ result.status = CompileCacheEnableStatus::FAILED ;
614+ return result;
615+ }
582616 }
583617
584618 result.cache_directory = absolute_cache_dir_base;
585619 compile_cache_dir_ = cache_dir_with_tag;
586620 portable_ = option;
587- if (option == EnableOption::PORTABLE ) {
621+ read_only_ = read_only;
622+ if (HasOption (option, EnableOption::PORTABLE )) {
588623 normalized_compile_cache_dir_ =
589624 NormalizeFileURLOrPath (env, compile_cache_dir_);
590625 }
0 commit comments