diff --git a/.Rbuildignore b/.Rbuildignore index e3cbc3e..9ed6386 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -4,3 +4,4 @@ ^azkit\.code-workspace$ ^CODEOWNERS$ ^\.github$ +^\.lintr$ diff --git a/R/get_auth_token.R b/R/get_auth_token.R index 52fd99e..71a7aa5 100644 --- a/R/get_auth_token.R +++ b/R/get_auth_token.R @@ -131,8 +131,7 @@ get_auth_token <- function( ) invisible(NULL) } else { - # check_that(token, AzureAuth::is_azure_token, "Invalid token returned") - token + check_that(token, AzureAuth::is_azure_token, "Invalid token returned") } } diff --git a/R/get_container.R b/R/get_container.R index edc7331..4bbd257 100644 --- a/R/get_container.R +++ b/R/get_container.R @@ -1,43 +1,48 @@ #' Get Azure storage container #' -#' The environment variable "AZ_STORAGE_EP" must be set. This provides the URL +#' The environment variable "AZ_STORAGE_EP" should be set. This provides the URL #' for the default Azure storage endpoint. #' Use [list_container_names] to get a list of available container names. #' #' @param container_name Name of the container as a string. `NULL` by default, #' which means the function will look instead for a container name stored in #' the environment variable "AZ_CONTAINER" -#' @param ... arguments to be passed through to [get_auth_token] +#' @param token An Azure authentication token. If left as `NULL`, a token +#' returned by [get_auth_token] will be used +#' @param endpoint_url An Azure endpoint URL. If left as `NULL`, the default, +#' the value of the environment variable "AZ_STORAGE_EP" will be used +#' @param ... arguments to be passed through to [get_auth_token], if a token is +#' not already supplied #' @returns An Azure blob container (list object of class "blob_container") #' @export -get_container <- function(container_name = NULL, ...) { - msg <- glue::glue( +get_container <- function( + container_name = NULL, + token = NULL, + endpoint_url = NULL, + ... +) { + msg <- paste0( "{.var container_name} is empty. ", "Did you forget to set an environment variable?" ) - cont_nm <- check_nzchar(container_name, msg) %||% check_envvar("AZ_CONTAINER") - token <- get_auth_token(...) - endpoint <- get_default_endpoint(token) - container_names <- list_container_names(token) - not_found_msg <- ct_error_msg("Container {.val {cont_nm}} not found") - cont_nm |> - check_that(\(x) x %in% container_names, not_found_msg) |> - AzureStor::blob_container(endpoint = endpoint) + container_name <- (container_name %||% check_envvar("AZ_CONTAINER")) |> + check_nzchar(msg) + token <- token %||% get_auth_token(...) + + get_azure_endpoint(token, endpoint_url) |> + AzureStor::blob_container(container_name) } -#' Return a list of container names that are found at the default endpoint +#' Return a list of container names that are found at the endpoint #' #' @inheritParams get_container -#' @inheritParams get_default_endpoint #' @returns A character vector of all container names found #' @export -list_container_names <- function(token = NULL, ...) { +list_container_names <- function(token = NULL, endpoint_url = NULL, ...) { token <- token %||% get_auth_token(...) - endpoint <- get_default_endpoint(token) - lcn <- "list_container_names" # nolint - container_list <- AzureStor::list_blob_containers(endpoint) |> - rlang::try_fetch(error = \(e) cli::cli_abort("Error in {.fn {lcn}}: {e}")) + endpoint <- get_azure_endpoint(token, endpoint_url) + container_list <- AzureStor::list_blob_containers(endpoint) stopifnot("no containers found" = length(container_list) >= 1L) names(container_list) } @@ -45,12 +50,16 @@ list_container_names <- function(token = NULL, ...) { #' Return an Azure "blob_endpoint" #' -#' @param token An Azure authentication token +#' This function will return the endpoint specified in the environment variable +#' "AZ_STORAGE_EP" by default +#' +#' @inheritParams get_container #' @returns An Azure blob endpoint (object of class "blob_endpoint") #' @keywords internal -get_default_endpoint <- function(token) { - check_envvar("AZ_STORAGE_EP") |> - AzureStor::blob_endpoint(token = token) +get_azure_endpoint <- function(token = NULL, endpoint_url = NULL, ...) { + token <- token %||% get_auth_token(...) + endpoint_url <- endpoint_url %||% check_envvar("AZ_STORAGE_EP") + AzureStor::blob_endpoint(endpoint_url, token = token) } diff --git a/R/read_azure_files.R b/R/read_azure_files.R index 201ecda..b174e0d 100644 --- a/R/read_azure_files.R +++ b/R/read_azure_files.R @@ -129,7 +129,7 @@ check_blob_exists <- function(container, file, ext, info, path) { # though this usage pattern should be quite rare! dpath <- file.path(path, dir_name) fname <- basename(file) - if (nzchar(ext) & !gregg(fname, "\\.{ext}$")) { + if (nzchar(ext) && !gregg(fname, "\\.{ext}$")) { fname <- glue::glue("{fname}.{ext}") } # remove duplicate slashes and any initial slashes diff --git a/man/check_scalar_type.Rd b/man/check_scalar_type.Rd index ef9f097..7b44f15 100644 --- a/man/check_scalar_type.Rd +++ b/man/check_scalar_type.Rd @@ -15,7 +15,7 @@ check_scalar_type(x, type, message, pf = parent.frame()) user if the predicate check does not succeed. Can include \code{glue}d variables and \code{{cli}} semantic markup.} -\item{pf}{Set as \link{parent.frame} so variables in the caller environment can +\item{pf}{Set as \code{\link[=parent.frame]{parent.frame()}} so variables in the caller environment can be used in the custom error message.} } \description{ diff --git a/man/check_vec.Rd b/man/check_vec.Rd index ea4698b..4663939 100644 --- a/man/check_vec.Rd +++ b/man/check_vec.Rd @@ -30,7 +30,7 @@ predicate. "none" can be used to generate an inverse predicate, or the situation where success means that none of the elements of x satisfies the predicate. "some" is unlikely to be useful often, but it is available.} -\item{pf}{Set as \link{parent.frame} so variables in the caller environment can +\item{pf}{Set as \code{\link[=parent.frame]{parent.frame()}} so variables in the caller environment can be used in the custom error message.} } \description{ diff --git a/man/get_azure_endpoint.Rd b/man/get_azure_endpoint.Rd new file mode 100644 index 0000000..d1d4be7 --- /dev/null +++ b/man/get_azure_endpoint.Rd @@ -0,0 +1,26 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/get_container.R +\name{get_azure_endpoint} +\alias{get_azure_endpoint} +\title{Return an Azure "blob_endpoint"} +\usage{ +get_azure_endpoint(token = NULL, endpoint_url = NULL, ...) +} +\arguments{ +\item{token}{An Azure authentication token. If left as \code{NULL}, a token +returned by \link{get_auth_token} will be used} + +\item{endpoint_url}{An Azure endpoint URL. If left as \code{NULL}, the default, +the value of the environment variable "AZ_STORAGE_EP" will be used} + +\item{...}{arguments to be passed through to \link{get_auth_token}, if a token is +not already supplied} +} +\value{ +An Azure blob endpoint (object of class "blob_endpoint") +} +\description{ +This function will return the endpoint specified in the environment variable +"AZ_STORAGE_EP" by default +} +\keyword{internal} diff --git a/man/get_container.Rd b/man/get_container.Rd index 7fe762a..6e88a05 100644 --- a/man/get_container.Rd +++ b/man/get_container.Rd @@ -4,20 +4,27 @@ \alias{get_container} \title{Get Azure storage container} \usage{ -get_container(container_name = NULL, ...) +get_container(container_name = NULL, token = NULL, endpoint_url = NULL, ...) } \arguments{ \item{container_name}{Name of the container as a string. \code{NULL} by default, which means the function will look instead for a container name stored in the environment variable "AZ_CONTAINER"} -\item{...}{arguments to be passed through to \link{get_auth_token}} +\item{token}{An Azure authentication token. If left as \code{NULL}, a token +returned by \link{get_auth_token} will be used} + +\item{endpoint_url}{An Azure endpoint URL. If left as \code{NULL}, the default, +the value of the environment variable "AZ_STORAGE_EP" will be used} + +\item{...}{arguments to be passed through to \link{get_auth_token}, if a token is +not already supplied} } \value{ An Azure blob container (list object of class "blob_container") } \description{ -The environment variable "AZ_STORAGE_EP" must be set. This provides the URL +The environment variable "AZ_STORAGE_EP" should be set. This provides the URL for the default Azure storage endpoint. Use \link{list_container_names} to get a list of available container names. } diff --git a/man/get_default_endpoint.Rd b/man/get_default_endpoint.Rd deleted file mode 100644 index 7e76e8f..0000000 --- a/man/get_default_endpoint.Rd +++ /dev/null @@ -1,18 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/get_container.R -\name{get_default_endpoint} -\alias{get_default_endpoint} -\title{Return an Azure "blob_endpoint"} -\usage{ -get_default_endpoint(token) -} -\arguments{ -\item{token}{An Azure authentication token} -} -\value{ -An Azure blob endpoint (object of class "blob_endpoint") -} -\description{ -Return an Azure "blob_endpoint" -} -\keyword{internal} diff --git a/man/list_container_names.Rd b/man/list_container_names.Rd index 814b723..3587268 100644 --- a/man/list_container_names.Rd +++ b/man/list_container_names.Rd @@ -2,18 +2,23 @@ % Please edit documentation in R/get_container.R \name{list_container_names} \alias{list_container_names} -\title{Return a list of container names that are found at the default endpoint} +\title{Return a list of container names that are found at the endpoint} \usage{ -list_container_names(token = NULL, ...) +list_container_names(token = NULL, endpoint_url = NULL, ...) } \arguments{ -\item{token}{An Azure authentication token} +\item{token}{An Azure authentication token. If left as \code{NULL}, a token +returned by \link{get_auth_token} will be used} -\item{...}{arguments to be passed through to \code{\link[=get_auth_token]{get_auth_token()}}} +\item{endpoint_url}{An Azure endpoint URL. If left as \code{NULL}, the default, +the value of the environment variable "AZ_STORAGE_EP" will be used} + +\item{...}{arguments to be passed through to \link{get_auth_token}, if a token is +not already supplied} } \value{ A character vector of all container names found } \description{ -Return a list of container names that are found at the default endpoint +Return a list of container names that are found at the endpoint } diff --git a/man/read_azure_csv.Rd b/man/read_azure_csv.Rd index cccbb65..29f55ed 100644 --- a/man/read_azure_csv.Rd +++ b/man/read_azure_csv.Rd @@ -24,7 +24,7 @@ container) by default.} being read. Useful for checking the function is doing what is expected, but can be turned off with \code{FALSE}. Can be set persistently with the option "azkit.info". If \code{NULL} then it will default to the value of -\link[rlang:is_interactive]{rlang::is_interactive} (ie \code{TRUE} for interactive sessions).} +\link[rlang:is_interactive]{rlang::is_interactive} (that is, \code{TRUE} for interactive sessions).} \item{...}{optional arguments to be passed through to \link[readr:read_delim]{readr::read_delim}} } diff --git a/man/read_azure_file.Rd b/man/read_azure_file.Rd index 5cb50da..eaa51ea 100644 --- a/man/read_azure_file.Rd +++ b/man/read_azure_file.Rd @@ -24,7 +24,7 @@ container) by default.} being read. Useful for checking the function is doing what is expected, but can be turned off with \code{FALSE}. Can be set persistently with the option "azkit.info". If \code{NULL} then it will default to the value of -\link[rlang:is_interactive]{rlang::is_interactive} (ie \code{TRUE} for interactive sessions).} +\link[rlang:is_interactive]{rlang::is_interactive} (that is, \code{TRUE} for interactive sessions).} \item{ext}{If a custom extension needs to be supplied, you can specify it here. If \code{NULL}, the default, the extension of \code{file} will be used} diff --git a/man/read_azure_json.Rd b/man/read_azure_json.Rd index 1fe47d2..2df1630 100644 --- a/man/read_azure_json.Rd +++ b/man/read_azure_json.Rd @@ -24,7 +24,7 @@ container) by default.} being read. Useful for checking the function is doing what is expected, but can be turned off with \code{FALSE}. Can be set persistently with the option "azkit.info". If \code{NULL} then it will default to the value of -\link[rlang:is_interactive]{rlang::is_interactive} (ie \code{TRUE} for interactive sessions).} +\link[rlang:is_interactive]{rlang::is_interactive} (that is, \code{TRUE} for interactive sessions).} \item{...}{optional arguments to be passed through to \link[yyjsonr:read_json_raw]{yyjsonr::read_json_raw}} diff --git a/man/read_azure_jsongz.Rd b/man/read_azure_jsongz.Rd index a8e3bdc..b44a541 100644 --- a/man/read_azure_jsongz.Rd +++ b/man/read_azure_jsongz.Rd @@ -24,7 +24,7 @@ container) by default.} being read. Useful for checking the function is doing what is expected, but can be turned off with \code{FALSE}. Can be set persistently with the option "azkit.info". If \code{NULL} then it will default to the value of -\link[rlang:is_interactive]{rlang::is_interactive} (ie \code{TRUE} for interactive sessions).} +\link[rlang:is_interactive]{rlang::is_interactive} (that is, \code{TRUE} for interactive sessions).} \item{...}{optional arguments to be passed through to \link[yyjsonr:read_json_file]{yyjsonr::read_json_file}} diff --git a/man/read_azure_parquet.Rd b/man/read_azure_parquet.Rd index 39e6954..2bee797 100644 --- a/man/read_azure_parquet.Rd +++ b/man/read_azure_parquet.Rd @@ -24,7 +24,7 @@ container) by default.} being read. Useful for checking the function is doing what is expected, but can be turned off with \code{FALSE}. Can be set persistently with the option "azkit.info". If \code{NULL} then it will default to the value of -\link[rlang:is_interactive]{rlang::is_interactive} (ie \code{TRUE} for interactive sessions).} +\link[rlang:is_interactive]{rlang::is_interactive} (that is, \code{TRUE} for interactive sessions).} \item{...}{optional arguments to be passed through to \link[arrow:read_parquet]{arrow::read_parquet}} } diff --git a/man/read_azure_rds.Rd b/man/read_azure_rds.Rd index 7a6a5d3..c099418 100644 --- a/man/read_azure_rds.Rd +++ b/man/read_azure_rds.Rd @@ -24,7 +24,7 @@ container) by default.} being read. Useful for checking the function is doing what is expected, but can be turned off with \code{FALSE}. Can be set persistently with the option "azkit.info". If \code{NULL} then it will default to the value of -\link[rlang:is_interactive]{rlang::is_interactive} (ie \code{TRUE} for interactive sessions).} +\link[rlang:is_interactive]{rlang::is_interactive} (that is, \code{TRUE} for interactive sessions).} } \value{ Data object that was stored in the rds file