From fbbdc16010cda4665926758f1fef3edcbb7b390a Mon Sep 17 00:00:00 2001
From: Laurent BEAULATON <laurent.beaulaton@ofb.gouv.fr>
Date: Tue, 1 Oct 2024 09:56:05 +0200
Subject: [PATCH 01/11] fix gitalb CI

---
 .gitlab-ci.yml | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index cbd3dd4..a0961de 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -35,7 +35,6 @@ variables:
   REPO_NAME: "{repo_name}"
   R_LIBS: "ci/lib"
   R_LIBS_USER: "ci/lib"
-  postgres_version: "14"
   
 
 #key for caching per branch    
@@ -81,8 +80,10 @@ buildpackage:
       #- install2.r --deps TRUE --libloc "ci/lib" --repos "https://pbil.univ-lyon1.fr/CRAN/" --error --skipinstalled  RODBC
       - install2.r --deps TRUE --libloc "ci/lib" --repos "https://pbil.univ-lyon1.fr/CRAN/" --error --skipinstalled  stacomirtools RPostgres xtable magrittr intervals RColorBrewer
       # these are for code coverage
-      - install2.r --deps TRUE --libloc "ci/lib" --repos "https://pbil.univ-lyon1.fr/CRAN/" --error --skipinstalled covr DT
-      - install2.r --deps TRUE --libloc "ci/lib" --repos "https://pbil.univ-lyon1.fr/CRAN/" --error --skipinstalled reshape2 graphics utils stats lattice grDevices Hmisc lubridate mgcv withr XML
+      - install2.r --deps TRUE --libloc "ci/lib" --repos "https://pbil.univ-lyon1.fr/CRAN/" --error --skipinstalled covr DT &> install.log
+      - Rscript -e 'if(!requireNamespace("pak", quietly = TRUE)) {install.packages("pak")}'
+      - Rscript -e 'pak::pkg_install(pkg = c("reshape2", "graphics", "utils", "stats", "lattice", "grDevices", "Hmisc", "lubridate", "mgcv", "withr", "XML"), upgrade = TRUE)'
+      #- install2.r --deps TRUE --libloc "ci/lib" --repos "https://pbil.univ-lyon1.fr/CRAN/" --error --skipinstalled reshape2 graphics utils stats lattice grDevices Hmisc lubridate mgcv withr XML
       - rm -rf /tmp/downloaded_packages
       #- r -e 'install.packages(c("stacomirtools","RPostgres","xtable","magrittr","intervals","RColorBrewer"), lib= "ci/lib", dependencies = TRUE, repos =)'> public/logr
       #- r -e 'install.packages(c(), lib= "ci/lib", repos= "https://pbil.univ-lyon1.fr/CRAN/", dependencies = TRUE)'>> public/logr  
-- 
GitLab


From fdaa2967ef0d9b333ed1934092ce0bb0c4463bc1 Mon Sep 17 00:00:00 2001
From: Laurent BEAULATON <laurent.beaulaton@ofb.gouv.fr>
Date: Tue, 1 Oct 2024 10:17:39 +0200
Subject: [PATCH 02/11] fix: gitlab-ci using pak

---
 .gitlab-ci.yml | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index a0961de..cd1bf1b 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -78,12 +78,11 @@ buildpackage:
       - apt-get install -y libpq-dev
       - apt-get install -y r-cran-rodbc
       #- install2.r --deps TRUE --libloc "ci/lib" --repos "https://pbil.univ-lyon1.fr/CRAN/" --error --skipinstalled  RODBC
-      - install2.r --deps TRUE --libloc "ci/lib" --repos "https://pbil.univ-lyon1.fr/CRAN/" --error --skipinstalled  stacomirtools RPostgres xtable magrittr intervals RColorBrewer
-      # these are for code coverage
-      - install2.r --deps TRUE --libloc "ci/lib" --repos "https://pbil.univ-lyon1.fr/CRAN/" --error --skipinstalled covr DT &> install.log
       - Rscript -e 'if(!requireNamespace("pak", quietly = TRUE)) {install.packages("pak")}'
-      - Rscript -e 'pak::pkg_install(pkg = c("reshape2", "graphics", "utils", "stats", "lattice", "grDevices", "Hmisc", "lubridate", "mgcv", "withr", "XML"), upgrade = TRUE)'
-      #- install2.r --deps TRUE --libloc "ci/lib" --repos "https://pbil.univ-lyon1.fr/CRAN/" --error --skipinstalled reshape2 graphics utils stats lattice grDevices Hmisc lubridate mgcv withr XML
+      - Rscript -e 'pak::pkg_install(pkg = c("stacomirtools", "RPostgres", "xtable", "magrittr", "intervals", "RColorBrewer"), lib = "'$R_LIBS_USER'", upgrade = TRUE)'
+      # these are for code coverage
+      - Rscript -e 'pak::pkg_install(pkg = c("covr", "DT"), lib = "'$R_LIBS_USER'", upgrade = TRUE)'
+      - Rscript -e 'pak::pkg_install(pkg = c("reshape2", "graphics", "utils", "stats", "lattice", "grDevices", "Hmisc", "lubridate", "mgcv", "withr", "XML"), lib = "'$R_LIBS_USER'", upgrade = TRUE)'
       - rm -rf /tmp/downloaded_packages
       #- r -e 'install.packages(c("stacomirtools","RPostgres","xtable","magrittr","intervals","RColorBrewer"), lib= "ci/lib", dependencies = TRUE, repos =)'> public/logr
       #- r -e 'install.packages(c(), lib= "ci/lib", repos= "https://pbil.univ-lyon1.fr/CRAN/", dependencies = TRUE)'>> public/logr  
@@ -95,7 +94,7 @@ buildpackage:
     when: always
     paths:
       - public
-      - ci/lib
+      - ${R_LIBS_USER}
       - "$(ls -rt *.zip |tail -1)" 
       - "$(ls -rt *.tar.gz |tail -1)" 
 
-- 
GitLab


From 1889f13c5cc27354fa937f74a6798b6c8f154d39 Mon Sep 17 00:00:00 2001
From: Laurent BEAULATON <laurent.beaulaton@ofb.gouv.fr>
Date: Tue, 1 Oct 2024 14:42:10 +0200
Subject: [PATCH 03/11] Merge branch 'renv'

---
 .Rbuildignore      |    4 +-
 renv.lock          | 1155 +++++++++++++++++++++++++++++++++++++++++
 renv/.gitignore    |    7 +
 renv/activate.R    | 1220 ++++++++++++++++++++++++++++++++++++++++++++
 renv/settings.json |   19 +
 5 files changed, 2404 insertions(+), 1 deletion(-)
 create mode 100644 renv.lock
 create mode 100644 renv/.gitignore
 create mode 100644 renv/activate.R
 create mode 100644 renv/settings.json

diff --git a/.Rbuildignore b/.Rbuildignore
index aae23e1..74e08d2 100644
--- a/.Rbuildignore
+++ b/.Rbuildignore
@@ -1,3 +1,5 @@
+^renv$
+^renv\.lock$
 ^README\.Rmd$
 ^README-.*\.png$
 ^README\.md$
@@ -26,4 +28,4 @@ tests/testhat/\~import_coe20092015\.csv
 ^CRAN-RELEASE$
 ^public
 ^ci
-^Scripts
\ No newline at end of file
+^Scripts
diff --git a/renv.lock b/renv.lock
new file mode 100644
index 0000000..53554c0
--- /dev/null
+++ b/renv.lock
@@ -0,0 +1,1155 @@
+{
+  "R": {
+    "Version": "4.4.1",
+    "Repositories": [
+      {
+        "Name": "CRAN",
+        "URL": "https://cloud.r-project.org"
+      }
+    ]
+  },
+  "Packages": {
+    "DBI": {
+      "Package": "DBI",
+      "Version": "1.2.3",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "methods"
+      ],
+      "Hash": "065ae649b05f1ff66bb0c793107508f5"
+    },
+    "Formula": {
+      "Package": "Formula",
+      "Version": "1.2-5",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "stats"
+      ],
+      "Hash": "7a29697b75e027767a53fde6c903eca7"
+    },
+    "Hmisc": {
+      "Package": "Hmisc",
+      "Version": "5.1-3",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "Formula",
+        "R",
+        "base64enc",
+        "cluster",
+        "colorspace",
+        "data.table",
+        "foreign",
+        "ggplot2",
+        "grid",
+        "gridExtra",
+        "gtable",
+        "htmlTable",
+        "htmltools",
+        "knitr",
+        "methods",
+        "nnet",
+        "rmarkdown",
+        "rpart",
+        "viridis"
+      ],
+      "Hash": "9a446aea30bff7e8ee20f4c0973e8851"
+    },
+    "MASS": {
+      "Package": "MASS",
+      "Version": "7.3-61",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "grDevices",
+        "graphics",
+        "methods",
+        "stats",
+        "utils"
+      ],
+      "Hash": "0cafd6f0500e5deba33be22c46bf6055"
+    },
+    "Matrix": {
+      "Package": "Matrix",
+      "Version": "1.7-0",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "grDevices",
+        "graphics",
+        "grid",
+        "lattice",
+        "methods",
+        "stats",
+        "utils"
+      ],
+      "Hash": "1920b2f11133b12350024297d8a4ff4a"
+    },
+    "R6": {
+      "Package": "R6",
+      "Version": "2.5.1",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R"
+      ],
+      "Hash": "470851b6d5d0ac559e9d01bb352b4021"
+    },
+    "RColorBrewer": {
+      "Package": "RColorBrewer",
+      "Version": "1.1-3",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R"
+      ],
+      "Hash": "45f0398006e83a5b10b72a90663d8d8c"
+    },
+    "RODBC": {
+      "Package": "RODBC",
+      "Version": "1.3-23",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "stats"
+      ],
+      "Hash": "544fd4ca5c8fa534604c3c0336f1a9e4"
+    },
+    "RPostgres": {
+      "Package": "RPostgres",
+      "Version": "1.4.7",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "DBI",
+        "R",
+        "bit64",
+        "blob",
+        "cpp11",
+        "hms",
+        "lubridate",
+        "methods",
+        "plogr",
+        "withr"
+      ],
+      "Hash": "beb7e18bf3f9e096f716a52a77ec793c"
+    },
+    "Rcpp": {
+      "Package": "Rcpp",
+      "Version": "1.0.12",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "methods",
+        "utils"
+      ],
+      "Hash": "5ea2700d21e038ace58269ecdbeb9ec0"
+    },
+    "backports": {
+      "Package": "backports",
+      "Version": "1.4.1",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R"
+      ],
+      "Hash": "c39fbec8a30d23e721980b8afb31984c"
+    },
+    "base64enc": {
+      "Package": "base64enc",
+      "Version": "0.1-3",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R"
+      ],
+      "Hash": "543776ae6848fde2f48ff3816d0628bc"
+    },
+    "bit": {
+      "Package": "bit",
+      "Version": "4.5.0",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R"
+      ],
+      "Hash": "5dc7b2677d65d0e874fc4aaf0e879987"
+    },
+    "bit64": {
+      "Package": "bit64",
+      "Version": "4.5.2",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "bit",
+        "methods",
+        "stats",
+        "utils"
+      ],
+      "Hash": "e84984bf5f12a18628d9a02322128dfd"
+    },
+    "blob": {
+      "Package": "blob",
+      "Version": "1.2.4",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "methods",
+        "rlang",
+        "vctrs"
+      ],
+      "Hash": "40415719b5a479b87949f3aa0aee737c"
+    },
+    "bslib": {
+      "Package": "bslib",
+      "Version": "0.7.0",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "base64enc",
+        "cachem",
+        "fastmap",
+        "grDevices",
+        "htmltools",
+        "jquerylib",
+        "jsonlite",
+        "lifecycle",
+        "memoise",
+        "mime",
+        "rlang",
+        "sass"
+      ],
+      "Hash": "8644cc53f43828f19133548195d7e59e"
+    },
+    "cachem": {
+      "Package": "cachem",
+      "Version": "1.1.0",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "fastmap",
+        "rlang"
+      ],
+      "Hash": "cd9a672193789068eb5a2aad65a0dedf"
+    },
+    "checkmate": {
+      "Package": "checkmate",
+      "Version": "2.3.1",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "backports",
+        "utils"
+      ],
+      "Hash": "c01cab1cb0f9125211a6fc99d540e315"
+    },
+    "cli": {
+      "Package": "cli",
+      "Version": "3.6.2",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "utils"
+      ],
+      "Hash": "1216ac65ac55ec0058a6f75d7ca0fd52"
+    },
+    "cluster": {
+      "Package": "cluster",
+      "Version": "2.1.6",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "grDevices",
+        "graphics",
+        "stats",
+        "utils"
+      ],
+      "Hash": "0aaa05204035dc43ea0004b9c76611dd"
+    },
+    "colorspace": {
+      "Package": "colorspace",
+      "Version": "2.1-0",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "grDevices",
+        "graphics",
+        "methods",
+        "stats"
+      ],
+      "Hash": "f20c47fd52fae58b4e377c37bb8c335b"
+    },
+    "cpp11": {
+      "Package": "cpp11",
+      "Version": "0.4.7",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R"
+      ],
+      "Hash": "5a295d7d963cc5035284dcdbaf334f4e"
+    },
+    "data.table": {
+      "Package": "data.table",
+      "Version": "1.15.4",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "methods"
+      ],
+      "Hash": "8ee9ac56ef633d0c7cab8b2ca87d683e"
+    },
+    "digest": {
+      "Package": "digest",
+      "Version": "0.6.35",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "utils"
+      ],
+      "Hash": "698ece7ba5a4fa4559e3d537e7ec3d31"
+    },
+    "dplyr": {
+      "Package": "dplyr",
+      "Version": "1.1.4",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "R6",
+        "cli",
+        "generics",
+        "glue",
+        "lifecycle",
+        "magrittr",
+        "methods",
+        "pillar",
+        "rlang",
+        "tibble",
+        "tidyselect",
+        "utils",
+        "vctrs"
+      ],
+      "Hash": "fedd9d00c2944ff00a0e2696ccf048ec"
+    },
+    "evaluate": {
+      "Package": "evaluate",
+      "Version": "0.23",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "methods"
+      ],
+      "Hash": "daf4a1246be12c1fa8c7705a0935c1a0"
+    },
+    "fansi": {
+      "Package": "fansi",
+      "Version": "1.0.6",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "grDevices",
+        "utils"
+      ],
+      "Hash": "962174cf2aeb5b9eea581522286a911f"
+    },
+    "farver": {
+      "Package": "farver",
+      "Version": "2.1.2",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Hash": "680887028577f3fa2a81e410ed0d6e42"
+    },
+    "fastmap": {
+      "Package": "fastmap",
+      "Version": "1.2.0",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Hash": "aa5e1cd11c2d15497494c5292d7ffcc8"
+    },
+    "fontawesome": {
+      "Package": "fontawesome",
+      "Version": "0.5.2",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "htmltools",
+        "rlang"
+      ],
+      "Hash": "c2efdd5f0bcd1ea861c2d4e2a883a67d"
+    },
+    "foreign": {
+      "Package": "foreign",
+      "Version": "0.8-86",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "methods",
+        "stats",
+        "utils"
+      ],
+      "Hash": "550170303dbb19d07b2bcc288068e7dc"
+    },
+    "fs": {
+      "Package": "fs",
+      "Version": "1.6.4",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "methods"
+      ],
+      "Hash": "15aeb8c27f5ea5161f9f6a641fafd93a"
+    },
+    "generics": {
+      "Package": "generics",
+      "Version": "0.1.3",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "methods"
+      ],
+      "Hash": "15e9634c0fcd294799e9b2e929ed1b86"
+    },
+    "ggplot2": {
+      "Package": "ggplot2",
+      "Version": "3.5.1",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "MASS",
+        "R",
+        "cli",
+        "glue",
+        "grDevices",
+        "grid",
+        "gtable",
+        "isoband",
+        "lifecycle",
+        "mgcv",
+        "rlang",
+        "scales",
+        "stats",
+        "tibble",
+        "vctrs",
+        "withr"
+      ],
+      "Hash": "44c6a2f8202d5b7e878ea274b1092426"
+    },
+    "glue": {
+      "Package": "glue",
+      "Version": "1.7.0",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "methods"
+      ],
+      "Hash": "e0b3a53876554bd45879e596cdb10a52"
+    },
+    "gridExtra": {
+      "Package": "gridExtra",
+      "Version": "2.3",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "grDevices",
+        "graphics",
+        "grid",
+        "gtable",
+        "utils"
+      ],
+      "Hash": "7d7f283939f563670a697165b2cf5560"
+    },
+    "gtable": {
+      "Package": "gtable",
+      "Version": "0.3.5",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "cli",
+        "glue",
+        "grid",
+        "lifecycle",
+        "rlang"
+      ],
+      "Hash": "e18861963cbc65a27736e02b3cd3c4a0"
+    },
+    "highr": {
+      "Package": "highr",
+      "Version": "0.11",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "xfun"
+      ],
+      "Hash": "d65ba49117ca223614f71b60d85b8ab7"
+    },
+    "hms": {
+      "Package": "hms",
+      "Version": "1.1.3",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "lifecycle",
+        "methods",
+        "pkgconfig",
+        "rlang",
+        "vctrs"
+      ],
+      "Hash": "b59377caa7ed00fa41808342002138f9"
+    },
+    "htmlTable": {
+      "Package": "htmlTable",
+      "Version": "2.4.2",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "checkmate",
+        "htmltools",
+        "htmlwidgets",
+        "knitr",
+        "magrittr",
+        "methods",
+        "rstudioapi",
+        "stringr"
+      ],
+      "Hash": "0164d8cade33fac2190703da7e6e3241"
+    },
+    "htmltools": {
+      "Package": "htmltools",
+      "Version": "0.5.8.1",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "base64enc",
+        "digest",
+        "fastmap",
+        "grDevices",
+        "rlang",
+        "utils"
+      ],
+      "Hash": "81d371a9cc60640e74e4ab6ac46dcedc"
+    },
+    "htmlwidgets": {
+      "Package": "htmlwidgets",
+      "Version": "1.6.4",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "grDevices",
+        "htmltools",
+        "jsonlite",
+        "knitr",
+        "rmarkdown",
+        "yaml"
+      ],
+      "Hash": "04291cc45198225444a397606810ac37"
+    },
+    "intervals": {
+      "Package": "intervals",
+      "Version": "0.15.5",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "graphics",
+        "methods",
+        "utils"
+      ],
+      "Hash": "da1fd6a5634e370ad0ef99a1aa2b17cb"
+    },
+    "isoband": {
+      "Package": "isoband",
+      "Version": "0.2.7",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "grid",
+        "utils"
+      ],
+      "Hash": "0080607b4a1a7b28979aecef976d8bc2"
+    },
+    "jquerylib": {
+      "Package": "jquerylib",
+      "Version": "0.1.4",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "htmltools"
+      ],
+      "Hash": "5aab57a3bd297eee1c1d862735972182"
+    },
+    "jsonlite": {
+      "Package": "jsonlite",
+      "Version": "1.8.8",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "methods"
+      ],
+      "Hash": "e1b9c55281c5adc4dd113652d9e26768"
+    },
+    "knitr": {
+      "Package": "knitr",
+      "Version": "1.48",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "evaluate",
+        "highr",
+        "methods",
+        "tools",
+        "xfun",
+        "yaml"
+      ],
+      "Hash": "acf380f300c721da9fde7df115a5f86f"
+    },
+    "labeling": {
+      "Package": "labeling",
+      "Version": "0.4.3",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "graphics",
+        "stats"
+      ],
+      "Hash": "b64ec208ac5bc1852b285f665d6368b3"
+    },
+    "later": {
+      "Package": "later",
+      "Version": "1.3.2",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "Rcpp",
+        "rlang"
+      ],
+      "Hash": "a3e051d405326b8b0012377434c62b37"
+    },
+    "lattice": {
+      "Package": "lattice",
+      "Version": "0.22-6",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "grDevices",
+        "graphics",
+        "grid",
+        "stats",
+        "utils"
+      ],
+      "Hash": "cc5ac1ba4c238c7ca9fa6a87ca11a7e2"
+    },
+    "lifecycle": {
+      "Package": "lifecycle",
+      "Version": "1.0.4",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "cli",
+        "glue",
+        "rlang"
+      ],
+      "Hash": "b8552d117e1b808b09a832f589b79035"
+    },
+    "lubridate": {
+      "Package": "lubridate",
+      "Version": "1.9.3",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "generics",
+        "methods",
+        "timechange"
+      ],
+      "Hash": "680ad542fbcf801442c83a6ac5a2126c"
+    },
+    "magrittr": {
+      "Package": "magrittr",
+      "Version": "2.0.3",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R"
+      ],
+      "Hash": "7ce2733a9826b3aeb1775d56fd305472"
+    },
+    "memoise": {
+      "Package": "memoise",
+      "Version": "2.0.1",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "cachem",
+        "rlang"
+      ],
+      "Hash": "e2817ccf4a065c5d9d7f2cfbe7c1d78c"
+    },
+    "mgcv": {
+      "Package": "mgcv",
+      "Version": "1.9-1",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "Matrix",
+        "R",
+        "graphics",
+        "methods",
+        "nlme",
+        "splines",
+        "stats",
+        "utils"
+      ],
+      "Hash": "110ee9d83b496279960e162ac97764ce"
+    },
+    "mime": {
+      "Package": "mime",
+      "Version": "0.12",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "tools"
+      ],
+      "Hash": "18e9c28c1d3ca1560ce30658b22ce104"
+    },
+    "munsell": {
+      "Package": "munsell",
+      "Version": "0.5.1",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "colorspace",
+        "methods"
+      ],
+      "Hash": "4fd8900853b746af55b81fda99da7695"
+    },
+    "nlme": {
+      "Package": "nlme",
+      "Version": "3.1-165",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "graphics",
+        "lattice",
+        "stats",
+        "utils"
+      ],
+      "Hash": "2769a88be217841b1f33ed469675c3cc"
+    },
+    "nnet": {
+      "Package": "nnet",
+      "Version": "7.3-19",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "stats",
+        "utils"
+      ],
+      "Hash": "2c797b46eea7fb58ede195bc0b1f1138"
+    },
+    "pillar": {
+      "Package": "pillar",
+      "Version": "1.9.0",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "cli",
+        "fansi",
+        "glue",
+        "lifecycle",
+        "rlang",
+        "utf8",
+        "utils",
+        "vctrs"
+      ],
+      "Hash": "15da5a8412f317beeee6175fbc76f4bb"
+    },
+    "pkgconfig": {
+      "Package": "pkgconfig",
+      "Version": "2.0.3",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "utils"
+      ],
+      "Hash": "01f28d4278f15c76cddbea05899c5d6f"
+    },
+    "plogr": {
+      "Package": "plogr",
+      "Version": "0.2.0",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Hash": "09eb987710984fc2905c7129c7d85e65"
+    },
+    "plyr": {
+      "Package": "plyr",
+      "Version": "1.8.9",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "Rcpp"
+      ],
+      "Hash": "6b8177fd19982f0020743fadbfdbd933"
+    },
+    "pool": {
+      "Package": "pool",
+      "Version": "1.0.3",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "DBI",
+        "R",
+        "R6",
+        "later",
+        "methods",
+        "rlang"
+      ],
+      "Hash": "b336b9f1b3cc72033258c70dc17edbf1"
+    },
+    "rappdirs": {
+      "Package": "rappdirs",
+      "Version": "0.3.3",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R"
+      ],
+      "Hash": "5e3c5dc0b071b21fa128676560dbe94d"
+    },
+    "renv": {
+      "Package": "renv",
+      "Version": "1.0.7",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "utils"
+      ],
+      "Hash": "397b7b2a265bc5a7a06852524dabae20"
+    },
+    "reshape2": {
+      "Package": "reshape2",
+      "Version": "1.4.4",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "Rcpp",
+        "plyr",
+        "stringr"
+      ],
+      "Hash": "bb5996d0bd962d214a11140d77589917"
+    },
+    "rlang": {
+      "Package": "rlang",
+      "Version": "1.1.4",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "utils"
+      ],
+      "Hash": "3eec01f8b1dee337674b2e34ab1f9bc1"
+    },
+    "rmarkdown": {
+      "Package": "rmarkdown",
+      "Version": "2.28",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "bslib",
+        "evaluate",
+        "fontawesome",
+        "htmltools",
+        "jquerylib",
+        "jsonlite",
+        "knitr",
+        "methods",
+        "tinytex",
+        "tools",
+        "utils",
+        "xfun",
+        "yaml"
+      ],
+      "Hash": "062470668513dcda416927085ee9bdc7"
+    },
+    "rpart": {
+      "Package": "rpart",
+      "Version": "4.1.23",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "grDevices",
+        "graphics",
+        "stats"
+      ],
+      "Hash": "b3d390424f41d04174cccf84d49676c2"
+    },
+    "rstudioapi": {
+      "Package": "rstudioapi",
+      "Version": "0.16.0",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Hash": "96710351d642b70e8f02ddeb237c46a7"
+    },
+    "sass": {
+      "Package": "sass",
+      "Version": "0.4.9",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R6",
+        "fs",
+        "htmltools",
+        "rappdirs",
+        "rlang"
+      ],
+      "Hash": "d53dbfddf695303ea4ad66f86e99b95d"
+    },
+    "scales": {
+      "Package": "scales",
+      "Version": "1.3.0",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "R6",
+        "RColorBrewer",
+        "cli",
+        "farver",
+        "glue",
+        "labeling",
+        "lifecycle",
+        "munsell",
+        "rlang",
+        "viridisLite"
+      ],
+      "Hash": "c19df082ba346b0ffa6f833e92de34d1"
+    },
+    "stacomirtools": {
+      "Package": "stacomirtools",
+      "Version": "0.6.0.1",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "DBI",
+        "RODBC",
+        "RPostgres",
+        "methods",
+        "pool",
+        "utils",
+        "xtable"
+      ],
+      "Hash": "2b32e7d7b518bc46946e3b020e682d7d"
+    },
+    "stringi": {
+      "Package": "stringi",
+      "Version": "1.8.4",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "stats",
+        "tools",
+        "utils"
+      ],
+      "Hash": "39e1144fd75428983dc3f63aa53dfa91"
+    },
+    "stringr": {
+      "Package": "stringr",
+      "Version": "1.5.1",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "cli",
+        "glue",
+        "lifecycle",
+        "magrittr",
+        "rlang",
+        "stringi",
+        "vctrs"
+      ],
+      "Hash": "960e2ae9e09656611e0b8214ad543207"
+    },
+    "tibble": {
+      "Package": "tibble",
+      "Version": "3.2.1",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "fansi",
+        "lifecycle",
+        "magrittr",
+        "methods",
+        "pillar",
+        "pkgconfig",
+        "rlang",
+        "utils",
+        "vctrs"
+      ],
+      "Hash": "a84e2cc86d07289b3b6f5069df7a004c"
+    },
+    "tidyselect": {
+      "Package": "tidyselect",
+      "Version": "1.2.1",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "cli",
+        "glue",
+        "lifecycle",
+        "rlang",
+        "vctrs",
+        "withr"
+      ],
+      "Hash": "829f27b9c4919c16b593794a6344d6c0"
+    },
+    "timechange": {
+      "Package": "timechange",
+      "Version": "0.3.0",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "cpp11"
+      ],
+      "Hash": "c5f3c201b931cd6474d17d8700ccb1c8"
+    },
+    "tinytex": {
+      "Package": "tinytex",
+      "Version": "0.51",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "xfun"
+      ],
+      "Hash": "d44e2fcd2e4e076f0aac540208559d1d"
+    },
+    "utf8": {
+      "Package": "utf8",
+      "Version": "1.2.4",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R"
+      ],
+      "Hash": "62b65c52671e6665f803ff02954446e9"
+    },
+    "vctrs": {
+      "Package": "vctrs",
+      "Version": "0.6.5",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "cli",
+        "glue",
+        "lifecycle",
+        "rlang"
+      ],
+      "Hash": "c03fa420630029418f7e6da3667aac4a"
+    },
+    "viridis": {
+      "Package": "viridis",
+      "Version": "0.6.5",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "ggplot2",
+        "gridExtra",
+        "viridisLite"
+      ],
+      "Hash": "acd96d9fa70adeea4a5a1150609b9745"
+    },
+    "viridisLite": {
+      "Package": "viridisLite",
+      "Version": "0.4.2",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R"
+      ],
+      "Hash": "c826c7c4241b6fc89ff55aaea3fa7491"
+    },
+    "withr": {
+      "Package": "withr",
+      "Version": "3.0.1",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "grDevices",
+        "graphics"
+      ],
+      "Hash": "07909200e8bbe90426fbfeb73e1e27aa"
+    },
+    "xfun": {
+      "Package": "xfun",
+      "Version": "0.44",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "grDevices",
+        "stats",
+        "tools"
+      ],
+      "Hash": "317a0538d32f4a009658bcedb7923f4b"
+    },
+    "xtable": {
+      "Package": "xtable",
+      "Version": "1.8-4",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Requirements": [
+        "R",
+        "stats",
+        "utils"
+      ],
+      "Hash": "b8acdf8af494d9ec19ccb2481a9b11c2"
+    },
+    "yaml": {
+      "Package": "yaml",
+      "Version": "2.3.8",
+      "Source": "Repository",
+      "Repository": "CRAN",
+      "Hash": "29240487a071f535f5e5d5a323b7afbd"
+    }
+  }
+}
diff --git a/renv/.gitignore b/renv/.gitignore
new file mode 100644
index 0000000..0ec0cbb
--- /dev/null
+++ b/renv/.gitignore
@@ -0,0 +1,7 @@
+library/
+local/
+cellar/
+lock/
+python/
+sandbox/
+staging/
diff --git a/renv/activate.R b/renv/activate.R
new file mode 100644
index 0000000..d13f993
--- /dev/null
+++ b/renv/activate.R
@@ -0,0 +1,1220 @@
+
+local({
+
+  # the requested version of renv
+  version <- "1.0.7"
+  attr(version, "sha") <- NULL
+
+  # the project directory
+  project <- Sys.getenv("RENV_PROJECT")
+  if (!nzchar(project))
+    project <- getwd()
+
+  # use start-up diagnostics if enabled
+  diagnostics <- Sys.getenv("RENV_STARTUP_DIAGNOSTICS", unset = "FALSE")
+  if (diagnostics) {
+    start <- Sys.time()
+    profile <- tempfile("renv-startup-", fileext = ".Rprof")
+    utils::Rprof(profile)
+    on.exit({
+      utils::Rprof(NULL)
+      elapsed <- signif(difftime(Sys.time(), start, units = "auto"), digits = 2L)
+      writeLines(sprintf("- renv took %s to run the autoloader.", format(elapsed)))
+      writeLines(sprintf("- Profile: %s", profile))
+      print(utils::summaryRprof(profile))
+    }, add = TRUE)
+  }
+
+  # figure out whether the autoloader is enabled
+  enabled <- local({
+
+    # first, check config option
+    override <- getOption("renv.config.autoloader.enabled")
+    if (!is.null(override))
+      return(override)
+
+    # if we're being run in a context where R_LIBS is already set,
+    # don't load -- presumably we're being run as a sub-process and
+    # the parent process has already set up library paths for us
+    rcmd <- Sys.getenv("R_CMD", unset = NA)
+    rlibs <- Sys.getenv("R_LIBS", unset = NA)
+    if (!is.na(rlibs) && !is.na(rcmd))
+      return(FALSE)
+
+    # next, check environment variables
+    # TODO: prefer using the configuration one in the future
+    envvars <- c(
+      "RENV_CONFIG_AUTOLOADER_ENABLED",
+      "RENV_AUTOLOADER_ENABLED",
+      "RENV_ACTIVATE_PROJECT"
+    )
+
+    for (envvar in envvars) {
+      envval <- Sys.getenv(envvar, unset = NA)
+      if (!is.na(envval))
+        return(tolower(envval) %in% c("true", "t", "1"))
+    }
+
+    # enable by default
+    TRUE
+
+  })
+
+  # bail if we're not enabled
+  if (!enabled) {
+
+    # if we're not enabled, we might still need to manually load
+    # the user profile here
+    profile <- Sys.getenv("R_PROFILE_USER", unset = "~/.Rprofile")
+    if (file.exists(profile)) {
+      cfg <- Sys.getenv("RENV_CONFIG_USER_PROFILE", unset = "TRUE")
+      if (tolower(cfg) %in% c("true", "t", "1"))
+        sys.source(profile, envir = globalenv())
+    }
+
+    return(FALSE)
+
+  }
+
+  # avoid recursion
+  if (identical(getOption("renv.autoloader.running"), TRUE)) {
+    warning("ignoring recursive attempt to run renv autoloader")
+    return(invisible(TRUE))
+  }
+
+  # signal that we're loading renv during R startup
+  options(renv.autoloader.running = TRUE)
+  on.exit(options(renv.autoloader.running = NULL), add = TRUE)
+
+  # signal that we've consented to use renv
+  options(renv.consent = TRUE)
+
+  # load the 'utils' package eagerly -- this ensures that renv shims, which
+  # mask 'utils' packages, will come first on the search path
+  library(utils, lib.loc = .Library)
+
+  # unload renv if it's already been loaded
+  if ("renv" %in% loadedNamespaces())
+    unloadNamespace("renv")
+
+  # load bootstrap tools   
+  `%||%` <- function(x, y) {
+    if (is.null(x)) y else x
+  }
+  
+  catf <- function(fmt, ..., appendLF = TRUE) {
+  
+    quiet <- getOption("renv.bootstrap.quiet", default = FALSE)
+    if (quiet)
+      return(invisible())
+  
+    msg <- sprintf(fmt, ...)
+    cat(msg, file = stdout(), sep = if (appendLF) "\n" else "")
+  
+    invisible(msg)
+  
+  }
+  
+  header <- function(label,
+                     ...,
+                     prefix = "#",
+                     suffix = "-",
+                     n = min(getOption("width"), 78))
+  {
+    label <- sprintf(label, ...)
+    n <- max(n - nchar(label) - nchar(prefix) - 2L, 8L)
+    if (n <= 0)
+      return(paste(prefix, label))
+  
+    tail <- paste(rep.int(suffix, n), collapse = "")
+    paste0(prefix, " ", label, " ", tail)
+  
+  }
+  
+  heredoc <- function(text, leave = 0) {
+  
+    # remove leading, trailing whitespace
+    trimmed <- gsub("^\\s*\\n|\\n\\s*$", "", text)
+  
+    # split into lines
+    lines <- strsplit(trimmed, "\n", fixed = TRUE)[[1L]]
+  
+    # compute common indent
+    indent <- regexpr("[^[:space:]]", lines)
+    common <- min(setdiff(indent, -1L)) - leave
+    paste(substring(lines, common), collapse = "\n")
+  
+  }
+  
+  startswith <- function(string, prefix) {
+    substring(string, 1, nchar(prefix)) == prefix
+  }
+  
+  bootstrap <- function(version, library) {
+  
+    friendly <- renv_bootstrap_version_friendly(version)
+    section <- header(sprintf("Bootstrapping renv %s", friendly))
+    catf(section)
+  
+    # attempt to download renv
+    catf("- Downloading renv ... ", appendLF = FALSE)
+    withCallingHandlers(
+      tarball <- renv_bootstrap_download(version),
+      error = function(err) {
+        catf("FAILED")
+        stop("failed to download:\n", conditionMessage(err))
+      }
+    )
+    catf("OK")
+    on.exit(unlink(tarball), add = TRUE)
+  
+    # now attempt to install
+    catf("- Installing renv  ... ", appendLF = FALSE)
+    withCallingHandlers(
+      status <- renv_bootstrap_install(version, tarball, library),
+      error = function(err) {
+        catf("FAILED")
+        stop("failed to install:\n", conditionMessage(err))
+      }
+    )
+    catf("OK")
+  
+    # add empty line to break up bootstrapping from normal output
+    catf("")
+  
+    return(invisible())
+  }
+  
+  renv_bootstrap_tests_running <- function() {
+    getOption("renv.tests.running", default = FALSE)
+  }
+  
+  renv_bootstrap_repos <- function() {
+  
+    # get CRAN repository
+    cran <- getOption("renv.repos.cran", "https://cloud.r-project.org")
+  
+    # check for repos override
+    repos <- Sys.getenv("RENV_CONFIG_REPOS_OVERRIDE", unset = NA)
+    if (!is.na(repos)) {
+  
+      # check for RSPM; if set, use a fallback repository for renv
+      rspm <- Sys.getenv("RSPM", unset = NA)
+      if (identical(rspm, repos))
+        repos <- c(RSPM = rspm, CRAN = cran)
+  
+      return(repos)
+  
+    }
+  
+    # check for lockfile repositories
+    repos <- tryCatch(renv_bootstrap_repos_lockfile(), error = identity)
+    if (!inherits(repos, "error") && length(repos))
+      return(repos)
+  
+    # retrieve current repos
+    repos <- getOption("repos")
+  
+    # ensure @CRAN@ entries are resolved
+    repos[repos == "@CRAN@"] <- cran
+  
+    # add in renv.bootstrap.repos if set
+    default <- c(FALLBACK = "https://cloud.r-project.org")
+    extra <- getOption("renv.bootstrap.repos", default = default)
+    repos <- c(repos, extra)
+  
+    # remove duplicates that might've snuck in
+    dupes <- duplicated(repos) | duplicated(names(repos))
+    repos[!dupes]
+  
+  }
+  
+  renv_bootstrap_repos_lockfile <- function() {
+  
+    lockpath <- Sys.getenv("RENV_PATHS_LOCKFILE", unset = "renv.lock")
+    if (!file.exists(lockpath))
+      return(NULL)
+  
+    lockfile <- tryCatch(renv_json_read(lockpath), error = identity)
+    if (inherits(lockfile, "error")) {
+      warning(lockfile)
+      return(NULL)
+    }
+  
+    repos <- lockfile$R$Repositories
+    if (length(repos) == 0)
+      return(NULL)
+  
+    keys <- vapply(repos, `[[`, "Name", FUN.VALUE = character(1))
+    vals <- vapply(repos, `[[`, "URL", FUN.VALUE = character(1))
+    names(vals) <- keys
+  
+    return(vals)
+  
+  }
+  
+  renv_bootstrap_download <- function(version) {
+  
+    sha <- attr(version, "sha", exact = TRUE)
+  
+    methods <- if (!is.null(sha)) {
+  
+      # attempting to bootstrap a development version of renv
+      c(
+        function() renv_bootstrap_download_tarball(sha),
+        function() renv_bootstrap_download_github(sha)
+      )
+  
+    } else {
+  
+      # attempting to bootstrap a release version of renv
+      c(
+        function() renv_bootstrap_download_tarball(version),
+        function() renv_bootstrap_download_cran_latest(version),
+        function() renv_bootstrap_download_cran_archive(version)
+      )
+  
+    }
+  
+    for (method in methods) {
+      path <- tryCatch(method(), error = identity)
+      if (is.character(path) && file.exists(path))
+        return(path)
+    }
+  
+    stop("All download methods failed")
+  
+  }
+  
+  renv_bootstrap_download_impl <- function(url, destfile) {
+  
+    mode <- "wb"
+  
+    # https://bugs.r-project.org/bugzilla/show_bug.cgi?id=17715
+    fixup <-
+      Sys.info()[["sysname"]] == "Windows" &&
+      substring(url, 1L, 5L) == "file:"
+  
+    if (fixup)
+      mode <- "w+b"
+  
+    args <- list(
+      url      = url,
+      destfile = destfile,
+      mode     = mode,
+      quiet    = TRUE
+    )
+  
+    if ("headers" %in% names(formals(utils::download.file)))
+      args$headers <- renv_bootstrap_download_custom_headers(url)
+  
+    do.call(utils::download.file, args)
+  
+  }
+  
+  renv_bootstrap_download_custom_headers <- function(url) {
+  
+    headers <- getOption("renv.download.headers")
+    if (is.null(headers))
+      return(character())
+  
+    if (!is.function(headers))
+      stopf("'renv.download.headers' is not a function")
+  
+    headers <- headers(url)
+    if (length(headers) == 0L)
+      return(character())
+  
+    if (is.list(headers))
+      headers <- unlist(headers, recursive = FALSE, use.names = TRUE)
+  
+    ok <-
+      is.character(headers) &&
+      is.character(names(headers)) &&
+      all(nzchar(names(headers)))
+  
+    if (!ok)
+      stop("invocation of 'renv.download.headers' did not return a named character vector")
+  
+    headers
+  
+  }
+  
+  renv_bootstrap_download_cran_latest <- function(version) {
+  
+    spec <- renv_bootstrap_download_cran_latest_find(version)
+    type  <- spec$type
+    repos <- spec$repos
+  
+    baseurl <- utils::contrib.url(repos = repos, type = type)
+    ext <- if (identical(type, "source"))
+      ".tar.gz"
+    else if (Sys.info()[["sysname"]] == "Windows")
+      ".zip"
+    else
+      ".tgz"
+    name <- sprintf("renv_%s%s", version, ext)
+    url <- paste(baseurl, name, sep = "/")
+  
+    destfile <- file.path(tempdir(), name)
+    status <- tryCatch(
+      renv_bootstrap_download_impl(url, destfile),
+      condition = identity
+    )
+  
+    if (inherits(status, "condition"))
+      return(FALSE)
+  
+    # report success and return
+    destfile
+  
+  }
+  
+  renv_bootstrap_download_cran_latest_find <- function(version) {
+  
+    # check whether binaries are supported on this system
+    binary <-
+      getOption("renv.bootstrap.binary", default = TRUE) &&
+      !identical(.Platform$pkgType, "source") &&
+      !identical(getOption("pkgType"), "source") &&
+      Sys.info()[["sysname"]] %in% c("Darwin", "Windows")
+  
+    types <- c(if (binary) "binary", "source")
+  
+    # iterate over types + repositories
+    for (type in types) {
+      for (repos in renv_bootstrap_repos()) {
+  
+        # retrieve package database
+        db <- tryCatch(
+          as.data.frame(
+            utils::available.packages(type = type, repos = repos),
+            stringsAsFactors = FALSE
+          ),
+          error = identity
+        )
+  
+        if (inherits(db, "error"))
+          next
+  
+        # check for compatible entry
+        entry <- db[db$Package %in% "renv" & db$Version %in% version, ]
+        if (nrow(entry) == 0)
+          next
+  
+        # found it; return spec to caller
+        spec <- list(entry = entry, type = type, repos = repos)
+        return(spec)
+  
+      }
+    }
+  
+    # if we got here, we failed to find renv
+    fmt <- "renv %s is not available from your declared package repositories"
+    stop(sprintf(fmt, version))
+  
+  }
+  
+  renv_bootstrap_download_cran_archive <- function(version) {
+  
+    name <- sprintf("renv_%s.tar.gz", version)
+    repos <- renv_bootstrap_repos()
+    urls <- file.path(repos, "src/contrib/Archive/renv", name)
+    destfile <- file.path(tempdir(), name)
+  
+    for (url in urls) {
+  
+      status <- tryCatch(
+        renv_bootstrap_download_impl(url, destfile),
+        condition = identity
+      )
+  
+      if (identical(status, 0L))
+        return(destfile)
+  
+    }
+  
+    return(FALSE)
+  
+  }
+  
+  renv_bootstrap_download_tarball <- function(version) {
+  
+    # if the user has provided the path to a tarball via
+    # an environment variable, then use it
+    tarball <- Sys.getenv("RENV_BOOTSTRAP_TARBALL", unset = NA)
+    if (is.na(tarball))
+      return()
+  
+    # allow directories
+    if (dir.exists(tarball)) {
+      name <- sprintf("renv_%s.tar.gz", version)
+      tarball <- file.path(tarball, name)
+    }
+  
+    # bail if it doesn't exist
+    if (!file.exists(tarball)) {
+  
+      # let the user know we weren't able to honour their request
+      fmt <- "- RENV_BOOTSTRAP_TARBALL is set (%s) but does not exist."
+      msg <- sprintf(fmt, tarball)
+      warning(msg)
+  
+      # bail
+      return()
+  
+    }
+  
+    catf("- Using local tarball '%s'.", tarball)
+    tarball
+  
+  }
+  
+  renv_bootstrap_download_github <- function(version) {
+  
+    enabled <- Sys.getenv("RENV_BOOTSTRAP_FROM_GITHUB", unset = "TRUE")
+    if (!identical(enabled, "TRUE"))
+      return(FALSE)
+  
+    # prepare download options
+    pat <- Sys.getenv("GITHUB_PAT")
+    if (nzchar(Sys.which("curl")) && nzchar(pat)) {
+      fmt <- "--location --fail --header \"Authorization: token %s\""
+      extra <- sprintf(fmt, pat)
+      saved <- options("download.file.method", "download.file.extra")
+      options(download.file.method = "curl", download.file.extra = extra)
+      on.exit(do.call(base::options, saved), add = TRUE)
+    } else if (nzchar(Sys.which("wget")) && nzchar(pat)) {
+      fmt <- "--header=\"Authorization: token %s\""
+      extra <- sprintf(fmt, pat)
+      saved <- options("download.file.method", "download.file.extra")
+      options(download.file.method = "wget", download.file.extra = extra)
+      on.exit(do.call(base::options, saved), add = TRUE)
+    }
+  
+    url <- file.path("https://api.github.com/repos/rstudio/renv/tarball", version)
+    name <- sprintf("renv_%s.tar.gz", version)
+    destfile <- file.path(tempdir(), name)
+  
+    status <- tryCatch(
+      renv_bootstrap_download_impl(url, destfile),
+      condition = identity
+    )
+  
+    if (!identical(status, 0L))
+      return(FALSE)
+  
+    renv_bootstrap_download_augment(destfile)
+  
+    return(destfile)
+  
+  }
+  
+  # Add Sha to DESCRIPTION. This is stop gap until #890, after which we
+  # can use renv::install() to fully capture metadata.
+  renv_bootstrap_download_augment <- function(destfile) {
+    sha <- renv_bootstrap_git_extract_sha1_tar(destfile)
+    if (is.null(sha)) {
+      return()
+    }
+  
+    # Untar
+    tempdir <- tempfile("renv-github-")
+    on.exit(unlink(tempdir, recursive = TRUE), add = TRUE)
+    untar(destfile, exdir = tempdir)
+    pkgdir <- dir(tempdir, full.names = TRUE)[[1]]
+  
+    # Modify description
+    desc_path <- file.path(pkgdir, "DESCRIPTION")
+    desc_lines <- readLines(desc_path)
+    remotes_fields <- c(
+      "RemoteType: github",
+      "RemoteHost: api.github.com",
+      "RemoteRepo: renv",
+      "RemoteUsername: rstudio",
+      "RemotePkgRef: rstudio/renv",
+      paste("RemoteRef: ", sha),
+      paste("RemoteSha: ", sha)
+    )
+    writeLines(c(desc_lines[desc_lines != ""], remotes_fields), con = desc_path)
+  
+    # Re-tar
+    local({
+      old <- setwd(tempdir)
+      on.exit(setwd(old), add = TRUE)
+  
+      tar(destfile, compression = "gzip")
+    })
+    invisible()
+  }
+  
+  # Extract the commit hash from a git archive. Git archives include the SHA1
+  # hash as the comment field of the tarball pax extended header
+  # (see https://www.kernel.org/pub/software/scm/git/docs/git-archive.html)
+  # For GitHub archives this should be the first header after the default one
+  # (512 byte) header.
+  renv_bootstrap_git_extract_sha1_tar <- function(bundle) {
+  
+    # open the bundle for reading
+    # We use gzcon for everything because (from ?gzcon)
+    # > Reading from a connection which does not supply a 'gzip' magic
+    # > header is equivalent to reading from the original connection
+    conn <- gzcon(file(bundle, open = "rb", raw = TRUE))
+    on.exit(close(conn))
+  
+    # The default pax header is 512 bytes long and the first pax extended header
+    # with the comment should be 51 bytes long
+    # `52 comment=` (11 chars) + 40 byte SHA1 hash
+    len <- 0x200 + 0x33
+    res <- rawToChar(readBin(conn, "raw", n = len)[0x201:len])
+  
+    if (grepl("^52 comment=", res)) {
+      sub("52 comment=", "", res)
+    } else {
+      NULL
+    }
+  }
+  
+  renv_bootstrap_install <- function(version, tarball, library) {
+  
+    # attempt to install it into project library
+    dir.create(library, showWarnings = FALSE, recursive = TRUE)
+    output <- renv_bootstrap_install_impl(library, tarball)
+  
+    # check for successful install
+    status <- attr(output, "status")
+    if (is.null(status) || identical(status, 0L))
+      return(status)
+  
+    # an error occurred; report it
+    header <- "installation of renv failed"
+    lines <- paste(rep.int("=", nchar(header)), collapse = "")
+    text <- paste(c(header, lines, output), collapse = "\n")
+    stop(text)
+  
+  }
+  
+  renv_bootstrap_install_impl <- function(library, tarball) {
+  
+    # invoke using system2 so we can capture and report output
+    bin <- R.home("bin")
+    exe <- if (Sys.info()[["sysname"]] == "Windows") "R.exe" else "R"
+    R <- file.path(bin, exe)
+  
+    args <- c(
+      "--vanilla", "CMD", "INSTALL", "--no-multiarch",
+      "-l", shQuote(path.expand(library)),
+      shQuote(path.expand(tarball))
+    )
+  
+    system2(R, args, stdout = TRUE, stderr = TRUE)
+  
+  }
+  
+  renv_bootstrap_platform_prefix <- function() {
+  
+    # construct version prefix
+    version <- paste(R.version$major, R.version$minor, sep = ".")
+    prefix <- paste("R", numeric_version(version)[1, 1:2], sep = "-")
+  
+    # include SVN revision for development versions of R
+    # (to avoid sharing platform-specific artefacts with released versions of R)
+    devel <-
+      identical(R.version[["status"]],   "Under development (unstable)") ||
+      identical(R.version[["nickname"]], "Unsuffered Consequences")
+  
+    if (devel)
+      prefix <- paste(prefix, R.version[["svn rev"]], sep = "-r")
+  
+    # build list of path components
+    components <- c(prefix, R.version$platform)
+  
+    # include prefix if provided by user
+    prefix <- renv_bootstrap_platform_prefix_impl()
+    if (!is.na(prefix) && nzchar(prefix))
+      components <- c(prefix, components)
+  
+    # build prefix
+    paste(components, collapse = "/")
+  
+  }
+  
+  renv_bootstrap_platform_prefix_impl <- function() {
+  
+    # if an explicit prefix has been supplied, use it
+    prefix <- Sys.getenv("RENV_PATHS_PREFIX", unset = NA)
+    if (!is.na(prefix))
+      return(prefix)
+  
+    # if the user has requested an automatic prefix, generate it
+    auto <- Sys.getenv("RENV_PATHS_PREFIX_AUTO", unset = NA)
+    if (is.na(auto) && getRversion() >= "4.4.0")
+      auto <- "TRUE"
+  
+    if (auto %in% c("TRUE", "True", "true", "1"))
+      return(renv_bootstrap_platform_prefix_auto())
+  
+    # empty string on failure
+    ""
+  
+  }
+  
+  renv_bootstrap_platform_prefix_auto <- function() {
+  
+    prefix <- tryCatch(renv_bootstrap_platform_os(), error = identity)
+    if (inherits(prefix, "error") || prefix %in% "unknown") {
+  
+      msg <- paste(
+        "failed to infer current operating system",
+        "please file a bug report at https://github.com/rstudio/renv/issues",
+        sep = "; "
+      )
+  
+      warning(msg)
+  
+    }
+  
+    prefix
+  
+  }
+  
+  renv_bootstrap_platform_os <- function() {
+  
+    sysinfo <- Sys.info()
+    sysname <- sysinfo[["sysname"]]
+  
+    # handle Windows + macOS up front
+    if (sysname == "Windows")
+      return("windows")
+    else if (sysname == "Darwin")
+      return("macos")
+  
+    # check for os-release files
+    for (file in c("/etc/os-release", "/usr/lib/os-release"))
+      if (file.exists(file))
+        return(renv_bootstrap_platform_os_via_os_release(file, sysinfo))
+  
+    # check for redhat-release files
+    if (file.exists("/etc/redhat-release"))
+      return(renv_bootstrap_platform_os_via_redhat_release())
+  
+    "unknown"
+  
+  }
+  
+  renv_bootstrap_platform_os_via_os_release <- function(file, sysinfo) {
+  
+    # read /etc/os-release
+    release <- utils::read.table(
+      file             = file,
+      sep              = "=",
+      quote            = c("\"", "'"),
+      col.names        = c("Key", "Value"),
+      comment.char     = "#",
+      stringsAsFactors = FALSE
+    )
+  
+    vars <- as.list(release$Value)
+    names(vars) <- release$Key
+  
+    # get os name
+    os <- tolower(sysinfo[["sysname"]])
+  
+    # read id
+    id <- "unknown"
+    for (field in c("ID", "ID_LIKE")) {
+      if (field %in% names(vars) && nzchar(vars[[field]])) {
+        id <- vars[[field]]
+        break
+      }
+    }
+  
+    # read version
+    version <- "unknown"
+    for (field in c("UBUNTU_CODENAME", "VERSION_CODENAME", "VERSION_ID", "BUILD_ID")) {
+      if (field %in% names(vars) && nzchar(vars[[field]])) {
+        version <- vars[[field]]
+        break
+      }
+    }
+  
+    # join together
+    paste(c(os, id, version), collapse = "-")
+  
+  }
+  
+  renv_bootstrap_platform_os_via_redhat_release <- function() {
+  
+    # read /etc/redhat-release
+    contents <- readLines("/etc/redhat-release", warn = FALSE)
+  
+    # infer id
+    id <- if (grepl("centos", contents, ignore.case = TRUE))
+      "centos"
+    else if (grepl("redhat", contents, ignore.case = TRUE))
+      "redhat"
+    else
+      "unknown"
+  
+    # try to find a version component (very hacky)
+    version <- "unknown"
+  
+    parts <- strsplit(contents, "[[:space:]]")[[1L]]
+    for (part in parts) {
+  
+      nv <- tryCatch(numeric_version(part), error = identity)
+      if (inherits(nv, "error"))
+        next
+  
+      version <- nv[1, 1]
+      break
+  
+    }
+  
+    paste(c("linux", id, version), collapse = "-")
+  
+  }
+  
+  renv_bootstrap_library_root_name <- function(project) {
+  
+    # use project name as-is if requested
+    asis <- Sys.getenv("RENV_PATHS_LIBRARY_ROOT_ASIS", unset = "FALSE")
+    if (asis)
+      return(basename(project))
+  
+    # otherwise, disambiguate based on project's path
+    id <- substring(renv_bootstrap_hash_text(project), 1L, 8L)
+    paste(basename(project), id, sep = "-")
+  
+  }
+  
+  renv_bootstrap_library_root <- function(project) {
+  
+    prefix <- renv_bootstrap_profile_prefix()
+  
+    path <- Sys.getenv("RENV_PATHS_LIBRARY", unset = NA)
+    if (!is.na(path))
+      return(paste(c(path, prefix), collapse = "/"))
+  
+    path <- renv_bootstrap_library_root_impl(project)
+    if (!is.null(path)) {
+      name <- renv_bootstrap_library_root_name(project)
+      return(paste(c(path, prefix, name), collapse = "/"))
+    }
+  
+    renv_bootstrap_paths_renv("library", project = project)
+  
+  }
+  
+  renv_bootstrap_library_root_impl <- function(project) {
+  
+    root <- Sys.getenv("RENV_PATHS_LIBRARY_ROOT", unset = NA)
+    if (!is.na(root))
+      return(root)
+  
+    type <- renv_bootstrap_project_type(project)
+    if (identical(type, "package")) {
+      userdir <- renv_bootstrap_user_dir()
+      return(file.path(userdir, "library"))
+    }
+  
+  }
+  
+  renv_bootstrap_validate_version <- function(version, description = NULL) {
+  
+    # resolve description file
+    #
+    # avoid passing lib.loc to `packageDescription()` below, since R will
+    # use the loaded version of the package by default anyhow. note that
+    # this function should only be called after 'renv' is loaded
+    # https://github.com/rstudio/renv/issues/1625
+    description <- description %||% packageDescription("renv")
+  
+    # check whether requested version 'version' matches loaded version of renv
+    sha <- attr(version, "sha", exact = TRUE)
+    valid <- if (!is.null(sha))
+      renv_bootstrap_validate_version_dev(sha, description)
+    else
+      renv_bootstrap_validate_version_release(version, description)
+  
+    if (valid)
+      return(TRUE)
+  
+    # the loaded version of renv doesn't match the requested version;
+    # give the user instructions on how to proceed
+    dev <- identical(description[["RemoteType"]], "github")
+    remote <- if (dev)
+      paste("rstudio/renv", description[["RemoteSha"]], sep = "@")
+    else
+      paste("renv", description[["Version"]], sep = "@")
+  
+    # display both loaded version + sha if available
+    friendly <- renv_bootstrap_version_friendly(
+      version = description[["Version"]],
+      sha     = if (dev) description[["RemoteSha"]]
+    )
+  
+    fmt <- heredoc("
+      renv %1$s was loaded from project library, but this project is configured to use renv %2$s.
+      - Use `renv::record(\"%3$s\")` to record renv %1$s in the lockfile.
+      - Use `renv::restore(packages = \"renv\")` to install renv %2$s into the project library.
+    ")
+    catf(fmt, friendly, renv_bootstrap_version_friendly(version), remote)
+  
+    FALSE
+  
+  }
+  
+  renv_bootstrap_validate_version_dev <- function(version, description) {
+    expected <- description[["RemoteSha"]]
+    is.character(expected) && startswith(expected, version)
+  }
+  
+  renv_bootstrap_validate_version_release <- function(version, description) {
+    expected <- description[["Version"]]
+    is.character(expected) && identical(expected, version)
+  }
+  
+  renv_bootstrap_hash_text <- function(text) {
+  
+    hashfile <- tempfile("renv-hash-")
+    on.exit(unlink(hashfile), add = TRUE)
+  
+    writeLines(text, con = hashfile)
+    tools::md5sum(hashfile)
+  
+  }
+  
+  renv_bootstrap_load <- function(project, libpath, version) {
+  
+    # try to load renv from the project library
+    if (!requireNamespace("renv", lib.loc = libpath, quietly = TRUE))
+      return(FALSE)
+  
+    # warn if the version of renv loaded does not match
+    renv_bootstrap_validate_version(version)
+  
+    # execute renv load hooks, if any
+    hooks <- getHook("renv::autoload")
+    for (hook in hooks)
+      if (is.function(hook))
+        tryCatch(hook(), error = warnify)
+  
+    # load the project
+    renv::load(project)
+  
+    TRUE
+  
+  }
+  
+  renv_bootstrap_profile_load <- function(project) {
+  
+    # if RENV_PROFILE is already set, just use that
+    profile <- Sys.getenv("RENV_PROFILE", unset = NA)
+    if (!is.na(profile) && nzchar(profile))
+      return(profile)
+  
+    # check for a profile file (nothing to do if it doesn't exist)
+    path <- renv_bootstrap_paths_renv("profile", profile = FALSE, project = project)
+    if (!file.exists(path))
+      return(NULL)
+  
+    # read the profile, and set it if it exists
+    contents <- readLines(path, warn = FALSE)
+    if (length(contents) == 0L)
+      return(NULL)
+  
+    # set RENV_PROFILE
+    profile <- contents[[1L]]
+    if (!profile %in% c("", "default"))
+      Sys.setenv(RENV_PROFILE = profile)
+  
+    profile
+  
+  }
+  
+  renv_bootstrap_profile_prefix <- function() {
+    profile <- renv_bootstrap_profile_get()
+    if (!is.null(profile))
+      return(file.path("profiles", profile, "renv"))
+  }
+  
+  renv_bootstrap_profile_get <- function() {
+    profile <- Sys.getenv("RENV_PROFILE", unset = "")
+    renv_bootstrap_profile_normalize(profile)
+  }
+  
+  renv_bootstrap_profile_set <- function(profile) {
+    profile <- renv_bootstrap_profile_normalize(profile)
+    if (is.null(profile))
+      Sys.unsetenv("RENV_PROFILE")
+    else
+      Sys.setenv(RENV_PROFILE = profile)
+  }
+  
+  renv_bootstrap_profile_normalize <- function(profile) {
+  
+    if (is.null(profile) || profile %in% c("", "default"))
+      return(NULL)
+  
+    profile
+  
+  }
+  
+  renv_bootstrap_path_absolute <- function(path) {
+  
+    substr(path, 1L, 1L) %in% c("~", "/", "\\") || (
+      substr(path, 1L, 1L) %in% c(letters, LETTERS) &&
+      substr(path, 2L, 3L) %in% c(":/", ":\\")
+    )
+  
+  }
+  
+  renv_bootstrap_paths_renv <- function(..., profile = TRUE, project = NULL) {
+    renv <- Sys.getenv("RENV_PATHS_RENV", unset = "renv")
+    root <- if (renv_bootstrap_path_absolute(renv)) NULL else project
+    prefix <- if (profile) renv_bootstrap_profile_prefix()
+    components <- c(root, renv, prefix, ...)
+    paste(components, collapse = "/")
+  }
+  
+  renv_bootstrap_project_type <- function(path) {
+  
+    descpath <- file.path(path, "DESCRIPTION")
+    if (!file.exists(descpath))
+      return("unknown")
+  
+    desc <- tryCatch(
+      read.dcf(descpath, all = TRUE),
+      error = identity
+    )
+  
+    if (inherits(desc, "error"))
+      return("unknown")
+  
+    type <- desc$Type
+    if (!is.null(type))
+      return(tolower(type))
+  
+    package <- desc$Package
+    if (!is.null(package))
+      return("package")
+  
+    "unknown"
+  
+  }
+  
+  renv_bootstrap_user_dir <- function() {
+    dir <- renv_bootstrap_user_dir_impl()
+    path.expand(chartr("\\", "/", dir))
+  }
+  
+  renv_bootstrap_user_dir_impl <- function() {
+  
+    # use local override if set
+    override <- getOption("renv.userdir.override")
+    if (!is.null(override))
+      return(override)
+  
+    # use R_user_dir if available
+    tools <- asNamespace("tools")
+    if (is.function(tools$R_user_dir))
+      return(tools$R_user_dir("renv", "cache"))
+  
+    # try using our own backfill for older versions of R
+    envvars <- c("R_USER_CACHE_DIR", "XDG_CACHE_HOME")
+    for (envvar in envvars) {
+      root <- Sys.getenv(envvar, unset = NA)
+      if (!is.na(root))
+        return(file.path(root, "R/renv"))
+    }
+  
+    # use platform-specific default fallbacks
+    if (Sys.info()[["sysname"]] == "Windows")
+      file.path(Sys.getenv("LOCALAPPDATA"), "R/cache/R/renv")
+    else if (Sys.info()[["sysname"]] == "Darwin")
+      "~/Library/Caches/org.R-project.R/R/renv"
+    else
+      "~/.cache/R/renv"
+  
+  }
+  
+  renv_bootstrap_version_friendly <- function(version, shafmt = NULL, sha = NULL) {
+    sha <- sha %||% attr(version, "sha", exact = TRUE)
+    parts <- c(version, sprintf(shafmt %||% " [sha: %s]", substring(sha, 1L, 7L)))
+    paste(parts, collapse = "")
+  }
+  
+  renv_bootstrap_exec <- function(project, libpath, version) {
+    if (!renv_bootstrap_load(project, libpath, version))
+      renv_bootstrap_run(version, libpath)
+  }
+  
+  renv_bootstrap_run <- function(version, libpath) {
+  
+    # perform bootstrap
+    bootstrap(version, libpath)
+  
+    # exit early if we're just testing bootstrap
+    if (!is.na(Sys.getenv("RENV_BOOTSTRAP_INSTALL_ONLY", unset = NA)))
+      return(TRUE)
+  
+    # try again to load
+    if (requireNamespace("renv", lib.loc = libpath, quietly = TRUE)) {
+      return(renv::load(project = getwd()))
+    }
+  
+    # failed to download or load renv; warn the user
+    msg <- c(
+      "Failed to find an renv installation: the project will not be loaded.",
+      "Use `renv::activate()` to re-initialize the project."
+    )
+  
+    warning(paste(msg, collapse = "\n"), call. = FALSE)
+  
+  }
+  
+  renv_json_read <- function(file = NULL, text = NULL) {
+  
+    jlerr <- NULL
+  
+    # if jsonlite is loaded, use that instead
+    if ("jsonlite" %in% loadedNamespaces()) {
+  
+      json <- tryCatch(renv_json_read_jsonlite(file, text), error = identity)
+      if (!inherits(json, "error"))
+        return(json)
+  
+      jlerr <- json
+  
+    }
+  
+    # otherwise, fall back to the default JSON reader
+    json <- tryCatch(renv_json_read_default(file, text), error = identity)
+    if (!inherits(json, "error"))
+      return(json)
+  
+    # report an error
+    if (!is.null(jlerr))
+      stop(jlerr)
+    else
+      stop(json)
+  
+  }
+  
+  renv_json_read_jsonlite <- function(file = NULL, text = NULL) {
+    text <- paste(text %||% readLines(file, warn = FALSE), collapse = "\n")
+    jsonlite::fromJSON(txt = text, simplifyVector = FALSE)
+  }
+  
+  renv_json_read_default <- function(file = NULL, text = NULL) {
+  
+    # find strings in the JSON
+    text <- paste(text %||% readLines(file, warn = FALSE), collapse = "\n")
+    pattern <- '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'
+    locs <- gregexpr(pattern, text, perl = TRUE)[[1]]
+  
+    # if any are found, replace them with placeholders
+    replaced <- text
+    strings <- character()
+    replacements <- character()
+  
+    if (!identical(c(locs), -1L)) {
+  
+      # get the string values
+      starts <- locs
+      ends <- locs + attr(locs, "match.length") - 1L
+      strings <- substring(text, starts, ends)
+  
+      # only keep those requiring escaping
+      strings <- grep("[[\\]{}:]", strings, perl = TRUE, value = TRUE)
+  
+      # compute replacements
+      replacements <- sprintf('"\032%i\032"', seq_along(strings))
+  
+      # replace the strings
+      mapply(function(string, replacement) {
+        replaced <<- sub(string, replacement, replaced, fixed = TRUE)
+      }, strings, replacements)
+  
+    }
+  
+    # transform the JSON into something the R parser understands
+    transformed <- replaced
+    transformed <- gsub("{}", "`names<-`(list(), character())", transformed, fixed = TRUE)
+    transformed <- gsub("[[{]", "list(", transformed, perl = TRUE)
+    transformed <- gsub("[]}]", ")", transformed, perl = TRUE)
+    transformed <- gsub(":", "=", transformed, fixed = TRUE)
+    text <- paste(transformed, collapse = "\n")
+  
+    # parse it
+    json <- parse(text = text, keep.source = FALSE, srcfile = NULL)[[1L]]
+  
+    # construct map between source strings, replaced strings
+    map <- as.character(parse(text = strings))
+    names(map) <- as.character(parse(text = replacements))
+  
+    # convert to list
+    map <- as.list(map)
+  
+    # remap strings in object
+    remapped <- renv_json_read_remap(json, map)
+  
+    # evaluate
+    eval(remapped, envir = baseenv())
+  
+  }
+  
+  renv_json_read_remap <- function(json, map) {
+  
+    # fix names
+    if (!is.null(names(json))) {
+      lhs <- match(names(json), names(map), nomatch = 0L)
+      rhs <- match(names(map), names(json), nomatch = 0L)
+      names(json)[rhs] <- map[lhs]
+    }
+  
+    # fix values
+    if (is.character(json))
+      return(map[[json]] %||% json)
+  
+    # handle true, false, null
+    if (is.name(json)) {
+      text <- as.character(json)
+      if (text == "true")
+        return(TRUE)
+      else if (text == "false")
+        return(FALSE)
+      else if (text == "null")
+        return(NULL)
+    }
+  
+    # recurse
+    if (is.recursive(json)) {
+      for (i in seq_along(json)) {
+        json[i] <- list(renv_json_read_remap(json[[i]], map))
+      }
+    }
+  
+    json
+  
+  }
+
+  # load the renv profile, if any
+  renv_bootstrap_profile_load(project)
+
+  # construct path to library root
+  root <- renv_bootstrap_library_root(project)
+
+  # construct library prefix for platform
+  prefix <- renv_bootstrap_platform_prefix()
+
+  # construct full libpath
+  libpath <- file.path(root, prefix)
+
+  # run bootstrap code
+  renv_bootstrap_exec(project, libpath, version)
+
+  invisible()
+
+})
diff --git a/renv/settings.json b/renv/settings.json
new file mode 100644
index 0000000..74c1d4b
--- /dev/null
+++ b/renv/settings.json
@@ -0,0 +1,19 @@
+{
+  "bioconductor.version": null,
+  "external.libraries": [],
+  "ignored.packages": [],
+  "package.dependency.fields": [
+    "Imports",
+    "Depends",
+    "LinkingTo"
+  ],
+  "ppm.enabled": null,
+  "ppm.ignored.urls": [],
+  "r.version": null,
+  "snapshot.type": "explicit",
+  "use.cache": true,
+  "vcs.ignore.cellar": true,
+  "vcs.ignore.library": true,
+  "vcs.ignore.local": true,
+  "vcs.manage.ignores": true
+}
-- 
GitLab


From ce82c68c0e59b6b8344c8ba0f87258e8596dda04 Mon Sep 17 00:00:00 2001
From: Laurent BEAULATON <laurent.beaulaton@ofb.gouv.fr>
Date: Thu, 3 Oct 2024 14:46:55 +0200
Subject: [PATCH 04/11] Renv

---
 .Rbuildignore   |   1 +
 .gitlab-ci.yml  |  70 ++++++++++++++++----------------
 renv.lock       |  80 ++++++++++++++++++------------------
 renv/activate.R | 105 +++++++++++++++++++++++++++++++++++++++++++-----
 4 files changed, 171 insertions(+), 85 deletions(-)

diff --git a/.Rbuildignore b/.Rbuildignore
index 74e08d2..5258263 100644
--- a/.Rbuildignore
+++ b/.Rbuildignore
@@ -29,3 +29,4 @@ tests/testhat/\~import_coe20092015\.csv
 ^public
 ^ci
 ^Scripts
+^cache
\ No newline at end of file
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index cd1bf1b..ba5263d 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -35,12 +35,16 @@ variables:
   REPO_NAME: "{repo_name}"
   R_LIBS: "ci/lib"
   R_LIBS_USER: "ci/lib"
+  RENV_PATHS_CACHE: "cache"
+  RENV_PATHS_LIBRARY: "renv/library"
   
 
 #key for caching per branch    
 cache:
   key: $CI_COMMIT_REF_SLUG
   paths:
+    - ${RENV_PATHS_CACHE}
+    - ${RENV_PATHS_LIBRARY}
     - ${R_LIBS_USER}
     
 
@@ -63,31 +67,16 @@ buildpackage:
   only:
     - main
     - master
-    - 0.6.0.7
+    - 0.6.0.7    
   needs: []
   script:
       - mkdir -p $R_LIBS_USER
+      - mkdir -p $RENV_PATHS_CACHE
       - mkdir -p public
-      # from https://www.algorist.co.uk/post/building-a-ci-pipeline-for-r-packages-in-gitlab/
-      - echo 'R_LIBS=$R_LIBS_USER' > .Renviron
-      - echo 'R_LIBS_USER=$R_LIBS_USER' >> .Renviron
-      - echo 'R_LIBS_SITE=$R_LIBS_USER' >> .Renviron
-      #- echo 'PGPASSWORD=$POSTGRES_PASSWORD' >> .Renviron # I need to pass the variable to use later in test
-      # d --deps dependencies, r 
-      - apt-get update -y
-      - apt-get install -y libpq-dev
-      - apt-get install -y r-cran-rodbc
-      #- install2.r --deps TRUE --libloc "ci/lib" --repos "https://pbil.univ-lyon1.fr/CRAN/" --error --skipinstalled  RODBC
+      - Rscript -e 'source("renv/activate.R")'
       - Rscript -e 'if(!requireNamespace("pak", quietly = TRUE)) {install.packages("pak")}'
-      - Rscript -e 'pak::pkg_install(pkg = c("stacomirtools", "RPostgres", "xtable", "magrittr", "intervals", "RColorBrewer"), lib = "'$R_LIBS_USER'", upgrade = TRUE)'
-      # these are for code coverage
-      - Rscript -e 'pak::pkg_install(pkg = c("covr", "DT"), lib = "'$R_LIBS_USER'", upgrade = TRUE)'
-      - Rscript -e 'pak::pkg_install(pkg = c("reshape2", "graphics", "utils", "stats", "lattice", "grDevices", "Hmisc", "lubridate", "mgcv", "withr", "XML"), lib = "'$R_LIBS_USER'", upgrade = TRUE)'
-      - rm -rf /tmp/downloaded_packages
-      #- r -e 'install.packages(c("stacomirtools","RPostgres","xtable","magrittr","intervals","RColorBrewer"), lib= "ci/lib", dependencies = TRUE, repos =)'> public/logr
-      #- r -e 'install.packages(c(), lib= "ci/lib", repos= "https://pbil.univ-lyon1.fr/CRAN/", dependencies = TRUE)'>> public/logr  
-      #- r -e 'install.packages(c("xml2"), repos= "https://pbil.univ-lyon1.fr/CRAN/", lib= "ci/lib", dependencies = TRUE)'>> public/logr # this one is for test with JUNIT reporter 
-      #- if [[ $CI_DEFAULT_BRANCH == "master" || $CI_DEFAULT_BRANCH = "main" || $CI_DEFAULT_BRANCH = "0.6.0.7"]]; then echo "OK - default branch is master or main or 0.6.0.7"; else echo "default branch is not master or main or 0.6.0.7, please add yours ($CI_0.6.0.7_BRANCH) where needed, as well as in the present line of code" ; exit 1; fi
+      - Rscript -e 'pak::pkg_install(pkg = c("rcmdcheck", "renv"), upgrade = FALSE)'
+      - Rscript -e 'renv::restore()'    
       - r -e 'devtools::build(binary = TRUE, path="public", vignettes=TRUE, manual=TRUE)' 
       - r -e 'devtools::build(binary = FALSE, path="public", vignettes=TRUE)' 
   artifacts:
@@ -95,8 +84,6 @@ buildpackage:
     paths:
       - public
       - ${R_LIBS_USER}
-      - "$(ls -rt *.zip |tail -1)" 
-      - "$(ls -rt *.tar.gz |tail -1)" 
 
 
                            
@@ -146,11 +133,27 @@ checkerrors:
     - 0.6.0.7
   script:
     - mkdir -p public/check
-    - echo 'R_LIBS=$R_LIBS_USER' > .Renviron
-    - echo 'R_LIBS_USER=$R_LIBS_USER' >> .Renviron
-    - echo 'R_LIBS_SITE=$R_LIBS_USER' >> .Renviron
-    - r -e 'devtools::load_all();devtools::check(document = FALSE, args = "--no-tests", check_dir="public/check")' 
-    #- check.r --repo "https://pbil.univ-lyon1.fr/CRAN/" --install-deps --library "ci/lib" 
+    - r -e 'devtools::load_all();devtools::check(document = FALSE, args = "--no-tests", check_dir="public/check")'
+  artifacts:
+    when: always  
+    paths:
+      - public/check
+    expire_in: 30 days
+
+checkerrors_update:
+  before_script:
+  - apt-get update
+  - apt-get install -y qpdf  
+  stage: check
+  needs: ["buildpackage"]
+  only:
+    - main
+    - master
+    - 0.6.0.7
+  script:
+    - mkdir -p public/check
+    - Rscript -e 'renv::update()'
+    - r -e 'devtools::load_all();devtools::check(document = FALSE, args = "--no-tests", check_dir="public/check")'
   artifacts:
     when: always  
     paths:
@@ -164,13 +167,10 @@ unittests:
   only:
     - main
     - master
-    - 0.6.0.7  
+    - 0.6.0.7
   script:
   
     - export PGPASSWORD=$POSTGRES_PASSWORD
-    - echo 'R_LIBS=$R_LIBS_USER' > .Renviron
-    - echo 'R_LIBS_USER=$R_LIBS_USER' >> .Renviron
-    - echo 'R_LIBS_SITE=$R_LIBS_USER' >> .Renviron
     - echo 'PGPASSWORD=$POSTGRES_PASSWORD' >> .Renviron
     - r -e 'devtools::load_all();options(stacomiR.dbname = "bd_contmig_nat",stacomiR.host ="db",	stacomiR.port = "5432",	stacomiR.user = "postgres",	stacomiR.password = "postgres"); test <- capture.output(devtools::test(reporter="junit")) ; XML::saveXML(XML::xmlParse(test[grep("?xml version",test):length(test)]), file="public/test.xml")'
     - r -e 'a<-1'
@@ -197,13 +197,11 @@ codecov:
     - master
     - 0.6.0.7
   script:
-    - echo 'R_LIBS=$R_LIBS_USER' > .Renviron
-    - echo 'R_LIBS_USER=$R_LIBS_USER' >> .Renviron
-    - echo 'R_LIBS_SITE=$R_LIBS_USER' >> .Renviron
-    #- echo 'PGPASSWORD=$POSTGRES_PASSWORD' >> .Renviron
+    # these are for code coverage
+    - Rscript -e 'pak::pkg_install(pkg = c("covr", "DT"), upgrade = FALSE)'
     - r -e 'Sys.setenv("NOT_CRAN"= "true"); devtools::load_all(); options(stacomiR.dbname = "bd_contmig_nat",stacomiR.host ="db",	stacomiR.port = "5432",	stacomiR.user = "postgres",	stacomiR.password = "postgres");co <- covr::package_coverage(type="all", quiet=FALSE, clean=FALSE);print(co);covr:::print.coverage(co);covr::report(co, file.path("dev/codecoverage_report", paste0("stacomiR-report.html")))' 
     # the following should be used when pages is set
-    #- r -e 'covr::gitlab(file = "public/coverage.html", type = c("all"), quiet = FALSE)'
+    - r -e 'covr::gitlab(file = "public/coverage.html", type = c("all"), quiet = FALSE)'
   #A line like Code coverage: 67.89% of lines covered would match.
   coverage: '/Coverage: \d+\.\d+/' 
   artifacts:
diff --git a/renv.lock b/renv.lock
index 53554c0..b518bbc 100644
--- a/renv.lock
+++ b/renv.lock
@@ -143,24 +143,24 @@
     },
     "Rcpp": {
       "Package": "Rcpp",
-      "Version": "1.0.12",
+      "Version": "1.0.13",
       "Source": "Repository",
       "Repository": "CRAN",
       "Requirements": [
         "methods",
         "utils"
       ],
-      "Hash": "5ea2700d21e038ace58269ecdbeb9ec0"
+      "Hash": "f27411eb6d9c3dada5edd444b8416675"
     },
     "backports": {
       "Package": "backports",
-      "Version": "1.4.1",
+      "Version": "1.5.0",
       "Source": "Repository",
       "Repository": "CRAN",
       "Requirements": [
         "R"
       ],
-      "Hash": "c39fbec8a30d23e721980b8afb31984c"
+      "Hash": "e1e1b9d75c37401117b636b7ae50827a"
     },
     "base64enc": {
       "Package": "base64enc",
@@ -210,7 +210,7 @@
     },
     "bslib": {
       "Package": "bslib",
-      "Version": "0.7.0",
+      "Version": "0.8.0",
       "Source": "Repository",
       "Repository": "CRAN",
       "Requirements": [
@@ -228,7 +228,7 @@
         "rlang",
         "sass"
       ],
-      "Hash": "8644cc53f43828f19133548195d7e59e"
+      "Hash": "b299c6741ca9746fb227debcb0f9fb6c"
     },
     "cachem": {
       "Package": "cachem",
@@ -243,7 +243,7 @@
     },
     "checkmate": {
       "Package": "checkmate",
-      "Version": "2.3.1",
+      "Version": "2.3.2",
       "Source": "Repository",
       "Repository": "CRAN",
       "Requirements": [
@@ -251,18 +251,18 @@
         "backports",
         "utils"
       ],
-      "Hash": "c01cab1cb0f9125211a6fc99d540e315"
+      "Hash": "0e14e01ce07e7c88fd25de6d4260d26b"
     },
     "cli": {
       "Package": "cli",
-      "Version": "3.6.2",
+      "Version": "3.6.3",
       "Source": "Repository",
       "Repository": "CRAN",
       "Requirements": [
         "R",
         "utils"
       ],
-      "Hash": "1216ac65ac55ec0058a6f75d7ca0fd52"
+      "Hash": "b21916dd77a27642b447374a5d30ecf3"
     },
     "cluster": {
       "Package": "cluster",
@@ -280,7 +280,7 @@
     },
     "colorspace": {
       "Package": "colorspace",
-      "Version": "2.1-0",
+      "Version": "2.1-1",
       "Source": "Repository",
       "Repository": "CRAN",
       "Requirements": [
@@ -290,39 +290,39 @@
         "methods",
         "stats"
       ],
-      "Hash": "f20c47fd52fae58b4e377c37bb8c335b"
+      "Hash": "d954cb1c57e8d8b756165d7ba18aa55a"
     },
     "cpp11": {
       "Package": "cpp11",
-      "Version": "0.4.7",
+      "Version": "0.5.0",
       "Source": "Repository",
       "Repository": "CRAN",
       "Requirements": [
         "R"
       ],
-      "Hash": "5a295d7d963cc5035284dcdbaf334f4e"
+      "Hash": "91570bba75d0c9d3f1040c835cee8fba"
     },
     "data.table": {
       "Package": "data.table",
-      "Version": "1.15.4",
+      "Version": "1.16.0",
       "Source": "Repository",
       "Repository": "CRAN",
       "Requirements": [
         "R",
         "methods"
       ],
-      "Hash": "8ee9ac56ef633d0c7cab8b2ca87d683e"
+      "Hash": "fb24e05d4a91d8b1c7ff8e284bde834a"
     },
     "digest": {
       "Package": "digest",
-      "Version": "0.6.35",
+      "Version": "0.6.37",
       "Source": "Repository",
       "Repository": "CRAN",
       "Requirements": [
         "R",
         "utils"
       ],
-      "Hash": "698ece7ba5a4fa4559e3d537e7ec3d31"
+      "Hash": "33698c4b3127fc9f506654607fb73676"
     },
     "dplyr": {
       "Package": "dplyr",
@@ -349,14 +349,13 @@
     },
     "evaluate": {
       "Package": "evaluate",
-      "Version": "0.23",
+      "Version": "1.0.0",
       "Source": "Repository",
       "Repository": "CRAN",
       "Requirements": [
-        "R",
-        "methods"
+        "R"
       ],
-      "Hash": "daf4a1246be12c1fa8c7705a0935c1a0"
+      "Hash": "6b567375113ceb7d9f800de4dd42218e"
     },
     "fansi": {
       "Package": "fansi",
@@ -398,7 +397,7 @@
     },
     "foreign": {
       "Package": "foreign",
-      "Version": "0.8-86",
+      "Version": "0.8-87",
       "Source": "Repository",
       "Repository": "CRAN",
       "Requirements": [
@@ -407,7 +406,7 @@
         "stats",
         "utils"
       ],
-      "Hash": "550170303dbb19d07b2bcc288068e7dc"
+      "Hash": "81fc09bdeab0077a73927ed1243404b6"
     },
     "fs": {
       "Package": "fs",
@@ -458,14 +457,14 @@
     },
     "glue": {
       "Package": "glue",
-      "Version": "1.7.0",
+      "Version": "1.8.0",
       "Source": "Repository",
       "Repository": "CRAN",
       "Requirements": [
         "R",
         "methods"
       ],
-      "Hash": "e0b3a53876554bd45879e596cdb10a52"
+      "Hash": "5899f1eaa825580172bb56c08266f37c"
     },
     "gridExtra": {
       "Package": "gridExtra",
@@ -523,7 +522,7 @@
     },
     "htmlTable": {
       "Package": "htmlTable",
-      "Version": "2.4.2",
+      "Version": "2.4.3",
       "Source": "Repository",
       "Repository": "CRAN",
       "Requirements": [
@@ -537,7 +536,7 @@
         "rstudioapi",
         "stringr"
       ],
-      "Hash": "0164d8cade33fac2190703da7e6e3241"
+      "Hash": "ca027d8771f2c039aed82f00a81e725b"
     },
     "htmltools": {
       "Package": "htmltools",
@@ -606,13 +605,13 @@
     },
     "jsonlite": {
       "Package": "jsonlite",
-      "Version": "1.8.8",
+      "Version": "1.8.9",
       "Source": "Repository",
       "Repository": "CRAN",
       "Requirements": [
         "methods"
       ],
-      "Hash": "e1b9c55281c5adc4dd113652d9e26768"
+      "Hash": "4e993b65c2c3ffbffce7bb3e2c6f832b"
     },
     "knitr": {
       "Package": "knitr",
@@ -754,7 +753,7 @@
     },
     "nlme": {
       "Package": "nlme",
-      "Version": "3.1-165",
+      "Version": "3.1-166",
       "Source": "Repository",
       "Repository": "CRAN",
       "Requirements": [
@@ -764,7 +763,7 @@
         "stats",
         "utils"
       ],
-      "Hash": "2769a88be217841b1f33ed469675c3cc"
+      "Hash": "ccbb8846be320b627e6aa2b4616a2ded"
     },
     "nnet": {
       "Package": "nnet",
@@ -850,13 +849,13 @@
     },
     "renv": {
       "Package": "renv",
-      "Version": "1.0.7",
+      "Version": "1.0.9",
       "Source": "Repository",
       "Repository": "CRAN",
       "Requirements": [
         "utils"
       ],
-      "Hash": "397b7b2a265bc5a7a06852524dabae20"
+      "Hash": "ef233f0e9064fc88c898b340c9add5c2"
     },
     "reshape2": {
       "Package": "reshape2",
@@ -1053,13 +1052,13 @@
     },
     "tinytex": {
       "Package": "tinytex",
-      "Version": "0.51",
+      "Version": "0.53",
       "Source": "Repository",
       "Repository": "CRAN",
       "Requirements": [
         "xfun"
       ],
-      "Hash": "d44e2fcd2e4e076f0aac540208559d1d"
+      "Hash": "9db859e8aabbb474293dde3097839420"
     },
     "utf8": {
       "Package": "utf8",
@@ -1122,15 +1121,16 @@
     },
     "xfun": {
       "Package": "xfun",
-      "Version": "0.44",
+      "Version": "0.47",
       "Source": "Repository",
       "Repository": "CRAN",
       "Requirements": [
+        "R",
         "grDevices",
         "stats",
         "tools"
       ],
-      "Hash": "317a0538d32f4a009658bcedb7923f4b"
+      "Hash": "36ab21660e2d095fef0d83f689e0477c"
     },
     "xtable": {
       "Package": "xtable",
@@ -1146,10 +1146,10 @@
     },
     "yaml": {
       "Package": "yaml",
-      "Version": "2.3.8",
+      "Version": "2.3.10",
       "Source": "Repository",
       "Repository": "CRAN",
-      "Hash": "29240487a071f535f5e5d5a323b7afbd"
+      "Hash": "51dab85c6c98e50a18d7551e9d49f76c"
     }
   }
 }
diff --git a/renv/activate.R b/renv/activate.R
index d13f993..c360bf2 100644
--- a/renv/activate.R
+++ b/renv/activate.R
@@ -2,7 +2,7 @@
 local({
 
   # the requested version of renv
-  version <- "1.0.7"
+  version <- "1.0.9"
   attr(version, "sha") <- NULL
 
   # the project directory
@@ -98,6 +98,66 @@ local({
     unloadNamespace("renv")
 
   # load bootstrap tools   
+  ansify <- function(text) {
+    if (renv_ansify_enabled())
+      renv_ansify_enhanced(text)
+    else
+      renv_ansify_default(text)
+  }
+  
+  renv_ansify_enabled <- function() {
+  
+    override <- Sys.getenv("RENV_ANSIFY_ENABLED", unset = NA)
+    if (!is.na(override))
+      return(as.logical(override))
+  
+    pane <- Sys.getenv("RSTUDIO_CHILD_PROCESS_PANE", unset = NA)
+    if (identical(pane, "build"))
+      return(FALSE)
+  
+    testthat <- Sys.getenv("TESTTHAT", unset = "false")
+    if (tolower(testthat) %in% "true")
+      return(FALSE)
+  
+    iderun <- Sys.getenv("R_CLI_HAS_HYPERLINK_IDE_RUN", unset = "false")
+    if (tolower(iderun) %in% "false")
+      return(FALSE)
+  
+    TRUE
+  
+  }
+  
+  renv_ansify_default <- function(text) {
+    text
+  }
+  
+  renv_ansify_enhanced <- function(text) {
+  
+    # R help links
+    pattern <- "`\\?(renv::(?:[^`])+)`"
+    replacement <- "`\033]8;;ide:help:\\1\a?\\1\033]8;;\a`"
+    text <- gsub(pattern, replacement, text, perl = TRUE)
+  
+    # runnable code
+    pattern <- "`(renv::(?:[^`])+)`"
+    replacement <- "`\033]8;;ide:run:\\1\a\\1\033]8;;\a`"
+    text <- gsub(pattern, replacement, text, perl = TRUE)
+  
+    # return ansified text
+    text
+  
+  }
+  
+  renv_ansify_init <- function() {
+  
+    envir <- renv_envir_self()
+    if (renv_ansify_enabled())
+      assign("ansify", renv_ansify_enhanced, envir = envir)
+    else
+      assign("ansify", renv_ansify_default, envir = envir)
+  
+  }
+  
   `%||%` <- function(x, y) {
     if (is.null(x)) y else x
   }
@@ -142,7 +202,10 @@ local({
     # compute common indent
     indent <- regexpr("[^[:space:]]", lines)
     common <- min(setdiff(indent, -1L)) - leave
-    paste(substring(lines, common), collapse = "\n")
+    text <- paste(substring(lines, common), collapse = "\n")
+  
+    # substitute in ANSI links for executable renv code
+    ansify(text)
   
   }
   
@@ -306,7 +369,11 @@ local({
     )
   
     if ("headers" %in% names(formals(utils::download.file)))
-      args$headers <- renv_bootstrap_download_custom_headers(url)
+    {
+      headers <- renv_bootstrap_download_custom_headers(url)
+      if (length(headers) && is.character(headers))
+        args$headers <- headers
+    }
   
     do.call(utils::download.file, args)
   
@@ -385,10 +452,22 @@ local({
     for (type in types) {
       for (repos in renv_bootstrap_repos()) {
   
+        # build arguments for utils::available.packages() call
+        args <- list(type = type, repos = repos)
+  
+        # add custom headers if available -- note that
+        # utils::available.packages() will pass this to download.file()
+        if ("headers" %in% names(formals(utils::download.file)))
+        {
+          headers <- renv_bootstrap_download_custom_headers(url)
+          if (length(headers) && is.character(headers))
+            args$headers <- headers
+        }
+  
         # retrieve package database
         db <- tryCatch(
           as.data.frame(
-            utils::available.packages(type = type, repos = repos),
+            do.call(utils::available.packages, args),
             stringsAsFactors = FALSE
           ),
           error = identity
@@ -470,6 +549,14 @@ local({
   
   }
   
+  renv_bootstrap_github_token <- function() {
+    for (envvar in c("GITHUB_TOKEN", "GITHUB_PAT", "GH_TOKEN")) {
+      envval <- Sys.getenv(envvar, unset = NA)
+      if (!is.na(envval))
+        return(envval)
+    }
+  }
+  
   renv_bootstrap_download_github <- function(version) {
   
     enabled <- Sys.getenv("RENV_BOOTSTRAP_FROM_GITHUB", unset = "TRUE")
@@ -477,16 +564,16 @@ local({
       return(FALSE)
   
     # prepare download options
-    pat <- Sys.getenv("GITHUB_PAT")
-    if (nzchar(Sys.which("curl")) && nzchar(pat)) {
+    token <- renv_bootstrap_github_token()
+    if (nzchar(Sys.which("curl")) && nzchar(token)) {
       fmt <- "--location --fail --header \"Authorization: token %s\""
-      extra <- sprintf(fmt, pat)
+      extra <- sprintf(fmt, token)
       saved <- options("download.file.method", "download.file.extra")
       options(download.file.method = "curl", download.file.extra = extra)
       on.exit(do.call(base::options, saved), add = TRUE)
-    } else if (nzchar(Sys.which("wget")) && nzchar(pat)) {
+    } else if (nzchar(Sys.which("wget")) && nzchar(token)) {
       fmt <- "--header=\"Authorization: token %s\""
-      extra <- sprintf(fmt, pat)
+      extra <- sprintf(fmt, token)
       saved <- options("download.file.method", "download.file.extra")
       options(download.file.method = "wget", download.file.extra = extra)
       on.exit(do.call(base::options, saved), add = TRUE)
-- 
GitLab


From b7c6faf9a0fdbf8d9bd22033a7a092cb5048f74d Mon Sep 17 00:00:00 2001
From: Laurent BEAULATON <laurent.beaulaton@ofb.gouv.fr>
Date: Thu, 3 Oct 2024 22:43:51 +0200
Subject: [PATCH 05/11] Draft: Resolve "Bugs in test on gitlab"

---
 .Rbuildignore                                |   5 +-
 .gitignore                                   |   2 +
 .gitlab-ci.yml                               | 201 +++----------------
 _pkgdown.yml                                 |   4 +
 gitlab-ci/buildpackage.gitlab-ci.yml         |  35 ++++
 gitlab-ci/check.gitlab-ci.yml                |  32 +++
 gitlab-ci/codecov.gitlab-ci.yml              |  32 +++
 gitlab-ci/image.gitlab-ci.yml                |  11 +
 gitlab-ci/integration.gitlab-ci.yml          |  31 +++
 gitlab-ci/pkgdown.gitlab-ci.yml              |  32 +++
 gitlab-ci/rules.gitlab-ci.yml                |  19 ++
 gitlab-ci/service.gitlab-ci.yml              |  10 +
 gitlab-ci/testdb.gitlab-ci.yml               |  25 +++
 gitlab-ci/unittests.gitlab-ci.yml            |  37 ++++
 gitlab-ci/update_check.gitlab-ci.yml         |  33 +++
 pkgdown/favicon/apple-touch-icon-120x120.png | Bin 0 -> 6541 bytes
 pkgdown/favicon/apple-touch-icon-152x152.png | Bin 0 -> 8870 bytes
 pkgdown/favicon/apple-touch-icon-180x180.png | Bin 0 -> 11015 bytes
 pkgdown/favicon/apple-touch-icon-60x60.png   | Bin 0 -> 2478 bytes
 pkgdown/favicon/apple-touch-icon-76x76.png   | Bin 0 -> 3423 bytes
 pkgdown/favicon/apple-touch-icon.png         | Bin 0 -> 11015 bytes
 pkgdown/favicon/favicon-16x16.png            | Bin 0 -> 877 bytes
 pkgdown/favicon/favicon-32x32.png            | Bin 0 -> 1754 bytes
 pkgdown/favicon/favicon.ico                  | Bin 0 -> 15086 bytes
 24 files changed, 331 insertions(+), 178 deletions(-)
 create mode 100644 _pkgdown.yml
 create mode 100644 gitlab-ci/buildpackage.gitlab-ci.yml
 create mode 100644 gitlab-ci/check.gitlab-ci.yml
 create mode 100644 gitlab-ci/codecov.gitlab-ci.yml
 create mode 100644 gitlab-ci/image.gitlab-ci.yml
 create mode 100644 gitlab-ci/integration.gitlab-ci.yml
 create mode 100644 gitlab-ci/pkgdown.gitlab-ci.yml
 create mode 100644 gitlab-ci/rules.gitlab-ci.yml
 create mode 100644 gitlab-ci/service.gitlab-ci.yml
 create mode 100644 gitlab-ci/testdb.gitlab-ci.yml
 create mode 100644 gitlab-ci/unittests.gitlab-ci.yml
 create mode 100644 gitlab-ci/update_check.gitlab-ci.yml
 create mode 100644 pkgdown/favicon/apple-touch-icon-120x120.png
 create mode 100644 pkgdown/favicon/apple-touch-icon-152x152.png
 create mode 100644 pkgdown/favicon/apple-touch-icon-180x180.png
 create mode 100644 pkgdown/favicon/apple-touch-icon-60x60.png
 create mode 100644 pkgdown/favicon/apple-touch-icon-76x76.png
 create mode 100644 pkgdown/favicon/apple-touch-icon.png
 create mode 100644 pkgdown/favicon/favicon-16x16.png
 create mode 100644 pkgdown/favicon/favicon-32x32.png
 create mode 100644 pkgdown/favicon/favicon.ico

diff --git a/.Rbuildignore b/.Rbuildignore
index 5258263..fb2cf7d 100644
--- a/.Rbuildignore
+++ b/.Rbuildignore
@@ -29,4 +29,7 @@ tests/testhat/\~import_coe20092015\.csv
 ^public
 ^ci
 ^Scripts
-^cache
\ No newline at end of file
+^cache
+^_pkgdown\.yml$
+^docs$
+^pkgdown$
diff --git a/.gitignore b/.gitignore
index 39bebef..479a553 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,3 +7,5 @@ stacomir.Rproj
 /doc/
 /Meta/
 /~import_coe20092015.csv
+.dbeaver/project-settings.json
+docs
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index ba5263d..0b405e5 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -7,87 +7,53 @@
 # public
 # For more information, see: https://docs.gitlab.com/ee/ci/yaml/index.html#stages
 
-image: rocker/tidyverse
-
-services:
-    - name:  registry.forgemia.inra.fr/stacomi/stacomi_db/$imagedb_name:$db_version-pg$postgres_version-ps$postgis_version
-      alias: host_db
-      
 stages:          # List of stages for jobs, and their order of execution
   - testdb
   - build  
-  #- document
+  - document
   - check
   - test
   - codecoverage
   - deploy
   
 variables:
-  tag_dev: "dev"
-  imagedb_name: "stacomi_db"
+  POSTGRES_PASSWORD: "postgres"
+  POSTGRES_HOSTNAME: "host_db"
+  stacomi_db_path: "registry.forgemia.inra.fr/stacomi/stacomi_db"
+  db_image_name: "stacomi_db"
   db_version: "0.6.1"
   postgres_version: "14"
   postgis_version: "3.2"
-  _R_CHECK_CRAN_INCOMING_: "false"
-  _R_CHECK_FORCE_SUGGESTS_: "true"
-  CODECOV_TOKEN: "CODECOV_TOKEN_STRING"
-  POSTGRES_PASSWORD: postgres
-  REPO_NAME: "{repo_name}"
-  R_LIBS: "ci/lib"
+  db_image_tagdev: "$db_version-pg$postgres_version-ps$postgis_version"
   R_LIBS_USER: "ci/lib"
   RENV_PATHS_CACHE: "cache"
   RENV_PATHS_LIBRARY: "renv/library"
-  
+  R_LIBS: "ci/lib"
+  CHECK_DIR: "$CI_PROJECT_DIR/ci/logs"
+  BUILD_DIR: "$CI_PROJECT_DIR/ci/build"
+  BUILD_LOGS_DIR: "$CI_PROJECT_DIR/ci/logs/$CI_PROJECT_NAME.Rcheck"
 
-#key for caching per branch    
+#key for caching per branch
 cache:
   key: $CI_COMMIT_REF_SLUG
   paths:
     - ${RENV_PATHS_CACHE}
     - ${RENV_PATHS_LIBRARY}
     - ${R_LIBS_USER}
-    
-
-
-test_db:
-  before_script:
-    - sleep 120 # waiting postgresql
-    - psql --version
-    - export PGPASSWORD=$POSTGRES_PASSWORD
-  image: postgres:${postgres_version}        
-  stage: testdb
-  script:
-    - psql -U postgres -h host_db  -c "SELECT * FROM pg_catalog.pg_tables WHERE schemaname != 'pg_catalog' AND schemaname != 'information_schema';"
-    - psql -U postgres -h host_db -c "select * from test.t_dispositifcomptage_dic" bd_contmig_nat
-    - export PGPASSWORD=test && psql -U test -h host_db -c "select * from test.t_dispositifcomptage_dic" bd_contmig_nat # test avec l'utilisateur iav pour vérfier les droits
-  
- 
-buildpackage:
-  stage: build 
-  only:
-    - main
-    - master
-    - 0.6.0.7    
-  needs: []
-  script:
-      - mkdir -p $R_LIBS_USER
-      - mkdir -p $RENV_PATHS_CACHE
-      - mkdir -p public
-      - Rscript -e 'source("renv/activate.R")'
-      - Rscript -e 'if(!requireNamespace("pak", quietly = TRUE)) {install.packages("pak")}'
-      - Rscript -e 'pak::pkg_install(pkg = c("rcmdcheck", "renv"), upgrade = FALSE)'
-      - Rscript -e 'renv::restore()'    
-      - r -e 'devtools::build(binary = TRUE, path="public", vignettes=TRUE, manual=TRUE)' 
-      - r -e 'devtools::build(binary = FALSE, path="public", vignettes=TRUE)' 
-  artifacts:
-    when: always
-    paths:
-      - public
-      - ${R_LIBS_USER}
 
+include:
+  - local: '/gitlab-ci/rules.gitlab-ci.yml'
+  - local: '/gitlab-ci/image.gitlab-ci.yml'
+  - local: '/gitlab-ci/service.gitlab-ci.yml'
+  - local: '/gitlab-ci/testdb.gitlab-ci.yml'
+  - local: '/gitlab-ci/buildpackage.gitlab-ci.yml'
+  - local: '/gitlab-ci/check.gitlab-ci.yml'
+  - local: '/gitlab-ci/update_check.gitlab-ci.yml'
+  - local: '/gitlab-ci/unittests.gitlab-ci.yml'
+  - local: '/gitlab-ci/codecov.gitlab-ci.yml'
+  - local: '/gitlab-ci/integration.gitlab-ci.yml'
+  - local: '/gitlab-ci/pkgdown.gitlab-ci.yml'
 
-                           
-                                    
 # pour lancer celui là il faudrait avoir un accès à un runner.... pour l'instant j'ai pas....
 #https://guillaumebriday.fr/installer-et-utiliser-les-gitlab-runners
 #https://forgemia.inra.fr/gaev/usecases/macosr
@@ -120,121 +86,6 @@ buildpackage:
 #    - r -e 'devtools::load_all()'   
 #    - r -e 'devtools::document()'
 
-# https://cran.r-project.org/web/packages/littler/vignettes/littler-examples.html        
-checkerrors:
-  before_script:
-  - apt-get update
-  - apt-get install -y qpdf  
-  stage: check
-  needs: ["buildpackage"]
-  only:
-    - main
-    - master
-    - 0.6.0.7
-  script:
-    - mkdir -p public/check
-    - r -e 'devtools::load_all();devtools::check(document = FALSE, args = "--no-tests", check_dir="public/check")'
-  artifacts:
-    when: always  
-    paths:
-      - public/check
-    expire_in: 30 days
-
-checkerrors_update:
-  before_script:
-  - apt-get update
-  - apt-get install -y qpdf  
-  stage: check
-  needs: ["buildpackage"]
-  only:
-    - main
-    - master
-    - 0.6.0.7
-  script:
-    - mkdir -p public/check
-    - Rscript -e 'renv::update()'
-    - r -e 'devtools::load_all();devtools::check(document = FALSE, args = "--no-tests", check_dir="public/check")'
-  artifacts:
-    when: always  
-    paths:
-      - public/check
-    expire_in: 30 days 
-    
-# https://docs.gitlab.com/ee/ci/testing/unit_test_reports.html
-unittests:
-  stage: test
-  needs: ["buildpackage"]
-  only:
-    - main
-    - master
-    - 0.6.0.7
-  script:
-  
-    - export PGPASSWORD=$POSTGRES_PASSWORD
-    - echo 'PGPASSWORD=$POSTGRES_PASSWORD' >> .Renviron
-    - r -e 'devtools::load_all();options(stacomiR.dbname = "bd_contmig_nat",stacomiR.host ="db",	stacomiR.port = "5432",	stacomiR.user = "postgres",	stacomiR.password = "postgres"); test <- capture.output(devtools::test(reporter="junit")) ; XML::saveXML(XML::xmlParse(test[grep("?xml version",test):length(test)]), file="public/test.xml")'
-    - r -e 'a<-1'
-    - r -e 'print(a)'
-    - r -e 'devtools::test'
-  artifacts:
-    when: always
-    # You should set the job that uploads the screenshot to
-    #artifacts:when: always so that it still uploads a screenshot
-    #when a test fails.
-    paths:
-      - public/test.xml
-    reports:
-      junit: public/test.xml
-    expire_in: 30 days 
-    
-# here covr:codecov publishes the report on codecov, this function writes  
-# the coverage.html  in public  
-codecov:
-  stage: codecoverage  
-  needs: ["buildpackage"]
-  only:
-    - main
-    - master
-    - 0.6.0.7
-  script:
-    # these are for code coverage
-    - Rscript -e 'pak::pkg_install(pkg = c("covr", "DT"), upgrade = FALSE)'
-    - r -e 'Sys.setenv("NOT_CRAN"= "true"); devtools::load_all(); options(stacomiR.dbname = "bd_contmig_nat",stacomiR.host ="db",	stacomiR.port = "5432",	stacomiR.user = "postgres",	stacomiR.password = "postgres");co <- covr::package_coverage(type="all", quiet=FALSE, clean=FALSE);print(co);covr:::print.coverage(co);covr::report(co, file.path("dev/codecoverage_report", paste0("stacomiR-report.html")))' 
-    # the following should be used when pages is set
-    - r -e 'covr::gitlab(file = "public/coverage.html", type = c("all"), quiet = FALSE)'
-  #A line like Code coverage: 67.89% of lines covered would match.
-  coverage: '/Coverage: \d+\.\d+/' 
-  artifacts:
-    when: always
-    paths:
-      - dev/codecoverage_report/stacomiR-report.html
-    expire_in: 30 days 
-    
-
-# adapted from
-# https://github.com/statnmap/gitlabr/blob/main/inst/gitlab-ci/check-coverage-pkgdown-renv.yml
-# https://gist.github.com/artemklevtsov/785ed0472c167246e947a75216852e10#file-gitlab-ci-yml-L15
-# ? need to create CI_JOB_TOKEN
-
-integration:
-  stage: deploy
-  allow_failure: true
-  only:
-    - main
-    - master
-    - 0.6.0.7
-  script: 
-    - echo "copy package to public"    
-    - cp -r "$(ls -rt *_*.zip |tail -1)" public
-    - cp -r "$(ls -rt *_*.tar.gz |tail -1)" public
-    - mkdir -p public/check
-    - cp -r check public/check
-  artifacts:
-    when: on_success
-    paths:
-      - public
-    expire_in: 30 days
-    
 # https://about.gitlab.com/blog/2016/11/03/publish-code-coverage-report-with-gitlab-pages/
 # A job that is meant to publish your code coverage report with GitLab Pages has to be placed in the separate stage.
 # Stages test, build and deploy are specified by 0.6.0.7, but you can change that if needed. 
@@ -257,8 +108,4 @@ integration:
 #    - echo "deployment with cache"
 #  artifacts:
 #    paths:
-#      - public
-
-    
-    
-    
+#      - public
\ No newline at end of file
diff --git a/_pkgdown.yml b/_pkgdown.yml
new file mode 100644
index 0000000..d71acfb
--- /dev/null
+++ b/_pkgdown.yml
@@ -0,0 +1,4 @@
+url: ~
+template:
+  bootstrap: 5
+
diff --git a/gitlab-ci/buildpackage.gitlab-ci.yml b/gitlab-ci/buildpackage.gitlab-ci.yml
new file mode 100644
index 0000000..248b5bc
--- /dev/null
+++ b/gitlab-ci/buildpackage.gitlab-ci.yml
@@ -0,0 +1,35 @@
+.buildpackage:
+  stage: build
+  needs: []
+  script:
+      - mkdir -p $R_LIBS_USER
+      - mkdir -p $RENV_PATHS_CACHE
+      - mkdir -p public
+      - Rscript -e 'source("renv/activate.R")'
+      - Rscript -e 'if(!requireNamespace("pak", quietly = TRUE)) {install.packages("pak")}'
+      - Rscript -e 'pak::pkg_install(pkg = c("rcmdcheck", "renv"), upgrade = FALSE)'
+      - Rscript -e 'renv::restore()'    
+      - r -e 'devtools::build(binary = TRUE, path="public", vignettes=TRUE, manual=TRUE)' 
+      - r -e 'devtools::build(binary = FALSE, path="public", vignettes=TRUE)' 
+
+  artifacts:
+    when: always
+    paths:
+      - public
+      - ${R_LIBS_USER}
+
+# en dev
+buildpackage-dev:
+  extends:
+    - .rules_other
+    - .buildpackage
+    - .image-dev
+    - .service-dev
+
+# en prod
+buildpackage-prod:
+  extends:
+    - .rules_main
+    - .buildpackage
+    - .image-prod
+    - .service-prod
\ No newline at end of file
diff --git a/gitlab-ci/check.gitlab-ci.yml b/gitlab-ci/check.gitlab-ci.yml
new file mode 100644
index 0000000..3714e3e
--- /dev/null
+++ b/gitlab-ci/check.gitlab-ci.yml
@@ -0,0 +1,32 @@
+# https://cran.r-project.org/web/packages/littler/vignettes/littler-examples.html        
+.checkerrors:
+  before_script:
+  - apt-get update
+  - apt-get install -y qpdf  
+  stage: check
+  script:
+    - mkdir -p public/check
+    - r -e 'devtools::load_all();devtools::check(document = FALSE, args = "--no-tests", check_dir="public/check")'
+  artifacts:
+    when: always  
+    paths:
+      - public/check
+    expire_in: 30 days
+
+# en dev
+checkerrors-dev:
+  extends:
+    - .rules_other
+    - .checkerrors
+    - .image-dev
+    - .service-dev
+  needs: ["buildpackage-dev"]
+
+# en prod
+checkerrors-prod:
+  extends:
+    - .rules_main
+    - .checkerrors
+    - .image-prod
+    - .service-prod
+  needs: ["buildpackage-prod"]
diff --git a/gitlab-ci/codecov.gitlab-ci.yml b/gitlab-ci/codecov.gitlab-ci.yml
new file mode 100644
index 0000000..ae5def6
--- /dev/null
+++ b/gitlab-ci/codecov.gitlab-ci.yml
@@ -0,0 +1,32 @@
+# here covr:codecov publishes the report on codecov, this function writes  
+# the coverage.html  in public  
+.codecov:
+  stage: codecoverage
+  script:
+    - Rscript -e 'pak::pkg_install(pkg = c("covr", "DT"), upgrade = FALSE)'
+    - Rscript -e 'pak::pak(pkg = ".", upgrade = FALSE)'
+    - Rscript -e 'Sys.setenv("NOT_CRAN"= "true"); devtools::load_all(); options(stacomiR.dbname = "bd_contmig_nat",stacomiR.host ="db",	stacomiR.port = "5432",	stacomiR.user = "postgres",	stacomiR.password ="${POSTGRES_PASSWORD}");covr::gitlab(quiet = FALSE)'
+  coverage: '/Coverage: \d+\.\d+/' 
+  artifacts:
+    when: always
+    paths:
+      - public
+    expire_in: 30 days
+
+# en dev
+codecov-dev:
+  extends:
+    - .rules_other
+    - .codecov
+    - .image-dev
+    - .service-dev
+  needs: ["buildpackage-dev"]
+
+# en prod
+codecov-prod:
+  extends:
+    - .rules_main
+    - .codecov
+    - .image-prod
+    - .service-prod
+  needs: ["buildpackage-prod"]
\ No newline at end of file
diff --git a/gitlab-ci/image.gitlab-ci.yml b/gitlab-ci/image.gitlab-ci.yml
new file mode 100644
index 0000000..d483c19
--- /dev/null
+++ b/gitlab-ci/image.gitlab-ci.yml
@@ -0,0 +1,11 @@
+# to use the right docker db image
+
+#######################
+# for any branch, but main
+.image-dev:   
+  image: rocker/tidyverse:latest
+      
+#######################
+# for main branch only
+.image-prod:   
+  image: rocker/tidyverse:latest
\ No newline at end of file
diff --git a/gitlab-ci/integration.gitlab-ci.yml b/gitlab-ci/integration.gitlab-ci.yml
new file mode 100644
index 0000000..fa38992
--- /dev/null
+++ b/gitlab-ci/integration.gitlab-ci.yml
@@ -0,0 +1,31 @@
+.integration:
+  stage: deploy
+  allow_failure: true
+  script: 
+    - echo "copy package to public"
+    - cp -r "$(ls -rt *_*.tar.gz |tail -1)" public
+    - mkdir -p public/check
+    - cp -r check public/check
+  artifacts:
+    when: on_success
+    paths:
+      - public
+    expire_in: 30 days
+
+# en dev
+integration-dev:
+  extends:
+    - .rules_other
+    - .integration
+    - .image-dev
+    - .service-dev
+  needs: ["buildpackage-dev"]
+
+# en prod
+integration-prod:
+  extends:
+    - .rules_main
+    - .integration
+    - .image-prod
+    - .service-prod
+  needs: ["buildpackage-prod"]
\ No newline at end of file
diff --git a/gitlab-ci/pkgdown.gitlab-ci.yml b/gitlab-ci/pkgdown.gitlab-ci.yml
new file mode 100644
index 0000000..eb6133d
--- /dev/null
+++ b/gitlab-ci/pkgdown.gitlab-ci.yml
@@ -0,0 +1,32 @@
+.pkgdown:
+    stage: document
+    allow_failure: true
+    when: on_success
+    script:
+      - mkdir -p public/documentation
+      - Rscript -e 'pak::pkg_install(pkg = c("pkgdown"), upgrade = FALSE)'
+      - Rscript -e 'pak::pak(pkg = ".", upgrade = FALSE)'
+      - Rscript -e 'pkgdown::build_site()'
+      - cp -r docs/* public/documentation
+    artifacts:
+      paths:
+        - public
+      expire_in: 30 days
+
+# en dev
+pkgdown-dev:
+  extends:
+    - .rules_other
+    - .pkgdown
+    - .image-dev
+    - .service-dev
+  needs: ["buildpackage-dev"]
+
+# en prod
+pkgdown-prod:
+  extends:
+    - .rules_main
+    - .pkgdown
+    - .image-prod
+    - .service-prod
+  needs: ["buildpackage-prod"]
\ No newline at end of file
diff --git a/gitlab-ci/rules.gitlab-ci.yml b/gitlab-ci/rules.gitlab-ci.yml
new file mode 100644
index 0000000..fe008cc
--- /dev/null
+++ b/gitlab-ci/rules.gitlab-ci.yml
@@ -0,0 +1,19 @@
+# generic rules to be used for main branch or others
+
+#######################
+# for any branch, but main
+.rules_other:
+  rules:
+    - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH && $CI_COMMIT_BRANCH != "main" && $CI_COMMIT_REF_PROTECTED  != "true"				# only if there is changes in branch other than main
+
+#######################            
+# for main banch only
+.rules_main:
+  rules:
+    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH == "main" || $CI_COMMIT_REF_PROTECTED  == "true"	# only if there is changes in the main branch
+
+#######################            
+# for shutting down the job
+.rules_shut_down:
+  rules:
+    - when: never
\ No newline at end of file
diff --git a/gitlab-ci/service.gitlab-ci.yml b/gitlab-ci/service.gitlab-ci.yml
new file mode 100644
index 0000000..9cca718
--- /dev/null
+++ b/gitlab-ci/service.gitlab-ci.yml
@@ -0,0 +1,10 @@
+.service-dev:
+  services:
+    - name:  ${stacomi_db_path}/${db_image_name}:${db_image_tagdev}
+      alias: ${POSTGRES_HOSTNAME}
+
+
+.service-prod:
+  services:
+    - name:  ${stacomi_db_path}/${db_image_name}:latest
+      alias: ${POSTGRES_HOSTNAME}
diff --git a/gitlab-ci/testdb.gitlab-ci.yml b/gitlab-ci/testdb.gitlab-ci.yml
new file mode 100644
index 0000000..4aa10e4
--- /dev/null
+++ b/gitlab-ci/testdb.gitlab-ci.yml
@@ -0,0 +1,25 @@
+.test_db:
+  stage: testdb
+  image: postgres:${postgres_version} 
+  before_script:
+    - sleep 120 # waiting postgresql
+    - psql --version
+    - export PGPASSWORD=$POSTGRES_PASSWORD
+    - psql -U postgres -h ${POSTGRES_HOSTNAME} -c "SELECT * FROM pg_catalog.pg_tables WHERE schemaname != 'pg_catalog' AND schemaname != 'information_schema';"
+  script:
+    - psql -U postgres -h ${POSTGRES_HOSTNAME} -c "select * from test.t_dispositifcomptage_dic" bd_contmig_nat
+    - export PGPASSWORD=test && psql -U test -h ${POSTGRES_HOSTNAME} -c "select * from test.t_dispositifcomptage_dic" bd_contmig_nat # test avec l'utilisateur
+
+# en dev
+test_db-dev:
+  extends:
+    - .rules_other
+    - .test_db
+    - .service-dev
+
+# en prod
+test_db-prod:
+  extends:
+    - .rules_main
+    - .test_db
+    - .service-prod
\ No newline at end of file
diff --git a/gitlab-ci/unittests.gitlab-ci.yml b/gitlab-ci/unittests.gitlab-ci.yml
new file mode 100644
index 0000000..8a6312a
--- /dev/null
+++ b/gitlab-ci/unittests.gitlab-ci.yml
@@ -0,0 +1,37 @@
+# https://docs.gitlab.com/ee/ci/testing/unit_test_reports.html
+.unittests:
+  stage: test
+  script:
+    - Rscript -e 'pak::pkg_install(pkg = c("XML"), upgrade = FALSE)'
+    - r -e "devtools::load_all();
+      options(stacomiR.dbname = 'bd_contmig_nat', stacomiR.host = '${POSTGRES_HOSTNAME}',	stacomiR.port = '5432',	stacomiR.user = 'postgres',	stacomiR.password = '${POSTGRES_PASSWORD}'); 
+      test <- capture.output(devtools::test(reporter='junit')) ; 
+      XML::saveXML(XML::xmlParse(test[grep('?xml version', test):length(test)]), file = 'public/test.xml')"
+  artifacts:
+    when: always
+    # You should set the job that uploads the screenshot to
+    #artifacts:when: always so that it still uploads a screenshot
+    #when a test fails.
+    paths:
+      - public/test.xml
+    reports:
+      junit: public/test.xml
+    expire_in: 30 days
+
+# en dev
+unittests-dev:
+  extends:
+    - .rules_other
+    - .unittests
+    - .image-dev
+    - .service-dev
+  needs: ["buildpackage-dev"]
+
+# en prod
+unittests-prod:
+  extends:
+    - .rules_main
+    - .unittests
+    - .image-prod
+    - .service-prod
+  needs: ["buildpackage-prod"]
\ No newline at end of file
diff --git a/gitlab-ci/update_check.gitlab-ci.yml b/gitlab-ci/update_check.gitlab-ci.yml
new file mode 100644
index 0000000..2e32a75
--- /dev/null
+++ b/gitlab-ci/update_check.gitlab-ci.yml
@@ -0,0 +1,33 @@
+# https://cran.r-project.org/web/packages/littler/vignettes/littler-examples.html        
+.checkerrors_update:
+  before_script:
+  - apt-get update
+  - apt-get install -y qpdf  
+  stage: check
+  script:
+    - mkdir -p public/check
+    - Rscript -e 'renv::update()'
+    - r -e 'devtools::load_all();devtools::check(document = FALSE, args = "--no-tests", check_dir="public/check")'
+  artifacts:
+    when: always  
+    paths:
+      - public/check
+    expire_in: 30 days
+
+# en dev
+checkerrors_update-dev:
+  extends:
+    - .rules_other
+    - .checkerrors_update
+    - .image-dev
+    - .service-dev
+  needs: ["buildpackage-dev"]
+
+# en prod
+checkerrors_update-prod:
+  extends:
+    - .rules_main
+    - .checkerrors_update
+    - .image-prod
+    - .service-prod
+  needs: ["buildpackage-prod"]
diff --git a/pkgdown/favicon/apple-touch-icon-120x120.png b/pkgdown/favicon/apple-touch-icon-120x120.png
new file mode 100644
index 0000000000000000000000000000000000000000..92e8e41c614a687a80e66433a24583ad9f37259c
GIT binary patch
literal 6541
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
G$o~NQP&RP@

literal 0
HcmV?d00001

diff --git a/pkgdown/favicon/apple-touch-icon-152x152.png b/pkgdown/favicon/apple-touch-icon-152x152.png
new file mode 100644
index 0000000000000000000000000000000000000000..fe3a66b2791c19d39068498789339c213401f436
GIT binary patch
literal 8870
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

literal 0
HcmV?d00001

diff --git a/pkgdown/favicon/apple-touch-icon-180x180.png b/pkgdown/favicon/apple-touch-icon-180x180.png
new file mode 100644
index 0000000000000000000000000000000000000000..5923b662fa09a4c87f9af71fbab7bfa83a263146
GIT binary patch
literal 11015
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

literal 0
HcmV?d00001

diff --git a/pkgdown/favicon/apple-touch-icon-60x60.png b/pkgdown/favicon/apple-touch-icon-60x60.png
new file mode 100644
index 0000000000000000000000000000000000000000..9296ab1ac490dc94e382c21fedc7362276da4f2f
GIT binary patch
literal 2478
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
bD(y6Y1!-~0ce7JPzmKxDbhKcb`CtAI<HcG@

literal 0
HcmV?d00001

diff --git a/pkgdown/favicon/apple-touch-icon-76x76.png b/pkgdown/favicon/apple-touch-icon-76x76.png
new file mode 100644
index 0000000000000000000000000000000000000000..b723790eb8c0cb72d0f9e9274253c31da8c80d1b
GIT binary patch
literal 3423
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
RhlecywCN?2S|d#Ce*j#HDzpFq

literal 0
HcmV?d00001

diff --git a/pkgdown/favicon/apple-touch-icon.png b/pkgdown/favicon/apple-touch-icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..153b2a698ce32cdc373b9d002eeaa26c029a57d6
GIT binary patch
literal 11015
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

literal 0
HcmV?d00001

diff --git a/pkgdown/favicon/favicon-16x16.png b/pkgdown/favicon/favicon-16x16.png
new file mode 100644
index 0000000000000000000000000000000000000000..40b94fba0820535e33780c8fae4c03ec4a95d015
GIT binary patch
literal 877
zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6e(pbstU$g(vPY0F
z14ES>14Ba#1H&(%P{RubhEf9thF1v;3|2E37{m+a><YADU|<vv@Ck7RDlkr;Xp}a|
zIDL}Gq;o(vL1dCK*(7r^L>Z7FXB#T0YzQ<5Vw6edR0tbR0#%x3Pveyax(Nz+rB#83
z7$*0yaf5t>223(0ndZ!pFmQ&83#k~JWKGqLZeZsZg$qI$%I+!Z{`nk&5^!;#8tw3E
z&7fjtHcq%8GaHAnnkm1$He3Xm0dyP4(yVC^PyPS@KSnm^H&8`PNsu2Xn1P|i!NTbp
z7%Jjp6lv}p$?a9_<I2Iv#m>ym%3`39m|7p0pWa@bm=T><m{k%HnVM1>x4fgiC3#{{
z<_rS|RbQ7>pTbO^NJnE!*BAvkSw&?nHAPo1Huk9O!`>j%lf2zsVqV=~m=5Hymw5WR
zvcKSB77^#=yItN66zcGFaSV~ToSdK_Yp`k4Mq?vI&VquX!p{auoCQUjK7Uf={=m(_
z#c8a}+0oI}Y3$+Q<$3yq(TS6%H4QYhG*_=!wK6*+EA#b>S1+XvB%~x~&zLncIwC6a
z_KjONZyH-zSXu7gv1?~_MOEeRAHRMYv#_wSwzIIdwXm?XwzayuEV7u?YN$1fXFnrD
z>nfpxS9O%90Ntco;u=wsl30>zm0Xkxq!^40j7)S54Rj5RLyQcpjEt=ejkOI7tPBh`
zKV7DUq9HdwB{QuOw}wMI<fZ{Ngja<`lmsP~D-;yvr)B1(DwI?fq$*?<lq54SRLpt&
ziHD;wOhe<8|LHTHPlFhkmAUnjxrLR5y(fz>3oE!Zm>f=FR^A+<aQeoT6GzS*kvYPC
dy1`?Cmmb3_alw*LPNv{=>gnp|vd$@?2>_K-?7RQ~

literal 0
HcmV?d00001

diff --git a/pkgdown/favicon/favicon-32x32.png b/pkgdown/favicon/favicon-32x32.png
new file mode 100644
index 0000000000000000000000000000000000000000..0972b62110ed2d7358ab87a204c1d0d59e53585a
GIT binary patch
literal 1754
zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyEa{HEjtmSN`?>!lvVtU&J%W50
z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+081Jk1bpAc7|0^^K{`sw{9
z=@X4XXp&jlMDzSP0!sP@855NACK#trFv*%|oH@Zb1IUJ`p#o`?irbJhuvEq*V<3Xr
zXp%WaFSbd|Hy7w&kegxR5H4H<!iCCaOk(2^geyR10L4u*CPS0~8OTz2*g*A$N!?f#
z$k~R$4FozHm%V6u;l41<o{lD^5m*E<5J(y%v@@}?qbY!JAtspT&BiLL;*}0}l~Gzh
zD;FPDWk5l*+?gPi8Iyoy>;L~)mGR4I0b>CaDL`deQ<-r%39DYXAg{C<FswwiZCE(C
z;etShVRDalc$IcorEYWsvN%>Yr;sGb8R<}jriMpS86L3z|NmdOiV@_WuO&f#!Kf;k
zv=Ym+)Y<bEx~$fYT`XCaJ;#=Xaau6{0)0kvnS_Zv+)HwKJtxhTO7@U#3ucpvxm_GG
znTeT6XO+o@WVV}yyslk|?jiweX6th&yK%WVRtDSFIVqIN+SecPwL3ZGM%vxYCwH~1
zFWwh)baw5%_CD`NGez<<!}Atu9GtdENWOA=L&r8zy#rqLlkFmRnnWK?yIONCscO@T
zMy<7(TQqg|b9hvGF{;mzY~3?$iGJV1>&cpncD0BZ3r<&3v0f%1#4o`qC2j92DJ(B8
zXJIWC>0$048ersO6KL<Lo1LLKk%OIum5(*RDs|6Nu5Cb%GbVYvyL@%MBz+smVK4FY
zb!C6S#VjJuH~o^DEl_%*r;B5V#p&b(308pvCywhYXsDby(&IeO)g{EoA;!aL66<s(
z%}hzLFtJF>7%rD5q7fofU8aN<Xa<A^U%znW(zT06mpb_0KXBp1jUyt{ZJ1~G&D`0#
zRMeV1EHYb~O)T2FnvLCE-C+LY(>GhCZ|a1bv&oh7`|G>s%g5XQZ#b~v!GsGNK5+a$
zvEs#y8#{iq99fdmCK4C?^2(MkJ!jTDc{AtEo<B{87CoADY15~!Q>$Lhx^&B`?HAj$
zW6Pd#wM`3a+xD&R+`4!3?q#&?`^Q-)d|BOhmW^tA;wzKf{+GsS=VsZaU%ONJSzIS(
zOU21csi(u&_{_PnFYBw+f~KvnujSv^ky(6e+S=RO-rv}n{e9lv-{0gdDpoxEFmdtm
zzV!JPCktMEnYp?B+}y2})fz8v{0tV?i`!N6^v2a};oNok8#(tEe!iC5W*z*_?Ot~G
zzW)#I9d_?ep2uQ0<I|R$OPg;N`pel={d@Fu^>v>7d;2!m{l53>?d|RF8$YZy71&dm
zU;C6f;KAab%g@JuSSli>DlRVmN_CGTFGGIvf|aj7z7qn*muiV?L`h0wNvc(HQ7VvP
zFfuSQ(KR&CH82h_GO#i-wlXx)HZZU<Fer1Hu>?g!ZhlH;S|x4`?D7f{Kn>wlArU1(
ziRB6fMfqu&IjIUIl?AB^nFS@u3=9=>9)IHDC=AokIOTu(jOWuJ24-b$y<~1-Wnu5h
zBFw@HE)6D!Q<#-EhbWxBaplC3Ge=~Ou%B-5Sm33{@Jd{;<dc)>RG<|Mp00i_>zopr
E07(TNkpKVy

literal 0
HcmV?d00001

diff --git a/pkgdown/favicon/favicon.ico b/pkgdown/favicon/favicon.ico
new file mode 100644
index 0000000000000000000000000000000000000000..ca9586c1046cc24483827aa15ace307660e34601
GIT binary patch
literal 15086
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

literal 0
HcmV?d00001

-- 
GitLab


From 2960a866687b606e3b836c71f604aa7b7ef10b16 Mon Sep 17 00:00:00 2001
From: Laurent BEAULATON <laurent.beaulaton@ofb.gouv.fr>
Date: Fri, 4 Oct 2024 08:03:58 +0200
Subject: [PATCH 06/11] fix codecov

---
 gitlab-ci/codecov.gitlab-ci.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gitlab-ci/codecov.gitlab-ci.yml b/gitlab-ci/codecov.gitlab-ci.yml
index ae5def6..41eaed0 100644
--- a/gitlab-ci/codecov.gitlab-ci.yml
+++ b/gitlab-ci/codecov.gitlab-ci.yml
@@ -5,7 +5,7 @@
   script:
     - Rscript -e 'pak::pkg_install(pkg = c("covr", "DT"), upgrade = FALSE)'
     - Rscript -e 'pak::pak(pkg = ".", upgrade = FALSE)'
-    - Rscript -e 'Sys.setenv("NOT_CRAN"= "true"); devtools::load_all(); options(stacomiR.dbname = "bd_contmig_nat",stacomiR.host ="db",	stacomiR.port = "5432",	stacomiR.user = "postgres",	stacomiR.password ="${POSTGRES_PASSWORD}");covr::gitlab(quiet = FALSE)'
+    - Rscript -e 'Sys.setenv("NOT_CRAN"= "true"); devtools::load_all(); options(stacomiR.dbname = "bd_contmig_nat",stacomiR.host = "${POSTGRES_HOSTNAME}",	stacomiR.port = "5432",	stacomiR.user = "postgres",	stacomiR.password ="${POSTGRES_PASSWORD}");covr::gitlab(quiet = FALSE)'
   coverage: '/Coverage: \d+\.\d+/' 
   artifacts:
     when: always
-- 
GitLab


From 5e405ed937f16eca65f3f6d74b7341c9d1d82632 Mon Sep 17 00:00:00 2001
From: Laurent BEAULATON <laurent.beaulaton@ofb.gouv.fr>
Date: Fri, 4 Oct 2024 09:02:43 +0200
Subject: [PATCH 07/11] fix: helper for gitlab-ci

---
 .gitlab-ci.yml                    |  3 ++-
 gitlab-ci/codecov.gitlab-ci.yml   |  2 +-
 gitlab-ci/testdb.gitlab-ci.yml    |  4 ++--
 gitlab-ci/unittests.gitlab-ci.yml |  2 +-
 tests/testthat/helper.R           | 14 +++++++-------
 5 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 0b405e5..5bd68db 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -17,7 +17,8 @@ stages:          # List of stages for jobs, and their order of execution
   - deploy
   
 variables:
-  POSTGRES_PASSWORD: "postgres"
+  POSTGRES_USER: "test"
+  POSTGRES_PASSWORD: "test"
   POSTGRES_HOSTNAME: "host_db"
   stacomi_db_path: "registry.forgemia.inra.fr/stacomi/stacomi_db"
   db_image_name: "stacomi_db"
diff --git a/gitlab-ci/codecov.gitlab-ci.yml b/gitlab-ci/codecov.gitlab-ci.yml
index 41eaed0..599977e 100644
--- a/gitlab-ci/codecov.gitlab-ci.yml
+++ b/gitlab-ci/codecov.gitlab-ci.yml
@@ -5,7 +5,7 @@
   script:
     - Rscript -e 'pak::pkg_install(pkg = c("covr", "DT"), upgrade = FALSE)'
     - Rscript -e 'pak::pak(pkg = ".", upgrade = FALSE)'
-    - Rscript -e 'Sys.setenv("NOT_CRAN"= "true"); devtools::load_all(); options(stacomiR.dbname = "bd_contmig_nat",stacomiR.host = "${POSTGRES_HOSTNAME}",	stacomiR.port = "5432",	stacomiR.user = "postgres",	stacomiR.password ="${POSTGRES_PASSWORD}");covr::gitlab(quiet = FALSE)'
+    - Rscript -e 'Sys.setenv("NOT_CRAN"= "true"); devtools::load_all(); options(stacomiR.dbname = "bd_contmig_nat",stacomiR.host = "${POSTGRES_HOSTNAME}",	stacomiR.port = "5432",	stacomiR.user = "${POSTGRES_USER}",	stacomiR.password ="${POSTGRES_PASSWORD}");covr::gitlab(quiet = FALSE)'
   coverage: '/Coverage: \d+\.\d+/' 
   artifacts:
     when: always
diff --git a/gitlab-ci/testdb.gitlab-ci.yml b/gitlab-ci/testdb.gitlab-ci.yml
index 4aa10e4..d53a046 100644
--- a/gitlab-ci/testdb.gitlab-ci.yml
+++ b/gitlab-ci/testdb.gitlab-ci.yml
@@ -5,9 +5,9 @@
     - sleep 120 # waiting postgresql
     - psql --version
     - export PGPASSWORD=$POSTGRES_PASSWORD
-    - psql -U postgres -h ${POSTGRES_HOSTNAME} -c "SELECT * FROM pg_catalog.pg_tables WHERE schemaname != 'pg_catalog' AND schemaname != 'information_schema';"
+    - psql -U ${POSTGRES_USER} -h ${POSTGRES_HOSTNAME} -c "SELECT * FROM pg_catalog.pg_tables WHERE schemaname != 'pg_catalog' AND schemaname != 'information_schema';"
   script:
-    - psql -U postgres -h ${POSTGRES_HOSTNAME} -c "select * from test.t_dispositifcomptage_dic" bd_contmig_nat
+    - psql -U ${POSTGRES_USER} -h ${POSTGRES_HOSTNAME} -c "select * from test.t_dispositifcomptage_dic" bd_contmig_nat
     - export PGPASSWORD=test && psql -U test -h ${POSTGRES_HOSTNAME} -c "select * from test.t_dispositifcomptage_dic" bd_contmig_nat # test avec l'utilisateur
 
 # en dev
diff --git a/gitlab-ci/unittests.gitlab-ci.yml b/gitlab-ci/unittests.gitlab-ci.yml
index 8a6312a..1170a9a 100644
--- a/gitlab-ci/unittests.gitlab-ci.yml
+++ b/gitlab-ci/unittests.gitlab-ci.yml
@@ -4,7 +4,7 @@
   script:
     - Rscript -e 'pak::pkg_install(pkg = c("XML"), upgrade = FALSE)'
     - r -e "devtools::load_all();
-      options(stacomiR.dbname = 'bd_contmig_nat', stacomiR.host = '${POSTGRES_HOSTNAME}',	stacomiR.port = '5432',	stacomiR.user = 'postgres',	stacomiR.password = '${POSTGRES_PASSWORD}'); 
+      options(stacomiR.dbname = 'bd_contmig_nat', stacomiR.host = '${POSTGRES_HOSTNAME}',	stacomiR.port = '5432',	stacomiR.user = '${POSTGRES_USER}',	stacomiR.password = '${POSTGRES_PASSWORD}'); 
       test <- capture.output(devtools::test(reporter='junit')) ; 
       XML::saveXML(XML::xmlParse(test[grep('?xml version', test):length(test)]), file = 'public/test.xml')"
   artifacts:
diff --git a/tests/testthat/helper.R b/tests/testthat/helper.R
index 9ba852e..f857709 100644
--- a/tests/testthat/helper.R
+++ b/tests/testthat/helper.R
@@ -3,13 +3,13 @@
 # this file is called before testhat so funcion will be available in all test
 # https://testthat.r-lib.org/articles/test-fixtures.html#withr-defer-
 # could have used with_envvar and local_envvar but had to set them each time
-options(					
-    stacomiR.dbname = "bd_contmig_nat_test",
-    stacomiR.host ="localhost",
-    stacomiR.port = "5432",
-    stacomiR.user = "test",
-    stacomiR.password = "test"				
-)
+# options(					
+#     stacomiR.dbname = "bd_contmig_nat_test",
+#     stacomiR.host ="localhost",
+#     stacomiR.port = "5432",
+#     stacomiR.user = "test",
+#     stacomiR.password = "test"				
+# )
 password <- getOption("stacomiR.password") #if not set will be ""
 dbname <- getOption("stacomiR.dbname") #if not set will be ""
 user <- getOption("stacomiR.user")
-- 
GitLab


From 67feb7e83856b30a3c8eeab0f689601b75deefa3 Mon Sep 17 00:00:00 2001
From: Laurent BEAULATON <laurent.beaulaton@ofb.gouv.fr>
Date: Fri, 4 Oct 2024 09:53:05 +0200
Subject: [PATCH 08/11] retour au user postgres

---
 .gitlab-ci.yml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 5bd68db..10770d6 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -17,8 +17,8 @@ stages:          # List of stages for jobs, and their order of execution
   - deploy
   
 variables:
-  POSTGRES_USER: "test"
-  POSTGRES_PASSWORD: "test"
+  POSTGRES_USER: "postgres"
+  POSTGRES_PASSWORD: "postgres"
   POSTGRES_HOSTNAME: "host_db"
   stacomi_db_path: "registry.forgemia.inra.fr/stacomi/stacomi_db"
   db_image_name: "stacomi_db"
-- 
GitLab


From af06c75973ba40fa1019ebc842925316eddbf1b3 Mon Sep 17 00:00:00 2001
From: Laurent BEAULATON <laurent.beaulaton@ofb.gouv.fr>
Date: Fri, 4 Oct 2024 10:03:53 +0200
Subject: [PATCH 09/11] =?UTF-8?q?retour=20=C3=A0=20test?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .gitlab-ci.yml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 10770d6..5bd68db 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -17,8 +17,8 @@ stages:          # List of stages for jobs, and their order of execution
   - deploy
   
 variables:
-  POSTGRES_USER: "postgres"
-  POSTGRES_PASSWORD: "postgres"
+  POSTGRES_USER: "test"
+  POSTGRES_PASSWORD: "test"
   POSTGRES_HOSTNAME: "host_db"
   stacomi_db_path: "registry.forgemia.inra.fr/stacomi/stacomi_db"
   db_image_name: "stacomi_db"
-- 
GitLab


From 9dbacb5bf0cd07ad4e1d13ae56b4614be9178079 Mon Sep 17 00:00:00 2001
From: Laurent BEAULATON <laurent.beaulaton@ofb.gouv.fr>
Date: Fri, 4 Oct 2024 10:05:56 +0200
Subject: [PATCH 10/11] =?UTF-8?q?retour=20=C3=A0=20user=20postgres?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .gitlab-ci.yml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 5bd68db..10770d6 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -17,8 +17,8 @@ stages:          # List of stages for jobs, and their order of execution
   - deploy
   
 variables:
-  POSTGRES_USER: "test"
-  POSTGRES_PASSWORD: "test"
+  POSTGRES_USER: "postgres"
+  POSTGRES_PASSWORD: "postgres"
   POSTGRES_HOSTNAME: "host_db"
   stacomi_db_path: "registry.forgemia.inra.fr/stacomi/stacomi_db"
   db_image_name: "stacomi_db"
-- 
GitLab


From 4edf10a9f3569f039ef75eebeb4e3a67a3b8c4fe Mon Sep 17 00:00:00 2001
From: Laurent BEAULATON <laurent.beaulaton@ofb.gouv.fr>
Date: Mon, 7 Oct 2024 11:11:10 +0200
Subject: [PATCH 11/11] Resolve "pkgdown"

---
 .gitlab-ci.yml                      |  1 +
 gitlab-ci/pkgdown.gitlab-ci.yml     |  2 +-
 gitlab-ci/publication.gitlab-ci.yml | 45 +++++++++++++++++++++++++++++
 gitlab-ci/rules.gitlab-ci.yml       |  4 +--
 4 files changed, 49 insertions(+), 3 deletions(-)
 create mode 100644 gitlab-ci/publication.gitlab-ci.yml

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 10770d6..fddc64a 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -54,6 +54,7 @@ include:
   - local: '/gitlab-ci/codecov.gitlab-ci.yml'
   - local: '/gitlab-ci/integration.gitlab-ci.yml'
   - local: '/gitlab-ci/pkgdown.gitlab-ci.yml'
+  - local: '/gitlab-ci/publication.gitlab-ci.yml'
 
 # pour lancer celui là il faudrait avoir un accès à un runner.... pour l'instant j'ai pas....
 #https://guillaumebriday.fr/installer-et-utiliser-les-gitlab-runners
diff --git a/gitlab-ci/pkgdown.gitlab-ci.yml b/gitlab-ci/pkgdown.gitlab-ci.yml
index eb6133d..c9c252d 100644
--- a/gitlab-ci/pkgdown.gitlab-ci.yml
+++ b/gitlab-ci/pkgdown.gitlab-ci.yml
@@ -7,7 +7,7 @@
       - Rscript -e 'pak::pkg_install(pkg = c("pkgdown"), upgrade = FALSE)'
       - Rscript -e 'pak::pak(pkg = ".", upgrade = FALSE)'
       - Rscript -e 'pkgdown::build_site()'
-      - cp -r docs/* public/documentation
+      - cp -r docs/* public
     artifacts:
       paths:
         - public
diff --git a/gitlab-ci/publication.gitlab-ci.yml b/gitlab-ci/publication.gitlab-ci.yml
new file mode 100644
index 0000000..14621dc
--- /dev/null
+++ b/gitlab-ci/publication.gitlab-ci.yml
@@ -0,0 +1,45 @@
+.publication:
+    stage: deploy
+    allow_failure: true
+    when: on_success
+    script:
+      - echo "publication"
+    artifacts:
+      paths:
+        - public
+      expire_in: 30 days
+
+# en dev
+publication-dev:
+  extends:
+    - .rules_other
+    - .publication
+    - .image-dev
+  needs: ["pkgdown-dev"]
+  environment:
+    name: $CI_COMMIT_REF_SLUG
+    url: https://$CI_PROJECT_NAMESPACE.$CI_PAGES_DOMAIN/-/$CI_PROJECT_NAME/-/jobs/$CI_JOB_ID/artifacts/public/index.html
+    on_stop: stop-pkgdown-dev
+
+stop-pkgdown-dev:
+  stage: deploy
+  extends:
+    - .rules_other
+  script:
+    - echo "Supprime l'environnement de test"
+  environment:
+    name:  $CI_COMMIT_REF_SLUG
+    action: stop
+  when: manual
+
+# en prod
+pages:
+  extends:
+    - .rules_main
+  stage: deploy
+  script:
+      - echo "deployment"
+  artifacts:
+      paths:
+          - public
+  needs: ["pkgdown-prod"]
\ No newline at end of file
diff --git a/gitlab-ci/rules.gitlab-ci.yml b/gitlab-ci/rules.gitlab-ci.yml
index fe008cc..1294670 100644
--- a/gitlab-ci/rules.gitlab-ci.yml
+++ b/gitlab-ci/rules.gitlab-ci.yml
@@ -4,13 +4,13 @@
 # for any branch, but main
 .rules_other:
   rules:
-    - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH && $CI_COMMIT_BRANCH != "main" && $CI_COMMIT_REF_PROTECTED  != "true"				# only if there is changes in branch other than main
+    - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH && $CI_COMMIT_BRANCH != "main" && $CI_COMMIT_REF_PROTECTED  != "true"	# only if there is changes in branch other than main
 
 #######################            
 # for main banch only
 .rules_main:
   rules:
-    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH == "main" || $CI_COMMIT_REF_PROTECTED  == "true"	# only if there is changes in the main branch
+    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH == "main" || $CI_COMMIT_REF_PROTECTED  == "true" # only if there is changes in the main branch
 
 #######################            
 # for shutting down the job
-- 
GitLab