@@ -602,7 +602,28 @@ normalize_prefetch_spaces <- function(spaces) {
602602 sort(unique(spaces ))
603603}
604604
605- get_prefetch_state_file <- function (templateflow_home ) {
605+ prefetch_state_cache_hash <- function (templateflow_home ) {
606+ normalized <- normalizePath(templateflow_home , winslash = " /" , mustWork = FALSE )
607+ tmp <- tempfile(" prefetch_state_hash_" )
608+ on.exit(unlink(tmp ), add = TRUE )
609+ writeLines(normalized , tmp , useBytes = TRUE )
610+ unname(tools :: md5sum(tmp ))
611+ }
612+
613+ get_prefetch_state_file <- function (log_directory , templateflow_home ) {
614+ if (! checkmate :: test_string(log_directory ) || ! nzchar(log_directory )) {
615+ stop(" log_directory must be a non-empty string when resolving prefetch state file." , call. = FALSE )
616+ }
617+ if (! checkmate :: test_string(templateflow_home ) || ! nzchar(templateflow_home )) {
618+ stop(" templateflow_home must be a non-empty string when resolving prefetch state file." , call. = FALSE )
619+ }
620+
621+ log_directory <- normalizePath(log_directory , winslash = " /" , mustWork = FALSE )
622+ cache_hash <- prefetch_state_cache_hash(templateflow_home )
623+ file.path(log_directory , sprintf(" .braingnomes_prefetch_state_%s.dcf" , cache_hash ))
624+ }
625+
626+ get_legacy_prefetch_state_file <- function (templateflow_home ) {
606627 file.path(templateflow_home , " .braingnomes_prefetch_state.dcf" )
607628}
608629
@@ -639,6 +660,87 @@ read_prefetch_state <- function(state_file) {
639660 state
640661}
641662
663+ prefetch_templateflow_cache_initialized <- function (templateflow_home ) {
664+ if (! checkmate :: test_directory_exists(templateflow_home )) return (FALSE )
665+ entries <- list.files(templateflow_home , all.files = FALSE , no.. = TRUE , full.names = FALSE )
666+ any(grepl(" ^tpl-" , entries ))
667+ }
668+
669+ copy_prefetch_state_file <- function (from , to ) {
670+ if (! checkmate :: test_file_exists(from )) {
671+ stop(glue :: glue(" Cannot copy prefetch state; source file does not exist: {from}" ), call. = FALSE )
672+ }
673+
674+ target_dir <- dirname(to )
675+ if (! dir.exists(target_dir )) dir.create(target_dir , recursive = TRUE , showWarnings = FALSE )
676+ tmp <- paste0(to , " .tmp." , Sys.getpid())
677+
678+ copied <- isTRUE(file.copy(from , tmp , overwrite = TRUE , copy.mode = TRUE , copy.date = TRUE ))
679+ if (! copied || ! file.exists(tmp )) {
680+ stop(glue :: glue(" Failed to stage copied prefetch state file: {tmp}" ), call. = FALSE )
681+ }
682+
683+ renamed <- isTRUE(file.rename(tmp , to ))
684+ if (! renamed ) {
685+ copied_final <- isTRUE(file.copy(tmp , to , overwrite = TRUE , copy.mode = TRUE , copy.date = TRUE ))
686+ suppressWarnings(unlink(tmp ))
687+ if (! copied_final || ! file.exists(to )) {
688+ stop(glue :: glue(" Failed to finalize copied prefetch state file: {to}" ), call. = FALSE )
689+ }
690+ }
691+
692+ invisible (to )
693+ }
694+
695+ migrate_prefetch_state_file <- function (state_file , legacy_state_file , templateflow_home ) {
696+ if (! checkmate :: test_file_exists(legacy_state_file )) return (invisible (NULL ))
697+
698+ if (! checkmate :: test_file_exists(state_file )) {
699+ copy_prefetch_state_file(legacy_state_file , state_file )
700+ message(glue :: glue(
701+ " Migrated legacy TemplateFlow prefetch state from {legacy_state_file} to {state_file}."
702+ ))
703+ } else {
704+ message(glue :: glue(
705+ " Found legacy TemplateFlow prefetch state at {legacy_state_file}; using logs-based state file at {state_file}."
706+ ))
707+ }
708+
709+ removed <- suppressWarnings(unlink(legacy_state_file ))
710+ if (! checkmate :: test_file_exists(legacy_state_file ) || identical(removed , 0L )) {
711+ message(glue :: glue(
712+ " Removed legacy TemplateFlow prefetch state file from templateflow_home: {legacy_state_file}"
713+ ))
714+ return (invisible (NULL ))
715+ }
716+
717+ cache_initialized <- prefetch_templateflow_cache_initialized(templateflow_home )
718+ base_msg <- glue :: glue(
719+ " Unable to remove legacy TemplateFlow prefetch state file at {legacy_state_file}. "
720+ )
721+ guidance <- " Remove it manually to avoid TemplateFlow standard-space resolution failures."
722+
723+ if (! cache_initialized ) {
724+ stop(
725+ paste0(
726+ base_msg ,
727+ " TemplateFlow cache appears uninitialized (no tpl-* directories). " ,
728+ guidance
729+ ),
730+ call. = FALSE
731+ )
732+ }
733+
734+ warning(
735+ paste0(
736+ base_msg ,
737+ " Continuing because TemplateFlow cache appears initialized (tpl-* directories detected). " ,
738+ guidance
739+ ),
740+ call. = FALSE
741+ )
742+ }
743+
642744find_container_runtime <- function () {
643745 runtimes <- Sys.which(c(" singularity" , " apptainer" ))
644746 available <- unname(runtimes [nzchar(runtimes )])
@@ -808,6 +910,8 @@ submit_prefetch_templates <- function(scfg, steps, sequence_id = NULL) {
808910
809911 tf_home <- normalizePath(tf_home , mustWork = FALSE )
810912 if (! dir.exists(tf_home )) dir.create(tf_home , showWarnings = FALSE , recursive = TRUE )
913+ prefetch_state_file <- get_prefetch_state_file(scfg $ metadata $ log_directory , tf_home )
914+ legacy_prefetch_state_file <- get_legacy_prefetch_state_file(tf_home )
811915
812916 spaces <- scfg $ fmriprep $ output_spaces
813917 if (isTRUE(steps [" aroma" ]) && (is.null(spaces ) || ! grepl(" MNI152NLin6Asym:res-2" , spaces , fixed = TRUE ))) {
@@ -832,14 +936,19 @@ submit_prefetch_templates <- function(scfg, steps, sequence_id = NULL) {
832936 # preflight permission checks for project-level paths
833937 pf_issues <- c(
834938 check_write_target(scfg $ metadata $ log_directory , " log directory" ),
835- check_write_target(tf_home , " templateflow_home directory" )
939+ check_write_target(tf_home , " templateflow_home directory" ),
940+ check_write_target(prefetch_state_file , " prefetch state file" )
836941 )
837942 if (length(pf_issues ) > 0L ) {
838943 stop(" Preflight permission check failed for prefetch_templates:\n " ,
839944 paste(paste0(" - " , pf_issues ), collapse = " \n " ), call. = FALSE )
840945 }
841946
842- prefetch_state_file <- get_prefetch_state_file(tf_home )
947+ migrate_prefetch_state_file(
948+ state_file = prefetch_state_file ,
949+ legacy_state_file = legacy_prefetch_state_file ,
950+ templateflow_home = tf_home
951+ )
843952 prefetch_state <- read_prefetch_state(prefetch_state_file )
844953 prefetch_plan <- resolve_prefetch_query_plan(
845954 container_path = container_path ,
0 commit comments