From 6bf4cd06a538ef7fa1ae16e12e632a8973cb3244 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mirko=20M=C3=A4licke?= Date: Tue, 15 Nov 2022 12:10:03 +0100 Subject: [PATCH] node tool template finished --- .github/workflows/docker-image.yml | 23 ++++++++++ Dockerfile | 10 ++-- in/foo_csv.csv | 11 +++++ in/foo_mat.dat | 8 ++++ in/parameters.json | 9 +++- src/getParameter.js | 74 +++++++++++++++++++++++++++++- src/run.js | 2 +- src/tool.yml | 27 ++++++++--- 8 files changed, 150 insertions(+), 14 deletions(-) create mode 100644 .github/workflows/docker-image.yml create mode 100644 in/foo_csv.csv create mode 100644 in/foo_mat.dat diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml new file mode 100644 index 0000000..a7282cd --- /dev/null +++ b/.github/workflows/docker-image.yml @@ -0,0 +1,23 @@ +name: Docker Image CI + +on: + release: + types: [published] + +jobs: + + build: + + runs-on: ubuntu-latest + + steps: + - name: Checkout repo + uses: actions/checkout@v2 + - name: build and push + uses: docker/build-push-action@v1 + with: + registry: ghcr.io + username: "vforwater" + password: ${{ secrets.PAT }} + repository: vforwater/tbr_template_node + tags: latest,${{ github.ref_name }} \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index f21dfba..b3a8697 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,8 +1,5 @@ FROM node:18.12.1-buster -# Do anything you need to install tool dependencies here -RUN echo "Replace this line with a tool" - # create the tool input structure RUN mkdir /in COPY ./in /in @@ -11,4 +8,11 @@ RUN mkdir /src COPY ./src /src WORKDIR /src + +# install dependencies: js-yaml and papaparse +# in node, the dependencies are directly install into /src/ +RUN npm install js-yaml +RUN npm install papaparse + +# run command CMD ["node", "run.js"] \ No newline at end of file diff --git a/in/foo_csv.csv b/in/foo_csv.csv new file mode 100644 index 0000000..92eb7e9 --- /dev/null +++ b/in/foo_csv.csv @@ -0,0 +1,11 @@ +A,B,C,D +3,14,10,17 +2,0,2,24 +2,17,19,24 +3,13,1,18 +13,13,7,10 +10,7,13,14 +12,12,9,5 +16,24,3,16 +11,3,2,14 +19,4,5,20 \ No newline at end of file diff --git a/in/foo_mat.dat b/in/foo_mat.dat new file mode 100644 index 0000000..3ddcc05 --- /dev/null +++ b/in/foo_mat.dat @@ -0,0 +1,8 @@ +# Created by Octave 6.4.0, Thu Oct 27 08:57:13 2022 UTC +# name: foo_matrix +# type: matrix +# rows: 3 +# columns: 2 + 1 2 + 3 4 + 5 6.0999999999999996 diff --git a/in/parameters.json b/in/parameters.json index 4c1067c..6314c67 100644 --- a/in/parameters.json +++ b/in/parameters.json @@ -1,6 +1,11 @@ { "foobar": { - "foo_int": "42", - "foo_str": "Foobar" + "foo_int": 42, + "foo_float": 13.37, + "foo_string": "Never eat yellow snow", + "foo_enum": "bar", + "foo_array": [34, 55, 23, 43, 23], + "foo_matrix": "/in/foo_matrix.dat", + "foo_csv": "/in/foo_csv.csv" } } \ No newline at end of file diff --git a/src/getParameter.js b/src/getParameter.js index 694e919..229d37d 100644 --- a/src/getParameter.js +++ b/src/getParameter.js @@ -1,10 +1,80 @@ -const { PARAM_FILE, CONF_FILE } = process.env; +const { PARAM_FILE, CONF_FILE, TOOL_RUN } = process.env; +const fs = require('fs'); +const yaml = require('js-yaml'); +const papa = require('papaparse'); const getParameter = () => { // load parameters file const params = require(PARAM_FILE || '/in/parameters.json'); - return params; + // if no tool name was passed, return first configured tool + const toolName = TOOL_RUN ? TOOL_RUN : Object.keys(params)[0] + + // load the yaml file + const config = yaml.load(fs.readFileSync(CONF_FILE || '/src/tool.yml')) + const toolConf = config['tools'][toolName] + + // create the kwargs + const kwargs = {} + + // foreach param passed + Object.entries(params[toolName]).forEach(([key, val]) => { + // get the param conf + const parConf = toolConf[key] + + // if it is not specified, add anyway + if (!parConf) { + kwargs[key] = val + } else { + // parse dates + if (['date', 'time', 'datetime'].includes(parConf['type'].toLowerCase())) { + kwargs[key] = new Date(val) + } + + if (parConf['type'] === 'file') { + ext = val.split('.').pop().toLowerCase() + + // switch the file extension + // json + if (ext === 'json') { + kwargs[key] = require(val) + } + + // dat + else if (ext === 'dat') { + raw = fs.readFileSync(val) + const dat = [] + raw.split('\n').forEach(line => { + if (!line.startsWith('#')) { + dat.push(line.split(' ')) + } + }) + + // add data + kwargs[key] = dat + + } + + // read csv data + else if (ext === 'csv') { + // + raw = fs.readFileSync(val).split('\n') + const recs = papa.parse(raw, {header: true}) + + // add + kwargs[key] = recs + } + + // else the tool should handle it + else { + // pass the file path anyway, because we don't know this file + kwargs[key] = val + } + } + } + }) + + return kwargs; } module.exports = getParameter \ No newline at end of file diff --git a/src/run.js b/src/run.js index a7c31c4..6f0c9c8 100644 --- a/src/run.js +++ b/src/run.js @@ -9,7 +9,7 @@ params = getParameter(); // switch the toolName if (toolName === 'foobar') { console.log('You are running the template directly. Please change the foobar function.') - console.log(params[toolName]) + console.log(params) } else { console.error(`The toolname ${toolName} is not recognized. Did you forget to implement it?`) } \ No newline at end of file diff --git a/src/tool.yml b/src/tool.yml index 5e9e077..a0827d2 100644 --- a/src/tool.yml +++ b/src/tool.yml @@ -1,10 +1,25 @@ tools: foobar: - title: Foobar function - description: Dummy default function of a toolbox template - version: 1.0 + title: Foo Bar + description: A dummy tool to exemplify the YAML file + version: 0.1 parameters: - foo_int: + foo_int: type: integer - foo_str: - type: string \ No newline at end of file + foo_float: + type: float + foo_string: + type: string + foo_enum: + type: enum + values: + - foo + - bar + - baz + foo_array: + type: integer + array: true + foo_matrix: + type: file + foo_csv: + type: file \ No newline at end of file