From 38f0b95ff7d89d51687018d37de106fabc49fdb6 Mon Sep 17 00:00:00 2001 From: Benedikt Peetz Date: Mon, 1 Apr 2024 12:46:23 +0200 Subject: refactor(treewide): Add a script to instantiate symlinks --- common/.licensure.yml | 166 +++++++++++++++++++++++++++++++ common/renew_copyright_header.sh | 86 ---------------- common/scripts/renew_copyright_header.sh | 86 ++++++++++++++++ common/treefmt.nix | 73 ++++++++++++++ update_common_files.sh | 19 ++++ 5 files changed, 344 insertions(+), 86 deletions(-) create mode 100644 common/.licensure.yml delete mode 100755 common/renew_copyright_header.sh create mode 100755 common/scripts/renew_copyright_header.sh create mode 100644 common/treefmt.nix create mode 100755 update_common_files.sh diff --git a/common/.licensure.yml b/common/.licensure.yml new file mode 100644 index 0000000..e1f5a01 --- /dev/null +++ b/common/.licensure.yml @@ -0,0 +1,166 @@ +--- +# Regexes which if matched by a file path will always be excluded from +# getting a license header +excludes: + - .*lock + - \.git/.* + - LICENSE.spdx + - COPYING + - COPYING.LESSER + - .*\.(rst|txt|pdf) +# Definition of the licenses used on this project and to what files +# they should apply. +# +# No default license configuration is provided. This section must be +# configured by the user. +licenses: + # Either a regex or the string "any" to determine to what files this + # license should apply. It is common for projects to have files + # under multiple licenses or with multiple copyright holders. This + # provides the ability to automatically license files correctly + # based on their file paths. + # + # If "any" is provided all files will match this license. + - files: any + # + # The license identifier, a list of common identifiers can be + # found at: https://spdx.org/licenses/ but existence of the ident + # in this list it is not enforced unless auto_template is set to + # true. + ident: GPL-3.0-or-later + # + # A list of authors who hold copyright over these files + authors: + # Provide either your full name or company name for copyright purposes + - name: Benedikt Peetz + # Optionally provide email for copyright purposes + email: "benedikt.peetz@b-peetz.de" + + # The template that will be rendered to generate the header before + # comment characters are applied. Available variables are: + # - [year]: substituted with the current year. + # - [name of author]: Substituted with name of the author and email + # if provided. If email is provided the output appears as Full + # Name . If multiple authors are provided the + # list is concatenated together with commas. + template: | + Copyright (C) 2023 - [year]: + [name of author] + SPDX-License-Identifier: GPL-3.0-or-later + + This file is part of the TODO. + + Trixy is free software: you can redistribute it and/or modify + it under the terms of the Lesser GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + and the Lesser GNU General Public License along with this program. + If not, see . + + + # If auto_template is true then template is ignored and the SPDX + # API will be queried with the ident value to automatically + # determine the license header template. auto_template works best + # with licenses that have a standardLicenseHeader field defined in + # their license info JSON, if it is not then we will use the full + # licenseText to generate the header which works fine for short + # licenses like MIT but can be quite lengthy for other licenses + # like BSD-4-Clause. The above default template is valid for most + # licenses and is recommended for MIT, and BSD licenses. Common + # licenses that work well with the auto_template feature are GPL + # variants, and the Apache 2.0 license. + # + # Important Note: this means the ident must be a valid SPDX identifier + # auto_template: true + + # If true try to detect the text wrapping of the template, and unwrap it + unwrap_text: false + +# Define type of comment characters to apply based on file extensions. +comments: + # The extensions (or singular extension) field defines which file + # extensions to apply the commenter to. + - extensions: + - js + - go + # The commenter field defines the kind of commenter to + # generate. There are two types of commenters: line and block. + # + # This demonstrates a line commenter configuration. A line + # commenter type will apply the comment_char to the beginning of + # each line in the license header. It will then apply a number of + # empty newlines to the end of the header equal to trailing_lines. + # + # If trailing_lines is omitted it is assumed to be 0. + commenter: + type: line + comment_char: "//" + trailing_lines: 1 + + - extensions: + - rs + - tri + - css + - cpp + - c + - h + # This demonstrates a block commenter configuration. A block + # commenter type will add start_block_char as the first character + # in the license header and add end_block_char as the last character + # in the license header. If per_line_char is provided each line of + # the header between the block start and end characters will be + # line commented with the per_line_char + # + # trailing_lines works the same for both block and line commenter + # types + commenter: + type: block + start_block_char: "/*\n" + end_block_char: "*/\n" + per_line_char: "*" + trailing_lines: 1 + + - extension: + - html + - md + commenter: + type: block + start_block_char: "\n" + trailing_lines: 1 + + - extensions: + - el + - lisp + commenter: + type: line + comment_char: ";;;" + trailing_lines: 1 + + - extensions: + - tex + commenter: + type: line + comment_char: "%" + trailing_lines: 1 + + # The extension string "any" is special and so will match any file + # extensions. Commenter configurations are always checked in the + # order they are defined, so if any is used it should be the last + # commenter configuration or else it will override all others. + # + # In this configuration if we can't match the file extension we fall + # back to the popular '#' line comment used in most scripting + # languages. + - extension: any + commenter: + type: line + comment_char: '#' + trailing_lines: 1 diff --git a/common/renew_copyright_header.sh b/common/renew_copyright_header.sh deleted file mode 100755 index edb0a65..0000000 --- a/common/renew_copyright_header.sh +++ /dev/null @@ -1,86 +0,0 @@ -#! /usr/bin/env sh - -# NOTE: This is the line length of the .licensure.yml header template **plus** the extra -# line after the template comment. -TEMPLATE_LINE_LENGTH=20 - -PROJECT_ROOT="$(git rev-parse --show-toplevel)" - -remove() { - extension="$1" - file="$2" - - # We need to differentiate, when removing the old copyright header, as some - # formatters do weird things to the file - case "$extension" in - # normal '#' comments (these are $TEMPLATE_LINE_LENGTH lines long) - "Makefile" | "toml" | "envrc" | "yml" | "gitignore" | "awk") - sed --in-place "1,${TEMPLATE_LINE_LENGTH}d" "$file" - ;; - # normal '/* ... */' like comments (these are $TEMPLATE_LINE_LENGTH + 2 lines long) - "c" | "h" | "md" | "rs") - length="$((TEMPLATE_LINE_LENGTH + 2))" - sed --in-place "1,${length}d;" "$file" - ;; - # alejandra (the nix formatter) removes the blank line after the comment, - # thus only $TEMPLATE_LINE_LENGTH - 1 lines - "nix") - length="$((TEMPLATE_LINE_LENGTH - 1))" - sed --in-place "1,${length}d;" "$file" - ;; - # Shell needs a shebang on the first line, only after the first line can we - # remove the $TEMPLATE_LINE_LENGTH lines - "sh") - sed --in-place "2,${TEMPLATE_LINE_LENGTH}d;" "$file" - licensure --in-place "$file" - - TEMPLATE_LINE_LENGTH_NEW="$(($(yq --raw-output '.licenses | map(.template) | join("")' "$PROJECT_ROOT/.licensure.yml" | wc -l) + $(yq '.comments | last | .commenter.trailing_lines' "$PROJECT_ROOT/.licensure.yml")))" - - # delete the current shebang - to="$((TEMPLATE_LINE_LENGTH_NEW + 1))" - sed --in-place "${TEMPLATE_LINE_LENGTH_NEW},${to}d;" "$file" - - # add a new one - sed --in-place "1i#! /usr/bin/env sh" "$file" - ;; - *) - echo "File '$file' with extension '$extension' is not know yet, please add it!" - ;; - esac -} - -list() { - echo "$extension -> $file" -} - -if [ -f "$1" ]; then - file="$(realpath "$1")" - filename="$(basename -- "$file")" - extension="${filename##*.}" - filename="${filename%.*}" - - if [ -n "$DRY_RUN" ]; then - list "$extension" "$file" - else - remove "$extension" "$file" - fi -else - fd --type file --hidden . | while read -r file; do - if grep --quiet 'SPDX-License-Identifier: GPL-3.0-or-later' "$file"; then - filename="$(basename -- "$file")" - extension="${filename##*.}" - filename="${filename%.*}" - - if [ -n "$DRY_RUN" ]; then - list "$extension" "$file" - else - remove "$extension" "$file" - fi - fi - done - - if [ -z "$DRY_RUN" ]; then - licensure --in-place --project - nix fmt - fi -fi diff --git a/common/scripts/renew_copyright_header.sh b/common/scripts/renew_copyright_header.sh new file mode 100755 index 0000000..edb0a65 --- /dev/null +++ b/common/scripts/renew_copyright_header.sh @@ -0,0 +1,86 @@ +#! /usr/bin/env sh + +# NOTE: This is the line length of the .licensure.yml header template **plus** the extra +# line after the template comment. +TEMPLATE_LINE_LENGTH=20 + +PROJECT_ROOT="$(git rev-parse --show-toplevel)" + +remove() { + extension="$1" + file="$2" + + # We need to differentiate, when removing the old copyright header, as some + # formatters do weird things to the file + case "$extension" in + # normal '#' comments (these are $TEMPLATE_LINE_LENGTH lines long) + "Makefile" | "toml" | "envrc" | "yml" | "gitignore" | "awk") + sed --in-place "1,${TEMPLATE_LINE_LENGTH}d" "$file" + ;; + # normal '/* ... */' like comments (these are $TEMPLATE_LINE_LENGTH + 2 lines long) + "c" | "h" | "md" | "rs") + length="$((TEMPLATE_LINE_LENGTH + 2))" + sed --in-place "1,${length}d;" "$file" + ;; + # alejandra (the nix formatter) removes the blank line after the comment, + # thus only $TEMPLATE_LINE_LENGTH - 1 lines + "nix") + length="$((TEMPLATE_LINE_LENGTH - 1))" + sed --in-place "1,${length}d;" "$file" + ;; + # Shell needs a shebang on the first line, only after the first line can we + # remove the $TEMPLATE_LINE_LENGTH lines + "sh") + sed --in-place "2,${TEMPLATE_LINE_LENGTH}d;" "$file" + licensure --in-place "$file" + + TEMPLATE_LINE_LENGTH_NEW="$(($(yq --raw-output '.licenses | map(.template) | join("")' "$PROJECT_ROOT/.licensure.yml" | wc -l) + $(yq '.comments | last | .commenter.trailing_lines' "$PROJECT_ROOT/.licensure.yml")))" + + # delete the current shebang + to="$((TEMPLATE_LINE_LENGTH_NEW + 1))" + sed --in-place "${TEMPLATE_LINE_LENGTH_NEW},${to}d;" "$file" + + # add a new one + sed --in-place "1i#! /usr/bin/env sh" "$file" + ;; + *) + echo "File '$file' with extension '$extension' is not know yet, please add it!" + ;; + esac +} + +list() { + echo "$extension -> $file" +} + +if [ -f "$1" ]; then + file="$(realpath "$1")" + filename="$(basename -- "$file")" + extension="${filename##*.}" + filename="${filename%.*}" + + if [ -n "$DRY_RUN" ]; then + list "$extension" "$file" + else + remove "$extension" "$file" + fi +else + fd --type file --hidden . | while read -r file; do + if grep --quiet 'SPDX-License-Identifier: GPL-3.0-or-later' "$file"; then + filename="$(basename -- "$file")" + extension="${filename##*.}" + filename="${filename%.*}" + + if [ -n "$DRY_RUN" ]; then + list "$extension" "$file" + else + remove "$extension" "$file" + fi + fi + done + + if [ -z "$DRY_RUN" ]; then + licensure --in-place --project + nix fmt + fi +fi diff --git a/common/treefmt.nix b/common/treefmt.nix new file mode 100644 index 0000000..1cbab40 --- /dev/null +++ b/common/treefmt.nix @@ -0,0 +1,73 @@ +{ + treefmt-nix, + pkgs, +}: +treefmt-nix.lib.evalModule pkgs ( + {pkgs, ...}: { + # Used to find the project root + projectRootFile = "flake.nix"; + + programs = { + alejandra.enable = true; + rustfmt.enable = true; + clang-format.enable = true; + mdformat.enable = true; + shfmt = { + enable = true; + indent_size = 4; + }; + shellcheck.enable = true; + prettier = { + settings = { + arrowParens = "always"; + bracketSameLine = false; + bracketSpacing = true; + editorconfig = true; + embeddedLanguageFormatting = "auto"; + endOfLine = "lf"; + # experimentalTernaries = false; + htmlWhitespaceSensitivity = "css"; + insertPragma = false; + jsxSingleQuote = true; + printWidth = 80; + proseWrap = "always"; + quoteProps = "consistent"; + requirePragma = false; + semi = true; + singleAttributePerLine = true; + singleQuote = true; + trailingComma = "all"; + useTabs = false; + vueIndentScriptAndStyle = false; + + tabWidth = 4; + overrides = { + files = ["*.js"]; + options.tabwidth = 2; + }; + }; + }; + stylua.enable = true; + ruff = { + enable = true; + format = true; + }; + taplo.enable = true; + }; + + settings = { + global.excludes = [ + "CHANGELOG.md" + "NEWS.md" + ]; + formatter = { + clang-format = { + options = ["--style" "GNU"]; + }; + shfmt = { + includes = ["*.bash"]; + }; + }; + }; + } +) diff --git a/update_common_files.sh b/update_common_files.sh new file mode 100755 index 0000000..f342850 --- /dev/null +++ b/update_common_files.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env sh + +ROOT="$(git rev-parse --show-toplevel)"; + +# This results in fd returning relative paths +cd "$ROOT/common" || echo "BUG, no root dir!" + +fd . "." --type file --hidden | while read -r file; do + echo "Instantiating '$file'..." + fd . "../templates" --type directory --max-depth 1 | while read -r template; do + echo " done in '$template'." + echo " " cp "$file" "$template$file" + rm "$template$file" + cp "$file" "$template$file" + done +done + + +# vim: ft=sh -- cgit 1.4.1