diff --git a/Dockerfile b/Dockerfile index 66b6dc7d..4fc9a48b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,12 @@ FROM bids/base_validator:1.13.1 +LABEL org.opencontainers.image.source="https://github.com/cpp-lln-lab/bidspm" +LABEL org.opencontainers.image.url="https://github.com/cpp-lln-lab/bidspm" +LABEL org.opencontainers.image.documentation="https://bidspm.readthedocs.io/en/latest" +LABEL org.opencontainers.image.licenses="GPL-3.0" +LABEL org.opencontainers.image.title="bidspm" +LABEL org.opencontainers.image.description="an SPM-centric BIDS app" + ARG DEBIAN_FRONTEND="noninteractive" ## basic OS tools install octave diff --git a/Makefile b/Makefile index 119b1490..168dca43 100644 --- a/Makefile +++ b/Makefile @@ -59,13 +59,15 @@ update: ## Tries to get the latest version of the current branch from upstream fix_submodule: ## Fix any submodules that would not be checked out git submodule update --init --recursive && git submodule update --recursive -bump_version: - bash tools/bump_version.sh +prepare_release: + python tools/citation_cff_maint.py + python tools/tools/add_links_to_changelog.py + python tools/bump_version.py validate_cff: ## Validate the citation file cffconvert --validate -release: validate_cff bump_version lint manual +release: validate_cff prepare_release lint manual ################################################################################ diff --git a/README.md b/README.md index fe1bdf12..4019766d 100644 --- a/README.md +++ b/README.md @@ -169,7 +169,7 @@ Please see our [documentation](https://bidspm.readthedocs.io/en/latest/index.htm license = {GPL-3.0}, title = {{bidspm}}, url = {https://github.com/cpp-lln-lab/bidspm}, - version = {3.1.0} + version = {3.1.0dev} } ``` diff --git a/docs/Makefile b/docs/Makefile index 86f7539d..f982decb 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -46,7 +46,7 @@ update_faq: cd faq/spm && faqtory build cd faq/stats && faqtory build -bidspm-manual.pdf: +bidspm-manual.pdf: update_faq bash create_manual.sh boilerplate: diff --git a/src/reports/bidspm.bib b/src/reports/bidspm.bib index 71a47cf2..e054d348 100644 --- a/src/reports/bidspm.bib +++ b/src/reports/bidspm.bib @@ -3,7 +3,7 @@ @software{bidspm license = {GPL-3.0}, title = {bidspm}, url = {https://github.com/cpp-lln-lab/bidspm}, - version = {3.1.0} + version = {3.1.0dev} doi = {10.5281/zenodo.3554331}, publisher = {Zenodo}, journal = {Software} diff --git a/tools/add_links_to_changlog.py b/tools/add_links_to_changelog.py similarity index 89% rename from tools/add_links_to_changlog.py rename to tools/add_links_to_changelog.py index 8a5f6080..74c91cd6 100644 --- a/tools/add_links_to_changlog.py +++ b/tools/add_links_to_changelog.py @@ -2,9 +2,10 @@ from __future__ import annotations import re -from pathlib import Path -change_log = Path(__file__).parent.parent / "CHANGELOG.md" +from utils import root_dir + +change_log = root_dir() / "CHANGELOG.md" with open(change_log) as f: lines = f.readlines() diff --git a/tools/bump_version.py b/tools/bump_version.py new file mode 100644 index 00000000..a73851ab --- /dev/null +++ b/tools/bump_version.py @@ -0,0 +1,58 @@ +import re +import subprocess +from pathlib import Path + +from update_versions_bug_report import main as update_bug_report + +from utils import root_dir + + +def read_version_from_citation() -> str: + with open(root_dir() / "CITATION.cff", encoding="utf-8") as file: + for line in file: + if line.startswith("version:"): + version = line.strip().replace("version: ", "v") + with open( + root_dir() / "version.txt", "w", encoding="utf-8" + ) as version_file: + version_file.write(version) + return version[1:] # Remove the leading 'v' + + +def update_file(file_path, pattern, replacement): + file_path = Path(file_path) + content = file_path.read_text(encoding="utf-8") + new_content = re.sub(pattern, replacement, content) + file_path.write_text(new_content, encoding="utf-8") + + +def main(): + version = read_version_from_citation() + + if not version: + print("Version not found in CITATION.cff") + return + + update_file("README.md", r"version = {.*}", f"version = {{{version}}}") + update_file("README.md", r"__version__ = .*", f"version = {{{version}}}") + update_file( + "src/reports/bidspm.bib", r" version = {.*}", f" version = {{{version}}}" + ) + + tools_dir = Path("tools") + + versions_txt_path = tools_dir / "versions.txt" + versions = ( + subprocess.run(["git", "tag", "--list"], capture_output=True, text=True) + .stdout.strip() + .split("\n")[::-1] + ) + versions_txt_path.write_text("\n".join(versions), encoding="utf-8") + + update_bug_report() + + print(f"Version updated to {version}") + + +if __name__ == "__main__": + main() diff --git a/tools/bump_version.sh b/tools/bump_version.sh deleted file mode 100644 index 69af23b4..00000000 --- a/tools/bump_version.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash - -# update version in version.txt, dockerfiles and readme - -grep -w "^version" CITATION.cff | sed "s/version: /v/g" >version.txt -VERSION=$(cat version.txt | cut -c2-) - -sed -i "s/version = {.*/version = {$VERSION}/g" README.md -sed -i "s/__version__ = .*/version = {$VERSION}/g" README.md - -sed -i "s/ version = {.*/ version = {$VERSION}/g" src/reports/bidspm.bib - -cd tools || exit - -git tag --list | tac >versions.txt -python update_versions_bug_report.py - -echo "Version updated to $VERSION" diff --git a/tools/citation_cff_maint.py b/tools/citation_cff_maint.py new file mode 100644 index 00000000..60f686e4 --- /dev/null +++ b/tools/citation_cff_maint.py @@ -0,0 +1,51 @@ +"""Update CITATION.cff file.""" + +from __future__ import annotations + +from pathlib import Path +from typing import Any + +import ruamel.yaml + +from utils import root_dir + +yaml = ruamel.yaml.YAML() +yaml.indent(mapping=2, sequence=4, offset=2) + + +def citation_file() -> Path: + """Return path to CITATIONS.cff file.""" + return root_dir() / "CITATION.cff" + + +def read_citation_cff() -> dict[str, Any]: + """Read CITATION.cff file.""" + print(f"Reading file: {citation_file()}") + with open(citation_file(), encoding="utf8") as f: + citation = yaml.load(f) + return citation + + +def write_citation_cff(citation: dict[str, Any]) -> None: + """Write CITATION.cff file.""" + print(f"Writing file: {citation_file()}") + with open(citation_file(), "w", encoding="utf8") as f: + yaml.dump(citation, f) + + +def sort_authors(authors: list[dict[str, str]]) -> list[dict[str, str]]: + """Sort authors by given name.""" + print(" Sorting authors by given name") + authors.sort(key=lambda x: x["given-names"]) + return authors + + +def main() -> None: + """Update names.rst and AUTHORS.rst files.""" + citation = read_citation_cff() + citation["authors"] = sort_authors(citation["authors"]) + write_citation_cff(citation) + + +if __name__ == "__main__": + main() diff --git a/tools/list_uncalled.py b/tools/list_uncalled.py new file mode 100644 index 00000000..41c32689 --- /dev/null +++ b/tools/list_uncalled.py @@ -0,0 +1,42 @@ +"""Print functions that are called less than twice in the code base.""" + +from pathlib import Path + +from rich import print + +from utils import root_dir + + +def find_files_with_extension(directory, extension) -> list[Path]: + """Recursively find all files in directory with the given extension.""" + return list(Path(directory).rglob(f"*{extension}")) + + +def main() -> None: + src_folder = root_dir() / "src" + files = find_files_with_extension(src_folder, ".m") + + for file in files: + function = file.stem + + occurrences = [] + for other_file in files: + with open(other_file, encoding="utf-8") as f: + content = f.read() + if function in content: + occurrences.append(f"{other_file}:{content.find(function)}") + + nb_lines = len(occurrences) + + if nb_lines < 2: + print( + "\n---------------------------------------------------------------------" + ) + print(function) + print() + for line in occurrences: + print(line) + + +if __name__ == "__main__": + main() diff --git a/tools/list_uncalled.sh b/tools/list_uncalled.sh deleted file mode 100644 index 2d96a42c..00000000 --- a/tools/list_uncalled.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/bash - -# simple script to list functions of the source folder -# that are not mentioned in the rest of source folder -# and is potential dead code - -src_folder="../src" - -files=$(find ${src_folder} -name "*.m") - -for file in ${files}; do - - this_file=$(basename "${file}" | rev | cut -c 1-2 --complement | rev) - - results=$(grep -or "${this_file}" ${src_folder}) - - nb_lines=$(wc -l <<< "${results}") - - if [ "${nb_lines}" -lt 2 ]; then - echo - echo "---------------------------------------------------------------------" - echo ${file} - echo ${this_file} - echo - for line in ${results}; do - echo $line - done - fi - -done diff --git a/tools/update_versions_bug_report.py b/tools/update_versions_bug_report.py index 45bfbbf5..98a809f4 100644 --- a/tools/update_versions_bug_report.py +++ b/tools/update_versions_bug_report.py @@ -1,21 +1,17 @@ from __future__ import annotations -from pathlib import Path - import ruamel.yaml +from utils import root_dir + yaml = ruamel.yaml.YAML() yaml.indent(mapping=2, sequence=4, offset=2) def main(): - bug_report = ( - Path(__file__) - .parent.parent.joinpath(".github", "ISSUE_TEMPLATE", "bug_report.yml") - .resolve() - ) + bug_report = (root_dir() / ".github" / "ISSUE_TEMPLATE" / "bug_report.yml").absolute() - versions_file = Path(__file__).parent.joinpath("versions.txt").resolve() + versions_file = (root_dir() / "tools" / "versions.txt").absolute() with open(bug_report, encoding="utf8") as input_file: content = yaml.load(input_file) diff --git a/tools/utils.py b/tools/utils.py new file mode 100644 index 00000000..6595ddf6 --- /dev/null +++ b/tools/utils.py @@ -0,0 +1,8 @@ +from __future__ import annotations + +from pathlib import Path + + +def root_dir() -> Path: + """Return path to root directory.""" + return Path(__file__).parent.parent