Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Detect dev/prod & data updates #25

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
Open
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
8 changes: 8 additions & 0 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,11 @@ Config/testthat/edition: 3
Encoding: UTF-8
Roxygen: list(markdown = TRUE)
RoxygenNote: 7.3.1
Imports:
dplyr,
gh,
golem,
lubridate,
renv,
rmarkdown,
usethis
8 changes: 7 additions & 1 deletion NAMESPACE
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
# Generated by roxygen2: do not edit by hand

export(make_child_app)
export(run_data_prep_local_data_folder)
export(use_batch_jobs)
importFrom(dplyr,filter)
importFrom(dplyr,inner_join)
importFrom(dplyr,mutate)
importFrom(gh,gh)
importFrom(golem,create_golem)
importFrom(lubridate,ymd_hms)
importFrom(renv,scaffold)
importFrom(rhino,init)
importFrom(rmarkdown,render)
importFrom(usethis,use_package)
importFrom(usethis,write_union)
68 changes: 68 additions & 0 deletions R/data_prep_update.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
## Handle local data in `data folder`


get_updated_time <- function(data_loc) {
current_files <- list.files(file.path(data_loc))

current_data_info <- file.info(file.path(data_loc, current_files))
current_data_info$file_name <- current_files

rownames(current_data_info) <- NULL
current_data_info <- current_data_info[, c("file_name", "mtime")]

return(current_data_info)
}

#' @export
run_data_prep_local_data_folder <- function(dev_data_loc) {

if (length(list.files(dev_data_loc)) == 0) {
message("There is no data. Skipping data processing")
return(invisible(NULL))
}

# Look for the file that has file name & last updated
data_update_log <- file.path("jobs", "data_update_log.csv")

# If not exist, make one
if (!file.exists(data_update_log)) {
curr_data_info <- get_updated_time(dev_data_loc)
write.csv(curr_data_info, data_update_log, row.names = FALSE)
}

data_update_log <- read.csv(data_update_log)

# Pull the current information in the data folder to compare against log
current_data_info <- get_updated_time(dev_data_loc)

# Conditionally run data prep
if (nrow(current_data_info) > nrow(data_update_log)) {
message("New data has been added! Running data prep")
rmarkdown::render("jobs/data_prep.Rmd")
} else if (nrow(current_data_info) < nrow(data_update_log)) {
message("Data has been removed! Running data prep")
rmarkdown::render("jobs/data_prep.Rmd")
} else {
joined <- data_update_log |>
dplyr::inner_join(current_data_info, by = "file_name")

n_updates <- joined |>
dplyr::mutate(
mtime.x = lubridate::ymd_hms(mtime.x),
mtime.y = lubridate::ymd_hms(mtime.y)
) |>
dplyr::filter(mtime.x < mtime.y) |>
nrow()

if (n_updates > 0) {
message("Data has been updated! Running data prep")
rmarkdown::render("jobs/data_prep.Rmd")
write.csv(current_data_info, "jobs/data_update_log.csv")
} else {
message("No change in data, skipping data prep")
}
}
return(invisible(NULL))
}


5 changes: 4 additions & 1 deletion R/dependencies.R
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
#' @importFrom golem create_golem
#' @importFrom rhino init
#' @importFrom renv scaffold
#' @importFrom usethis use_package write_union
#' @importFrom gh gh
#' @importFrom dplyr inner_join mutate filter
#' @importFrom lubridate ymd_hms
#' @importFrom rmarkdown render
#'
#'
NULL
136 changes: 99 additions & 37 deletions R/make_child_app.R
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#' Make Child app from Parent app with modules
#'
#' @param parent_app_dir `character` Path to existing parent app, including the parent app directory
#' @param parent_github_repo `character` github repo of the parent in the form of "parent/repo"
#' @param child_app_dir `character` Path to new child app, including the child app directory
#' @param include_renv `logical` Include `renv` structure in child app or now. Default is `FALSE`
#' @param copy_jobs_dir `logical` Copy the `jobs` directory from the parent app (`TRUE`)
Expand All @@ -14,25 +14,20 @@
#'
#' @examples
#' \dontrun{
#' make_child_app(parent_app_dir = "inst/parentApp",
#' child_app_dir = "~/childTest")
#'
#'
#' make_child_app(parent_app_dir = "inst/parentApp",
#' child_app_dir = "~/childTest2",
#' copy_jobs_dir = FALSE,
#' include_renv = TRUE)
#'
#' make_child_app(parent_app_dir = "inst/parentApp",
#' child_app_dir = "~/childTest3",
#' include_renv = TRUE,
#' framework = "golem")
#' make_child_app(parent_github_repo = "atorus-research/matteParentPkg",
#' child_app_dir = "~/childTest",
#' copy_jobs_dir = TRUE,
#' include_renv = FALSE,
#' include_meta_yaml = TRUE,
#' job_file_type = "Rmd",
#' overwrite = FALSE,
#' framework = "none")
#' }
#'

# TODO: add logging

make_child_app <- function(parent_app_dir,
make_child_app <- function(parent_github_repo,
child_app_dir,
include_renv = FALSE,
copy_jobs_dir = FALSE,
Expand All @@ -50,28 +45,31 @@ make_child_app <- function(parent_app_dir,
stop("`framework` must be one of: 'none', 'golem' or 'rhino'")
}

top_level_files <- gh::gh("/repos/:owner/:repo/contents", owner = "atorus-research", repo = "matteParentPkg")
r_folder_files <- gh::gh("/repos/:owner/:repo/contents/R", owner = "atorus-research", repo = "matteParentPkg")
jobs_folder_files <- gh::gh("/repos/:owner/:repo/contents/jobs", owner = "atorus-research", repo = "matteParentPkg")

##create the child app path dir (if it doesn't exist)
parent_app_dir_ <- normalizePath(parent_app_dir, winslash = "/")
child_app_dir_ <-
normalizePath(child_app_dir, winslash = "/") %>% suppressWarnings()
parent_pkg_name <- strsplit(parent_github_repo, "/")[[1]][[2]]
child_app_dir_ <- normalizePath(child_app_dir, winslash = "/") |> suppressWarnings()

## make sure all needed files/directories exist in parent_app
if (!file.exists(file.path(parent_app_dir_, "app.R")) ||
!file.exists(file.path(parent_app_dir_, "R", "app_ui.R")) ||
!file.exists(file.path(parent_app_dir_, "R", "app_server.R"))) {
if (length(Filter(function(x){x$name == "app.R"}, top_level_files)) == 0 ||
length(Filter(function(x){x$name == "app_ui.R"}, r_folder_files)) == 0 ||
length(Filter(function(x){x$name == "app_server.R"}, r_folder_files)) == 0) {
stop(
sprintf(
"%s must contain app.R, R/app_ui.R and R/app_server.R in order to be duplicated",
basename(parent_app_dir_)
parent_pkg_name
)
)
}

if (copy_jobs_dir && !file.exists(file.path(parent_app_dir_, "jobs"))) {
if (copy_jobs_dir && length(Filter(function(x){x$name == "jobs"}, top_level_files)) == 0) {
stop(
sprintf(
"%s must contain jobs folder when copy_jobs_dir = TRUE",
basename(parent_app_dir_)
parent_pkg_name
)
)
}
Expand All @@ -96,12 +94,49 @@ make_child_app <- function(parent_app_dir,
golem::create_golem(child_app_dir_, open = FALSE)
}
else if (framework == "rhino") {
rhino::init(child_app_dir_)
# rhino::init(child_app_dir_)
}
else {
dir.create(child_app_dir_)
}

## create Rproj
rproj_file <- paste0(child_app_dir_, "/", basename(child_app_dir), ".Rproj")
if (!file.exists(rproj_file)) {
file.create(rproj_file)
fileCon <- file(rproj_file)
writeLines(c("Version: 1.0",
"RestoreWorkspace: No",
"SaveWorkspace: No",
"AlwaysSaveHistory: Default",
"EnableCodeIndexing: Yes",
"UseSpacesForTab: Yes",
"NumSpacesForTab: 2",
"Encoding: UTF-8",
"RnwWeave: Sweave",
"LaTeX: pdfLaTeX",
"AutoAppendNewline: Yes",
"StripTrailingWhitespace: Yes",
"LineEndingConversion: Posix",
"BuildType: Package",
"PackageUseDevtools: Yes",
"PackageInstallArgs: --no-multiarch --with-keep.source",
"PackageRoxygenize: rd,collate,namespace"),
con = fileCon)
close(fileCon)
}

## create Renviron (dev/prod detection)
renviron_file <- paste0(child_app_dir_, "/", ".Renviron")
if (!file.exists(renviron_file)) {
file.create(renviron_file)
fileCon <- file(renviron_file)
writeLines(c("DEVELOPMENT_ENVIRONMENT=DEV",
"DEVELOPMENT_DATA_LOCATION_TYPE=LOCAL",
"DEVELOPMENT_DATA_LOCATION=data"),
con = fileCon)
close(fileCon)
}

## create R folder
if (!file.exists(paste0(child_app_dir_, "/R"))) {
Expand All @@ -110,31 +145,51 @@ make_child_app <- function(parent_app_dir,


## start copying over all of the needed files from parent_app or templates
## We're going to download from github into a temp location and copy it over


## Pull parent repo info from github
tmp_folder <- tempdir()

download.file("https://raw.githubusercontent.com/atorus-research/matteParentPkg/main/R/app_ui.R", file.path(tmp_folder, "app_ui.R"))
file.copy(
from = file.path(parent_app_dir_, "R", "app_ui.R"),
from = file.path(tmp_folder, "app_ui.R"),
to = file.path(child_app_dir_, "R", "app_ui.R"),
overwrite = TRUE
)

download.file("https://raw.githubusercontent.com/atorus-research/matteParentPkg/main/R/app_server.R", file.path(tmp_folder, "app_server.R"))
file.copy(
from = file.path(parent_app_dir_, "R", "app_server.R"),
from = file.path(tmp_folder, "app_server.R"),
to = file.path(child_app_dir_, "R", "app_server.R"),
overwrite = TRUE
)
if (file.exists(file.path(parent_app_dir_, "manifest.json"))) {


if (length(Filter(function(x){x$name == "manifest.json"}, top_level_files)) == 1) {

download.file("https://raw.githubusercontent.com/atorus-research/matteParentPkg/main/manifest.json", file.path(tmp_folder, "manifest.json"))
file.copy(
from = file.path(parent_app_dir_, "manifest.json"),
from = file.path(tmp_folder, "manifest.json"),
to = file.path(child_app_dir_, "manifest.json"),
overwrite = TRUE
)
}
## add the app.R templates
if (framework != "rhino") {

file.copy(
from = system.file(paste0("app_template_",framework,".R"),
package = "matte"),
to = file.path(child_app_dir_, "app.R"),
overwrite = TRUE
)

# app.R installs parent package
file_content <- readLines(file.path(child_app_dir_, "app.R"))
file_content <- gsub("PARENT_PACKAGE_REPO", parent_github_repo, file_content)
file_content <- gsub("PARENT_PACKAGE", parent_pkg_name, file_content)
writeLines(file_content, file.path(child_app_dir_, "app.R"))
}
## add the main.R template for rhino
else {
Expand All @@ -149,12 +204,19 @@ make_child_app <- function(parent_app_dir,
## create jobs directory
if (copy_jobs_dir) {
dir.create(paste0(child_app_dir_, "/jobs"))
file.copy(
from = paste0(parent_app_dir_, "/jobs"),
to = child_app_dir_,
recursive = TRUE,
overwrite = overwrite
)

dir.create(file.path(tmp_folder, "jobs"))

for (jobs_file in jobs_folder_files) {
download.file(jobs_file$download_url, file.path(tmp_folder, "jobs", jobs_file$name))

file.copy(
from = file.path(tmp_folder, "jobs", jobs_file$name),
to = file.path(child_app_dir_, "jobs"),
recursive = TRUE,
overwrite = overwrite
)
}
}
else{
dir.create(paste0(child_app_dir_, "/jobs"))
Expand All @@ -171,7 +233,7 @@ make_child_app <- function(parent_app_dir,
}

## if they want a meta yaml file, but do not have one in the parent app jobs folder, copy it from template
if (include_meta_yaml && all(!grepl(".yaml", list.files(paste0(parent_app_dir_, "/jobs"))))) {
if (include_meta_yaml && length(Filter(function(x){grepl(".yaml", x$name)}, jobs_folder_files)) == 0) {
file.copy(
from = system.file("meta_template.yaml",
package = "matte"),
Expand All @@ -189,7 +251,7 @@ make_child_app <- function(parent_app_dir,

#create dependencies.R
fileCon <- file(file.path(child_app_dir_, "R", "dependencies.R"))
writeLines(c(paste("#' @import", basename(parent_app_dir_)),
writeLines(c(paste("#' @import", parent_pkg_name),
"#'",
"NULL"),
con = fileCon)
Expand Down
15 changes: 13 additions & 2 deletions inst/app_template_none.R
Original file line number Diff line number Diff line change
@@ -1,4 +1,15 @@
## install parent package
if (!require(PARENT_PACKAGE, quietly = TRUE)) {
remotes::install_github("PARENT_PACKAGE_REPO")
}

## install matte
if (!require(matte, quietly = TRUE)) {
remotes::install_github("atorus-research/matte@data-dev-prod")
}

## Launch the ShinyApp
source("R/app_ui.R")
source("R/app_server.R")

shinyApp(ui = app_ui,
server = app_server)
shiny::shinyApp(ui = app_ui, server = app_server)
7 changes: 0 additions & 7 deletions inst/parentApp/.Rbuildignore

This file was deleted.

1 change: 0 additions & 1 deletion inst/parentApp/.gitignore

This file was deleted.

Empty file removed inst/parentApp/.here
Empty file.
17 changes: 0 additions & 17 deletions inst/parentApp/DESCRIPTION

This file was deleted.

Loading
Loading