diff --git a/.cpa/flake8.cfg b/.ci/flake8.cfg similarity index 100% rename from .cpa/flake8.cfg rename to .ci/flake8.cfg diff --git a/.cpa/prettier.json b/.ci/prettier.json similarity index 100% rename from .cpa/prettier.json rename to .ci/prettier.json diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 5d09436..36defc1 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -2,10 +2,6 @@ name: CI on: pull_request: # Start the job on all PRs - branches: [master, main] - types: [synchronize, opened, reopened, ready_for_review] - push: # Start the job on all main branch push - branches: [master, main] jobs: precommit: diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 99fad48..f2c12a9 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -6,7 +6,7 @@ repos: # Misc ############################################################################# - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.5.0 + rev: v4.6.0 hooks: - id: check-merge-conflict # Searches for merge conflict markers within files. - id: check-added-large-files # Blocks commits that add large files. Default limit is 500kB. @@ -24,7 +24,7 @@ repos: # JSON, TOML ############################################################################# - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.5.0 + rev: v4.6.0 hooks: - id: check-json # Validates JSON files to ensure they are properly formatted and syntactically correct. types: [json] @@ -46,7 +46,7 @@ repos: # Python ############################################################################# - repo: https://github.com/PyCQA/autoflake - rev: v2.2.1 + rev: v2.3.1 hooks: - id: autoflake # Removes unused imports and unused variables from Python code. args: @@ -54,7 +54,7 @@ repos: - --remove-all-unused-imports - repo: https://github.com/pycqa/isort - rev: 5.12.0 + rev: 5.13.2 hooks: - id: isort # Sorts Python imports into sections and by alphabetical order. args: @@ -64,7 +64,7 @@ repos: - python - repo: https://github.com/psf/black - rev: 23.10.1 + rev: 24.4.2 hooks: - id: black # Formats Python code to conform to the Black code style. args: @@ -75,11 +75,11 @@ repos: exclude: templates/ - repo: https://github.com/pycqa/flake8 - rev: 6.1.0 + rev: 7.0.0 hooks: - id: flake8 # Lints Python code for errors and code style issues based on PEP8. args: - - --config=.cpa/flake8.cfg + - --config=.ci/flake8.cfg types: - python exclude: templates/ @@ -99,11 +99,11 @@ repos: # CSS, Markdown, JavaScript, TypeScript, YAML style formatter ############################################################################# - repo: https://github.com/pre-commit/mirrors-prettier - rev: v3.0.3 + rev: v4.0.0-alpha.8 hooks: - id: prettier # An opinionated code formatter supporting multiple languages. name: prettier - args: [--config, .cpa/prettier.json, --write] + args: [--config, .ci/prettier.json, --write] types_or: - css - scss @@ -112,7 +112,7 @@ repos: - javascript - yaml - markdown - exclude: templates/.pre-commit-config.yaml|templates/.github/workflows/ci.yaml + exclude: templates/.pre-commit-config.yaml|templates/.github/workflows/ci.yaml|templates/base/ci.yaml ############################################################################# # Rust diff --git a/example/python/.pre-commit-config.yaml b/example/python/.pre-commit-config.yaml index 09b29e5..ca53ef4 100644 --- a/example/python/.pre-commit-config.yaml +++ b/example/python/.pre-commit-config.yaml @@ -77,7 +77,7 @@ repos: hooks: - id: flake8 # Lints Python code for errors and code style issues based on PEP8. args: - - --config=.cpa/flake8.cfg + - --config=.ci/flake8.cfg types: - python @@ -100,7 +100,7 @@ repos: hooks: - id: prettier # An opinionated code formatter supporting multiple languages. name: prettier - args: [--config, .cpa/prettier.json, --write] + args: [--config, .ci/prettier.json, --write] types_or: - css - scss diff --git a/example/python/.vscode/settings.json b/example/python/.vscode/settings.json index bd6b16b..86c68d8 100644 --- a/example/python/.vscode/settings.json +++ b/example/python/.vscode/settings.json @@ -4,6 +4,6 @@ "editor.formatOnSave": true, "editor.defaultFormatter": "ms-python.black-formatter" }, - "flake8.args": ["--config=.cpa/flake8.cfg"], + "flake8.args": ["--config=.ci/flake8.cfg"], "files.insertFinalNewline": true } diff --git a/example/rust/.pre-commit-config.yaml b/example/rust/.pre-commit-config.yaml index e60db58..6bb8930 100644 --- a/example/rust/.pre-commit-config.yaml +++ b/example/rust/.pre-commit-config.yaml @@ -59,7 +59,7 @@ repos: hooks: - id: prettier # An opinionated code formatter supporting multiple languages. name: prettier - args: [--config, .cpa/prettier.json, --write] + args: [--config, .ci/prettier.json, --write] types_or: - css - scss diff --git a/example/rust/.vscode/settings.json b/example/rust/.vscode/settings.json index bd6b16b..86c68d8 100644 --- a/example/rust/.vscode/settings.json +++ b/example/rust/.vscode/settings.json @@ -4,6 +4,6 @@ "editor.formatOnSave": true, "editor.defaultFormatter": "ms-python.black-formatter" }, - "flake8.args": ["--config=.cpa/flake8.cfg"], + "flake8.args": ["--config=.ci/flake8.cfg"], "files.insertFinalNewline": true } diff --git a/src/main.rs b/src/main.rs index 010df3c..5837965 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,7 +3,7 @@ mod presets; use std::process; use clap::Parser; -use presets::{common, python, rust}; +use presets::{base, common, python, rust}; use regex::Regex; #[derive(Parser)] @@ -46,6 +46,13 @@ pub struct Language { #[allow(clippy::needless_return)] fn validate_preset(preset: &str) -> Language { + if preset == "base" { + return Language { + language: "base".to_string(), + ver: "".to_string(), + }; + } + if preset == "rust" { return Language { language: "rust".to_string(), @@ -78,6 +85,8 @@ fn main() { } else if lang.language == "rust" { let prefix = common(&args.name, create, &lang); rust(&args.name, &prefix); + } else if lang.language == "base" { + let _prefix = base(&args.name, create, &lang); } else { eprintln!("Preset: {:?} not supported", args.preset); } @@ -93,6 +102,8 @@ fn main() { } else if lang.language == "rust" { let prefix = common(&args.name, create, &lang); rust(&args.name, &prefix); + } else if lang.language == "base" { + let _prefix = base(&args.name, create, &lang); } else { eprintln!("Preset: {:?} not supported", args.preset); } diff --git a/src/presets.rs b/src/presets.rs index 2d3e0d8..2c96ac6 100644 --- a/src/presets.rs +++ b/src/presets.rs @@ -45,7 +45,11 @@ pub struct Makefile {} pub struct GhCI {} #[derive(Template)] -#[template(path = ".cpa/prettier.json", escape = "none")] +#[template(path = "base/ci.yaml", escape = "none")] +pub struct GhCIBase {} + +#[derive(Template)] +#[template(path = ".ci/prettier.json", escape = "none")] pub struct Prettier {} #[derive(Template)] @@ -54,6 +58,10 @@ pub struct PreCommitConfig { pub language: String, } +#[derive(Template)] +#[template(path = "base/.pre-commit-config.yaml", escape = "none")] +pub struct PreCommitConfigBase {} + //////////////////////////////////// // PYTHON //////////////////////////////////// @@ -61,10 +69,6 @@ pub struct PreCommitConfig { #[template(path = "python/Dockerfile", escape = "none")] pub struct PyDockerfile {} -#[derive(Template)] -#[template(path = "python/main.py", escape = "none")] -pub struct PyMain {} - #[derive(Template)] #[template(path = "python/pyproject.toml", escape = "none")] pub struct PyProject { @@ -74,7 +78,7 @@ pub struct PyProject { } #[derive(Template)] -#[template(path = ".cpa/flake8.cfg", escape = "none")] +#[template(path = ".ci/flake8.cfg", escape = "none")] pub struct Flake8 {} //////////////////////////////////// @@ -98,7 +102,7 @@ pub fn common(name: &str, create: bool, lang: &Language) -> String { let prefix: String = if create { format!("./{}", name) } else { "./".to_string() }; // Create needed dirs - let _ = fs::create_dir_all(format!("{}/.cpa", prefix)); + let _ = fs::create_dir_all(format!("{}/.ci", prefix)); let _ = fs::create_dir_all(format!("{}/.vscode", prefix)); let _ = fs::create_dir_all(format!("{}/.github/workflows", prefix)); @@ -110,7 +114,7 @@ pub fn common(name: &str, create: bool, lang: &Language) -> String { language: lang.language.to_string(), } .write(&prefix, ".pre-commit-config.yaml"); - Prettier {}.write(&prefix, ".cpa/prettier.json"); + Prettier {}.write(&prefix, ".ci/prettier.json"); VSCodeSettings {}.write(&prefix, ".vscode/settings.json"); VSCodeExtensions {}.write(&prefix, ".vscode/extensions.json"); prefix @@ -120,8 +124,7 @@ pub fn python(name: &str, prefix: &str, lang: &Language) { let black_target_ver = format!("py{}", lang.ver.replace('.', "")); // Render Python-specific files - Flake8 {}.write(prefix, ".cpa/flake8.cfg"); - PyMain {}.write(prefix, "main.py"); + Flake8 {}.write(prefix, ".ci/flake8.cfg"); PyDockerfile {}.write(prefix, "Dockerfile"); let pyproj: PyProject = PyProject { @@ -140,3 +143,19 @@ pub fn rust(name: &str, prefix: &str) { CargoToml { name: name.to_string() }.write(prefix, "Cargo.toml"); RustFmt {}.write(prefix, "rustfmt.toml"); } + +pub fn base(name: &str, create: bool, _lang: &Language) -> String { + let prefix: String = if create { format!("./{}", name) } else { "./".to_string() }; + + // Create needed dirs + let _ = fs::create_dir_all(format!("{}/.ci", prefix)); + let _ = fs::create_dir_all(format!("{}/.github/workflows", prefix)); + + // Render common files + GhCIBase {}.write(&prefix, ".github/workflows/ci.yaml"); + GitIgnore {}.write(&prefix, ".gitignore"); + Makefile {}.write(&prefix, "Makefile"); + PreCommitConfigBase {}.write(&prefix, ".pre-commit-config.yaml"); + Prettier {}.write(&prefix, ".ci/prettier.json"); + prefix +} diff --git a/templates/.cpa/flake8.cfg b/templates/.ci/flake8.cfg similarity index 100% rename from templates/.cpa/flake8.cfg rename to templates/.ci/flake8.cfg diff --git a/templates/.cpa/prettier.json b/templates/.ci/prettier.json similarity index 100% rename from templates/.cpa/prettier.json rename to templates/.ci/prettier.json diff --git a/templates/.github/workflows/ci.yaml b/templates/.github/workflows/ci.yaml index e117565..dc9ed00 100644 --- a/templates/.github/workflows/ci.yaml +++ b/templates/.github/workflows/ci.yaml @@ -3,10 +3,6 @@ name: CI on: pull_request: # Start the job on all PRs - branches: [master, main] - types: [synchronize, opened, reopened, ready_for_review] - push: # Start the job on all main branch push - branches: [master, main] jobs: precommit: diff --git a/templates/.pre-commit-config.yaml b/templates/.pre-commit-config.yaml index 1c05b4e..65e50c3 100644 --- a/templates/.pre-commit-config.yaml +++ b/templates/.pre-commit-config.yaml @@ -77,7 +77,7 @@ repos: hooks: - id: flake8 # Lints Python code for errors and code style issues based on PEP8. args: - - --config=.cpa/flake8.cfg + - --config=.ci/flake8.cfg types: - python @@ -110,7 +110,7 @@ repos: hooks: - id: prettier # An opinionated code formatter supporting multiple languages. name: prettier - args: [--config, .cpa/prettier.json, --write] + args: [--config, .ci/prettier.json, --write] types_or: - css - scss diff --git a/templates/.vscode/settings.json b/templates/.vscode/settings.json index bd6b16b..86c68d8 100644 --- a/templates/.vscode/settings.json +++ b/templates/.vscode/settings.json @@ -4,6 +4,6 @@ "editor.formatOnSave": true, "editor.defaultFormatter": "ms-python.black-formatter" }, - "flake8.args": ["--config=.cpa/flake8.cfg"], + "flake8.args": ["--config=.ci/flake8.cfg"], "files.insertFinalNewline": true } diff --git a/templates/base/.pre-commit-config.yaml b/templates/base/.pre-commit-config.yaml new file mode 100644 index 0000000..478cfc9 --- /dev/null +++ b/templates/base/.pre-commit-config.yaml @@ -0,0 +1,52 @@ +default_language_version: + python: python3 + +repos: + ############################################################################# + # Misc + ############################################################################# + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.5.0 + hooks: + - id: check-merge-conflict # Searches for merge conflict markers within files. + - id: check-added-large-files # Blocks commits that add large files. Default limit is 500kB. + # Can be configured with args, e.g., '--maxkb=1000' to change the limit. + # exclude: 'your_dir/.*' + # args: ['--maxkb=5000'] + - id: check-case-conflict # Identifies potential case-insensitive file name conflicts. + - id: check-ast # Validates the syntax of Python files. + - id: check-symlinks # Detects broken symlinks. + - id: trailing-whitespace # Removes any trailing whitespace at the end of lines. + - id: end-of-file-fixer # Ensures files end with a single newline or are empty. + + ############################################################################# + # JSON, TOML + ############################################################################# + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.5.0 + hooks: + - id: check-json # Validates JSON files to ensure they are properly formatted and syntactically correct. + types: [json] + + ############################################################################# + # Shell + ############################################################################# + - repo: https://github.com/jumanjihouse/pre-commit-hooks + rev: 3.0.0 + hooks: + - id: shfmt # Formats shell scripts to a standard convention using shfmt. + - id: shellcheck # Lints shell scripts to identify syntax and usage errors, with a specified severity of 'warning'. + args: + - --severity=warning + ############################################################################# + # CSS, Markdown, JavaScript, TypeScript, YAML style formatter + ############################################################################# + - repo: https://github.com/pre-commit/mirrors-prettier + rev: v3.0.3 + hooks: + - id: prettier # An opinionated code formatter supporting multiple languages. + name: prettier + args: [--config, .ci/prettier.json, --write] + types_or: + - yaml + - markdown diff --git a/templates/base/ci.yaml b/templates/base/ci.yaml new file mode 100644 index 0000000..dc9ed00 --- /dev/null +++ b/templates/base/ci.yaml @@ -0,0 +1,84 @@ +{% raw -%} +name: CI + +on: + pull_request: # Start the job on all PRs + +jobs: + precommit: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: "3.10" + + - name: Set shfmt version environment variable + run: echo "SHFMT_VERSION=v3.7.0" >> $GITHUB_ENV + + - name: Cache pip dependencies + uses: actions/cache@v3 + with: + path: ~/.cache/pip + key: ${{ runner.os }}-pip- + restore-keys: | + ${{ runner.os }}-pip- + + - name: Cache shfmt binary + uses: actions/cache@v3 + with: + path: /usr/local/bin/shfmt + key: ${{ runner.os }}-shfmt-${{ env.SHFMT_VERSION }} + restore-keys: | + ${{ runner.os }}-shfmt-${{ env.SHFMT_VERSION }} + ${{ runner.os }}-shfmt- + + - name: Cache Pre-Commit environments + uses: actions/cache@v3 + with: + path: ~/.cache/pre-commit + key: ${{ runner.os }}-pc-${{ hashFiles('.pre-commit-config.yaml') }} + restore-keys: | + ${{ runner.os }}-pc-${{ hashFiles('.pre-commit-config.yaml') }} + ${{ runner.os }}-pc- + + - name: Install dependencies + run: | + python -m pip install pre-commit + pre-commit install + + - name: Install shfmt + run: | + SHFMT_VERSION=${{ env.SHFMT_VERSION }} + SHFMT_BIN="shfmt_${SHFMT_VERSION}_linux_amd64" + if [[ ! -f /usr/local/bin/shfmt ]]; then + wget -O shfmt "https://github.com/mvdan/sh/releases/download/${SHFMT_VERSION}/${SHFMT_BIN}" + chmod +x shfmt + sudo mv shfmt /usr/local/bin/ + fi + sudo apt-get install shellcheck + + - name: Run pre-commits + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + REPO_NAME=$(echo $GITHUB_REPOSITORY | sed 's/^.*\///') + DEFAULT_BRANCH=$(curl -H "Authorization: token $GITHUB_TOKEN" \ + "https://api.github.com/repos/$GITHUB_REPOSITORY" | jq -r '.default_branch') + + git fetch + CUR_SHA=$(git log --pretty=tformat:"%H" -n1 . | tail -n1) + + echo "Default branch is $DEFAULT_BRANCH" + echo "Current SHA is $CUR_SHA" + + if [[ $GITHUB_REF == "refs/heads/$DEFAULT_BRANCH" ]]; then + pre-commit run --all + else + pre-commit run --from-ref origin/$DEFAULT_BRANCH --to-ref $CUR_SHA + fi +{%- endraw %} diff --git a/templates/pyproject.toml b/templates/pyproject.toml deleted file mode 100644 index c1b9fe3..0000000 --- a/templates/pyproject.toml +++ /dev/null @@ -1,63 +0,0 @@ -# This file was configured by CPA. For additional details: https://github.com/ysawa0/create-python-app -[tool.poetry] -name = "{{ name }}" -version = "0.0.1" -description = "" -authors = [ - "My Name " -] -license = "" - -[build-system] -requires = ["poetry-core>=1.7.0"] -build-backend = "poetry.core.masonry.api" - -[tool.black] -line-length = 120 -skip-string-normalization = false -target-version = ['{{ black_target_ver }}'] -include = '\.pyi?$' -exclude = ''' -/( - \.eggs - | \.git - | \.hg - | \.mypy_cache - | \.tox - | \.venv - | _build - | buck-out - | build - | dist -)/ -''' -color = true - -[tool.isort] -balanced_wrapping = true -include_trailing_comma = true -known_first_party = "{{ name }}" -known_third_party = [ - "boto3", # Common for AWS - "django", # Common web framework, if used - "flask", # Common web framework, if used - "jinja2", # Common templating engine - "matplotlib", # Common for plotting - "numpy", # Common for numerical operations - "pandas", # Common for data manipulation - "pendulum", # Common for date time - "pytest", # Common for testing - "requests", # Common for HTTP requests - "sqlalchemy", # Common ORM for databases -] -multi_line_output = 3 -profile = "black" -line_length = 120 - -[tool.poetry.dependencies] -python = "^{{ python_ver }}" - -[tool.poetry.group.dev.dependencies] -pre-commit = ">=3.5.0" -pytest = "^7.3.1" -pytest-cov = "^4.1.0" diff --git a/templates/python/main.py b/templates/python/main.py deleted file mode 100644 index ad35e5a..0000000 --- a/templates/python/main.py +++ /dev/null @@ -1 +0,0 @@ -print("Hello World")