Symlink Tool Technical Vignette

Other Features

Other available features will be covered briefly, and will assume the reader has already read the Symlink Tool Intro section.

Mark Keep

It’s likely you’ll have other output versions you want to keep, but not as ‘best’. You can mark these as ‘keep’.

  • This will produce symlinks of the form keep_<version_name>
 suppressMessages(
 slt$mark_keep(version_name = "2024_02_10", user_entry = list(comment = "testing mark_keep"))
)
 print_tree(root_base)
 #> |-- log_symlinks_central.csv
 #> |-- modeled
 #> | |-- 2024_02_02
 #> | | `-- logs
 #> | | `-- log_version_history.csv
 #> | |-- 2024_02_10
 #> | | `-- logs
 #> | | `-- log_version_history.csv
 #> | |-- keep_2024_02_10
 #> | | `-- logs
 #> | | `-- log_version_history.csv
 #> | `-- report_key_versions.csv
 #> `-- to_model
 #> |-- 2024_02_02
 #> | `-- logs
 #> | `-- log_version_history.csv
 #> |-- 2024_02_10
 #> | `-- logs
 #> | `-- log_version_history.csv
 #> |-- keep_2024_02_10
 #> | `-- logs
 #> | `-- log_version_history.csv
 #> `-- report_key_versions.csv
 print_symlink("keep")
 #> [1] "lrwxrwxrwx 1 ssbyrne Domain Users 39 Jul 24 11:13 keep_2024_02_10 -> /tmp/Rtmp3tDGBK/slt/to_model/2024_02_10"

Reports pt 2

In addition to the report_key_versions.csv file, there are other reports available. These will show the status of the last log row for each version_name folder in each root folder.

You can view things like:

  • All your folders that are not currently symlinked (marked).
  • All symlinked folders.
    • Includes symlinks not recognized by this tool.

NOTE: This includes a discrepancy report that shows if logs do not conform to expected standards.

  • If you find a log discrepancy that is not caught by this report and you think it should be, please contact the package maintainer.
    • There is currently no issue queue, but this may be added if there is demand.
 # Show the types of reports currently available
slt$make_reports
 #> function () 
 #> {
 #> private$msg_sometimes("Writing last-row log reports for:\n")
 #> for (root in private$DICT$ROOTS) {
 #> private$msg_sometimes(" ", root)
 #> private$report_all_logs(root = root)
 #> private$report_all_logs_symlink(root = root)
 #> private$report_all_logs_tool_symlink(root = root)
 #> private$report_all_logs_non_symlink(root = root)
 #> private$report_discrepancies(root = root, verbose = FALSE)
 #> private$msg_sometimes(" ", root)
 #> }
 #> }
 #> <environment: 0x55d711ad6088>
 # Run the reports
 suppressMessages({
 slt$make_reports()
})
 print_tree(root_base)
 #> |-- log_symlinks_central.csv
 #> |-- modeled
 #> | |-- 2024_02_02
 #> | | `-- logs
 #> | | `-- log_version_history.csv
 #> | |-- 2024_02_10
 #> | | `-- logs
 #> | | `-- log_version_history.csv
 #> | |-- keep_2024_02_10
 #> | | `-- logs
 #> | | `-- log_version_history.csv
 #> | |-- report_all_logs.csv
 #> | |-- report_all_logs_non_symlink.csv
 #> | |-- report_all_logs_symlink.csv
 #> | `-- report_key_versions.csv
 #> `-- to_model
 #> |-- 2024_02_02
 #> | `-- logs
 #> | `-- log_version_history.csv
 #> |-- 2024_02_10
 #> | `-- logs
 #> | `-- log_version_history.csv
 #> |-- keep_2024_02_10
 #> | `-- logs
 #> | `-- log_version_history.csv
 #> |-- report_all_logs.csv
 #> |-- report_all_logs_non_symlink.csv
 #> |-- report_all_logs_symlink.csv
 #> `-- report_key_versions.csv
 # View an example report - logs for folders with no active symlink
 # - you can see this folder was previously marked 'best'
data.table::fread(file.path(root_input, "report_all_logs_non_symlink.csv"))
 #> log_id timestamp user version_name version_path action comment
 #> <int> <char> <char> <char> <char> <char> <char>
 #> 1: 2 2025_07_24_111339 ssbyrne 2024_02_02 /tmp/Rtmp3tDGBK/slt/to_model/2024_02_02 demote_best testing mark_best
 # Expect this to be absent for the vignette
 try(data.table::fread(file.path(root_input, "REPORT_DISCREPANCIES.csv")))
 #> Error in data.table::fread(file.path(root_input, "REPORT_DISCREPANCIES.csv")) : 
 #> File '/tmp/Rtmp3tDGBK/slt/to_model/REPORT_DISCREPANCIES.csv' does not exist or is non-readable. getwd()=='/tmp/RtmpBjZYIf/Rbuild3a7bce4ab1354e/vmTools/vignettes'

Roundups

Let’s say you have a set of folders you want to keep or remove, and you want to do it all at once.

We’ll demonstrate by:

  1. Making a set of dummy folders
    1. Marking some as remove_
      1. Rounding up the remove_ folders for deletion
    2. Round up the rest by date
      1. Mark these as keep_
 # Make a set of dummy folders
dv1 <- get_output_dir(root_input, "today")
slt$make_new_version_folder(dv1)
dv2 <- get_output_dir(root_input, "today")
slt$make_new_version_folder(dv2)
dv3 <- get_output_dir(root_input, "today")
slt$make_new_version_folder(dv3)
dv4 <- get_output_dir(root_input, "today")
slt$make_new_version_folder(dv4)
 
 print_tree(root_base)
 #> |-- log_symlinks_central.csv
 #> |-- modeled
 #> | |-- 2024_02_02
 #> | | `-- logs
 #> | | `-- log_version_history.csv
 #> | |-- 2024_02_10
 #> | | `-- logs
 #> | | `-- log_version_history.csv
 #> | |-- 2025_07_24.01
 #> | | `-- logs
 #> | | `-- log_version_history.csv
 #> | |-- 2025_07_24.02
 #> | | `-- logs
 #> | | `-- log_version_history.csv
 #> | |-- 2025_07_24.03
 #> | | `-- logs
 #> | | `-- log_version_history.csv
 #> | |-- 2025_07_24.04
 #> | | `-- logs
 #> | | `-- log_version_history.csv
 #> | |-- keep_2024_02_10
 #> | | `-- logs
 #> | | `-- log_version_history.csv
 #> | |-- report_all_logs.csv
 #> | |-- report_all_logs_non_symlink.csv
 #> | |-- report_all_logs_symlink.csv
 #> | `-- report_key_versions.csv
 #> `-- to_model
 #> |-- 2024_02_02
 #> | `-- logs
 #> | `-- log_version_history.csv
 #> |-- 2024_02_10
 #> | `-- logs
 #> | `-- log_version_history.csv
 #> |-- 2025_07_24.01
 #> | `-- logs
 #> | `-- log_version_history.csv
 #> |-- 2025_07_24.02
 #> | `-- logs
 #> | `-- log_version_history.csv
 #> |-- 2025_07_24.03
 #> | `-- logs
 #> | `-- log_version_history.csv
 #> |-- 2025_07_24.04
 #> | `-- logs
 #> | `-- log_version_history.csv
 #> |-- keep_2024_02_10
 #> | `-- logs
 #> | `-- log_version_history.csv
 #> |-- report_all_logs.csv
 #> |-- report_all_logs_non_symlink.csv
 #> |-- report_all_logs_symlink.csv
 #> `-- report_key_versions.csv

roundup_remove

 # Mark some as 'remove_'
 suppressMessages({
 for(dv in c(dv1, dv2)){
 slt$mark_remove(dv, user_entry = list(comment = "mark_remove for roundup"))
 }
})
 # Round up and delete
roundup_remove_list <- slt$roundup_remove()
 suppressMessages({
 for(dv in roundup_remove_list$root_input$version_name){
 slt$delete_version_folders(
 version_name = dv,
 user_entry = list(comment = "roundup_remove"),
 require_user_input = FALSE
 )
 }
})
 print_tree(root_base)
 #> |-- log_symlinks_central.csv
 #> |-- modeled
 #> | |-- 2024_02_02
 #> | | `-- logs
 #> | | `-- log_version_history.csv
 #> | |-- 2024_02_10
 #> | | `-- logs
 #> | | `-- log_version_history.csv
 #> | |-- 2025_07_24.03
 #> | | `-- logs
 #> | | `-- log_version_history.csv
 #> | |-- 2025_07_24.04
 #> | | `-- logs
 #> | | `-- log_version_history.csv
 #> | |-- keep_2024_02_10
 #> | | `-- logs
 #> | | `-- log_version_history.csv
 #> | |-- report_all_logs.csv
 #> | |-- report_all_logs_non_symlink.csv
 #> | |-- report_all_logs_symlink.csv
 #> | `-- report_key_versions.csv
 #> `-- to_model
 #> |-- 2024_02_02
 #> | `-- logs
 #> | `-- log_version_history.csv
 #> |-- 2024_02_10
 #> | `-- logs
 #> | `-- log_version_history.csv
 #> |-- 2025_07_24.03
 #> | `-- logs
 #> | `-- log_version_history.csv
 #> |-- 2025_07_24.04
 #> | `-- logs
 #> | `-- log_version_history.csv
 #> |-- keep_2024_02_10
 #> | `-- logs
 #> | `-- log_version_history.csv
 #> |-- report_all_logs.csv
 #> |-- report_all_logs_non_symlink.csv
 #> |-- report_all_logs_symlink.csv
 #> `-- report_key_versions.csv

roundup_by_date

Use the log creation date (first row) to round up folders created on, before, or after that date.

my_date <- format(Sys.Date(), "%Y_%m_%d")
roundup_date_list <- slt$roundup_by_date(
 user_date = my_date,
 date_selector = "lte" # less than or equal to today's date
)
 #> Finding all folders with log creation dates that are 'lte' 2025_07_24. 
 #> NOTE! Log creation dates are used as the file-system does not record creation times.
 #> roundup_by_date: Formatting date with time-zone: America/Los_Angeles
 #> Folders with symlinks will have duplicate rows by `version_name` (one row for each unique `dir_name`) - showing all for completeness.
 # mark all our dummy folders (with the ".VV" pattern) as keepers
dv_keep <- grep(
 pattern = "\\.\\d\\d"
 , x = roundup_date_list$root_input$version_name
 , value = TRUE
)
 suppressMessages({
 for(dv in dv_keep){
 slt$mark_keep(dv, user_entry = list(comment = "roundup_by_date"))
 }
})
 print_tree(root_base)
 #> |-- log_symlinks_central.csv
 #> |-- modeled
 #> | |-- 2024_02_02
 #> | | `-- logs
 #> | | `-- log_version_history.csv
 #> | |-- 2024_02_10
 #> | | `-- logs
 #> | | `-- log_version_history.csv
 #> | |-- 2025_07_24.03
 #> | | `-- logs
 #> | | `-- log_version_history.csv
 #> | |-- 2025_07_24.04
 #> | | `-- logs
 #> | | `-- log_version_history.csv
 #> | |-- keep_2024_02_10
 #> | | `-- logs
 #> | | `-- log_version_history.csv
 #> | |-- keep_2025_07_24.03
 #> | | `-- logs
 #> | | `-- log_version_history.csv
 #> | |-- keep_2025_07_24.04
 #> | | `-- logs
 #> | | `-- log_version_history.csv
 #> | |-- report_all_logs.csv
 #> | |-- report_all_logs_non_symlink.csv
 #> | |-- report_all_logs_symlink.csv
 #> | `-- report_key_versions.csv
 #> `-- to_model
 #> |-- 2024_02_02
 #> | `-- logs
 #> | `-- log_version_history.csv
 #> |-- 2024_02_10
 #> | `-- logs
 #> | `-- log_version_history.csv
 #> |-- 2025_07_24.03
 #> | `-- logs
 #> | `-- log_version_history.csv
 #> |-- 2025_07_24.04
 #> | `-- logs
 #> | `-- log_version_history.csv
 #> |-- keep_2024_02_10
 #> | `-- logs
 #> | `-- log_version_history.csv
 #> |-- keep_2025_07_24.03
 #> | `-- logs
 #> | `-- log_version_history.csv
 #> |-- keep_2025_07_24.04
 #> | `-- logs
 #> | `-- log_version_history.csv
 #> |-- report_all_logs.csv
 #> |-- report_all_logs_non_symlink.csv
 #> |-- report_all_logs_symlink.csv
 #> `-- report_key_versions.csv

Make new log

The date roundup relies on the log creation date (recall, the Linux filesystem does not record folder creation / birth dates). If you’ve made your own folders without the symlink tool, you can make a blank log easily. You can hand-edit the creation date if you know when the folder was made.

Note:

  • The tool tries to resolve all operations in each root independently. So even though we’re not creating a folder in both our roots, the tool will create as many logs as it can.
 # Make a naive folder without a log
 dir.create(file.path(root_output, "2024_02_10_naive"))
 try(slt$make_new_log(version_name = "2024_02_10_naive"))
 print_tree(root_base)
 #> |-- log_symlinks_central.csv
 #> |-- modeled
 #> | |-- 2024_02_02
 #> | | `-- logs
 #> | | `-- log_version_history.csv
 #> | |-- 2024_02_10
 #> | | `-- logs
 #> | | `-- log_version_history.csv
 #> | |-- 2024_02_10_naive
 #> | | `-- logs
 #> | | `-- log_version_history.csv
 #> | |-- 2025_07_24.03
 #> | | `-- logs
 #> | | `-- log_version_history.csv
 #> | |-- 2025_07_24.04
 #> | | `-- logs
 #> | | `-- log_version_history.csv
 #> | |-- keep_2024_02_10
 #> | | `-- logs
 #> | | `-- log_version_history.csv
 #> | |-- keep_2025_07_24.03
 #> | | `-- logs
 #> | | `-- log_version_history.csv
 #> | |-- keep_2025_07_24.04
 #> | | `-- logs
 #> | | `-- log_version_history.csv
 #> | |-- report_all_logs.csv
 #> | |-- report_all_logs_non_symlink.csv
 #> | |-- report_all_logs_symlink.csv
 #> | `-- report_key_versions.csv
 #> `-- to_model
 #> |-- 2024_02_02
 #> | `-- logs
 #> | `-- log_version_history.csv
 #> |-- 2024_02_10
 #> | `-- logs
 #> | `-- log_version_history.csv
 #> |-- 2024_02_10_naive
 #> | `-- logs
 #> | `-- log_version_history.csv
 #> |-- 2025_07_24.03
 #> | `-- logs
 #> | `-- log_version_history.csv
 #> |-- 2025_07_24.04
 #> | `-- logs
 #> | `-- log_version_history.csv
 #> |-- keep_2024_02_10
 #> | `-- logs
 #> | `-- log_version_history.csv
 #> |-- keep_2025_07_24.03
 #> | `-- logs
 #> | `-- log_version_history.csv
 #> |-- keep_2025_07_24.04
 #> | `-- logs
 #> | `-- log_version_history.csv
 #> |-- report_all_logs.csv
 #> |-- report_all_logs_non_symlink.csv
 #> |-- report_all_logs_symlink.csv
 #> `-- report_key_versions.csv

Internal State

You can audit the internal state of the tool with the print_ functions.

 # Print all static fields (output truncated)
slt$return_dictionaries()
 #> $FLAGS
 #> $FLAGS$allow_schema_repair
 #> [1] TRUE
 #> 
 #> 
 #> $ROOTS
 #> $ROOTS$root_input
 #> [1] "/tmp/Rtmp3tDGBK/slt/to_model"
 #> 
 #> $ROOTS$root_output
 #> [1] "/tmp/Rtmp3tDGBK/slt/modeled"
....
 #> [1] "^best"
 #> 
 #> $symlink_regex_extract$keep
 #> [1] "^keep_"
 #> 
 #> $symlink_regex_extract$remove
 #> [1] "^remove_"
 #> 
 #> 
 #> $verbose
 #> [1] TRUE
 # ROOTS are likely most interesting to the user.
slt$return_dictionaries(item_names = "ROOTS")
 #> $ROOTS
 #> $ROOTS$root_input
 #> [1] "/tmp/Rtmp3tDGBK/slt/to_model"
 #> 
 #> $ROOTS$root_output
 #> [1] "/tmp/Rtmp3tDGBK/slt/modeled"
 # Show the last 'action' the tool performed
 # - these fields are set as part of each 'marking' new action.
slt$return_dynamic_fields()
 #> $LOG
 #> $LOG$version_name
 #> [1] "2024_02_10_naive"
 #> 
 #> $LOG$action
 #> [1] "promote_keep"
 #> 
 #> 
 #> $VERS_PATHS
 #> $VERS_PATHS$root_input
 #> [1] "/tmp/Rtmp3tDGBK/slt/to_model/2024_02_10_naive"
 #> 
 #> $VERS_PATHS$root_output
 #> [1] "/tmp/Rtmp3tDGBK/slt/modeled/2024_02_10_naive"

Clean Up

 # Finally, clean up all our temporary folders
 system(paste("rm -rf", root_base))

AltStyle によって変換されたページ (->オリジナル) /