From 83d5d0b3c83c5ed365ef32a9e21ce269a52bf698 Mon Sep 17 00:00:00 2001 From: florisvdh Date: Fri, 5 Jan 2024 20:16:21 +0100 Subject: [PATCH 01/11] Import assertthat::noNA() --- NAMESPACE | 1 + R/qgisprocess-package.R | 1 + 2 files changed, 2 insertions(+) diff --git a/NAMESPACE b/NAMESPACE index 74b9307a..a3eff4ae 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -122,6 +122,7 @@ importFrom(assertthat,assert_that) importFrom(assertthat,is.flag) importFrom(assertthat,is.number) importFrom(assertthat,is.string) +importFrom(assertthat,noNA) importFrom(glue,glue) importFrom(rlang,"%||%") importFrom(rlang,abort) diff --git a/R/qgisprocess-package.R b/R/qgisprocess-package.R index e88ce7d5..cd59007e 100644 --- a/R/qgisprocess-package.R +++ b/R/qgisprocess-package.R @@ -13,6 +13,7 @@ #' @importFrom assertthat #' assert_that #' is.flag +#' noNA #' is.string #' is.number ## usethis namespace: end From 9d2b6113c5260491a0e880ef1a9b42a6c58755d9 Mon Sep 17 00:00:00 2001 From: florisvdh Date: Fri, 5 Jan 2024 20:50:59 +0100 Subject: [PATCH 02/11] assert_qgis_algorithm(): warn if alg is deprecated (closes #194) --- R/qgis-algorithms.R | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/R/qgis-algorithms.R b/R/qgis-algorithms.R index 206fb7ee..99d7944f 100644 --- a/R/qgis-algorithms.R +++ b/R/qgis-algorithms.R @@ -70,10 +70,29 @@ assert_qgis_algorithm <- function(algorithm) { ) } + check_algorithm_deprecation(algorithm) + invisible(algorithm) } +#' @keywords internal +check_algorithm_deprecation <- function(algorithm) { + algs <- qgis_algorithms() + if ("deprecated" %in% colnames(algs)) { + deprecated_algs <- algs$algorithm[algs$deprecated] + if (algorithm %in% deprecated_algs) { + warning( + glue( + "Algorithm '{ algorithm }' is deprecated and may be removed in a later ", + "QGIS version!\nCurrently using QGIS { qgis_version() }." + ), + call. = FALSE + ) + } + } +} + #' @keywords internal qgis_query_algorithms <- function(quiet = FALSE) { From 0739f44b909e37ca9643599dc5945eeac0d82ca5 Mon Sep 17 00:00:00 2001 From: florisvdh Date: Fri, 5 Jan 2024 20:52:10 +0100 Subject: [PATCH 03/11] qgis-help.R: also warn for deprecated alg with cached help --- R/qgis-help.R | 2 ++ 1 file changed, 2 insertions(+) diff --git a/R/qgis-help.R b/R/qgis-help.R index 3865eced..737cfef3 100644 --- a/R/qgis-help.R +++ b/R/qgis-help.R @@ -94,6 +94,7 @@ qgis_get_output_specs <- function(algorithm) { qgis_help_json <- function(algorithm) { cached <- help_cache_file(algorithm, json = TRUE) if (qgis_using_cached_help() && file.exists(cached)) { + check_algorithm_deprecation(algorithm) try(return(jsonlite::fromJSON(readRDS(cached)))) } @@ -116,6 +117,7 @@ qgis_help_json <- function(algorithm) { qgis_help_text <- function(algorithm) { cached <- help_cache_file(algorithm, json = FALSE) if (qgis_using_cached_help() && file.exists(cached)) { + check_algorithm_deprecation(algorithm) try(return(readRDS(cached))) } From 2b85a22c7dcb47a35b91b74f2ea1cfcb7e8a981a Mon Sep 17 00:00:00 2001 From: florisvdh Date: Fri, 5 Jan 2024 20:56:25 +0100 Subject: [PATCH 04/11] qgis_{algorithms,providers}: add argument include_deprecated * Default is TRUE; does not affect cached value of qgis_algorithms(). --- R/qgis-algorithms.R | 32 ++++++++++++++++++++++++++++---- man/qgis_algorithms.Rd | 12 ++++++++++-- 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/R/qgis-algorithms.R b/R/qgis-algorithms.R index 99d7944f..04abf47b 100644 --- a/R/qgis-algorithms.R +++ b/R/qgis-algorithms.R @@ -7,6 +7,10 @@ #' for a detailed description of the algorithms provided #' 'out of the box' on QGIS. #' +#' The `include_deprecated` argument in `qgis_algorithms()` does not affect the +#' cached value. The latter always includes deprecated algorithms if these are +#' returned by 'qgis_process' (this requires the JSON output method). +#' #' @family topics about information on algorithms & processing providers #' @family topics about reporting the QGIS state #' @concept functions to manage and explore QGIS and qgisprocess @@ -16,6 +20,7 @@ #' status in QGIS (enabled or disabled). #' Must be one of: `"all"`, `"enabled"`, `"disabled"`. #' @param ... Only used by other functions calling this function. +#' @param include_deprecated Logical. Should deprecated algorithms be included? #' @inheritParams qgis_path #' #' @returns @@ -25,11 +30,18 @@ #' #' @examplesIf has_qgis() #' qgis_algorithms() +#' qgis_algorithms(include_deprecated = FALSE) #' qgis_providers() #' qgis_plugins(quiet = FALSE) #' qgis_plugins(which = "disabled") #' -qgis_algorithms <- function(query = FALSE, quiet = TRUE) { +qgis_algorithms <- function( + query = FALSE, + quiet = TRUE, + include_deprecated = TRUE) { + assert_that(is.flag(query), noNA(query)) + assert_that(is.flag(quiet), noNA(quiet)) + assert_that(is.flag(include_deprecated), noNA(include_deprecated)) if (query) { qgisprocess_cache$algorithms <- qgis_query_algorithms(quiet = quiet) } @@ -38,13 +50,25 @@ qgis_algorithms <- function(query = FALSE, quiet = TRUE) { "access to { nrow(qgisprocess_cache$algorithms) } algorithms ", "from { nrow(qgis_providers()) } QGIS processing providers." )) - qgisprocess_cache$algorithms + algs <- qgisprocess_cache$algorithms + if (!include_deprecated && "deprecated" %in% colnames(algs)) { + algs[!algs$deprecated, ] + } else { + algs + } } #' @rdname qgis_algorithms #' @export -qgis_providers <- function(query = FALSE, quiet = TRUE) { - algs <- qgis_algorithms(query = query, quiet = quiet) +qgis_providers <- function( + query = FALSE, + quiet = TRUE, + include_deprecated = TRUE) { + algs <- qgis_algorithms( + query = query, + quiet = quiet, + include_deprecated = include_deprecated + ) counted <- stats::aggregate( algs[[1]], by = list(algs$provider, algs$provider_title), diff --git a/man/qgis_algorithms.Rd b/man/qgis_algorithms.Rd index ce969e59..65cdb91a 100644 --- a/man/qgis_algorithms.Rd +++ b/man/qgis_algorithms.Rd @@ -6,9 +6,9 @@ \alias{qgis_plugins} \title{List algorithms, processing providers or plugins} \usage{ -qgis_algorithms(query = FALSE, quiet = TRUE) +qgis_algorithms(query = FALSE, quiet = TRUE, include_deprecated = TRUE) -qgis_providers(query = FALSE, quiet = TRUE) +qgis_providers(query = FALSE, quiet = TRUE, include_deprecated = TRUE) qgis_plugins(which = "all", query = FALSE, quiet = TRUE, ...) } @@ -18,6 +18,8 @@ qgis_plugins(which = "all", query = FALSE, quiet = TRUE, ...) \item{quiet}{Use \code{FALSE} to display more information, possibly useful for debugging.} +\item{include_deprecated}{Logical. Should deprecated algorithms be included?} + \item{which}{String defining which plugins to select, based on their status in QGIS (enabled or disabled). Must be one of: \code{"all"}, \code{"enabled"}, \code{"disabled"}.} @@ -35,9 +37,15 @@ See the \href{https://docs.qgis.org/latest/en/docs/user_manual/processing_algs/q for a detailed description of the algorithms provided 'out of the box' on QGIS. } +\details{ +The \code{include_deprecated} argument in \code{qgis_algorithms()} does not affect the +cached value. The latter always includes deprecated algorithms if these are +returned by 'qgis_process' (this requires the JSON output method). +} \examples{ \dontshow{if (has_qgis()) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf} qgis_algorithms() +qgis_algorithms(include_deprecated = FALSE) qgis_providers() qgis_plugins(quiet = FALSE) qgis_plugins(which = "disabled") From 09ca48ad6ce6a90913f7f1e375e1eafff3af5e44 Mon Sep 17 00:00:00 2001 From: florisvdh Date: Fri, 5 Jan 2024 20:59:06 +0100 Subject: [PATCH 05/11] qgis_search_algorithms(): don't return deprecated algs by default --- R/qgis-algorithms.R | 10 ++++++++-- man/qgis_search_algorithms.Rd | 9 ++++++++- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/R/qgis-algorithms.R b/R/qgis-algorithms.R index 04abf47b..a2d75590 100644 --- a/R/qgis-algorithms.R +++ b/R/qgis-algorithms.R @@ -271,6 +271,7 @@ qgis_query_algorithms <- function(quiet = FALSE) { #' `provider_title` value from the output of [qgis_algorithms()]. #' @param group Regular expression to match the `group` value #' from the output of [qgis_algorithms()]. +#' @inheritParams qgis_algorithms #' #' @returns A tibble. #' @@ -284,12 +285,17 @@ qgis_query_algorithms <- function(quiet = FALSE) { qgis_search_algorithms <- function( algorithm = NULL, provider = NULL, - group = NULL) { + group = NULL, + include_deprecated = FALSE) { assert_that( !is.null(algorithm) || !is.null(provider) || !is.null(group), msg = "You must provide at least one of the arguments." ) - result <- qgis_algorithms(query = FALSE, quiet = TRUE) + result <- qgis_algorithms( + query = FALSE, + quiet = TRUE, + include_deprecated = include_deprecated + ) assert_that(inherits(result, "data.frame")) assert_that( nrow(result) > 0L, diff --git a/man/qgis_search_algorithms.Rd b/man/qgis_search_algorithms.Rd index e22efa98..d415478d 100644 --- a/man/qgis_search_algorithms.Rd +++ b/man/qgis_search_algorithms.Rd @@ -4,7 +4,12 @@ \alias{qgis_search_algorithms} \title{Search geoprocessing algorithms} \usage{ -qgis_search_algorithms(algorithm = NULL, provider = NULL, group = NULL) +qgis_search_algorithms( + algorithm = NULL, + provider = NULL, + group = NULL, + include_deprecated = FALSE +) } \arguments{ \item{algorithm}{Regular expression to match the \code{algorithm} or @@ -15,6 +20,8 @@ qgis_search_algorithms(algorithm = NULL, provider = NULL, group = NULL) \item{group}{Regular expression to match the \code{group} value from the output of \code{\link[=qgis_algorithms]{qgis_algorithms()}}.} + +\item{include_deprecated}{Logical. Should deprecated algorithms be included?} } \value{ A tibble. From d802fb3a2835b3421b3bb4ca07fd2a458101b4a0 Mon Sep 17 00:00:00 2001 From: florisvdh Date: Sat, 6 Jan 2024 12:13:14 +0100 Subject: [PATCH 06/11] test-qgis-algorithms.R: cosmetic update --- tests/testthat/test-qgis-algorithms.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/testthat/test-qgis-algorithms.R b/tests/testthat/test-qgis-algorithms.R index 15b2b5d2..91e28102 100644 --- a/tests/testthat/test-qgis-algorithms.R +++ b/tests/testthat/test-qgis-algorithms.R @@ -23,7 +23,7 @@ test_that("qgis_providers() works", { ) }) -test_that("assert_qgis_algorithm() works", { +test_that("Internal function assert_qgis_algorithm() works", { skip_if_not(has_qgis()) expect_error(assert_qgis_algorithm("notanalgorithm")) expect_identical(assert_qgis_algorithm("native:filedownloader"), "native:filedownloader") From c49cb07859c5635abe1eb557673f318c01711e5e Mon Sep 17 00:00:00 2001 From: florisvdh Date: Sat, 6 Jan 2024 12:14:12 +0100 Subject: [PATCH 07/11] test-qgis-algorithms.R: add test for check_algorithm_deprecation() --- tests/testthat/test-qgis-algorithms.R | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/testthat/test-qgis-algorithms.R b/tests/testthat/test-qgis-algorithms.R index 91e28102..bdc5ac16 100644 --- a/tests/testthat/test-qgis-algorithms.R +++ b/tests/testthat/test-qgis-algorithms.R @@ -29,6 +29,22 @@ test_that("Internal function assert_qgis_algorithm() works", { expect_identical(assert_qgis_algorithm("native:filedownloader"), "native:filedownloader") }) +test_that("Internal function check_algorithm_deprecation() works", { + skip_if_not(has_qgis()) + algs <- qgis_algorithms() + skip_if_not( + "deprecated" %in% colnames(algs) && sum(algs$deprecated) > 0, + paste( + "There are no deprecated algorithms available.", + "Unless using no-JSON output, rewrite this test to simulate deprecated algorithms." + ) + ) + alg_deprecated <- sample(algs$algorithm[algs$deprecated], 1) + alg_non_deprecated <- sample(algs$algorithm[!algs$deprecated], 1) + expect_warning(check_algorithm_deprecation(alg_deprecated)) + expect_no_warning(check_algorithm_deprecation(alg_non_deprecated)) +}) + test_that("qgis_search_algorithms() works", { skip_if_not(has_qgis()) expect_error(qgis_search_algorithms(), "at least one of the arguments") From a22c3d03b36b94f78852681798eedde27ccdfd50 Mon Sep 17 00:00:00 2001 From: florisvdh Date: Sat, 6 Jan 2024 12:14:51 +0100 Subject: [PATCH 08/11] test-qgis-algorithms.R: extend qgis_algorithms() test wrt deprecation --- tests/testthat/test-qgis-algorithms.R | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/testthat/test-qgis-algorithms.R b/tests/testthat/test-qgis-algorithms.R index bdc5ac16..73535773 100644 --- a/tests/testthat/test-qgis-algorithms.R +++ b/tests/testthat/test-qgis-algorithms.R @@ -4,6 +4,7 @@ test_that("qgis_algorithms() works", { expect_true(tibble::is_tibble(algs)) expect_gt(nrow(algs), 200) expect_gt(ncol(algs), 20) + expect_gte(nrow(algs), nrow(qgis_algorithms(include_deprecated = FALSE))) old_names <- c( "provider", "provider_title", "algorithm", "algorithm_id", "algorithm_title" From 68731689f257efa872e88afe7f6bcd91b173ceee Mon Sep 17 00:00:00 2001 From: florisvdh Date: Sat, 6 Jan 2024 12:15:08 +0100 Subject: [PATCH 09/11] test-qgis-algorithms.R: extend qgis_search_algorithms() test wrt deprecation --- tests/testthat/test-qgis-algorithms.R | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/testthat/test-qgis-algorithms.R b/tests/testthat/test-qgis-algorithms.R index 73535773..31bdcae1 100644 --- a/tests/testthat/test-qgis-algorithms.R +++ b/tests/testthat/test-qgis-algorithms.R @@ -63,4 +63,7 @@ test_that("qgis_search_algorithms() works", { expect_gt(nrow(res1), 0L) res2 <- qgis_search_algorithms(algorithm = "point.*line") expect_gt(nrow(res2), nrow(res1)) + res3 <- qgis_search_algorithms(algorithm = "raster") + res4 <- qgis_search_algorithms(algorithm = "raster", include_deprecated = TRUE) + expect_gte(nrow(res4), nrow(res3)) }) From 92583469b0766f216599275de2797ee3f308e118 Mon Sep 17 00:00:00 2001 From: florisvdh Date: Sat, 6 Jan 2024 13:25:31 +0100 Subject: [PATCH 10/11] Update NEWS.md --- NEWS.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/NEWS.md b/NEWS.md index b0d5631d..d6a490c9 100644 --- a/NEWS.md +++ b/NEWS.md @@ -2,6 +2,11 @@ - More consistent and intuitive handling of JSON input / output user settings (#195, #196; see `?qgis_using_json_output`). - Fix bug in support for environment variable `R_QGISPROCESS_DETECT_NEWER_QGIS` (#197). +- QGIS or third-party providers can expose deprecated algorithms that may be removed from future versions. +`{qgisprocess}` now handles these algorithms explicitly (#198): + - `qgis_run_algorithm()` and other functions (such as `qgis_show_help()` and `qgis_get_description()`) will warn if a deprecated algorithm is passed (feature request #194; original issue #193). + - `qgis_search_algorithms()` now **excludes** deprecated algorithms by default; they can still be included by setting the `include_deprecated` argument to `TRUE`. + - `qgis_algorithms()` can _optionally_ restrict its results to non-deprecated algorithms (set the `include_deprecated` argument to `FALSE`). By default they are included, just as before. # qgisprocess 0.2.0 From d32d03bad9a9811bd64efdc69bdff4fa26466828 Mon Sep 17 00:00:00 2001 From: florisvdh Date: Sat, 6 Jan 2024 13:26:10 +0100 Subject: [PATCH 11/11] DESCRIPTION: bump dev version number --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 568ea1b8..5c73596d 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: qgisprocess Title: Use 'QGIS' Processing Algorithms -Version: 0.2.0.9002 +Version: 0.2.0.9003 Authors@R: c( person("Dewey", "Dunnington", , "dewey@fishandwhistle.net", role = "aut", comment = c(ORCID = "0000-0002-9415-4582", affiliation = "Voltron Data")),