Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 40 additions & 1 deletion R/manifest.R
Original file line number Diff line number Diff line change
Expand Up @@ -189,15 +189,54 @@
if (.is_len_0(version_file)) {
return(paste0("Project: ", projr_version_get()))
}

# Get current and previous project versions
current_version <- projr_version_get()
previous_version <- NULL

if (any(grepl("^Project: ", version_file))) {
project_line <- grep("^Project: ", version_file, value = TRUE)[[1]]
previous_version <- gsub("^Project: ", "", project_line) |> trimws()
version_file <- version_file[!grepl("^Project: ", version_file)]
}
c(paste0("Project: ", projr_version_get()), version_file)

# If project version has changed, mark existing labels with # to indicate
# they may be out of date with the new project version
if (!is.null(previous_version) && previous_version != current_version) {
version_file <- .version_file_mark_labels_stale(version_file)
}

c(paste0("Project: ", current_version), version_file)
}

# Mark label versions with # to indicate they may be stale relative to new project version
.version_file_mark_labels_stale <- function(version_file) {
if (.is_len_0(version_file)) {
return(version_file)
}

# Process each line
vapply(version_file, function(line) {
# Skip if not a label line
if (!grepl(": ", line)) {
return(line)
}

# Skip if already marked with # or *
if (grepl("#$|\\*$", line)) {
return(line)
}

# Add # to indicate this version may be stale
paste0(line, "#")
}, character(1), USE.NAMES = FALSE)
}

.version_file_update_label_version <- function(version_file, # nolint
label,
add_asterisk) {
# When updating a label, remove the # marker (if present) since we're now uploading it
# The # marker indicates a label that may be stale relative to the current project version
version_add <- if (add_asterisk) {
.version_get() |> paste0("*")
} else {
Expand Down
12 changes: 7 additions & 5 deletions R/remote-versions.R
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@
if (is.null(remote_pre)) {
return(character(0L))
}
remote_final_vec_basename <- .(
remote_final_vec_basename <- .remote_final_ls(
type, remote_pre_down
)
.remote_version_latest_get(remote_final_vec_basename, type, label) |>
Expand Down Expand Up @@ -498,10 +498,12 @@
if (.is_len_0(label_regex)) {
return(character(0L))
}
# Extract version, removing the asterisk if present
version_with_possible_asterisk <- gsub(match_str, "", label_regex) |> trimws()
# Remove asterisk for version comparison purposes but don't mark as trusted
gsub("\\*$", "", version_with_possible_asterisk) |> .version_v_rm()
# Extract version, removing the asterisk and hash if present
# * indicates untrusted upload
# # indicates potentially stale (not checked against current project version)
version_with_markers <- gsub(match_str, "", label_regex) |> trimws()
# Remove asterisk and hash for version comparison purposes
gsub("\\*$|#$", "", version_with_markers) |> .version_v_rm()
}


Expand Down
41 changes: 41 additions & 0 deletions man/dot-gh_release_create_httr.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions man/dot-gh_api_base.Rd → man/dot-github_api_base.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

46 changes: 46 additions & 0 deletions man/dot-remote_file_get_all_github_httr.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion man/projr_osf_create_project.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

142 changes: 142 additions & 0 deletions tests/testthat/test-version-file-hash-marker.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
test_that(".version_file_mark_labels_stale marks labels with hash", {
skip_if(.is_test_select())

# Test with no labels
version_file <- character(0L)
result <- .version_file_mark_labels_stale(version_file)
expect_identical(result, character(0L))

# Test with one label
version_file <- c("raw-data: v0.3.0")
result <- .version_file_mark_labels_stale(version_file)
expect_identical(result, c("raw-data: v0.3.0#"))

# Test with multiple labels
version_file <- c("raw-data: v0.3.0", "cache: v0.2.0")
result <- .version_file_mark_labels_stale(version_file)
expect_identical(result, c("raw-data: v0.3.0#", "cache: v0.2.0#"))

# Test with label already having asterisk (don't add hash)
version_file <- c("raw-data: v0.3.0*")
result <- .version_file_mark_labels_stale(version_file)
expect_identical(result, c("raw-data: v0.3.0*"))

# Test with label already having hash (don't add another)
version_file <- c("raw-data: v0.3.0#")
result <- .version_file_mark_labels_stale(version_file)
expect_identical(result, c("raw-data: v0.3.0#"))

# Test with mixed markers
version_file <- c("raw-data: v0.3.0", "cache: v0.2.0*", "output: v0.1.0#")
result <- .version_file_mark_labels_stale(version_file)
expect_identical(result, c("raw-data: v0.3.0#", "cache: v0.2.0*", "output: v0.1.0#"))
})

test_that(".version_file_update_project_version marks labels stale when version changes", {
skip_if(.is_test_select())
dir_test <- .test_setup_project(git = FALSE, set_env_var = TRUE)
usethis::with_project(
path = dir_test,
code = {
# Start with empty version file
version_file <- character(0L)
result <- .version_file_update_project_version(version_file)
expect_identical(result[[1]], paste0("Project: ", projr_version_get()))
expect_identical(length(result), 1L)

# Add a label version, then update project version (no change)
projr_version_set("0.0.1")
version_file <- c("Project: 0.0.1", "raw-data: v0.0.1")

result <- .version_file_update_project_version(version_file)
# Should not add hash since version didn't change
expect_identical(result, c("Project: 0.0.1", "raw-data: v0.0.1"))

# Now bump project version and update
projr_version_set("0.0.2")
result <- .version_file_update_project_version(version_file)
# Should add hash to raw-data since project version changed
expect_identical(result[[1]], "Project: 0.0.2")
expect_identical(result[[2]], "raw-data: v0.0.1#")

# Multiple labels with version change
projr_version_set("0.0.3")
version_file <- c("Project: 0.0.2", "raw-data: v0.0.2", "cache: v0.0.1")
result <- .version_file_update_project_version(version_file)
expect_identical(result[[1]], "Project: 0.0.3")
expect_identical(result[[2]], "raw-data: v0.0.2#")
expect_identical(result[[3]], "cache: v0.0.1#")

# Label with asterisk should keep it when adding hash (but only add hash, not replace)
projr_version_set("0.0.4")
version_file <- c("Project: 0.0.3", "raw-data: v0.0.3*")
result <- .version_file_update_project_version(version_file)
expect_identical(result[[1]], "Project: 0.0.4")
expect_identical(result[[2]], "raw-data: v0.0.3*")
}
)
})

test_that(".version_file_update_label_version removes hash marker", {
skip_if(.is_test_select())
dir_test <- .test_setup_project(git = FALSE, set_env_var = TRUE)
usethis::with_project(
path = dir_test,
code = {
projr_version_set("0.0.5")

# Add new label (no hash to remove)
version_file <- c("Project: 0.0.5")
result <- .version_file_update_label_version(version_file, "raw-data", FALSE)
expect_identical(result[[2]], "raw-data: 0.0.5")

# Update existing label with hash (should remove hash)
version_file <- c("Project: 0.0.5", "raw-data: v0.0.3#")
result <- .version_file_update_label_version(version_file, "raw-data", FALSE)
expect_identical(result[[2]], "raw-data: 0.0.5")
expect_false(grepl("#", result[[2]]))

# Update with asterisk should not have hash
version_file <- c("Project: 0.0.5", "raw-data: v0.0.3#")
result <- .version_file_update_label_version(version_file, "raw-data", TRUE)
expect_identical(result[[2]], "raw-data: 0.0.5*")
expect_false(grepl("#", result[[2]]))
}
)
})

test_that(".remote_get_version_label_non_project_file_extract handles hash marker", {
skip_if(.is_test_select())

# Test extracting version without markers
version_file <- c("Project: v0.5.0", "raw-data: v0.3.0")
result <- .remote_get_version_label_non_project_file_extract(version_file, "raw-data")
expect_identical(result, "0.3.0")

# Test extracting version with hash marker
version_file <- c("Project: v0.5.0", "raw-data: v0.3.0#")
result <- .remote_get_version_label_non_project_file_extract(version_file, "raw-data")
expect_identical(result, "0.3.0")

# Test extracting version with asterisk marker
version_file <- c("Project: v0.5.0", "raw-data: v0.3.0*")
result <- .remote_get_version_label_non_project_file_extract(version_file, "raw-data")
expect_identical(result, "0.3.0")

# Test extracting version with both markers should not happen in practice
# but should still extract version correctly
version_file <- c("Project: v0.5.0", "raw-data: v0.3.0#")
result <- .remote_get_version_label_non_project_file_extract(version_file, "raw-data")
expect_identical(result, "0.3.0")

# Test with multiple labels, extract specific one
version_file <- c("Project: v0.5.0", "raw-data: v0.3.0#", "cache: v0.2.0", "output: v0.4.0*")
result <- .remote_get_version_label_non_project_file_extract(version_file, "cache")
expect_identical(result, "0.2.0")

result <- .remote_get_version_label_non_project_file_extract(version_file, "raw-data")
expect_identical(result, "0.3.0")

result <- .remote_get_version_label_non_project_file_extract(version_file, "output")
expect_identical(result, "0.4.0")
})