diff options
| author | Gertjan van den Burg <gertjanvandenburg@gmail.com> | 2020-03-12 14:33:57 +0000 |
|---|---|---|
| committer | Gertjan van den Burg <gertjanvandenburg@gmail.com> | 2020-03-12 14:33:57 +0000 |
| commit | 7ef8f6e58990fc069cccc71ed6564e8c639ea4fc (patch) | |
| tree | 9e7662a34b7d0c1f1c5d9faf6d7d6ea8672f6410 /utils | |
| download | TCPDBench-7ef8f6e58990fc069cccc71ed6564e8c639ea4fc.tar.gz TCPDBench-7ef8f6e58990fc069cccc71ed6564e8c639ea4fc.zip | |
initial commit
Diffstat (limited to 'utils')
| -rw-r--r-- | utils/R_setup.sh | 68 | ||||
| -rw-r--r-- | utils/install_if_not_exist.R | 75 | ||||
| -rw-r--r-- | utils/validate_schema.py | 63 |
3 files changed, 206 insertions, 0 deletions
diff --git a/utils/R_setup.sh b/utils/R_setup.sh new file mode 100644 index 00000000..532f6987 --- /dev/null +++ b/utils/R_setup.sh @@ -0,0 +1,68 @@ +#!/bin/bash +# +# Setup an R environment in a given directory. +# +# This works as follows. We create an ".Rprofile" file in the current +# directory that sets the .libPaths to the desired Rlib directory. We do the +# same with an .Renviron file because it's R so one place isn't enough. This +# essentially makes that the only source of packages read by anything that +# respects this .Rprofile. Next we install packages as normal using the +# install_if_not_exists.R script, which only installs packages if necessary +# and supports GitHub and local packages as well. +# +# This file is part of RSimpleVenv: https://github.com/GjjvdBurg/RSimpleVenv +# +# Author: G.J.J. van den Burg +# Date: 2019-06-19 +# License: MIT + +res='\033[1m\033[0m' +log() { echo -e "\e[32m$*${res}"; } +err() { echo -e "\e[31m$*${res}"; exit 1; } + +install() { + log "Installing $1"; + Rscript ./utils/install_if_not_exist.R "$1" + # exit on failure + if [ ! $? == 0 ] + then + err "Non-zero exit status after installing $1" + fi +} + +if [ $# -ne 2 ] +then + echo "Usage: $0 packageFile rlib_dir" + exit 1 +fi + +PACKAGE_FILE="$1" +LIBDIR=$(realpath "$2") +mkdir -p ${LIBDIR} + +# Ensure that this is the only libPath from now on. +echo ".libPaths(c('${LIBDIR}'))" > .Rprofile +echo "R_LIBS=${LIBDIR}" > .Renviron +echo "R_LIBS_USER=${LIBDIR}" >> .Renviron + +# Here's a fun one: for some reason R tests lazy loading in vanilla mode by +# default, which overwrites all the environment and library stuff we just +# carefully set. This can break things when you have a different package +# version installed in your user R package library. Luckily, if you dig +# through the R source code (not in the documentation!), you can find out that +# there's an obscure environment variable that can be set to disable this +# behaviour. What fun! What an intuitively designed programming language! /s +export _R_CHECK_INSTALL_DEPENDS_="TRUE" + +# Install devtools for GitHub-based packages +install devtools + +# Install all packages from the provided package file +while read -r pkg +do + if [ -z ${pkg} ] + then + continue + fi + install "${pkg}" +done < ${PACKAGE_FILE} diff --git a/utils/install_if_not_exist.R b/utils/install_if_not_exist.R new file mode 100644 index 00000000..9daf21ca --- /dev/null +++ b/utils/install_if_not_exist.R @@ -0,0 +1,75 @@ +#!/usr/bin/env Rscript +# +# Install an R package from the command line. Supports CRAN, GitHub, and local +# packages. +# +# It is expected that this is only run through R_setup.sh. +# +# This file is part of RSimpleVenv: https://github.com/GjjvdBurg/RSimpleVenv +# +# Author: G.J.J. van den Burg +# Date: 2019-06-20 +# License: MIT + +REPOS <- c("https://cran.r-project.org") + +# Parse args +args <- commandArgs(trailingOnly=T) +if (!length(args) == 1) { + print("Please provide a package name") + quit() +} +pkg <- args[1] + +# As a sanity check, ensure that nothing overwrote the R_LIBS variable +if (Sys.getenv("R_LIBS") != .libPaths()[1]) { + print("Mismatch between R_LIBS and .libPaths()[1]") + quit(status=1, save="no") +} + +# Install the package +if (startsWith(pkg, "github:")) { + pkg <- substring(pkg, nchar("github:")+1, nchar(pkg)) + # this check only works if the package name matches the repo name + pkgName <- basename(pkg) + if (pkgName %in% installed.packages()) { + cat("Package", pkgName, "exists.\n") + quit() + } + Sys.setenv(R_REMOTES_NO_ERRORS_FROM_WARNINGS="true") + # install_github returns the package name (yay!) + pkgName <- devtools::install_github(pkg) +} else if (startsWith(pkg, "local:")) { + pkgPath <- substring(pkg, nchar("local:")+1, nchar(pkg)) + pkgName <- basename(pkgPath) + if (pkgName %in% installed.packages()) { + cat("Package", pkgName, "exists.\n") + quit() + } + devtools::build(pkgPath) + devtools::install(pkgPath) +} else { + version <- NULL + if (grepl('==', pkg)) { + pkgName <- sub('==(.*)', '', pkg) + version <- sub('(.*)==', '', pkg) + } else { + pkgName <- pkg + } + + if (pkgName %in% installed.packages()) { + cat("Package", pkg, "exists.\n") + quit() + } + + if (pkgName == 'devtools') { + install.packages(pkgName, Sys.getenv('R_LIBS'), repos=REPOS, + dependencies=c('Depends', 'Imports', 'LinkingTo')) + } else { + devtools::install_version(pkgName, version=version, repos=REPOS) + } +} + +# Test if it works +if (!library(pkgName, character.only=T, logical.return=T)) + quit(status=1, save='no') diff --git a/utils/validate_schema.py b/utils/validate_schema.py new file mode 100644 index 00000000..647cc310 --- /dev/null +++ b/utils/validate_schema.py @@ -0,0 +1,63 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +Validate all result files against a given JSON schema. + +Author: Gertjan van den Burg + +""" + + +import argparse +import json +import jsonschema +import os + + +def parse_args(): + parser = argparse.ArgumentParser() + parser.add_argument( + "-s", "--schema-file", help="Schema file", default="./schema.json" + ) + parser.add_argument("-r", "--result-dir", help="Directory with results") + parser.add_argument( + "-v", "--verbose", help="Enable verbose mode", action="store_true" + ) + return parser.parse_args() + + +def load_schema(schema_file): + with open(schema_file, "rb") as fp: + schema = json.load(fp) + return schema + + +def scantree(path): + """Recursively yield DirEntry objects for given directory.""" + for entry in os.scandir(path): + if entry.is_dir(follow_symlinks=False): + yield from scantree(entry.path) + else: + yield entry + + +def validate_file(filename, schema): + with open(filename, "rb") as fp: + data = json.load(fp) + jsonschema.validate(instance=data, schema=schema) + + +def main(): + args = parse_args() + + log = lambda *a, **kw: print(*a, **kw) if args.verbose else None + + schema = load_schema(args.schema_file) + for entry in scantree(args.result_dir): + log("Checking file: %s" % entry.path) + validate_file(entry.path, schema) + + +if __name__ == "__main__": + main() |
