From 2b5be851ff429ad86e0b8718ad195a6c14aeabec Mon Sep 17 00:00:00 2001 From: tison Date: Tue, 23 Dec 2025 12:16:59 +0800 Subject: [PATCH] refactor: rework bootstrap Signed-off-by: tison --- .gitignore | 4 ++ README.md | 22 ++++--- bootstrap.py | 119 +++++++++++++++++++++++++++++++++++++ rename-project.ps1 | 133 ----------------------------------------- rename-project.sh | 144 --------------------------------------------- 5 files changed, 133 insertions(+), 289 deletions(-) create mode 100755 bootstrap.py delete mode 100644 rename-project.ps1 delete mode 100755 rename-project.sh diff --git a/.gitignore b/.gitignore index ea8c4bf..31222b7 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,5 @@ /target + +# temporary files +.DS_Store +__pycache__ diff --git a/README.md b/README.md index 44afbc1..348a114 100644 --- a/README.md +++ b/README.md @@ -6,32 +6,30 @@ [![Apache 2.0 licensed][license-badge]][license-url] [![Build Status][actions-badge]][actions-url] -[crates-badge]: https://img.shields.io/crates/v/template.svg -[crates-url]: https://crates.io/crates/template -[docs-badge]: https://docs.rs/template/badge.svg +[crates-badge]: https://img.shields.io/crates/v/${projectName}.svg +[crates-url]: https://crates.io/crates/${projectName} +[docs-badge]: https://docs.rs/${projectName}/badge.svg [msrv-badge]: https://img.shields.io/badge/MSRV-1.85-green?logo=rust -[docs-url]: https://docs.rs/template -[license-badge]: https://img.shields.io/crates/l/template +[docs-url]: https://docs.rs/${projectName} +[license-badge]: https://img.shields.io/crates/l/${projectName} [license-url]: LICENSE [actions-badge]: https://github.com/fast/template/workflows/CI/badge.svg -[actions-url]:https://github.com/fast/template/actions?query=workflow%3ACI +[actions-url]: https://github.com/fast/template/actions?query=workflow%3ACI Use this repository as a GitHub template to quickly start a new Rust project. ## Getting Started -1. Create a new repository using this template -2. Clone your repository and run the rename script: - - **Linux/macOS:** `./rename-project.sh` - - **Windows:** `.\rename-project.ps1` -3. Follow the prompts, review changes, and commit +1. Create a new repository using this template; +2. Clone your repository and run the bootstrap script: `./bootstrap.py`; +3. Follow the prompts, review changes, and commit; 4. Start building your project! ## Minimum Rust version policy This crate is built against the latest stable release, and its minimum supported rustc version is 1.85.0. -The policy is that the minimum Rust version required to use this crate can be increased in minor version updates. For example, if Template 1.0 requires Rust 1.60.0, then Template 1.0.z for all values of z will also require Rust 1.60.0 or newer. However, Template 1.y for y > 0 may require a newer minimum version of Rust. +The policy is that the minimum Rust version required to use this crate can be increased in minor version updates. For example, if version 1.0 requires Rust 1.60.0, then version 1.0.z for all values of z will also require Rust 1.60.0 or newer. However, version 1.y for y > 0 may require a newer minimum version of Rust. ## License diff --git a/bootstrap.py b/bootstrap.py new file mode 100755 index 0000000..c6d4b68 --- /dev/null +++ b/bootstrap.py @@ -0,0 +1,119 @@ +#!/usr/bin/env python3 + +# Copyright 2025 FastLabs Developers +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os +import sys + +def main(): + print("Welcome to the project bootstrap script!") + + # 1. Get user input + try: + project_name = input("Enter your project name (e.g., my-awesome-project): ").strip() + if not project_name: + print("Error: Project name cannot be empty.") + sys.exit(1) + + github_username = input("Enter your GitHub username (e.g., torvalds): ").strip() + if not github_username: + print("Error: GitHub username cannot be empty.") + sys.exit(1) + except KeyboardInterrupt: + print("\nOperation cancelled.") + sys.exit(0) + + print(f"\nBootstrapping project '{project_name}' for user '{github_username}'...\n") + + # 2. Update README.md + # Replaces: + # - fast/template -> username/project_name + # - ${projectName} -> project_name + readme_path = "README.md" + if os.path.exists(readme_path): + with open(readme_path, "r", encoding="utf-8") as f: + content = f.read() + + new_content = content.replace("fast/template", f"{github_username}/{project_name}") + new_content = new_content.replace("${projectName}", project_name) + + if content != new_content: + with open(readme_path, "w", encoding="utf-8") as f: + f.write(new_content) + print(f"✅ Updated {readme_path}") + else: + print(f"ℹ️ No changes needed in {readme_path}") + else: + print(f"⚠️ Warning: {readme_path} not found.") + + # 3. Update Cargo.toml (Workspace Root) + # Replaces: + # - fast/template -> username/project_name + # - "template" (in members) -> "project_name" + root_cargo_path = "Cargo.toml" + if os.path.exists(root_cargo_path): + with open(root_cargo_path, "r", encoding="utf-8") as f: + content = f.read() + + new_content = content.replace("fast/template", f"{github_username}/{project_name}") + # Identify workspace member "template" specifically to avoid false positives + new_content = new_content.replace('"template"', f'"{project_name}"') + + if content != new_content: + with open(root_cargo_path, "w", encoding="utf-8") as f: + f.write(new_content) + print(f"✅ Updated {root_cargo_path}") + else: + print(f"ℹ️ No changes needed in {root_cargo_path}") + else: + print(f"⚠️ Warning: {root_cargo_path} not found.") + + # 4. Update template/Cargo.toml (Package Name) + # Replaces: + # - name = "template" -> name = "project_name" + # Note: We edit the file inside the directory *before* renaming the directory + template_cargo_path = "template/Cargo.toml" + if os.path.exists(template_cargo_path): + with open(template_cargo_path, "r", encoding="utf-8") as f: + content = f.read() + + new_content = content.replace('name = "template"', f'name = "{project_name}"') + + if content != new_content: + with open(template_cargo_path, "w", encoding="utf-8") as f: + f.write(new_content) + print(f"✅ Updated {template_cargo_path}") + else: + print(f"ℹ️ No changes needed in {template_cargo_path}") + else: + # If the directory was already renamed in a previous run, we might want to check the new name + # but for a simple bootstrap script, assuming standard state is fine. + print(f"⚠️ Warning: {template_cargo_path} not found (Did you already run this script?)") + + # 5. Rename template directory + if os.path.exists("template"): + os.rename("template", project_name) + print(f"✅ Renamed directory 'template' to '{project_name}'") + else: + if os.path.exists(project_name): + print(f"ℹ️ Directory '{project_name}' already exists.") + else: + print("⚠️ Warning: Directory 'template' not found.") + + print("\n🎉 Bootstrap complete!") + print(f"You can now delete this script: rm {os.path.basename(__file__)}") + +if __name__ == "__main__": + main() diff --git a/rename-project.ps1 b/rename-project.ps1 deleted file mode 100644 index cb42cfc..0000000 --- a/rename-project.ps1 +++ /dev/null @@ -1,133 +0,0 @@ -# Copyright 2025 FastLabs Developers -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -$ErrorActionPreference = "Stop" - -Write-Host "========================================" -ForegroundColor Blue -Write-Host " Template Project Batch Renamer " -ForegroundColor Blue -Write-Host "========================================" -ForegroundColor Blue -Write-Host "" - -if (-not (Test-Path "Cargo.toml") -or -not (Test-Path "template" -PathType Container)) { - Write-Host "ERROR: This script must be run from the project root directory" -ForegroundColor Red - exit 1 -} - -Write-Host "Please provide the following information:" -ForegroundColor Yellow -Write-Host "" - -$ProjectName = Read-Host "New project name (e.g., my-awesome-project)" -$GitHubUser = Read-Host "GitHub username/org (e.g., myname)" - -if ([string]::IsNullOrWhiteSpace($ProjectName)) { - Write-Host "ERROR: Project name is required" -ForegroundColor Red - exit 1 -} - -if ([string]::IsNullOrWhiteSpace($GitHubUser)) { - Write-Host "ERROR: GitHub username is required" -ForegroundColor Red - exit 1 -} - -# Validate project name format (Rust package naming convention) -if ($ProjectName -notmatch '^[a-z][a-z0-9_-]*$') { - Write-Host "ERROR: Project name must start with a lowercase letter and contain only lowercase letters, numbers, hyphens, and underscores" -ForegroundColor Red - exit 1 -} - -Write-Host "" -Write-Host "Summary:" -ForegroundColor Blue -Write-Host " Project name: $ProjectName" -ForegroundColor Green -Write-Host " GitHub repo: $GitHubUser/$ProjectName" -ForegroundColor Green -Write-Host " Crates.io URL: https://crates.io/crates/$ProjectName" -ForegroundColor Green -Write-Host "" - -$Confirm = Read-Host "Continue with renaming? (y/N)" -$ConfirmLower = $Confirm.ToLower() -if ($ConfirmLower -ne "y" -and $ConfirmLower -ne "yes") { - Write-Host "Cancelled." -ForegroundColor Yellow - exit 0 -} - -Write-Host "" -Write-Host "Starting batch rename..." -ForegroundColor Blue -Write-Host "" - -function Update-FileContent { - param( - [string]$FilePath, - [string]$OldValue, - [string]$NewValue - ) - - $content = Get-Content $FilePath -Raw - $content = $content -replace [regex]::Escape($OldValue), $NewValue - Set-Content $FilePath -Value $content -NoNewline -} - -# 1. Update root Cargo.toml -Write-Host "[OK] Updating Cargo.toml..." -ForegroundColor Green -Update-FileContent "Cargo.toml" "https://github.com/fast/template" "https://github.com/$GitHubUser/$ProjectName" -Update-FileContent "Cargo.toml" '"template"' "`"$ProjectName`"" - -# 2. Update template/Cargo.toml -Write-Host "[OK] Updating template/Cargo.toml..." -ForegroundColor Green -Update-FileContent "template/Cargo.toml" 'name = "template"' "name = `"$ProjectName`"" - -# 3. Update README.md -Write-Host "[OK] Updating README.md..." -ForegroundColor Green -Update-FileContent "README.md" "crates.io/crates/template" "crates.io/crates/$ProjectName" -Update-FileContent "README.md" "img.shields.io/crates/v/template.svg" "img.shields.io/crates/v/$ProjectName.svg" -Update-FileContent "README.md" "img.shields.io/crates/l/template" "img.shields.io/crates/l/$ProjectName" -Update-FileContent "README.md" "github.com/fast/template" "github.com/$GitHubUser/$ProjectName" -Update-FileContent "README.md" "docs.rs/template" "docs.rs/$ProjectName" - -# 4. Update .github/semantic.yml -Write-Host "[OK] Updating .github/semantic.yml..." -ForegroundColor Green -Update-FileContent ".github/semantic.yml" "github.com/fast/template" "github.com/$GitHubUser/$ProjectName" - -# 5. Rename template directory -Write-Host "[OK] Renaming template/ directory to $ProjectName/..." -ForegroundColor Green -if (Test-Path "template" -PathType Container) { - Rename-Item "template" $ProjectName -} - -# 6. Update Cargo.lock -Write-Host "[OK] Updating Cargo.lock..." -ForegroundColor Green -Update-FileContent "Cargo.lock" 'name = "template"' "name = `"$ProjectName`"" - -Write-Host "" -Write-Host "========================================" -ForegroundColor Green -Write-Host " SUCCESS: Renaming completed! " -ForegroundColor Green -Write-Host "========================================" -ForegroundColor Green -Write-Host "" -Write-Host "Next steps:" -ForegroundColor Blue -Write-Host "" -Write-Host " 1. Review the changes:" -Write-Host " git diff" -ForegroundColor Yellow -Write-Host "" -Write-Host " 2. Delete the rename scripts (no longer needed):" -Write-Host " Remove-Item rename-project.sh, rename-project.ps1" -ForegroundColor Yellow -Write-Host "" -Write-Host " 3. Update the project description in README.md" -Write-Host "" -Write-Host " 4. Commit your changes:" -Write-Host " git add ." -ForegroundColor Yellow -Write-Host " git commit -m `"chore: initialize project as $ProjectName`"" -ForegroundColor Yellow -Write-Host "" -Write-Host " 5. Push to GitHub:" -Write-Host " git push" -ForegroundColor Yellow -Write-Host "" -Write-Host "Happy coding!" -ForegroundColor Green - diff --git a/rename-project.sh b/rename-project.sh deleted file mode 100755 index efcaefb..0000000 --- a/rename-project.sh +++ /dev/null @@ -1,144 +0,0 @@ -#!/usr/bin/env bash -# Copyright 2025 FastLabs Developers -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -set -euo pipefail - -# Colors for output -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -BLUE='\033[0;34m' -NC='\033[0m' # No Color - -echo -e "${BLUE}========================================${NC}" -echo -e "${BLUE} Template Project Batch Renamer ${NC}" -echo -e "${BLUE}========================================${NC}" -echo "" - -if [[ ! -f "Cargo.toml" ]] || [[ ! -d "template" ]]; then - echo -e "${RED}ERROR: This script must be run from the project root directory${NC}" - exit 1 -fi - -echo -e "${YELLOW}Please provide the following information:${NC}" -echo "" - -read -p "New project name (e.g., my-awesome-project): " PROJECT_NAME -read -p "GitHub username/org (e.g., myname): " GITHUB_USER - -if [[ -z "$PROJECT_NAME" ]]; then - echo -e "${RED}ERROR: Project name is required${NC}" - exit 1 -fi - -if [[ -z "$GITHUB_USER" ]]; then - echo -e "${RED}ERROR: GitHub username is required${NC}" - exit 1 -fi - -# Validate project name format (Rust package naming convention) -if [[ ! "$PROJECT_NAME" =~ ^[a-z][a-z0-9_-]*$ ]]; then - echo -e "${RED}ERROR: Project name must start with a lowercase letter and contain only lowercase letters, numbers, hyphens, and underscores${NC}" - exit 1 -fi - -echo "" -echo -e "${BLUE}Summary:${NC}" -echo -e " Project name: ${GREEN}$PROJECT_NAME${NC}" -echo -e " GitHub repo: ${GREEN}$GITHUB_USER/$PROJECT_NAME${NC}" -echo -e " Crates.io URL: ${GREEN}https://crates.io/crates/$PROJECT_NAME${NC}" -echo "" -read -p "Continue with renaming? (y/N): " CONFIRM - -CONFIRM_LOWER=$(echo "$CONFIRM" | tr '[:upper:]' '[:lower:]') - -if [[ "$CONFIRM_LOWER" != "y" ]] && [[ "$CONFIRM_LOWER" != "yes" ]]; then - echo -e "${YELLOW}Cancelled.${NC}" - exit 0 -fi - -echo "" -echo -e "${BLUE}Starting batch rename...${NC}" -echo "" - -update_file() { - local file=$1 - local old=$2 - local new=$3 - - if [[ "$OSTYPE" == "darwin"* ]]; then - # macOS - sed -i '' "s|$old|$new|g" "$file" - else - # Linux - sed -i "s|$old|$new|g" "$file" - fi -} - -# 1. Update root Cargo.toml -echo -e "${GREEN}[OK]${NC} Updating Cargo.toml..." -update_file "Cargo.toml" "https://github.com/fast/template" "https://github.com/$GITHUB_USER/$PROJECT_NAME" -update_file "Cargo.toml" '"template"' "\"$PROJECT_NAME\"" - -# 2. Update template/Cargo.toml -echo -e "${GREEN}[OK]${NC} Updating template/Cargo.toml..." -update_file "template/Cargo.toml" 'name = "template"' "name = \"$PROJECT_NAME\"" - -# 3. Update README.md -echo -e "${GREEN}[OK]${NC} Updating README.md..." -update_file "README.md" "crates.io/crates/template" "crates.io/crates/$PROJECT_NAME" -update_file "README.md" "img.shields.io/crates/v/template.svg" "img.shields.io/crates/v/$PROJECT_NAME.svg" -update_file "README.md" "img.shields.io/crates/l/template" "img.shields.io/crates/l/$PROJECT_NAME" -update_file "README.md" "github.com/fast/template" "github.com/$GITHUB_USER/$PROJECT_NAME" -update_file "README.md" "docs.rs/template" "docs.rs/$PROJECT_NAME" - -# 4. Update .github/semantic.yml -echo -e "${GREEN}[OK]${NC} Updating .github/semantic.yml..." -update_file ".github/semantic.yml" "github.com/fast/template" "github.com/$GITHUB_USER/$PROJECT_NAME" - -# 5. Rename template directory -echo -e "${GREEN}[OK]${NC} Renaming template/ directory to $PROJECT_NAME/..." -if [[ -d "template" ]]; then - mv template "$PROJECT_NAME" -fi - -# 6. Update Cargo.lock -echo -e "${GREEN}[OK]${NC} Updating Cargo.lock..." -update_file "Cargo.lock" 'name = "template"' "name = \"$PROJECT_NAME\"" - -echo "" -echo -e "${GREEN}========================================${NC}" -echo -e "${GREEN} SUCCESS: Renaming completed! ${NC}" -echo -e "${GREEN}========================================${NC}" -echo "" -echo -e "${BLUE}Next steps:${NC}" -echo "" -echo -e " 1. Review the changes:" -echo -e " ${YELLOW}git diff${NC}" -echo "" -echo -e " 2. Delete the rename scripts (no longer needed):" -echo -e " ${YELLOW}rm rename-project.sh rename-project.ps1${NC}" -echo "" -echo -e " 3. Update the project description in README.md" -echo "" -echo -e " 4. Commit your changes:" -echo -e " ${YELLOW}git add .${NC}" -echo -e " ${YELLOW}git commit -m \"chore: initialize project as $PROJECT_NAME\"${NC}" -echo "" -echo -e " 5. Push to GitHub:" -echo -e " ${YELLOW}git push${NC}" -echo "" -echo -e "${GREEN}Happy coding!${NC}" -