Временно игнорировать определенные библиотеки в R - PullRequest
1 голос
/ 18 апреля 2019

В настоящее время я работаю над настройкой непрерывной интеграции для пакетов R, разработанных нашей компанией.У нас есть один проект Jenkins для каждого пакета R и соответствующая библиотека для каждого проекта.

Я уже определил логику, которая устанавливает все зависимости пакета в библиотеку проекта.Теперь я хочу определить этап проверки, который в основном выполняется

devtools::check("${PROJECT_DIR}/pkg")

, но использует только библиотеку проекта для зависимостей.Я попытался использовать пакет callr следующим образом.

callr::r(
  function(...) {
    devtools::check(...)
  ),
  args = list("${PROJECT_DIR}/pkg"),
  libpath = "${PROJECT_DIR}/lib"
)

Однако процесс проверки все еще может найти пакеты, которые не установлены в libpath.Есть ли способ убедиться, что на этапе сборки используется только "${PROJECT_DIR}/lib"?

До сих пор я пробовал следующее безрезультатно

  • callr() сlibpath аргумент
  • withr::with_libpaths с аргументом new
  • Просмотрите документацию в devtools::check и R CMD BUILD для соответствующих параметров
  • Используйте .libPaths("${JOB_DIR}/lib")

Ниже приведено описание, объясняющее неожиданное поведение callr.Я ожидаю ошибку в строке 3.

find.package("ggplot2", .libPaths()[1])
#> Error in find.package("ggplot2", .libPaths()[1]): there is no package called 'ggplot2'
callr::r(function() {  ggplot2::vars() }, libpath = .libPaths()[1])
#> named list()
find.package("ggplot2", .libPaths()[2])
#> [1] "/data/R/3.5.3/lib/R/library/ggplot2"
callr::r(function() {  ggplot2::vars() }, libpath = .libPaths()[2])
#> named list()

Ответы [ 2 ]

1 голос
/ 19 апреля 2019

Это может быть немного не по теме, но вы рассматривали возможность использования docker для этого варианта использования?

Вы можете определить Dockerfile, на который вы ссылаетесь в Jenkinsfile,который будет определять пользовательский образ для каждого запускаемого задания CI.Вы устанавливаете пакеты в Docker-контейнер, используя devtools::install() в Jenkins.Этот контейнер затем подбрасывается после завершения CI.

При таком подходе вам не нужно беспокоиться о ручной установке пакетов самостоятельно, когда вы запускаете CI, и не нужно беспокоиться о конфликтующих пространствах имен в разных пакетах.

Это определенноимеет более высокую начальную стоимость, но я думаю, что в долгосрочной перспективе это будет стоить того, чтобы протестировать ваши пакеты R.Источник: я также тестирую внутренние пакеты R на своей работе.

sample Dockerfile

FROM docker.io/rocker/r-base

USER root

# Install packages needed for package development
RUN R -e 'install.packages(c("devtools", "rmarkdown", "testthat", "roxygen2"))'

Затем вы ссылаетесь на этот Dockerfile в Jenkinsfile, чтобы установить, протестировать,и проверьте пакет (пример конвейера ниже)

    agent {
        dockerfile {
            args '-u root'
        }
    }
    stages {
        stage('Install') {
            steps {
                sh 'r -e "devtools::install()"'
            }
        }
        stage('Test') {
            steps {
                sh '''
                  r -e "options(testthat.output_file = 'test-out.xml'); devtools::test(reporter = 'junit')"
                '''
                junit 'test-out.xml'
            }
        }
        stage('Check') {
           // Might need to modify expected ouput, depends on devtools version
            steps {
                sh '''
                  testOutput=$(R -e "devtools::check(args='--no-tests')" 2>&1)
                  echo "${testOutput}" | grep -q "0 errors ✔ | 0 warnings ✔ | 0 notes ✔"
                '''
            }
        }
    }
}

1 голос
/ 18 апреля 2019

Согласно этому вопросу есть способ архивировать это с помощью base::assign.Если есть более правильное решение, я хотел бы услышать его.

callr::r(function() {
  assign(".lib.loc", .libPaths()[1], envir = environment(.libPaths))
  ggplot2::vars() 
})
#> Error in loadNamespace(name): there is no package called ‘ggplot2’

У меня есть две проблемы

  1. Это в основном взлом и может сломаться в любое времяесли внутренности .libPaths() изменятся
  2. , мне, возможно, придется изменить .Library и .Library.site (внутренности .libPaths()), чтобы убедиться, что на devtools::check воздействуют соответствующим образом.
...