From 36803489ec7fbb4ca1a54f67431ea68d06750a9f Mon Sep 17 00:00:00 2001 From: eitsupi Date: Sun, 22 Sep 2024 05:15:39 +0000 Subject: [PATCH] chore: temporary revert lib update for test --- DESCRIPTION | 5 +- NEWS.md | 8 --- R/000-wrappers.R | 4 +- R/compile.R | 28 ++++------ R/knitr-engine.R | 4 +- man/prql_compile.Rd | 24 ++++----- src/init.c | 6 +-- src/rust/Cargo.lock | 3 +- src/rust/Cargo.toml | 3 +- src/rust/api.h | 2 +- src/rust/src/lib.rs | 89 ++++++++++++++++++-------------- tests/testthat/_snaps/compile.md | 53 +++++++------------ tests/testthat/test-compile.R | 30 +++-------- tools/lib-sums.tsv | 6 +++ 14 files changed, 113 insertions(+), 152 deletions(-) create mode 100644 tools/lib-sums.tsv diff --git a/DESCRIPTION b/DESCRIPTION index 0d36c9a7..ac36e7e5 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -25,8 +25,7 @@ Suggests: dplyr, testthat (>= 3.2.0), patrick, - withr, - cli + withr License: MIT + file LICENSE Language: en-US Encoding: UTF-8 @@ -48,4 +47,4 @@ Config/Needs/dev: rhub Config/Needs/website: pkgdown -Config/prqlr/LibVersion: 0.13.1 +Config/prqlr/LibVersion: 0.13.0 diff --git a/NEWS.md b/NEWS.md index 429814a3..e33c7d2b 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,13 +1,5 @@ # prqlr (development version) -## Breaking changes - -- For the `prql_compile()` funtion, arguments `format` and `singnature_comment` should be named arguments. (#317) - -## New features - -- New experimental argument `display` of `prql_compile()` function to colorize the error message from prqlc. (#317) - # prqlr 0.9.0 ## Breaking changes diff --git a/R/000-wrappers.R b/R/000-wrappers.R index cdec6955..a17fd144 100644 --- a/R/000-wrappers.R +++ b/R/000-wrappers.R @@ -30,8 +30,8 @@ NULL #' @param signature_comment a logical flag. Whether to add a signature comment to the output SQL query. #' @return a list contains a SQL string or an error message. #' @noRd -`compile` <- function(`prql_query`, `target`, `format`, `signature_comment`, `display`) { - .Call(savvy_compile__impl, `prql_query`, `target`, `format`, `signature_comment`, `display`) +`compile` <- function(`prql_query`, `target`, `format`, `signature_comment`) { + .Call(savvy_compile__impl, `prql_query`, `target`, `format`, `signature_comment`) } #' @noRd diff --git a/R/compile.R b/R/compile.R index f0d73ead..c673f9b8 100644 --- a/R/compile.R +++ b/R/compile.R @@ -1,15 +1,13 @@ #' @title Compile a PRQL query into a SQL query -#' @param prql_query A character of PRQL query. -#' @param target A character of the target name to use or `NULL`. -#' If `NULL`, the target contained in the query will be used. -#' All available target names can be listed with the [prql_get_targets()] function. -#' @param ... Ignored. -#' @param format A logical flag (default: `TRUE`). Whether to format the SQL query. +#' @param prql_query a PRQL query string. +#' @param target a compile target name to use. If not specified (`NULL`), +#' the target contained in the query will be used. +#' All available target names can be listed with the [prql_get_targets] function. +#' @param format a logical flag (default: `TRUE`). Whether to format the SQL query. #' @param signature_comment a logical flag. (default: `TRUE`). #' Whether to add a signature comment to the output SQL query. -#' @param display A character, one of `"plain"` (default) or `"ansi_color"`. -#' If `"ansi_color"`, error will be displayed with ANSI color. -#' @return A character of the compiled SQL query. +#' @return a SQL query string +#' @seealso [prql_get_targets] #' @examples #' "from mtcars | filter cyl > 6 | select {cyl, mpg}" |> #' prql_compile() @@ -40,17 +38,9 @@ prql_compile <- function( prql_query, target = getOption("prqlr.target", default = NULL), - ..., format = getOption("prqlr.format", default = TRUE), - signature_comment = getOption("prqlr.signature_comment", default = TRUE), - display = getOption("prqlr.display", default = "plain")) { - compile( - prql_query, - target = target %||% "sql.any", - format = format, - signature_comment = signature_comment, - display = display - ) + signature_comment = getOption("prqlr.signature_comment", default = TRUE)) { + compile(prql_query, target %||% "sql.any", format, signature_comment) } #' @title prqlc's version diff --git a/R/knitr-engine.R b/R/knitr-engine.R index 2c1202f3..30594afc 100644 --- a/R/knitr-engine.R +++ b/R/knitr-engine.R @@ -1,4 +1,3 @@ -# TODO: support the `error=TRUE` option and support `ansi_color`ed error message with the `cli` package. #' @title PRQL knitr engine #' @description #' If options$connection is NULL, the output is SQL query. @@ -28,8 +27,7 @@ eng_prql <- function(options) { prql_compile( target = options$engine.opts[["target"]] %||% getOption("prqlr.target"), format = TRUE, - signature_comment = options$engine.opts[["signature_comment"]] %||% getOption("prqlr.signature_comment", TRUE), - display = "plain" + signature_comment = options$engine.opts[["signature_comment"]] %||% getOption("prqlr.signature_comment", TRUE) ) # Prints a SQL code block if there is no connection diff --git a/man/prql_compile.Rd b/man/prql_compile.Rd index 781b37f3..70f79f47 100644 --- a/man/prql_compile.Rd +++ b/man/prql_compile.Rd @@ -7,31 +7,24 @@ prql_compile( prql_query, target = getOption("prqlr.target", default = NULL), - ..., format = getOption("prqlr.format", default = TRUE), - signature_comment = getOption("prqlr.signature_comment", default = TRUE), - display = getOption("prqlr.display", default = "plain") + signature_comment = getOption("prqlr.signature_comment", default = TRUE) ) } \arguments{ -\item{prql_query}{A character of PRQL query.} +\item{prql_query}{a PRQL query string.} -\item{target}{A character of the target name to use or \code{NULL}. -If \code{NULL}, the target contained in the query will be used. -All available target names can be listed with the \code{\link[=prql_get_targets]{prql_get_targets()}} function.} +\item{target}{a compile target name to use. If not specified (\code{NULL}), +the target contained in the query will be used. +All available target names can be listed with the \link{prql_get_targets} function.} -\item{...}{Ignored.} - -\item{format}{A logical flag (default: \code{TRUE}). Whether to format the SQL query.} +\item{format}{a logical flag (default: \code{TRUE}). Whether to format the SQL query.} \item{signature_comment}{a logical flag. (default: \code{TRUE}). Whether to add a signature comment to the output SQL query.} - -\item{display}{A character, one of \code{"plain"} (default) or \code{"ansi_color"}. -If \code{"ansi_color"}, error will be displayed with ANSI color.} } \value{ -A character of the compiled SQL query. +a SQL query string } \description{ Compile a PRQL query into a SQL query @@ -63,3 +56,6 @@ select !{cyl} prql_compile() |> cat() } +\seealso{ +\link{prql_get_targets} +} diff --git a/src/init.c b/src/init.c index 62b7e140..d776e1d1 100644 --- a/src/init.c +++ b/src/init.c @@ -34,8 +34,8 @@ SEXP handle_result(SEXP res_) { return (SEXP)res; } -SEXP savvy_compile__impl(SEXP c_arg__prql_query, SEXP c_arg__target, SEXP c_arg__format, SEXP c_arg__signature_comment, SEXP c_arg__display) { - SEXP res = savvy_compile__ffi(c_arg__prql_query, c_arg__target, c_arg__format, c_arg__signature_comment, c_arg__display); +SEXP savvy_compile__impl(SEXP c_arg__prql_query, SEXP c_arg__target, SEXP c_arg__format, SEXP c_arg__signature_comment) { + SEXP res = savvy_compile__ffi(c_arg__prql_query, c_arg__target, c_arg__format, c_arg__signature_comment); return handle_result(res); } @@ -66,7 +66,7 @@ SEXP savvy_prql_get_targets__impl(void) { static const R_CallMethodDef CallEntries[] = { - {"savvy_compile__impl", (DL_FUNC) &savvy_compile__impl, 5}, + {"savvy_compile__impl", (DL_FUNC) &savvy_compile__impl, 4}, {"savvy_prql_to_pl__impl", (DL_FUNC) &savvy_prql_to_pl__impl, 1}, {"savvy_pl_to_rq__impl", (DL_FUNC) &savvy_pl_to_rq__impl, 1}, {"savvy_rq_to_sql__impl", (DL_FUNC) &savvy_rq_to_sql__impl, 1}, diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index 93447471..fb52d08a 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -401,8 +401,9 @@ dependencies = [ [[package]] name = "prqlr" -version = "0.13.1" +version = "0.13.0" dependencies = [ + "anstream", "prqlc", "savvy", ] diff --git a/src/rust/Cargo.toml b/src/rust/Cargo.toml index 47b2e47e..015a0a25 100644 --- a/src/rust/Cargo.toml +++ b/src/rust/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "prqlr" -version = "0.13.1" +version = "0.13.0" edition = "2021" rust-version = "1.69" publish = false @@ -15,3 +15,4 @@ savvy = "0.6.8" # prqlc 0.13.0 is not compatible with Rust 1.69.0, so a slightly modified version is installed # See https://github.com/PRQL/prql/pull/4916 prqlc = { git = "https://github.com/PRQL/prql", rev = "c7bd7a6fc73040394ffbbd85cea2ed6f986fd9dd", default-features = false } +anstream = { version = "0", features = ["auto"] } diff --git a/src/rust/api.h b/src/rust/api.h index 487d6d4b..8e5b6173 100644 --- a/src/rust/api.h +++ b/src/rust/api.h @@ -1,4 +1,4 @@ -SEXP savvy_compile__ffi(SEXP c_arg__prql_query, SEXP c_arg__target, SEXP c_arg__format, SEXP c_arg__signature_comment, SEXP c_arg__display); +SEXP savvy_compile__ffi(SEXP c_arg__prql_query, SEXP c_arg__target, SEXP c_arg__format, SEXP c_arg__signature_comment); SEXP savvy_prql_to_pl__ffi(SEXP c_arg__prql_query); SEXP savvy_pl_to_rq__ffi(SEXP c_arg__pl_json); SEXP savvy_rq_to_sql__ffi(SEXP c_arg__rq_json); diff --git a/src/rust/src/lib.rs b/src/rust/src/lib.rs index 95bf996f..a9d796b5 100644 --- a/src/rust/src/lib.rs +++ b/src/rust/src/lib.rs @@ -1,5 +1,5 @@ -use prqlc::ErrorMessages; -use savvy::{savvy, Result, Sexp}; +use anstream::ColorChoice; +use savvy::{savvy, Sexp}; use std::str::FromStr; /// @title Compile a PRQL query into a SQL query @@ -15,83 +15,96 @@ pub fn compile( target: &str, format: bool, signature_comment: bool, - display: &str, -) -> Result { +) -> savvy::Result { let options = convert_options(CompileOptions { format, target: target.to_string(), signature_comment, - display: display.to_string(), - }) - .map_err(|e| e.to_string())?; + }); + + let result = options + .and_then(|opts| { + Ok(prql_query) + .and_then(prqlc::prql_to_pl) + .and_then(prqlc::pl_to_rq) + .and_then(|rq| prqlc::rq_to_sql(rq, &opts)) + }) + .map_err(|e| e.composed(&prql_query.into())); + + ColorChoice::write_global(self::ColorChoice::Never); - prqlc::compile(prql_query, &options) - .map_err(|e| e.to_string().into()) - .and_then(|x| x.try_into()) + match result { + Ok(msg) => msg.try_into(), + Err(e) => Err(e.to_string().into()), + } } struct CompileOptions { format: bool, target: String, signature_comment: bool, - display: String, } -fn convert_options(o: CompileOptions) -> core::result::Result { - let target = prqlc::Target::from_str(&o.target).map_err(ErrorMessages::from)?; - let display = prqlc::DisplayOptions::from_str(&o.display).map_err(|_| ErrorMessages { - inner: vec![prqlc::Error::new_simple(format!( - "`display` must be one of `plain` or `ansi_color`. got: {}", - &o.display - )) - .into()], - })?; +fn convert_options( + o: CompileOptions, +) -> core::result::Result { + let target = prqlc::Target::from_str(&o.target).map_err(prqlc::ErrorMessages::from)?; + // TODO: support `display` option Ok(prqlc::Options { format: o.format, target, signature_comment: o.signature_comment, color: false, - display, + ..std::default::Default::default() }) } /// @noRd #[savvy] -pub fn prql_to_pl(prql_query: &str) -> Result { - Ok(prql_query) +pub fn prql_to_pl(prql_query: &str) -> savvy::Result { + let result = Ok(prql_query) .and_then(prqlc::prql_to_pl) - .and_then(|x| prqlc::json::from_pl(&x)) - .map_err(|e| e.to_string().into()) - .and_then(|x| x.try_into()) + .and_then(|x| prqlc::json::from_pl(&x)); + + match result { + Ok(msg) => msg.try_into(), + Err(e) => Err(e.to_string().into()), + } } /// @noRd #[savvy] -pub fn pl_to_rq(pl_json: &str) -> Result { - Ok(pl_json) +pub fn pl_to_rq(pl_json: &str) -> savvy::Result { + let result = Ok(pl_json) .and_then(prqlc::json::to_pl) .and_then(prqlc::pl_to_rq) - .and_then(|x| prqlc::json::from_rq(&x)) - .map_err(|e| e.to_string().into()) - .and_then(|x| x.try_into()) + .and_then(|x| prqlc::json::from_rq(&x)); + + match result { + Ok(msg) => msg.try_into(), + Err(e) => Err(e.to_string().into()), + } } /// @noRd #[savvy] -pub fn rq_to_sql(rq_json: &str) -> Result { - Ok(rq_json) +pub fn rq_to_sql(rq_json: &str) -> savvy::Result { + let result = Ok(rq_json) .and_then(prqlc::json::to_rq) - .and_then(|x| prqlc::rq_to_sql(x, &prqlc::Options::default())) - .map_err(|e| e.to_string().into()) - .and_then(|x| x.try_into()) + .and_then(|x| prqlc::rq_to_sql(x, &prqlc::Options::default())); + + match result { + Ok(msg) => msg.try_into(), + Err(e) => Err(e.to_string().into()), + } } /// @title prqlc's version /// @return a prqlc's version string /// @noRd #[savvy] -pub fn compiler_version() -> Result { +pub fn compiler_version() -> savvy::Result { prqlc::COMPILER_VERSION.to_string().try_into() } @@ -102,6 +115,6 @@ pub fn compiler_version() -> Result { /// prql_get_targets() /// @export #[savvy] -pub fn prql_get_targets() -> Result { +pub fn prql_get_targets() -> savvy::Result { prqlc::Target::names().try_into() } diff --git a/tests/testthat/_snaps/compile.md b/tests/testthat/_snaps/compile.md index 9e60a499..44ee73c6 100644 --- a/tests/testthat/_snaps/compile.md +++ b/tests/testthat/_snaps/compile.md @@ -13,17 +13,16 @@ --- Code - cat(prql_compile("from a | select {b}", target = NULL, format = FALSE, - signature_comment = FALSE)) + cat(prql_compile("from a | select {b}", NULL, FALSE, FALSE)) Output SELECT b FROM a --- Code - cat(prql_compile( + cat(compile( "from star_wars\n select {star_wars.*}\n select !{jar_jar_binks, midichlorians}", - "sql.duckdb", format = TRUE, signature_comment = TRUE)) + "sql.duckdb", TRUE, TRUE)) Output SELECT * EXCLUDE (jar_jar_binks, midichlorians) @@ -35,7 +34,7 @@ # Syntax error query=Mississippi has four S’s and four I’s. Code - cat(prql_compile(query, "sql.any", format = TRUE, signature_comment = FALSE)) + cat(prql_compile(query, "sql.any", TRUE, FALSE)) Condition Error: ! Error: @@ -63,7 +62,7 @@ # Syntax error query=from a | select [b] Code - cat(prql_compile(query, "sql.any", format = TRUE, signature_comment = FALSE)) + cat(prql_compile(query, "sql.any", TRUE, FALSE)) Condition Error: ! Error: @@ -77,7 +76,7 @@ # Syntax error query=from a | select {{{b Code - cat(prql_compile(query, "sql.any", format = TRUE, signature_comment = FALSE)) + cat(prql_compile(query, "sql.any", TRUE, FALSE)) Condition Error: ! Error: @@ -91,7 +90,7 @@ # Targets target=sql.any Code - cat(prql_compile(query, target, format = TRUE, signature_comment = FALSE)) + cat(prql_compile(query, target, TRUE, FALSE)) Output SELECT origin, @@ -115,7 +114,7 @@ # Targets target=sql.ansi Code - cat(prql_compile(query, target, format = TRUE, signature_comment = FALSE)) + cat(prql_compile(query, target, TRUE, FALSE)) Output SELECT origin, @@ -139,7 +138,7 @@ # Targets target=sql.bigquery Code - cat(prql_compile(query, target, format = TRUE, signature_comment = FALSE)) + cat(prql_compile(query, target, TRUE, FALSE)) Output SELECT origin, @@ -163,7 +162,7 @@ # Targets target=sql.clickhouse Code - cat(prql_compile(query, target, format = TRUE, signature_comment = FALSE)) + cat(prql_compile(query, target, TRUE, FALSE)) Output SELECT origin, @@ -187,7 +186,7 @@ # Targets target=sql.duckdb Code - cat(prql_compile(query, target, format = TRUE, signature_comment = FALSE)) + cat(prql_compile(query, target, TRUE, FALSE)) Output SELECT origin, @@ -211,7 +210,7 @@ # Targets target=sql.generic Code - cat(prql_compile(query, target, format = TRUE, signature_comment = FALSE)) + cat(prql_compile(query, target, TRUE, FALSE)) Output SELECT origin, @@ -235,7 +234,7 @@ # Targets target=sql.glaredb Code - cat(prql_compile(query, target, format = TRUE, signature_comment = FALSE)) + cat(prql_compile(query, target, TRUE, FALSE)) Output SELECT origin, @@ -259,7 +258,7 @@ # Targets target=sql.mssql Code - cat(prql_compile(query, target, format = TRUE, signature_comment = FALSE)) + cat(prql_compile(query, target, TRUE, FALSE)) Output SELECT origin, @@ -283,7 +282,7 @@ # Targets target=sql.mysql Code - cat(prql_compile(query, target, format = TRUE, signature_comment = FALSE)) + cat(prql_compile(query, target, TRUE, FALSE)) Output SELECT origin, @@ -307,7 +306,7 @@ # Targets target=sql.postgres Code - cat(prql_compile(query, target, format = TRUE, signature_comment = FALSE)) + cat(prql_compile(query, target, TRUE, FALSE)) Output SELECT origin, @@ -331,7 +330,7 @@ # Targets target=sql.sqlite Code - cat(prql_compile(query, target, format = TRUE, signature_comment = FALSE)) + cat(prql_compile(query, target, TRUE, FALSE)) Output SELECT origin, @@ -355,7 +354,7 @@ # Targets target=sql.snowflake Code - cat(prql_compile(query, target, format = TRUE, signature_comment = FALSE)) + cat(prql_compile(query, target, TRUE, FALSE)) Output SELECT origin, @@ -383,19 +382,3 @@ Output [1] '0.13.0' -# display display=plain - - Code - tryCatch(prql_compile(query, format = TRUE, display = display), error = function( - e) cli::ansi_html(e)) - Output - [1] "Error: Error:\n ╭─[:3:1]\n │\n 3 │ select\n │ ───┬──\n │ ╰──── main expected type `relation`, but found type `func relation -> relation`\n │\n │ Help: Have you forgotten an argument to function std.select?\n │\n │ Note: Type `relation` expands to `[tuple]`\n───╯\n\n" - -# display display=bar - - Code - tryCatch(prql_compile(query, format = TRUE, display = display), error = function( - e) cli::ansi_html(e)) - Output - [1] "Error: Error: `display` must be one of `plain` or `ansi_color`. got: bar\n\n" - diff --git a/tests/testthat/test-compile.R b/tests/testthat/test-compile.R index 2d001cca..8b4f9e6a 100644 --- a/tests/testthat/test-compile.R +++ b/tests/testthat/test-compile.R @@ -6,11 +6,11 @@ test_that("target set in the header ", { "SELECT * FROM a ORDER BY (SELECT NULL) OFFSET 0 ROWS FETCH FIRST 1 ROWS ONLY" ) expect_equal( - prql_compile(mssql_query, "sql.any", format = FALSE, signature_comment = FALSE), + prql_compile(mssql_query, target = "sql.any", format = FALSE, signature_comment = FALSE), "SELECT * FROM a ORDER BY (SELECT NULL) OFFSET 0 ROWS FETCH FIRST 1 ROWS ONLY" ) expect_equal( - prql_compile(mssql_query, "sql.generic", format = FALSE, signature_comment = FALSE), + prql_compile(mssql_query, target = "sql.generic", format = FALSE, signature_comment = FALSE), "SELECT * FROM a LIMIT 1" ) }) @@ -58,23 +58,20 @@ test_that("Options", { test_that("PRQL query", { expect_snapshot(cat(prql_compile("from a | select {b}"))) - expect_snapshot(cat(prql_compile("from a | select {b}", target = NULL, format = FALSE, signature_comment = FALSE))) + expect_snapshot(cat(prql_compile("from a | select {b}", NULL, FALSE, FALSE))) expect_snapshot( "from star_wars select {star_wars.*} select !{jar_jar_binks, midichlorians}" |> - prql_compile("sql.duckdb", format = TRUE, signature_comment = TRUE) |> + compile("sql.duckdb", TRUE, TRUE) |> cat() ) }) patrick::with_parameters_test_that("Syntax error", { - expect_snapshot( - cat(prql_compile(query, "sql.any", format = TRUE, signature_comment = FALSE)), - error = TRUE - ) + expect_snapshot(cat(prql_compile(query, "sql.any", TRUE, FALSE)), error = TRUE) }, query = c("Mississippi has four S’s and four I’s.", "from a | select [b]", "from a | select {{{b") ) @@ -94,7 +91,7 @@ group {origin, dest} ( sort {-origin, avg_delay} take 2 " - expect_snapshot(cat(prql_compile(query, target, format = TRUE, signature_comment = FALSE))) + expect_snapshot(cat(prql_compile(query, target, TRUE, FALSE))) }, target = prql_get_targets() ) @@ -103,18 +100,3 @@ test_that("prqlc's version", { expect_snapshot(prql_version()) expect_s3_class(prql_version(), "numeric_version") }) - -patrick::with_parameters_test_that("display", - { - query <- " -from foo -select -" - skip_if_not_installed("cli") - expect_snapshot( - tryCatch(prql_compile(query, format = TRUE, display = display), error = \(e) cli::ansi_html(e)) - ) - }, - # The `ansi_color` option is not working on CI, so not tested. - display = c("plain", "bar") -) diff --git a/tools/lib-sums.tsv b/tools/lib-sums.tsv new file mode 100644 index 00000000..c7162a1c --- /dev/null +++ b/tools/lib-sums.tsv @@ -0,0 +1,6 @@ +url sha256sum +https://github.com/PRQL/prqlc-r/releases/download/lib-v0.13.0/libprqlr-0.13.0-aarch64-apple-darwin.tar.gz 1b83bf8eda8341b0d7dde0ee10aac681e86d48f6e32026f3e9c3d0b061130f8c +https://github.com/PRQL/prqlc-r/releases/download/lib-v0.13.0/libprqlr-0.13.0-aarch64-unknown-linux-musl.tar.gz c6d944886e058c401fa51f47b917a21a231e4b5f09a9b9a36589f06ca6db39e4 +https://github.com/PRQL/prqlc-r/releases/download/lib-v0.13.0/libprqlr-0.13.0-x86_64-apple-darwin.tar.gz f1b4dc4cc9f33fd66575afd1bf51a50f921929ddbb731265cde2959373abf84d +https://github.com/PRQL/prqlc-r/releases/download/lib-v0.13.0/libprqlr-0.13.0-x86_64-pc-windows-gnu.tar.gz 46c43712e6ede1d011233f300588e555ab58e7312464fa09d86c26e63f688ad2 +https://github.com/PRQL/prqlc-r/releases/download/lib-v0.13.0/libprqlr-0.13.0-x86_64-unknown-linux-musl.tar.gz 9f5e5d99b49fa3dff9e702e80960ef8ca452e78737751d01ca5a33f2307c606f