From 5c317d3e47a769eba105683c4b9d32f2fda2657c Mon Sep 17 00:00:00 2001 From: "arman.avesta" Date: Thu, 8 Aug 2024 16:33:19 -0400 Subject: [PATCH] Run bootstrap.sh --- .github/workflows/ci.yml | 4 +- Dockerfile | 10 +- README.md | 107 +++----------- bootstrap.sh | 267 ----------------------------------- app.py => images_register.py | 11 +- setup.py | 14 +- tests/test_example.py | 2 +- 7 files changed, 43 insertions(+), 372 deletions(-) delete mode 100755 bootstrap.sh rename app.py => images_register.py (79%) mode change 100755 => 100644 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 966e0c5..cb25c93 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,7 +19,6 @@ on: jobs: test: name: Unit tests - if: false # delete this line to enable automatic testing runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v4 @@ -41,8 +40,7 @@ jobs: build: name: Build - if: false # delete this line and uncomment the line below to enable automatic builds - # if: github.event_name == 'push' || github.event_name == 'release' + if: github.event_name == 'push' || github.event_name == 'release' # needs: [ test ] # uncomment to require passing tests runs-on: ubuntu-22.04 diff --git a/Dockerfile b/Dockerfile index b3fd92b..c163046 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,11 +3,11 @@ # FROM ghcr.io/mamba-org/micromamba:1.5.1-focal-cuda-11.3.1 FROM docker.io/python:3.12.1-slim-bookworm -LABEL org.opencontainers.image.authors="FNNDSC " \ - org.opencontainers.image.title="ChRIS Plugin Title" \ - org.opencontainers.image.description="A ChRIS plugin that..." +LABEL org.opencontainers.image.authors="FNNDSC " \ + org.opencontainers.image.title="Multiple image registration" \ + org.opencontainers.image.description="A ChRIS plugin to do multiple image registration" -ARG SRCDIR=/usr/local/src/app +ARG SRCDIR=/usr/local/src/pl-images-register WORKDIR ${SRCDIR} COPY requirements.txt . @@ -19,4 +19,4 @@ RUN pip install ".[${extras_require}]" \ && cd / && rm -rf ${SRCDIR} WORKDIR / -CMD ["commandname"] +CMD ["images_register"] diff --git a/README.md b/README.md index a8ff3ec..ba48f85 100644 --- a/README.md +++ b/README.md @@ -1,76 +1,10 @@ -# _ChRIS_ Plugin Template +# Multiple image registration -[![test status](https://github.com/FNNDSC/python-chrisapp-template/actions/workflows/src.yml/badge.svg)](https://github.com/FNNDSC/python-chrisapp-template/actions/workflows/src.yml) -[![MIT License](https://img.shields.io/github/license/FNNDSC/python-chrisapp-template)](LICENSE) +[![Version](https://img.shields.io/docker/v/fnndsc/pl-images-register?sort=semver)](https://hub.docker.com/r/fnndsc/pl-images-register) +[![MIT License](https://img.shields.io/github/license/fnndsc/pl-images-register)](https://github.com/FNNDSC/pl-images-register/blob/main/LICENSE) +[![ci](https://github.com/FNNDSC/pl-images-register/actions/workflows/ci.yml/badge.svg)](https://github.com/FNNDSC/pl-images-register/actions/workflows/ci.yml) -This is a minimal template repository for _ChRIS_ plugin applications in Python. - -## About _ChRIS_ Plugins - -A _ChRIS_ plugin is a scientific data-processing software which can run anywhere all-the-same: -in the cloud via a [web app](https://github.com/FNNDSC/ChRIS_ui/), or on your own laptop -from the terminal. They are easy to build and easy to understand: most simply, a -_ChRIS_ plugin is a command-line program which processes data from an input directory -and creates data to an output directory with the usage -`commandname [options...] inputdir/ outputdir/`. - -For more information, visit our website https://chrisproject.org - -## How to Use This Template - -Go to https://github.com/FNNDSC/python-chrisapp-template and click "Use this template". -The newly created repository is ready to use right away. - -A script `bootstrap.sh` is provided to help fill in and rename values for your new project. -It is optional to use. - -1. Edit the variables in `bootstrap.sh` -2. Run `./bootstrap.sh` -3. Follow the instructions it will print out - -## Example Plugins - -Here are some good, complete examples of _ChRIS_ plugins created from this template. - -- https://github.com/FNNDSC/pl-dcm2niix (basic command wrapper example) -- (parallelizes a command) -- https://github.com/FNNDSC/pl-mri-preview (uses [NiBabel](https://nipy.org/nibabel/)) -- https://github.com/FNNDSC/pl-pyvista-volume (example using Python package project structure and pytest) -- https://github.com/FNNDSC/pl-fetal-cp-surface-extract (has a good README.md) - -## What's Inside - -| Path | Purpose | -|----------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `app.py` | Main script: start editing here! | -| `tests/` | Unit tests | -| `setup.py` | [Python project metadata and installation script](https://packaging.python.org/en/latest/guides/distributing-packages-using-setuptools/#setup-py) | -| `requirements.txt` | List of Python dependencies | -| `Dockerfile` | [Container image build recipe](https://docs.docker.com/engine/reference/builder/) | -| `.github/workflows/ci.yml` | "continuous integration" using [Github Actions](https://docs.github.com/en/actions/learn-github-actions/understanding-github-actions): automatic testing, building, and uploads to https://chrisstore.co | - -## Contributing - -The source code for the `main` branch of this repository is on the -[src](https://github.com/fnndsc/python-chrisapp-template/tree/src) -branch, which has an additional file -[`.github/workflows/src.yml`](https://github.com/FNNDSC/python-chrisapp-template/blob/src/.github/workflows/src.yml) -When tests pass, changes are automatically merged into `main`. -Developers should commit to or make pull requests targeting `src`. -Do not push directly to `main`. - -This is a workaround in order to do automatic testing of this template -without including the `.github/workflows/src.yml` file in the template itself. - - diff --git a/bootstrap.sh b/bootstrap.sh deleted file mode 100755 index 55cae3d..0000000 --- a/bootstrap.sh +++ /dev/null @@ -1,267 +0,0 @@ -#!/usr/bin/env bash -# bootstrap.sh: customize python-chrisapp-template with project details -# -# WARNING: This script is for advanced users only! Do not proceed -# unless you understand what this does. New developers would find -# it easier to use python-chrisapp-template as is. Simply ignore -# and optionally delete this file. - -# ======================================== -# CONFIGURATION -# ======================================== - -# ---------------------------------------- -# STEP 1. Change these values to your liking. -# ---------------------------------------- - -PLUGIN_NAME="$(basename $(dirname $(realpath $0)))" # name of current directory -PLUGIN_TITLE='Multiple image registration' -SCRIPT_NAME='images_register' -DESCRIPTION='A ChRIS plugin to do multiple image registration' -ORGANIZATION='FNNDSC' -EMAIL='arman.avasta@childrens.harvard.edu' - -# Github Actions: automatically test and build your code. -# https://github.com/FNNDSC/python-chrisapp-template/wiki/Continuous-Integration -# -# These options will fail unless your Github settings are preconfigured. -# Repositories under github.com/FNNDSC are preconfigured, so these defaults might work. -# Please review the file .github/workflows/ci.yml before you push it. - -# Automatically test on Github Actions each time you run `git push` -# If the value is "no" then tests are not performed. There are no side effects. -ENABLE_ACTIONS_TEST=yes -# Automatically build images on Github Actions each time you run `git push`, -# and also publish to https://chrisstore.co each time you run `git push --tags` -# If the value is "no" then builds will not be automated. -ENABLE_ACTIONS_BUILD=yes - -# WARNING: the default configuration in .github/workflows/ci.yml is to allow for -# the build to proceed regardless of whether tests pass. To modify this behavior -# and other advanced features (such as multi-architecture builds such as arm64, ppc64le) -# you must edit .github/workflows/ci.yml by hand. - - -# ---------------------------------------- -# STEP 2. Uncomment the line where it says READY=yes -# ---------------------------------------- - -READY=yes - -# ---------------------------------------- -# STEP 3. Run: ./bootstrap.sh -# ---------------------------------------- - - -if [ "$(uname -o 2> /dev/null)" != 'GNU/Linux' ]; then - >&2 echo "error: this script only works on GNU/Linux." -fi - -if ! [ "$READY" = 'yes' ]; then - >&2 echo "error: you are not READY." - exit 1 -fi - -cd $(dirname "$0") - - -# ======================================== -# VALIDATE INPUT -# ======================================== - -function contains_invalid_characters () { - [[ "$1" = *"/"* ]] -} - -# given a variable name, exit if the variable's value contains invalid characters. -function check_variable_value_valid () { - local varname="$1" - local varvalue="${!varname}" - if contains_invalid_characters "$varvalue"; then - >&2 echo "error: invalid characters in $varname=$varvalue" - exit 1 - fi -} - -# may not contain '/' -check_variable_value_valid PLUGIN_NAME -check_variable_value_valid SCRIPT_NAME -check_variable_value_valid ORGANIZATION -check_variable_value_valid EMAIL - - -# ======================================== -# COMMIT THE USER-SET CONFIG -# ======================================== - -# print command to run before running it -function verb () { - set -x - "$@" - { set +x; } 2> /dev/null -} - -# fail on error -set -e -set -o pipefail - -verb git commit -m 'Configure python-chrisapp-template/bootstrap.sh' -- "$0" - - -# ======================================== -# REPLACE VALUES -# ======================================== - -# execute sed on all files in project, excluding hidden paths and venv/ -function replace_in_all () { - if [ -z "$2" ]; then - return - fi - find . -type f \ - -not -path '*/\.*/*' -not -path '*/\venv/*' -not -name 'bootstrap.sh' \ - -exec sed -i -e "s/$1/$2/g" '{}' \; -} - -replace_in_all commandname "$SCRIPT_NAME" -replace_in_all pl-appname "$PLUGIN_NAME" -replace_in_all 'dev@babyMRI.org' "$EMAIL" -replace_in_all FNNDSC "$ORGANIZATION" - -# .github/ -if [ "${ENABLE_ACTIONS_TEST,,}" = 'yes' ]; then - sed -i -e '/delete this line to enable automatic testing/d' .github/workflows/ci.yml -fi - -if [ "${ENABLE_ACTIONS_BUILD,,}" = 'yes' ]; then - sed -i -e '/delete this line and uncomment the line below to enable automatic builds/d' .github/workflows/ci.yml - sed -i -e 's/# *if: github\.event_name/if: github\.event_name/' .github/workflows/ci.yml -fi - -# replace "/" with "\/" in string -function escape_slashes () { - sed 's/\//\\&/g' <<< "$@" -} - -escaped_description="$(escape_slashes "$DESCRIPTION")" -escaped_title="$(escape_slashes "$PLUGIN_TITLE")" - -# README.md -temp_file=$(mktemp) -sed -e'/^# ChRIS Plugin Title$/'\{ -e:1 -en\;b1 -e\} -ed README.md \ - | sed "s/^# ChRIS Plugin Title\$/# $escaped_title/" \ - | sed '/^END README TEMPLATE -->$/d' \ - | sed "s/fnndsc/${ORGANIZATION,,}/g" \ - | sed "s/app\\.py/$SCRIPT_NAME.py/g" \ - > $temp_file -mv $temp_file README.md - -# Dockerfile -sed "s#ARG SRCDIR=/usr/local/src/app#ARG SRCDIR=/usr/local/src/$PLUGIN_NAME#" Dockerfile \ - | sed "s/org\.opencontainers\.image\.title=\"ChRIS Plugin Title\"/org.opencontainers.image.title=\"$escaped_title\"/" \ - | sed "s/org\.opencontainers\.image\.description=\"A ChRIS plugin that\.\.\.\"/org.opencontainers.image.description=\"$escaped_description\"/" \ - > $temp_file -mv $temp_file Dockerfile - -# setup.py - -function guess_https_url () { - local origin="$(git remote get-url origin)" - local https_url="$origin" - if [[ "$https_url" = "git@"* ]]; then - # convert SSH url to HTTPS url by - # 1. change last ':' to '/' - # 2. replace leading 'git@' with 'https://' - https_url="$( - echo "$https_url" \ - | sed 's#\(.*\):#\1/#' \ - | sed 's#^git@#https://#' - )" - fi - echo "${https_url:0:-4}" # remove trailing ".git" -} - -appname_without_prefix="$(sed -E 's/(pl|dbg|ep)-//' <<< "$PLUGIN_NAME")" -sed "s/name='.*'/name='$appname_without_prefix'/" setup.py \ - | sed "s/description='.*'/description='$escaped_description'/" \ - | sed "s/py_modules=\['app'\]/py_modules=['$SCRIPT_NAME']/" \ - | sed "s/app:main/$SCRIPT_NAME:main/" \ - | sed "s#url='.*'#url='$(guess_https_url)'#" \ - | sed "s/app\.py/$SCRIPT_NAME.py/" \ - > $temp_file -mv $temp_file setup.py - -# app.py - -# FIGlet over HTTPS, since it's probably not installed locally -function figlet_wrapper () { - curl -fsSG 'https://figlet.chrisproject.org/' --data-urlencode "message=$*" \ - | grep -v '^[[:space:]]*$' -} - -function inject_figleted_title () { - python << EOF -for line in open('app.py'): - if line == 'ChRIS Plugin Template Title\n': - print(r"""$1""") - else: - print(line, end='') -EOF -} - -figleted_title="$(figlet_wrapper "$PLUGIN_NAME")" -echo "$figleted_title" -inject_figleted_title "$figleted_title" \ - | sed "s/title='My ChRIS plugin'/title='$escaped_title'/" \ - | sed "s/description='cli description'/description='$escaped_description'/" \ - > "$SCRIPT_NAME.py" -rm app.py - -# tests/ -for test_file in tests/*.py; do - sed "s/from app import/from $SCRIPT_NAME import/" $test_file > $temp_file - mv $temp_file $test_file -done - -# ======================================== -# SETUP -# ======================================== - -if ! [ -e venv ]; then - verb python -m venv venv -fi - ->&2 echo + source venv/bin/activate -source venv/bin/activate -verb pip install -r requirements.txt -verb pip install -e '.[dev]' - - -if [ -z "$TERM" ]; then - tput=tput -else - tput=true -fi - -$tput bold ->&2 printf '\n%s\n\n' '✨Done!✨' -$tput sgr0 - -$tput setaf 3 ->&2 echo 'To undo these actions and start over, run:' ->&2 printf '\n\t%s\n\t%s\n\t%s\n\t%s\n\n' \ - 'git reset --hard' \ - 'git clean -df' \ - 'rm -rf venv *.egg-info' \ - "git reset 'HEAD^'" -$tput setaf 6 ->&2 echo 'Activate the Python virtual environment by running:' ->&2 printf '\n\t%s\n\n' 'source venv/bin/activate' ->&2 echo 'Save these changes by running:' ->&2 printf '\n\t%s\n\n' 'git add -A && git commit -m "Run bootstrap.sh"' -$tput setaf 2 -echo 'For more information on how to get started, see README.md' -$tput sgr0 - -verb rm -v "$0" - -# Note to self: consider rewriting this in Python? diff --git a/app.py b/images_register.py old mode 100755 new mode 100644 similarity index 79% rename from app.py rename to images_register.py index 68e8e68..e6a5a51 --- a/app.py +++ b/images_register.py @@ -8,7 +8,14 @@ __version__ = '1.0.0' DISPLAY_TITLE = r""" -ChRIS Plugin Template Title + _ _ _ _ + | | (_) (_) | | + _ __ | |______ _ _ __ ___ __ _ __ _ ___ ___ ______ _ __ ___ __ _ _ ___| |_ ___ _ __ +| '_ \| |______| | '_ ` _ \ / _` |/ _` |/ _ \/ __|______| '__/ _ \/ _` | / __| __/ _ \ '__| +| |_) | | | | | | | | | (_| | (_| | __/\__ \ | | | __/ (_| | \__ \ || __/ | +| .__/|_| |_|_| |_| |_|\__,_|\__, |\___||___/ |_| \___|\__, |_|___/\__\___|_| +| | __/ | __/ | +|_| |___/ |___/ """ @@ -30,7 +37,7 @@ # documentation: https://fnndsc.github.io/chris_plugin/chris_plugin.html#chris_plugin @chris_plugin( parser=parser, - title='My ChRIS plugin', + title='Multiple image registration', category='', # ref. https://chrisstore.co/plugins min_memory_limit='100Mi', # supported units: Mi, Gi min_cpu_limit='1000m', # millicores, e.g. "1000m" = 1 CPU core diff --git a/setup.py b/setup.py index 240b0dd..664ed20 100644 --- a/setup.py +++ b/setup.py @@ -19,18 +19,18 @@ def get_version(rel_path: str) -> str: setup( - name='chris-plugin-template', - version=get_version('app.py'), - description='A ChRIS DS plugin template', + name='images-register', + version=get_version('images_register.py'), + description='A ChRIS plugin to do multiple image registration', author='FNNDSC', - author_email='dev@babyMRI.org', - url='https://github.com/FNNDSC/python-chrisapp-template', - py_modules=['app'], + author_email='arman.avasta@childrens.harvard.edu', + url='https://github.com/FNNDSC/pl-images-regi', + py_modules=['images_register'], install_requires=['chris_plugin'], license='MIT', entry_points={ 'console_scripts': [ - 'commandname = app:main' + 'images_register = images_register:main' ] }, classifiers=[ diff --git a/tests/test_example.py b/tests/test_example.py index 83d3846..e362d69 100644 --- a/tests/test_example.py +++ b/tests/test_example.py @@ -1,6 +1,6 @@ from pathlib import Path -from app import parser, main +from images_register import parser, main def test_main(tmp_path: Path):