From 258f1e6f22763e102cf749d2dfd8e2e17cb64434 Mon Sep 17 00:00:00 2001 From: Gabriel Schubiner Date: Thu, 23 May 2024 12:14:26 -0400 Subject: [PATCH] Update template --- CODE_OF_CONDUCT.md | 2 +- CONTRIBUTING.md | 4 +- LICENSE | 2 +- README.md | 18 ++-- SECURITY.md | 13 +-- pyproject.toml | 10 +- setup/__init__.py | 1 - setup/licenses.py | 128 -------------------------- setup/settings.py | 14 --- setup_template.py | 123 ------------------------- src/{APP_NAME => bidsi}/__init__.py | 0 src/{APP_NAME => bidsi}/algorithms.py | 2 +- tests/test_fibonacci.py | 2 +- 13 files changed, 21 insertions(+), 298 deletions(-) delete mode 100644 setup/__init__.py delete mode 100644 setup/licenses.py delete mode 100644 setup/settings.py delete mode 100644 setup_template.py rename src/{APP_NAME => bidsi}/__init__.py (100%) rename src/{APP_NAME => bidsi}/algorithms.py (92%) diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 97aff48..2934e87 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -60,7 +60,7 @@ representative at an online or offline event. Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at -ENTER_YOUR_EMAIL_ADDRESS. +gabriel.schubiner@childmind.org. All complaints will be reviewed and investigated promptly and fairly. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b899aff..9e9cf9c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,6 @@ -# template-python-repository pull request guidelines +# bidsi pull request guidelines -Pull requests are always welcome, and we appreciate any help you give. Note that a code of conduct applies to all spaces managed by the template-python-repository project, including issues and pull requests. Please see the [Code of Conduct](CODE_OF_CONDUCT.md) for details. +Pull requests are always welcome, and we appreciate any help you give. Note that a code of conduct applies to all spaces managed by the bidsi project, including issues and pull requests. Please see the [Code of Conduct](CODE_OF_CONDUCT.md) for details. When submitting a pull request, we ask you to check the following: diff --git a/LICENSE b/LICENSE index 20566e6..55fdf53 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2023 Child Mind Institute +Copyright (c) 2024 Child Mind Institute Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index c8507f3..e8780b0 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ Welcome to the CMI-DAIR Template Python Repository! This template is designed to streamline your project setup and ensure a consistent structure. To get started, follow these steps: -- [ ] Run `setup_template.py` to initialize the repository. +- [x] Run `setup_template.py` to initialize the repository. - [ ] Replace the content of this `README.md` with details specific to your project. - [ ] Install the `pre-commit` hooks to ensure code quality on each commit. - [ ] Revise SECURITY.md to reflect supported versions or remove it if not applicable. @@ -16,12 +16,12 @@ Welcome to the CMI-DAIR Template Python Repository! This template is designed to # Project name -[![Build](https://github.com/childmindresearch/template-python-repository/actions/workflows/test.yaml/badge.svg?branch=main)](https://github.com/childmindresearch/template-python-repository/actions/workflows/test.yaml?query=branch%3Amain) -[![codecov](https://codecov.io/gh/childmindresearch/template-python-repository/branch/main/graph/badge.svg?token=22HWWFWPW5)](https://codecov.io/gh/childmindresearch/template-python-repository) +[![Build](https://github.com/childmindresearch/bidsi/actions/workflows/test.yaml/badge.svg?branch=main)](https://github.com/childmindresearch/bidsi/actions/workflows/test.yaml?query=branch%3Amain) +[![codecov](https://codecov.io/gh/childmindresearch/bidsi/branch/main/graph/badge.svg?token=22HWWFWPW5)](https://codecov.io/gh/childmindresearch/bidsi) [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff) ![stability-stable](https://img.shields.io/badge/stability-stable-green.svg) -[![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/childmindresearch/template-python-repository/blob/main/LICENSE) -[![pages](https://img.shields.io/badge/api-docs-blue)](https://childmindresearch.github.io/template-python-repository) +[![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/childmindresearch/bidsi/blob/main/LICENSE) +[![pages](https://img.shields.io/badge/api-docs-blue)](https://childmindresearch.github.io/bidsi) What problem does this tool solve? @@ -36,13 +36,13 @@ What problem does this tool solve? Install this package via : ```sh -pip install APP_NAME +pip install bidsi ``` Or get the newest development version via: ```sh -pip install git+https://github.com/childmindresearch/template-python-repository +pip install git+https://github.com/childmindresearch/bidsi ``` ## Quick start @@ -50,9 +50,9 @@ pip install git+https://github.com/childmindresearch/template-python-repository Short tutorial, maybe with a ```Python -import APP_NAME +import bidsi -APP_NAME.short_example() +bidsi.short_example() ``` ## Links or References diff --git a/SECURITY.md b/SECURITY.md index 9fd57bf..5de3e77 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -2,19 +2,8 @@ Child Mind Institute values the security of our users, data, and servers. We take the security of our systems seriously and encourage users to report any suspected security vulnerabilities promptly. -## Supported Versions - -MODIFY: - -Note which version(s) will receive security updates. For example: - -| Version | Supported | -| ------- | ------------------ | -| 1.0.x | :white_check_mark: | -| 0.9.x | :x: | - ## Reporting Vulnerabilities -To report security vulnerabilities, please do NOT use our issues page. Instead, kindly email us at ENTER_YOUR_EMAIL_ADDRESS. Please refrain from using other communication channels. +To report security vulnerabilities, please do NOT use our issues page. Instead, kindly email us at gabriel.schubiner@childmind.org. Please refrain from using other communication channels. For non-security-related issues, we welcome your input and feedback on our issues page. Feel free to share your ideas and suggestions to help us improve our services. diff --git a/pyproject.toml b/pyproject.toml index 4d9d966..2785a32 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,11 +1,11 @@ [tool.poetry] -name = "app-name" +name = "bidsi" version = "0.1.0" -description = "A beautiful description." -authors = ["Reinder Vos de Wael "] -license = "LGPL-2.1" +description = "Library for writing BIDS file structures." +authors = ["Gabriel Schubiner "] +license = "MIT License" readme = "README.md" -packages = [{include = "APP_NAME", from = "src"}] +packages = [{include = "bidsi", from = "src"}] [tool.poetry.dependencies] python = "~3.11" diff --git a/setup/__init__.py b/setup/__init__.py deleted file mode 100644 index 5b41398..0000000 --- a/setup/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""Module for code required by the setup_template.py script.""" diff --git a/setup/licenses.py b/setup/licenses.py deleted file mode 100644 index 6633d2b..0000000 --- a/setup/licenses.py +++ /dev/null @@ -1,128 +0,0 @@ -"""Functions for fetching and replacing the license file.""" - -from __future__ import annotations - -import json -import re -from datetime import datetime -from typing import Optional -from urllib import request - -from setup import settings - -DIR_REPO = settings.DIR_REPO -LICENSES = settings.LICENSES - - -def get_license(name: str) -> dict[str, str]: - """Fetches the license files from GitHub. - - Args: - name: The name of the license to fetch. - - Returns: - The license text. - - """ - if name not in LICENSES: - raise ValueError(f"License {name} is not in {LICENSES}.") - with request.urlopen(f"https://api.github.com/licenses/{name}") as response: - license_info = response.read().decode() - return json.loads(license_info) - - -def modify_license_placeholder_text(selected_license: dict[str, str]) -> dict[str, str]: - """Modifies the placeholder text in the license. - - Args: - selected_license: The license to modify. - - Returns: - The modified license. - - """ - if selected_license["key"] == "mit": - license_holder = input("Who is the holder of the license? ") - current_year = datetime.now().year - selected_license["body"] = selected_license["body"].replace( - "[year]", - str(current_year), - ) - selected_license["body"] = selected_license["body"].replace( - "[fullname]", - license_holder, - ) - - return selected_license - - -def request_license() -> Optional[dict[str, str]]: - """Asks the user to select a license. - - Returns: - The path to the selected license. - - """ - print("Available licenses:") - print("\t0. No license") - for i, option in enumerate(LICENSES): - print(f"\t{i + 1}. {option}") - while True: - try: - choice = int(input("Enter the number of the license you want to use: ")) - if choice == 0: - return None - if 0 < choice <= len(LICENSES): - selected_license = get_license(LICENSES[choice - 1]) - break - raise ValueError("Invalid choice. Please try again.") - except ValueError: - print("Invalid choice. Please try again.") - - final_license = modify_license_placeholder_text(selected_license) - return final_license - - -def replace_license_badge(content: str, repo_license: Optional[dict[str, str]]) -> str: - """Replaces the license badge with the specified license. - - Args: - content: Content of any file that might contain a license badge. - repo_license: The license to replace the current license with. If None, - the current license badge will be deleted. - - Returns: - The content with the license badge replaced. - """ - if repo_license is None: - # remove line containing license badge - return re.sub( - r"\[!\[.*License\]\(https://img\.shields\.io/badge/license.*\)\]\(.*\)\n", - "", - content, - ) - # shield.io uses -- as an escape character, so we need to replace - with -- - license_name_upper = repo_license["key"].upper().replace("-", "--") - return content.replace( - "![MIT License]" "(https://img.shields.io/badge/license-MIT-blue.svg)]", - f"![{license_name_upper} License]" - f"(https://img.shields.io/badge/license-{license_name_upper}-blue.svg)]", - ) - - -def replace_license(repo_license: Optional[dict[str, str]]) -> None: - """Replaces the license file in the repository with the specified license. - - Args: - repo_license: The license to replace the current license with. If None, - the current license file will be deleted. - - """ - license_file = DIR_REPO / "LICENSE" - license_file.unlink(missing_ok=True) - - if repo_license is None: - return - - with open(license_file, "w", encoding="utf-8") as file_buffer: - file_buffer.write(repo_license["body"]) diff --git a/setup/settings.py b/setup/settings.py deleted file mode 100644 index cd8faa8..0000000 --- a/setup/settings.py +++ /dev/null @@ -1,14 +0,0 @@ -"""Constants for the setup module.""" - -import pathlib as pl - -DIR_REPO = pl.Path(__file__).parent.parent -LICENSES = ("mit", "lgpl-2.1", "lgpl-3.0", "mpl-2.0", "unlicense") -TARGET_EXTENSIONS = { - ".py", - ".md", - ".yml", - ".yaml", - ".toml", - ".txt", -} diff --git a/setup_template.py b/setup_template.py deleted file mode 100644 index 462c3d5..0000000 --- a/setup_template.py +++ /dev/null @@ -1,123 +0,0 @@ -#!/usr/bin python3 -"""Setup template for Python repositories.""" - -import os -import pathlib as pl -import shutil - -from setup import licenses, settings - -DIR_REPO = settings.DIR_REPO -TARGET_EXTENSIONS = settings.TARGET_EXTENSIONS - - -def main() -> None: - """Entrypoint to the template setup script. - - This script will ask the user for details of the repository and then replace - the template values with the user input. It will also remove the setup files - and the setup directory. - """ - # Collect some data - git_uncommitted_changes = ( - os.popen(f"git -C {DIR_REPO} status -s").read().strip() != "" - ) - git_username = os.popen(f"git -C {DIR_REPO} config user.name").read().strip() - git_email = os.popen(f"git -C {DIR_REPO} config user.email").read().strip() - git_repo_name = ( - os.popen(f"git -C {DIR_REPO} remote get-url origin") - .read() - .split("/")[-1] - .split(".")[0] - .strip() - ) - - # Ask for some data - if git_uncommitted_changes: - print("You have uncommitted changes. Please commit or stash them first.") - exit(1) - repo_name = ( - input(f"Enter the name of the repository [{git_repo_name}]: ").strip() - or git_repo_name - ) - module_name = ( - input(f"Enter the name of the module [{repo_name}]: ").strip() or repo_name - ) - username = input(f"Enter your username [{git_username}]: ").strip() or git_username - email = input(f"Enter your email [{git_email}]: ").strip() or git_email - description = ( - input("Enter a short description of the project: ").strip() - or "A beautiful description." - ) - repo_license = licenses.request_license() - - # Print the data - print( - f"Using the following values:\n" - f"\tRepository name: '{repo_name}'\n" - f"\tModule name: '{module_name}'\n" - f"\tAuthor: '{username} <{email}'>\n" - f"\tDescription: '{description}'\n" - f"\tLicense: '{repo_license['name'] if repo_license else 'No license'}'", - ) - input("Press enter to continue...") - - # Replace the template values - for file in pl.Path(DIR_REPO).glob("**/*"): - if ( - not file.is_file() - or file.suffix not in TARGET_EXTENSIONS - or file.name == "setup_template.py" - ): - continue - - with open(file, encoding="utf-8") as f: - content = f.read() - - content_before = content - content = content.replace( - "- [ ] Run `setup_template.py`", - "- [x] Run `setup_template.py`", - ) - content = content.replace( - "- [ ] Update the `LICENSE`", - "- [x] Update the `LICENSE`", - ) - content = content.replace("template-python-repository", repo_name) - content = content.replace("APP_NAME", module_name) - content = content.replace("app-name", module_name) - content = content.replace("A beautiful description.", description) - content = content.replace("reinder.vosdewael@childmind.org", email) - content = content.replace("ENTER_YOUR_EMAIL_ADDRESS", email) - content = content.replace("Reinder Vos de Wael", username) - - content = licenses.replace_license_badge(content, repo_license) - content = content.replace( - "LGPL-2.1", repo_license["name"] if repo_license else "" - ) - - if content != content_before: - print(f"Updating {file.relative_to(DIR_REPO)}") - with open(file, "w", encoding="utf-8") as f: - f.write(content) - - licenses.replace_license(repo_license) - - dir_module = DIR_REPO / "src" / "APP_NAME" - if dir_module.exists(): - dir_module.rename(dir_module.parent / module_name) - - # Remove setup files - print("Removing setup files.") - setup_files = pl.Path(DIR_REPO / "setup").glob("*.py") - for setup_file in setup_files: - pl.Path(DIR_REPO / "setup" / setup_file).unlink() - if pl.Path(DIR_REPO / "setup" / "__pycache__").exists(): - # Use a more robust method to remove the cache directory - shutil.rmtree(DIR_REPO / "setup" / "__pycache__") - pl.Path(DIR_REPO / "setup").rmdir() - pl.Path(__file__).unlink() - - -if __name__ == "__main__": - main() diff --git a/src/APP_NAME/__init__.py b/src/bidsi/__init__.py similarity index 100% rename from src/APP_NAME/__init__.py rename to src/bidsi/__init__.py diff --git a/src/APP_NAME/algorithms.py b/src/bidsi/algorithms.py similarity index 92% rename from src/APP_NAME/algorithms.py rename to src/bidsi/algorithms.py index 020e25f..71ca49c 100644 --- a/src/APP_NAME/algorithms.py +++ b/src/bidsi/algorithms.py @@ -1,4 +1,4 @@ -"""Example functions for APP_NAME.""" +"""Example functions for bidsi.""" def fibonacci(n: int) -> int: diff --git a/tests/test_fibonacci.py b/tests/test_fibonacci.py index b09e49c..79880d3 100644 --- a/tests/test_fibonacci.py +++ b/tests/test_fibonacci.py @@ -2,7 +2,7 @@ import pytest -from APP_NAME import algorithms +from bidsi import algorithms def test_fibonacci_success_0() -> None: