Loading scripts/maintainer-tools/copyright-headers/gekkofs-syntax.yml 0 → 100644 +296 −0 Original line number Original line Diff line number Diff line ruby: ext: ['.rb', '.rake'] after: ['^#!', '^#.*encoding:', '^#.*frozen_string_literal:'] comment: open: '%repeat{#, :word_wrap:}%\n' close: '%repeat{#, :word_wrap:}%\n\n' prefix: '# ' suffix: '' perl: ext: ['.pl'] after: ['^#!', '^#.*encoding:'] comment: open: '#\n' close: '#\n' prefix: '# ' suffix: '' # Support PEP 0263 comments: # coding=<encoding name> # -*- coding: <encoding name> -*- # vim: set fileencoding=<encoding name> : python: ext: ['.py'] after: ['^#!', '^#.*coding:', '^#.*coding=', '^#.*fileencoding='] comment: open: '%repeat{#, :word_wrap:}%\n' close: '%repeat{#, :word_wrap:}%\n\n' prefix: '# ' suffix: '#\n' html: ext: ['.html', '.htm', '.xhtml'] comment: open: '<!--\n' close: '-->\n' prefix: ' ' suffix: '' php: ext: ['.php'] after: [ '^#!' ] comment: open: '<?php \n/*\n' close: ' */ ?>\n' prefix: ' * ' suffix: '' javacript: ext: ['.js', '.jsx'] comment: open: '/*\n' close: ' */\n\n' prefix: ' * ' suffix: '' qml: ext: ['.qml'] comment: open: '/*\n' close: ' */\n\n' prefix: ' * ' suffix: '' qmake_project: ext: ['.pro'] comment: open: '#\n' close: '#\n' prefix: '# ' suffix: '' css: ext: ['.css'] comment: open: '/*\n' close: ' */\n\n' prefix: ' * ' suffix: '' c: ext: ['.c', '.h'] comment: open: '/*\n' close: '*/\n\n' prefix: ' ' suffix: '\n' cpp: ext: ['.cpp', '.hpp', '.cc', '.hh'] comment: open: '/*\n' close: '*/\n\n' prefix: ' ' suffix: '\n' java: ext: ['.java'] comment: open: '/*\n' close: ' */\n\n' prefix: ' * ' suffix: '' kotlin: ext: ['.kt'] comment: open: '/*\n' clone: ' */\n\n' prefix: ' * ' suffix: '' golang: ext: ['.go'] comment: open: '/*\n' close: ' */\n\n' prefix: ' * ' suffix: '' groovy: ext: ['.groovy'] comment: open: '/*\n' close: ' */\n\n' prefix: ' * ' suffix: '' haml: ext: ['.haml', '.hamlc'] comment: open: '-#\n' close: '-#\n' prefix: '-# ' suffix: '' coffee: ext: ['.coffee'] comment: open: '###\n' close: '###\n' prefix: '' suffix: '' # M4 macro language, use #, not dnl m4: ext: ['.m4'] comment: open: '#\n' close: '#\n' prefix: '# ' suffix: '' am: ext: ['.am'] comment: open: '##########################################################################\n' close: '##########################################################################\n\n' prefix: '# ' suffix: '#\n' ac: ext: ['.ac'] comment: open: '##########################################################################\n' close: '##########################################################################\n\n' prefix: '# ' suffix: '#\n' mk: ext: ['.mk'] comment: open: '##########################################################################\n' close: '##########################################################################\n\n' prefix: '# ' suffix: '#\n' # Most shells, really shell: ext: ['.sh'] after: ['^#!'] comment: open: '%repeat{#, :word_wrap:}%\n' close: '%repeat{#, :word_wrap:}%\n\n' prefix: '# ' suffix: '#\n' # Use "-- " to make sure e.g. MySQL understands it sql: ext: ['.sql'] comment: open: '-- \n' close: '-- \n' prefix: '-- ' suffix: '' # XML is *not* the same as HTML, and the comments need to go after a # preprocessing directive, if present. # FIXME: only supports single line directives xml: ext: ['.xml', '.xsd', '.mxml'] after: ['^<\?'] comment: open: '<!--\n' close: '-->\n' prefix: ' ' suffix: '' yaml: ext: ['.yml', '.yaml'] comment: open: '%repeat{#, :word_wrap:}%\n' close: '%repeat{#, :word_wrap:}%\n\n' prefix: '# ' suffix: '#\n' action_script: ext: ['.as'] comment: open: '//\n' close: '//\n\n' prefix: '// ' suffix: '' sass: ext: ['.sass', '.scss'] comment: open: '/*\n' close: ' */\n\n' prefix: ' * ' suffix: '' verilog: ext: ['.v', '.sv'] comment: open: '//\n' close: '//\n\n' prefix: '// ' suffix: '' vhdl: ext: ['.vhd'] comment: open: '--\n' close: '--\n\n' prefix: '-- ' suffix: '' elm: ext: ['.elm'] comment: open: '{-\n' close: '-}\n\n' prefix: ' ' suffix: '' swift: ext: ['.swift'] comment: open: '/*\n' close: ' */\n\n' prefix: ' * ' suffix: '' rust: ext: ['.rs'] comment: open: '/*\n' close: ' */\n\n' prefix: ' * ' suffix: '' # Conf files i.e. apache config, splunk.conf files conf: ext: ['.conf'] comment: open: '#\n' close: '#\n' prefix: '# ' suffix: '' cmake: ext: ['CMakeLists.txt', '.cmake'] comment: open: '%repeat{#, :word_wrap:}%\n' close: '%repeat{#, :word_wrap:}%\n\n' prefix: '# ' suffix: '#\n' dockerfile: ext: ['Dockerfile'] comment: open: '%repeat{#, :word_wrap:}%\n' close: '%repeat{#, :word_wrap:}%\n\n' prefix: '# ' suffix: '#\n' scripts/maintainer-tools/copyright-headers/gekkofs-template.erb 0 → 100644 +10 −0 Original line number Original line Diff line number Diff line Copyright <%=eval(copyright_years[0])[:bsc].join('-')%>, Barcelona Supercomputing Center (BSC), Spain Copyright <%=eval(copyright_years[0])[:jgu].join('-')%>, Johannes Gutenberg Universitaet Mainz, Germany This software was partially supported by the EC H2020 funded project NEXTGenIO (Project ID: 671951, www.nextgenio.eu). This software was partially supported by the ADA-FS project under the SPPEXA project funded by the DFG. SPDX-License-Identifier: MIT scripts/maintainer-tools/copyright-headers/manage-headers.sh 0 → 100755 +365 −0 Original line number Original line Diff line number Diff line #!/bin/bash PROJECT_DIR=$(readlink -f .) PROJECT_CONFIG_FILE="project.config" DOCKER_DIR="/usr/src" INCLUDE_PATTERNS=( "*.c" "*.h" "*.cpp" "*.hpp" "*.am" "*.ac" "*.py" "*.sh" "*.mk") EXCLUDE_PATTERNS=( ".git" "*build*" "*externals*" "*spdlog*" "*ctypesgen*" "./tests/catch.hpp" ) function help() { cat << EOF Usage: $(basename "$0") COMMAND [OPTIONS] [PATH]... Add or remove license headers for each PATH specified by the user. If no PATH is specified, the specified command is recursively applied to all files in the current directory matching the following __default__ expressions: INCLUDE_PATTERNS: ${INCLUDE_PATTERNS[@]} EXCLUDE_PATTERNS: ${EXCLUDE_PATTERNS[@]} These default patterns can be overriden with a '${PROJECT_CONFIG_FILE}' file. The following commands can be used: -a, --add Add license header to targets. -r, --remove Remove license header from targets. -h, --help Show this help message, then exit. Additionally, the following options are supported: -p, --project-dir DIR The root directory of the project's target files. Defaults to '\$PWD', the current directory. -s, --show-targets Don't actually execute, just show which targets would be considered. -n, --dry-run Don't actually execute, just show what would happen. EOF exit 1 } function parse_args() { show_targets_only=false # $@ is all command line parameters passed to the script. # -o is for short options like -v # -l is for long options with double dash like --version # the comma separates different long options options=$(getopt -l \ "add,remove,help,project-dir:,dry-run,show-targets" \ -o "arhp:ns" -- "$@") # set --: # If no arguments follow this option, then the positional parameters are # unset. Otherwise, the positional parameters are set to the arguments, # even if some of them begin with a ‘-’. eval set -- "${options}" while true; do OPT="$1" case "${OPT}" in -a | --add) PARSED_COMMAND="--add" ;; -r | --remove) PARSED_COMMAND="--remove" ;; -p | --project-dir) shift if [[ -z "$1" ]]; then echo "option '${OPT}' requires an argument" exit 1 fi if ! [[ -d $1 ]]; then echo "directory '${1}' does not exist." exit 1 fi PROJECT_DIR=$(readlink -f "$1") ;; -n | --dry-run) EXTRA_PROG_ARGS+=( "-n" ) ;; -s | --show-targets) show_targets_only=true ;; --) shift EXTRA_SCRIPT_ARGS=( "$@" ) break ;; -h | --help | *) help exit 0 ;; esac shift done echo "-- Project directory: '${PROJECT_DIR}' --" if [[ -z "${PARSED_COMMAND}" ]]; then echo "$(basename "$0"): ERROR: no command provided" help exit 1 fi } function validate_gem_version() { if shopt -qo xtrace; then return fi IFS=' .' read -r -a VERSION < <( (${COPYRIGHT_PROG} -v 2>&1) |& head -n1) if [[ "${VERSION[1]}" -lt 1 ]] || [[ "${VERSION[2]}" -lt 0 ]] || [[ "${VERSION[3]}" -lt 27 ]]; then echo "CopyrightHeader gem too old" exit 1 fi } function find_command() { COPYRIGHT_LICENSE_HOST=$(readlink -f "${COPYRIGHT_LICENSE}") COPYRIGHT_LICENSE_DOCKER="${DOCKER_DIR}/"$(basename "${COPYRIGHT_LICENSE}") PROG_ARGS=( "--rm" "--volume=${PROJECT_DIR}:${PROJECT_DIR}" "--volume=${COPYRIGHT_LICENSE_HOST}:${COPYRIGHT_LICENSE_DOCKER}" ) if [[ -n "${COPYRIGHT_SYNTAX}" ]]; then COPYRIGHT_SYNTAX_HOST=$(readlink -f "${COPYRIGHT_SYNTAX}") COPYRIGHT_SYNTAX_DOCKER="${DOCKER_DIR}/"$(basename "${COPYRIGHT_SYNTAX}") PROG_ARGS+=( "--volume=${COPYRIGHT_SYNTAX_HOST}:${COPYRIGHT_SYNTAX_DOCKER}" ) fi COPYRIGHT_PROG="docker run ${PROG_ARGS[*]} gekkofs/copyright-header:latest" validate_gem_version } function print_target() { target="$1" message="$2" prefix="Checking " target_length="${#target}" message_length="${#message}" prefix_length="${#prefix}" maxcols=$(echo "scale=0; ($(tput cols)*0.6)/1" | bc -l) # the +2 and -2 accounts for quotes used when printing targets # the +1 for the separation space if [[ $((target_length + prefix_length + 2 + 1 + message_length)) -gt $maxcols ]]; then printf "$prefix%s\n%$(( maxcols ))s\n" "'${t}'" "${message}" else printf "$prefix%s %$(( maxcols - prefix_length - target_length - 3))s\n" "'${t}'" "${message}" fi } function find_targets() { TARGETS=() # option1: targets are passed as arguments if [[ -n "$*" ]]; then TARGETS=( "$@" ) for t in "${TARGETS[@]}"; do t="$(readlink -f ${t})" if [ "${t##$PROJECT_DIR}" != "${PROJECT_DIR}" ]; then print_target "${t}" "[SKIPPED -- outside project directory]" else PATH_ARGS+="${t}:" fi done return fi # option 2: targets are auto-detected based on ${PROJECT_DIR}, # ${INCLUDE_PATTERNS}, and ${EXCLUDE_PATTERNS} if [[ ${#EXCLUDE_PATTERNS[@]} -ne 0 ]]; then for p in "${EXCLUDE_PATTERNS[@]}"; do exclude_args+=( -not \( -path "${p}" -prune \) ) done fi if [[ ${#INCLUDE_PATTERNS[@]} -ne 0 ]]; then include_args=( \( -path "${INCLUDE_PATTERNS[0]}" \) ) for ((i = 1; i < ${#INCLUDE_PATTERNS[@]}; ++i)); do include_args+=( -o \( -path "${INCLUDE_PATTERNS[$i]}" \) ) done fi #### see https://stackoverflow.com/questions/23356779/how-can-i-store-the-find-command-results-as-an-array-in-bash while IFS= read -r -d $'\0'; do TARGETS+=("$REPLY") done < <(find "${PROJECT_DIR}" \( "${exclude_args[@]}" \) -and \( "${include_args[@]}" \) -print0) for t in "${TARGETS[@]}"; do if ! git ls-files --error-unmatch "${t}" > /dev/null 2>&1; then print_target "${t}" "[SKIPPED -- not under version control]" else print_target "${t}" "[OK]" PATH_ARGS+="${t}:" fi done if $show_targets_only; then exit 0 fi } function read_project_config() { ## read project configuration if [[ ! -f "${PROJECT_CONFIG_FILE}" ]]; then echo "ERROR: Missing project configuration file." exit 1 fi source "${PROJECT_CONFIG_FILE}" ## verify mandatory options if [[ -z "${COPYRIGHT_LICENSE}" ]]; then echo "ERROR: missing COPYRIGHT_LICENSE in '${PROJECT_CONFIG_FILE}'" exit 1 fi } function prepare_command_args() { ARGS=() # mandatory args ARGS+=( "--guess-extension" ) ARGS+=( "--license-file=${COPYRIGHT_LICENSE}" ) ARGS+=( "--output-dir=/" ) # optional if [[ -n "${COPYRIGHT_SYNTAX}" ]]; then ARGS+=( "--syntax=${COPYRIGHT_SYNTAX}" ) fi if [[ -n "${COPYRIGHT_SOFTWARE}" ]]; then ARGS+=( "--copyright-software=\"${COPYRIGHT_SOFTWARE}\"" ) fi if [[ -n "${COPYRIGHT_DESCRIPTION}" ]]; then ARGS+=( "--copyright-software-description=\"${COPYRIGHT_DESCRIPTION}\"" ) fi if [[ -n "${COPYRIGHT_YEARS}" ]]; then ARGS+=( "--copyright-year=${COPYRIGHT_YEARS}" ) fi if [[ -n "${COPYRIGHT_WORD_WRAP}" ]]; then ARGS+=( "--word-wrap=${COPYRIGHT_WORD_WRAP}" ) fi COPYRIGHT_PROG_ARGS=( "${ARGS[@]}" ) } function add_header() { # load project configuration read_project_config find_targets "$@" if [[ -z $PATH_ARGS ]] ; then echo No targets detected. Nothing to do. exit 0 fi # prepare command to execute and its args find_command prepare_command_args # execute command ${COPYRIGHT_PROG} \ --add-path "${PATH_ARGS::-1}" \ "${COPYRIGHT_PROG_ARGS[@]}" \ "${EXTRA_PROG_ARGS[@]}" exit $? } function remove_header() { # load project configuration read_project_config find_targets "$@" if [[ -z $PATH_ARGS ]]; then echo No targets detected. Nothing to do. exit 0 fi # prepare command to execute and its args find_command prepare_command_args ${COPYRIGHT_PROG} \ --remove-path "${PATH_ARGS::-1}" \ "${COPYRIGHT_PROG_ARGS[@]}" \ "${EXTRA_PROG_ARGS[@]}" exit $? } ################################################################################ ### Script starts here ### ################################################################################ # process command line args if [[ $# -eq 0 ]]; then help fi parse_args "$@" # execute selected command case $PARSED_COMMAND in -a | --add) add_header "${EXTRA_SCRIPT_ARGS[@]}" ;; -r | --remove) remove_header "${EXTRA_SCRIPT_ARGS[@]}" ;; esac exit 0 scripts/maintainer-tools/copyright-headers/project.config 0 → 100644 +53 −0 Original line number Original line Diff line number Diff line # vi: filetype=sh ################################################################################ ## Variables to control how the header is generated ################################################################################ # COPYRIGHT_SOFTWARE="gekkofs" # COPYRIGHT_DESCRIPTION="an ephemeral distributed file system for HPC applications" COPYRIGHT_YEARS="{:bsc => [2018, 2020], :jgu => [2015, 2020]}" COPYRIGHT_LICENSE="gekkofs-template.erb" COPYRIGHT_SYNTAX="gekkofs-syntax.yml" COPYRIGHT_WORD_WRAP=80 ################################################################################ ## Variables to control which files are considered ## N.B: these are **glob patterns**, NOT regular expressions ################################################################################ INCLUDE_PATTERNS=( "*.c" "*.h" "*.cpp" "*.hpp" "*.hpp.in" "*.am" "*.ac" "*.py" "*.sh" "*.mk" "*CMakeLists.txt" "*.cmake" "*.yml" "*.erb" "*.ini.in" "*.py.in" "*Dockerfile" ) EXCLUDE_PATTERNS=( "*.git" "*.gitlab-ci.yml" "*build*" "*external?*" "*spdlog*" "*ctypesgen*" "./tests/catch.hpp" "*agios.conf" "*.diff" "*.erb" "*.coverage-exclusions" "*.project.config" ) Loading
scripts/maintainer-tools/copyright-headers/gekkofs-syntax.yml 0 → 100644 +296 −0 Original line number Original line Diff line number Diff line ruby: ext: ['.rb', '.rake'] after: ['^#!', '^#.*encoding:', '^#.*frozen_string_literal:'] comment: open: '%repeat{#, :word_wrap:}%\n' close: '%repeat{#, :word_wrap:}%\n\n' prefix: '# ' suffix: '' perl: ext: ['.pl'] after: ['^#!', '^#.*encoding:'] comment: open: '#\n' close: '#\n' prefix: '# ' suffix: '' # Support PEP 0263 comments: # coding=<encoding name> # -*- coding: <encoding name> -*- # vim: set fileencoding=<encoding name> : python: ext: ['.py'] after: ['^#!', '^#.*coding:', '^#.*coding=', '^#.*fileencoding='] comment: open: '%repeat{#, :word_wrap:}%\n' close: '%repeat{#, :word_wrap:}%\n\n' prefix: '# ' suffix: '#\n' html: ext: ['.html', '.htm', '.xhtml'] comment: open: '<!--\n' close: '-->\n' prefix: ' ' suffix: '' php: ext: ['.php'] after: [ '^#!' ] comment: open: '<?php \n/*\n' close: ' */ ?>\n' prefix: ' * ' suffix: '' javacript: ext: ['.js', '.jsx'] comment: open: '/*\n' close: ' */\n\n' prefix: ' * ' suffix: '' qml: ext: ['.qml'] comment: open: '/*\n' close: ' */\n\n' prefix: ' * ' suffix: '' qmake_project: ext: ['.pro'] comment: open: '#\n' close: '#\n' prefix: '# ' suffix: '' css: ext: ['.css'] comment: open: '/*\n' close: ' */\n\n' prefix: ' * ' suffix: '' c: ext: ['.c', '.h'] comment: open: '/*\n' close: '*/\n\n' prefix: ' ' suffix: '\n' cpp: ext: ['.cpp', '.hpp', '.cc', '.hh'] comment: open: '/*\n' close: '*/\n\n' prefix: ' ' suffix: '\n' java: ext: ['.java'] comment: open: '/*\n' close: ' */\n\n' prefix: ' * ' suffix: '' kotlin: ext: ['.kt'] comment: open: '/*\n' clone: ' */\n\n' prefix: ' * ' suffix: '' golang: ext: ['.go'] comment: open: '/*\n' close: ' */\n\n' prefix: ' * ' suffix: '' groovy: ext: ['.groovy'] comment: open: '/*\n' close: ' */\n\n' prefix: ' * ' suffix: '' haml: ext: ['.haml', '.hamlc'] comment: open: '-#\n' close: '-#\n' prefix: '-# ' suffix: '' coffee: ext: ['.coffee'] comment: open: '###\n' close: '###\n' prefix: '' suffix: '' # M4 macro language, use #, not dnl m4: ext: ['.m4'] comment: open: '#\n' close: '#\n' prefix: '# ' suffix: '' am: ext: ['.am'] comment: open: '##########################################################################\n' close: '##########################################################################\n\n' prefix: '# ' suffix: '#\n' ac: ext: ['.ac'] comment: open: '##########################################################################\n' close: '##########################################################################\n\n' prefix: '# ' suffix: '#\n' mk: ext: ['.mk'] comment: open: '##########################################################################\n' close: '##########################################################################\n\n' prefix: '# ' suffix: '#\n' # Most shells, really shell: ext: ['.sh'] after: ['^#!'] comment: open: '%repeat{#, :word_wrap:}%\n' close: '%repeat{#, :word_wrap:}%\n\n' prefix: '# ' suffix: '#\n' # Use "-- " to make sure e.g. MySQL understands it sql: ext: ['.sql'] comment: open: '-- \n' close: '-- \n' prefix: '-- ' suffix: '' # XML is *not* the same as HTML, and the comments need to go after a # preprocessing directive, if present. # FIXME: only supports single line directives xml: ext: ['.xml', '.xsd', '.mxml'] after: ['^<\?'] comment: open: '<!--\n' close: '-->\n' prefix: ' ' suffix: '' yaml: ext: ['.yml', '.yaml'] comment: open: '%repeat{#, :word_wrap:}%\n' close: '%repeat{#, :word_wrap:}%\n\n' prefix: '# ' suffix: '#\n' action_script: ext: ['.as'] comment: open: '//\n' close: '//\n\n' prefix: '// ' suffix: '' sass: ext: ['.sass', '.scss'] comment: open: '/*\n' close: ' */\n\n' prefix: ' * ' suffix: '' verilog: ext: ['.v', '.sv'] comment: open: '//\n' close: '//\n\n' prefix: '// ' suffix: '' vhdl: ext: ['.vhd'] comment: open: '--\n' close: '--\n\n' prefix: '-- ' suffix: '' elm: ext: ['.elm'] comment: open: '{-\n' close: '-}\n\n' prefix: ' ' suffix: '' swift: ext: ['.swift'] comment: open: '/*\n' close: ' */\n\n' prefix: ' * ' suffix: '' rust: ext: ['.rs'] comment: open: '/*\n' close: ' */\n\n' prefix: ' * ' suffix: '' # Conf files i.e. apache config, splunk.conf files conf: ext: ['.conf'] comment: open: '#\n' close: '#\n' prefix: '# ' suffix: '' cmake: ext: ['CMakeLists.txt', '.cmake'] comment: open: '%repeat{#, :word_wrap:}%\n' close: '%repeat{#, :word_wrap:}%\n\n' prefix: '# ' suffix: '#\n' dockerfile: ext: ['Dockerfile'] comment: open: '%repeat{#, :word_wrap:}%\n' close: '%repeat{#, :word_wrap:}%\n\n' prefix: '# ' suffix: '#\n'
scripts/maintainer-tools/copyright-headers/gekkofs-template.erb 0 → 100644 +10 −0 Original line number Original line Diff line number Diff line Copyright <%=eval(copyright_years[0])[:bsc].join('-')%>, Barcelona Supercomputing Center (BSC), Spain Copyright <%=eval(copyright_years[0])[:jgu].join('-')%>, Johannes Gutenberg Universitaet Mainz, Germany This software was partially supported by the EC H2020 funded project NEXTGenIO (Project ID: 671951, www.nextgenio.eu). This software was partially supported by the ADA-FS project under the SPPEXA project funded by the DFG. SPDX-License-Identifier: MIT
scripts/maintainer-tools/copyright-headers/manage-headers.sh 0 → 100755 +365 −0 Original line number Original line Diff line number Diff line #!/bin/bash PROJECT_DIR=$(readlink -f .) PROJECT_CONFIG_FILE="project.config" DOCKER_DIR="/usr/src" INCLUDE_PATTERNS=( "*.c" "*.h" "*.cpp" "*.hpp" "*.am" "*.ac" "*.py" "*.sh" "*.mk") EXCLUDE_PATTERNS=( ".git" "*build*" "*externals*" "*spdlog*" "*ctypesgen*" "./tests/catch.hpp" ) function help() { cat << EOF Usage: $(basename "$0") COMMAND [OPTIONS] [PATH]... Add or remove license headers for each PATH specified by the user. If no PATH is specified, the specified command is recursively applied to all files in the current directory matching the following __default__ expressions: INCLUDE_PATTERNS: ${INCLUDE_PATTERNS[@]} EXCLUDE_PATTERNS: ${EXCLUDE_PATTERNS[@]} These default patterns can be overriden with a '${PROJECT_CONFIG_FILE}' file. The following commands can be used: -a, --add Add license header to targets. -r, --remove Remove license header from targets. -h, --help Show this help message, then exit. Additionally, the following options are supported: -p, --project-dir DIR The root directory of the project's target files. Defaults to '\$PWD', the current directory. -s, --show-targets Don't actually execute, just show which targets would be considered. -n, --dry-run Don't actually execute, just show what would happen. EOF exit 1 } function parse_args() { show_targets_only=false # $@ is all command line parameters passed to the script. # -o is for short options like -v # -l is for long options with double dash like --version # the comma separates different long options options=$(getopt -l \ "add,remove,help,project-dir:,dry-run,show-targets" \ -o "arhp:ns" -- "$@") # set --: # If no arguments follow this option, then the positional parameters are # unset. Otherwise, the positional parameters are set to the arguments, # even if some of them begin with a ‘-’. eval set -- "${options}" while true; do OPT="$1" case "${OPT}" in -a | --add) PARSED_COMMAND="--add" ;; -r | --remove) PARSED_COMMAND="--remove" ;; -p | --project-dir) shift if [[ -z "$1" ]]; then echo "option '${OPT}' requires an argument" exit 1 fi if ! [[ -d $1 ]]; then echo "directory '${1}' does not exist." exit 1 fi PROJECT_DIR=$(readlink -f "$1") ;; -n | --dry-run) EXTRA_PROG_ARGS+=( "-n" ) ;; -s | --show-targets) show_targets_only=true ;; --) shift EXTRA_SCRIPT_ARGS=( "$@" ) break ;; -h | --help | *) help exit 0 ;; esac shift done echo "-- Project directory: '${PROJECT_DIR}' --" if [[ -z "${PARSED_COMMAND}" ]]; then echo "$(basename "$0"): ERROR: no command provided" help exit 1 fi } function validate_gem_version() { if shopt -qo xtrace; then return fi IFS=' .' read -r -a VERSION < <( (${COPYRIGHT_PROG} -v 2>&1) |& head -n1) if [[ "${VERSION[1]}" -lt 1 ]] || [[ "${VERSION[2]}" -lt 0 ]] || [[ "${VERSION[3]}" -lt 27 ]]; then echo "CopyrightHeader gem too old" exit 1 fi } function find_command() { COPYRIGHT_LICENSE_HOST=$(readlink -f "${COPYRIGHT_LICENSE}") COPYRIGHT_LICENSE_DOCKER="${DOCKER_DIR}/"$(basename "${COPYRIGHT_LICENSE}") PROG_ARGS=( "--rm" "--volume=${PROJECT_DIR}:${PROJECT_DIR}" "--volume=${COPYRIGHT_LICENSE_HOST}:${COPYRIGHT_LICENSE_DOCKER}" ) if [[ -n "${COPYRIGHT_SYNTAX}" ]]; then COPYRIGHT_SYNTAX_HOST=$(readlink -f "${COPYRIGHT_SYNTAX}") COPYRIGHT_SYNTAX_DOCKER="${DOCKER_DIR}/"$(basename "${COPYRIGHT_SYNTAX}") PROG_ARGS+=( "--volume=${COPYRIGHT_SYNTAX_HOST}:${COPYRIGHT_SYNTAX_DOCKER}" ) fi COPYRIGHT_PROG="docker run ${PROG_ARGS[*]} gekkofs/copyright-header:latest" validate_gem_version } function print_target() { target="$1" message="$2" prefix="Checking " target_length="${#target}" message_length="${#message}" prefix_length="${#prefix}" maxcols=$(echo "scale=0; ($(tput cols)*0.6)/1" | bc -l) # the +2 and -2 accounts for quotes used when printing targets # the +1 for the separation space if [[ $((target_length + prefix_length + 2 + 1 + message_length)) -gt $maxcols ]]; then printf "$prefix%s\n%$(( maxcols ))s\n" "'${t}'" "${message}" else printf "$prefix%s %$(( maxcols - prefix_length - target_length - 3))s\n" "'${t}'" "${message}" fi } function find_targets() { TARGETS=() # option1: targets are passed as arguments if [[ -n "$*" ]]; then TARGETS=( "$@" ) for t in "${TARGETS[@]}"; do t="$(readlink -f ${t})" if [ "${t##$PROJECT_DIR}" != "${PROJECT_DIR}" ]; then print_target "${t}" "[SKIPPED -- outside project directory]" else PATH_ARGS+="${t}:" fi done return fi # option 2: targets are auto-detected based on ${PROJECT_DIR}, # ${INCLUDE_PATTERNS}, and ${EXCLUDE_PATTERNS} if [[ ${#EXCLUDE_PATTERNS[@]} -ne 0 ]]; then for p in "${EXCLUDE_PATTERNS[@]}"; do exclude_args+=( -not \( -path "${p}" -prune \) ) done fi if [[ ${#INCLUDE_PATTERNS[@]} -ne 0 ]]; then include_args=( \( -path "${INCLUDE_PATTERNS[0]}" \) ) for ((i = 1; i < ${#INCLUDE_PATTERNS[@]}; ++i)); do include_args+=( -o \( -path "${INCLUDE_PATTERNS[$i]}" \) ) done fi #### see https://stackoverflow.com/questions/23356779/how-can-i-store-the-find-command-results-as-an-array-in-bash while IFS= read -r -d $'\0'; do TARGETS+=("$REPLY") done < <(find "${PROJECT_DIR}" \( "${exclude_args[@]}" \) -and \( "${include_args[@]}" \) -print0) for t in "${TARGETS[@]}"; do if ! git ls-files --error-unmatch "${t}" > /dev/null 2>&1; then print_target "${t}" "[SKIPPED -- not under version control]" else print_target "${t}" "[OK]" PATH_ARGS+="${t}:" fi done if $show_targets_only; then exit 0 fi } function read_project_config() { ## read project configuration if [[ ! -f "${PROJECT_CONFIG_FILE}" ]]; then echo "ERROR: Missing project configuration file." exit 1 fi source "${PROJECT_CONFIG_FILE}" ## verify mandatory options if [[ -z "${COPYRIGHT_LICENSE}" ]]; then echo "ERROR: missing COPYRIGHT_LICENSE in '${PROJECT_CONFIG_FILE}'" exit 1 fi } function prepare_command_args() { ARGS=() # mandatory args ARGS+=( "--guess-extension" ) ARGS+=( "--license-file=${COPYRIGHT_LICENSE}" ) ARGS+=( "--output-dir=/" ) # optional if [[ -n "${COPYRIGHT_SYNTAX}" ]]; then ARGS+=( "--syntax=${COPYRIGHT_SYNTAX}" ) fi if [[ -n "${COPYRIGHT_SOFTWARE}" ]]; then ARGS+=( "--copyright-software=\"${COPYRIGHT_SOFTWARE}\"" ) fi if [[ -n "${COPYRIGHT_DESCRIPTION}" ]]; then ARGS+=( "--copyright-software-description=\"${COPYRIGHT_DESCRIPTION}\"" ) fi if [[ -n "${COPYRIGHT_YEARS}" ]]; then ARGS+=( "--copyright-year=${COPYRIGHT_YEARS}" ) fi if [[ -n "${COPYRIGHT_WORD_WRAP}" ]]; then ARGS+=( "--word-wrap=${COPYRIGHT_WORD_WRAP}" ) fi COPYRIGHT_PROG_ARGS=( "${ARGS[@]}" ) } function add_header() { # load project configuration read_project_config find_targets "$@" if [[ -z $PATH_ARGS ]] ; then echo No targets detected. Nothing to do. exit 0 fi # prepare command to execute and its args find_command prepare_command_args # execute command ${COPYRIGHT_PROG} \ --add-path "${PATH_ARGS::-1}" \ "${COPYRIGHT_PROG_ARGS[@]}" \ "${EXTRA_PROG_ARGS[@]}" exit $? } function remove_header() { # load project configuration read_project_config find_targets "$@" if [[ -z $PATH_ARGS ]]; then echo No targets detected. Nothing to do. exit 0 fi # prepare command to execute and its args find_command prepare_command_args ${COPYRIGHT_PROG} \ --remove-path "${PATH_ARGS::-1}" \ "${COPYRIGHT_PROG_ARGS[@]}" \ "${EXTRA_PROG_ARGS[@]}" exit $? } ################################################################################ ### Script starts here ### ################################################################################ # process command line args if [[ $# -eq 0 ]]; then help fi parse_args "$@" # execute selected command case $PARSED_COMMAND in -a | --add) add_header "${EXTRA_SCRIPT_ARGS[@]}" ;; -r | --remove) remove_header "${EXTRA_SCRIPT_ARGS[@]}" ;; esac exit 0
scripts/maintainer-tools/copyright-headers/project.config 0 → 100644 +53 −0 Original line number Original line Diff line number Diff line # vi: filetype=sh ################################################################################ ## Variables to control how the header is generated ################################################################################ # COPYRIGHT_SOFTWARE="gekkofs" # COPYRIGHT_DESCRIPTION="an ephemeral distributed file system for HPC applications" COPYRIGHT_YEARS="{:bsc => [2018, 2020], :jgu => [2015, 2020]}" COPYRIGHT_LICENSE="gekkofs-template.erb" COPYRIGHT_SYNTAX="gekkofs-syntax.yml" COPYRIGHT_WORD_WRAP=80 ################################################################################ ## Variables to control which files are considered ## N.B: these are **glob patterns**, NOT regular expressions ################################################################################ INCLUDE_PATTERNS=( "*.c" "*.h" "*.cpp" "*.hpp" "*.hpp.in" "*.am" "*.ac" "*.py" "*.sh" "*.mk" "*CMakeLists.txt" "*.cmake" "*.yml" "*.erb" "*.ini.in" "*.py.in" "*Dockerfile" ) EXCLUDE_PATTERNS=( "*.git" "*.gitlab-ci.yml" "*build*" "*external?*" "*spdlog*" "*ctypesgen*" "./tests/catch.hpp" "*agios.conf" "*.diff" "*.erb" "*.coverage-exclusions" "*.project.config" )