diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9731ea19..a184015f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -72,6 +72,41 @@ jobs: run: | pytest pins -m 'fs_rsc and not skip_on_github' + check-cross-compatibility: + name: "Check cross lib compatibility" + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - name: Install libcurl on Linux + run: sudo apt-get update -y && sudo apt-get install -y libcurl4-openssl-dev + + # r --- + + - uses: r-lib/actions/setup-r@v2 + with: + use-public-rspm: true + + - name: Install R dependencies + run: "install.packages('pins')" + shell: Rscript {0} + + # python --- + + - uses: actions/setup-python@v2 + with: + python-version: 3.8 + - name: Install py dependencies + run: | + python -m pip install --upgrade pip + python -m pip install -r requirements/dev.txt + python -m pip install -e . + + # write and test --- + + - name: Run script/ci-compat-check + run: make ci-compat-check + build-docs: name: "Build Docs" runs-on: ubuntu-latest diff --git a/Makefile b/Makefile index b62e5fb7..8be38df1 100644 --- a/Makefile +++ b/Makefile @@ -36,3 +36,7 @@ requirements/dev.txt: setup.cfg binder/requirements.txt: requirements/dev.txt cp $< $@ + +ci-compat-check: + # TODO: mark as dummy + $(MAKE) -C script/$@ diff --git a/script/ci-compat-check/.gitignore b/script/ci-compat-check/.gitignore new file mode 100644 index 00000000..a9a5aecf --- /dev/null +++ b/script/ci-compat-check/.gitignore @@ -0,0 +1 @@ +tmp diff --git a/script/ci-compat-check/Makefile b/script/ci-compat-check/Makefile new file mode 100644 index 00000000..741029df --- /dev/null +++ b/script/ci-compat-check/Makefile @@ -0,0 +1,20 @@ +BOARD_BASE_DIR=tmp +BOARD_PY=$(BOARD_BASE_DIR)/board-py +BOARD_R=$(BOARD_BASE_DIR)/board-r + +all: validate + +clean: + rm -r $(BOARD_PY) $(BOARD_R) + +validate: $(BOARD_PY) $(BOARD_R) + @echo "\n\nRUNNING R PINS ---\n" + Rscript validate_py_to_r.R $(BOARD_PY) $(BOARD_R) + @echo "\n\nRUNNING PYTHON PINS ---\n" + python validate_r_to_py.py $(BOARD_PY) $(BOARD_R) + +$(BOARD_PY): dump_py_pins.py + python dump_py_pins.py $@ + +$(BOARD_R): dump_r_pins.R + Rscript dump_r_pins.R $@ diff --git a/script/ci-compat-check/dump_py_pins.py b/script/ci-compat-check/dump_py_pins.py new file mode 100644 index 00000000..b9d22a13 --- /dev/null +++ b/script/ci-compat-check/dump_py_pins.py @@ -0,0 +1,12 @@ +import sys + +from pins.data import mtcars +from pins import board_folder + +if len(sys.argv) < 2: + raise ValueError("must pass board location as command-line argument") +else: + BOARD_PATH = sys.argv[1] + +board = board_folder(BOARD_PATH) +board.pin_write(mtcars, "mtcars", type="csv") diff --git a/script/ci-compat-check/dump_r_pins.R b/script/ci-compat-check/dump_r_pins.R new file mode 100644 index 00000000..7deff314 --- /dev/null +++ b/script/ci-compat-check/dump_r_pins.R @@ -0,0 +1,5 @@ +library(pins) +args <- commandArgs(trailingOnly=TRUE) + +board <- board_folder(args[1]) +board %>% pin_write(mtcars, "mtcars", type="csv") diff --git a/script/ci-compat-check/validate_py_to_r.R b/script/ci-compat-check/validate_py_to_r.R new file mode 100644 index 00000000..1106796b --- /dev/null +++ b/script/ci-compat-check/validate_py_to_r.R @@ -0,0 +1,25 @@ +library(pins) + +args <- commandArgs(trailingOnly=TRUE) + + +# create board ---- + +board_py <- board_folder(args[1]) +board_r <- board_folder(args[2]) + + +# check pins ---- + +cat("Checking mtcars pin\n") + +res_mtcars <- board_py %>% pin_read("mtcars") +stopifnot(all.equal(res_mtcars, datasets::mtcars, check.attributes=FALSE)) + +meta_mtcars_py <- board_py %>% pin_meta("mtcars") +cat("\nPython meta:\n\n") +print(meta_mtcars_py) + +meta_mtcars_r <- board_r %>% pin_meta("mtcars") +cat("\nR meta:\n\n") +print(meta_mtcars_r) diff --git a/script/ci-compat-check/validate_r_to_py.py b/script/ci-compat-check/validate_r_to_py.py new file mode 100644 index 00000000..593be711 --- /dev/null +++ b/script/ci-compat-check/validate_r_to_py.py @@ -0,0 +1,27 @@ +import sys + +from pins import board_folder +from pins import data + +path_py, path_r = sys.argv[1], sys.argv[2] + +# create board ---- + +board_py = board_folder(path_py) +board_r = board_folder(path_r) + + +# check pins ---- + +print("Checking mtcars pin") + +res_mtcars = board_r.pin_read("mtcars") +assert res_mtcars.equals(data.mtcars) + +meta_mtcars_py = board_py.pin_meta("mtcars") +print("\nPython meta:\n") +print(meta_mtcars_py) + +meta_mtcars_r = board_r.pin_meta("mtcars") +print("\nR meta:\n") +print(meta_mtcars_r)