diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..bc720cb --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,30 @@ +version: 2 +updates: + # Rust dependencies + - package-ecosystem: "cargo" + directory: "/" + schedule: + interval: "weekly" + day: "monday" + time: "09:00" + open-pull-requests-limit: 10 + labels: + - "dependencies" + - "rust" + commit-message: + prefix: "chore" + include: "scope" + + # GitHub Actions + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + day: "monday" + time: "09:00" + open-pull-requests-limit: 5 + labels: + - "dependencies" + - "ci" + commit-message: + prefix: "ci" \ No newline at end of file diff --git a/.github/workflows/auto-changelog.yml b/.github/workflows/auto-changelog.yml new file mode 100644 index 0000000..58811d4 --- /dev/null +++ b/.github/workflows/auto-changelog.yml @@ -0,0 +1,32 @@ +name: Auto Changelog + +on: + push: + tags: + - 'v*' + +jobs: + changelog: + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Generate changelog + uses: orhun/git-cliff-action@v3 + with: + config: cliff.toml + args: --verbose --tag ${{ github.ref_name }} + env: + OUTPUT: CHANGELOG.md + + - name: Commit CHANGELOG + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git add CHANGELOG.md + git commit -m "chore: update CHANGELOG for ${{ github.ref_name }}" || exit 0 + git push origin HEAD:main \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..d396817 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,87 @@ +name: CI + +on: + push: + branches: + - main + - dev + pull_request: + branches: + - main + - dev + +env: + CARGO_TERM_COLOR: always + RUST_BACKTRACE: 1 + +jobs: + check: + name: Check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + - uses: Swatinem/rust-cache@v2 + - run: cargo check --all-features --workspace + + test: + name: Test + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + - uses: Swatinem/rust-cache@v2 + - run: cargo test --all-features --workspace + + fmt: + name: Format + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + with: + components: rustfmt + - run: cargo fmt --all -- --check + + clippy: + name: Clippy + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + with: + components: clippy + - uses: Swatinem/rust-cache@v2 + - run: cargo clippy --all-features --workspace -- -D warnings + + build: + name: Build + strategy: + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + - uses: Swatinem/rust-cache@v2 + - run: cargo build --release --all-features --workspace + + audit: + name: Security Audit + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: taiki-e/install-action@v2 + with: + tool: cargo-audit + - run: cargo audit + + deny: + name: Cargo Deny + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: taiki-e/install-action@v2 + with: + tool: cargo-deny + - run: cargo deny check \ No newline at end of file diff --git a/.github/workflows/dependabot-auto.yml b/.github/workflows/dependabot-auto.yml new file mode 100644 index 0000000..009b09c --- /dev/null +++ b/.github/workflows/dependabot-auto.yml @@ -0,0 +1,27 @@ +name: Dependabot Auto-Merge + +on: + pull_request: + branches: + - main + +permissions: + contents: write + pull-requests: write + +jobs: + auto-merge: + name: Auto-merge Dependabot PRs + runs-on: ubuntu-latest + if: github.actor == 'dependabot[bot]' + steps: + - name: Dependabot metadata + id: metadata + uses: dependabot/fetch-metadata@v2 + + - name: Auto-merge minor updates + if: steps.metadata.outputs.update-type == 'version-update:semver-minor' || steps.metadata.outputs.update-type == 'version-update:semver-patch' + run: gh pr merge --auto --squash "$PR_URL" + env: + PR_URL: ${{ github.event.pull_request.html_url }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..2dd8ce7 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,122 @@ +name: Release + +on: + push: + tags: + - 'v*' + +env: + CARGO_TERM_COLOR: always + +jobs: + publish-crates: + name: Publish to crates.io + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + - uses: Swatinem/rust-cache@v2 + + - name: Publish dev-forge-core + run: | + cargo login ${{ secrets.CARGO_TOKEN }} + cargo publish -p dev-forge-core --no-verify + + - name: Wait for crates.io indexing + run: sleep 30 + + - name: Publish dev-forge CLI + run: cargo publish -p dev-forge --no-verify + + build-binaries: + name: Build Binaries + needs: publish-crates + strategy: + matrix: + include: + - os: ubuntu-latest + target: x86_64-unknown-linux-gnu + artifact: dev-forge-linux-x64 + - os: ubuntu-latest + target: x86_64-unknown-linux-musl + artifact: dev-forge-linux-musl-x64 + - os: macos-latest + target: x86_64-apple-darwin + artifact: dev-forge-macos-x64 + - os: macos-latest + target: aarch64-apple-darwin + artifact: dev-forge-macos-arm64 + - os: windows-latest + target: x86_64-pc-windows-msvc + artifact: dev-forge-windows-x64.exe + + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + with: + targets: ${{ matrix.target }} + - uses: Swatinem/rust-cache@v2 + + - name: Install musl tools + if: matrix.target == 'x86_64-unknown-linux-musl' + run: sudo apt-get install -y musl-tools + + - name: Build binary + run: cargo build --release --target ${{ matrix.target }} -p dev-forge + + - name: Rename binary (Unix) + if: runner.os != 'Windows' + run: | + cp target/${{ matrix.target }}/release/dev-forge ${{ matrix.artifact }} + + - name: Rename binary (Windows) + if: runner.os == 'Windows' + run: | + cp target/${{ matrix.target }}/release/dev-forge.exe ${{ matrix.artifact }} + + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: ${{ matrix.artifact }} + path: ${{ matrix.artifact }} + + create-release: + name: Create GitHub Release + needs: build-binaries + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - uses: actions/checkout@v4 + + - name: Download all artifacts + uses: actions/download-artifact@v4 + with: + path: artifacts + + - name: Create Release + uses: softprops/action-gh-release@v2 + with: + files: artifacts/**/* + generate_release_notes: true + body: | + ## 🚀 Installation + + ### Via cargo (recommended) + ```bash + cargo install dev-forge + ``` + + ### Via binary + Download the binary for your platform below and add it to your PATH. + + ### Verification + ```bash + dev-forge --version + ``` + + ## 📝 What's Changed + See the auto-generated release notes below. + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.gitignore b/.gitignore index ec2acbe..9cfd144 100644 --- a/.gitignore +++ b/.gitignore @@ -12,4 +12,6 @@ # Ignorer les fichiers spécifiques à l'IDE .idea/ .vscode/ -*.iml \ No newline at end of file +*.iml + +explain_project.md \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..e0e7def --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,68 @@ +# Guide de Contribution + +Merci de vouloir contribuer à ce projet ! Voici quelques règles pour garantir une collaboration efficace et harmonieuse. + +## Processus de Contribution + +1. **Forker le dépôt** : Créez une copie de ce dépôt sur votre compte GitHub. +2. **Créer une branche de travail** : Travaillez sur une branche dédiée pour chaque fonctionnalité ou correction de bug. Cette branche doit être créée à partir de `dev`. + + ```bash + git checkout dev + git checkout -b nom-de-la-branche + ``` + +3. **Pousser la branche de travail** : Une fois votre travail terminé ou prêt à être partagé, poussez votre branche vers le dépôt distant. + + ```bash + git push origin nom-de-la-branche + ``` + +4. **Soumettre une Pull Request (PR)** : + - **Vers `dev`** : + - Ouvrez une PR de votre branche de travail vers la branche `dev`. + - Cette branche est utilisée pour le développement actif. + - **Vers `main`** : + - Une fois que `dev` est stable, ouvrez une PR de `dev` vers `main` pour les releases stables. + +## Règles de Codage + +- Respectez les conventions de codage définies dans le projet. +- Ajoutez des tests pour toute nouvelle fonctionnalité ou correction de bug. +- Assurez-vous que votre code est bien formaté et documenté. + +## Règles pour les Commits + +Nous utilisons la convention [Conventional Commits](https://www.conventionalcommits.org/) pour garantir des messages de commit clairs et standardisés. Tous les messages de commit doivent être rédigés en anglais. Voici les types de commits acceptés : + +- **feat** : Ajout d'une nouvelle fonctionnalité. +- **fix** : Correction d'un bug. +- **docs** : Modifications de la documentation. +- **style** : Changements de style (formatage, espaces, etc.) sans impact sur le code. +- **refactor** : Refactorisation du code sans ajout de fonctionnalité ni correction de bug. +- **test** : Ajout ou modification de tests. +- **chore** : Changements mineurs (mise à jour des dépendances, configuration, etc.). + +### Exemple de message de commit + +```text +feat: Add a command to analyze errors + +This command allows analyzing compiler errors and suggesting solutions. +``` + +- La première ligne doit être concise (50 caractères max) et décrire le changement. +- Ajoutez une ligne vide après la première ligne. +- Fournissez une description plus détaillée si nécessaire. + +## Revue de Code + +- Les PR doivent être approuvées par au moins un mainteneur avant d'être fusionnées. +- Répondez rapidement aux commentaires sur votre PR. + +## CI/CD + +- Toutes les PR doivent passer les tests automatisés avant d'être fusionnées. +- Vérifiez que votre code ne casse pas le pipeline CI. + +Merci pour votre contribution ! 🚀 diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..df91521 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1 @@ +[workspace] \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..abeaa9d --- /dev/null +++ b/Makefile @@ -0,0 +1,42 @@ +.PHONY: help check test fmt clippy build release install publish + +help: ## Show this help + @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}' + +check: ## Check compilation + cargo check --all-features --workspace + +test: ## Run tests + cargo test --all-features --workspace + +fmt: ## Check formatting + cargo fmt --all -- --check + +clippy: ## Run clippy + cargo clippy --all-features --workspace -- -D warnings + +build: ## Build release + cargo build --release --all-features --workspace + +ci: fmt clippy test ## Run full CI locally + +release: ## Create a new release (usage: make release VERSION=0.1.0) + @if [ -z "$(VERSION)" ]; then echo "Usage: make release VERSION=0.1.0"; exit 1; fi + @echo "Creating release v$(VERSION)" + cargo set-version $(VERSION) + git add . + git commit -m "chore: release v$(VERSION)" + git tag v$(VERSION) + git push origin main --tags + @echo "✅ Release v$(VERSION) created! GitHub Actions will publish to crates.io" + +install: ## Install binary locally + cargo install --path crates/dev-forge-cli --force + +publish: ## Publish to crates.io manually + cargo publish -p dev-forge-core + @sleep 30 + cargo publish -p dev-forge + +clean: ## Clean build artifacts + cargo clean \ No newline at end of file diff --git a/RELEASE.md b/RELEASE.md new file mode 100644 index 0000000..bca81cc --- /dev/null +++ b/RELEASE.md @@ -0,0 +1,108 @@ +# Gestion des Versions et Publication + +## Conventions de Versioning + +Ce projet suit le versioning sémantique (SemVer) : + +- **MAJEUR** : Changements incompatibles avec les versions précédentes. +- **MINEUR** : Nouvelles fonctionnalités rétrocompatibles. +- **PATCH** : Corrections de bugs rétrocompatibles. + +## Processus de Versioning Automatique + +1. **Détection des changements** : + + - Les messages de commit doivent suivre le format [Conventional Commits](https://www.conventionalcommits.org/). + - Exemple : + + ```bash + feat: Ajouter une nouvelle commande CLI + fix: Corriger un bug dans le parser + ``` + +2. **Génération de version** : + + - Utilisation d'un outil comme [cargo-release](https://github.com/crate-ci/cargo-release) pour incrémenter automatiquement la version. + +3. **Publication** : + + - La commande suivante publie le workspace complet : + + ```bash + cargo publish --workspace + ``` + +## Publication sur crates.io + +1. **Créer un compte** : + + - Assurez-vous d'avoir un compte sur [crates.io](https://crates.io/). + +2. **Configurer l'authentification** : + + - Ajoutez votre clé API : + + ```bash + cargo login + ``` + +3. **Vérification avant publication** : + + - Testez votre projet : + + ```bash + cargo test + ``` + + - Vérifiez les warnings : + + ```bash + cargo check + ``` + +4. **Publier** : + + - Publiez chaque crate si nécessaire : + + ```bash + cargo publish -p + ``` + +## Gestion du Workspace + +- Ce projet utilise un workspace Cargo pour gérer plusieurs crates. +- Structure typique : + + ```text + dev-forge/ + ├── Cargo.toml # Workspace + ├── crates/ + │ ├── dev-forge-core/ # Lib (logic) + │ └── dev-forge-cli/ # Bin (interface) + ``` + +- Commandes utiles : + + - Construire tout le workspace : + + ```bash + cargo build --workspace + ``` + + - Tester tout le workspace : + + ```bash + cargo test --workspace + ``` + +## Checklist avant une Release + +- [ ] Tous les tests passent. +- [ ] Les dépendances sont à jour. +- [ ] Le fichier `CHANGELOG.md` est mis à jour. +- [ ] La version est incrémentée correctement. +- [ ] La publication est testée en local. + +--- + +**Note** : Assurez-vous de respecter les bonnes pratiques pour éviter les erreurs lors de la publication. diff --git a/cliff.toml b/cliff.toml new file mode 100644 index 0000000..8fba6aa --- /dev/null +++ b/cliff.toml @@ -0,0 +1,34 @@ +[changelog] +header = """ +# Changelog\n +All notable changes to this project will be documented in this file.\n +""" +body = """ +{% if version %}\ + ## [{{ version | trim_start_matches(pat="v") }}] - {{ timestamp | date(format="%Y-%m-%d") }} +{% else %}\ + ## [unreleased] +{% endif %}\ +{% for group, commits in commits | group_by(attribute="group") %} + ### {{ group | upper_first }} + {% for commit in commits %} + - {{ commit.message | upper_first }}\ + {% endfor %} +{% endfor %}\n +""" +trim = true + +[git] +conventional_commits = true +filter_unconventional = true +commit_parsers = [ + { message = "^feat", group = "Features" }, + { message = "^fix", group = "Bug Fixes" }, + { message = "^doc", group = "Documentation" }, + { message = "^perf", group = "Performance" }, + { message = "^refactor", group = "Refactor" }, + { message = "^style", group = "Styling" }, + { message = "^test", group = "Testing" }, + { message = "^chore", skip = true }, + { message = "^ci", skip = true }, +] \ No newline at end of file diff --git a/deny.toml b/deny.toml new file mode 100644 index 0000000..5c5e503 --- /dev/null +++ b/deny.toml @@ -0,0 +1,27 @@ +[advisories] +db-path = "~/.cargo/advisory-db" +db-urls = ["https://github.com/rustsec/advisory-db"] +vulnerability = "deny" +unmaintained = "warn" +unsound = "warn" +yanked = "warn" +notice = "warn" + +[licenses] +unlicensed = "deny" +allow = [ + "MIT", + "Apache-2.0", + "BSD-3-Clause", + "ISC", +] +confidence-threshold = 0.8 + +[bans] +multiple-versions = "warn" +wildcards = "allow" + +[sources] +unknown-registry = "warn" +unknown-git = "warn" +allow-registry = ["https://github.com/rust-lang/crates.io-index"] \ No newline at end of file diff --git a/explain_project.md b/explain_project.md deleted file mode 100644 index 2602439..0000000 --- a/explain_project.md +++ /dev/null @@ -1,586 +0,0 @@ -**PARFAIT ! `dev-forge` avec le tiret pour le SEO, excellent choix !** 🎯 - -## 🚀 Setup pragmatique : Commence par ce qui T'AIDE TOI direct - -### **Stratégie : Dogfooding immédiat** - -Au lieu de coder dans le vide, on va créer un outil qui **t'aide MAINTENANT** pendant que tu codes `dev-forge` lui-même ! 🤯 - ---- - -## 📋 Plan d'action : 3 semaines progressives - -### **Semaine 1 : CLI minimal qui marche** - -**Objectif** : Un outil que tu peux utiliser dès aujourd'hui - -```bash -dev-forge/ -├── Cargo.toml # Workspace -├── crates/ -│ ├── dev-forge-core/ # Lib (logic) -│ └── dev-forge-cli/ # Bin (interface) -└── rules/ - └── rust-borrow-simple.toml # 1 rule pour tester -``` - -**Feature unique à implémenter** : **Clipboard fixer** - -```bash -# Use case RÉEL qui t'aide maintenant: - -# 1. Tu as une erreur borrow checker -# 2. Tu copies l'erreur (Ctrl+C) -# 3. Tu runs: -dev-forge fix-clipboard - -# 4. Ça affiche les solutions possibles: -# ✅ Solution 1 (confidence: 95%): Split into scopes -# ✅ Solution 2 (confidence: 85%): Clone the value -# ✅ Solution 3 (confidence: 60%): Use RefCell - -# 5. Tu choisis et ça copie le fix dans clipboard -``` - -**Code minimal** : - -```rust -// crates/dev-forge-cli/src/main.rs -use clap::{Parser, Subcommand}; - -#[derive(Parser)] -#[command(name = "dev-forge")] -#[command(about = "Intelligent development assistant")] -struct Cli { - #[command(subcommand)] - command: Commands, -} - -#[derive(Subcommand)] -enum Commands { - /// Analyze clipboard for errors and suggest fixes - FixClipboard, - - /// Analyze a file - Fix { - #[arg(short, long)] - file: String, - }, -} - -fn main() -> anyhow::Result<()> { - let cli = Cli::parse(); - - match cli.command { - Commands::FixClipboard => { - let clipboard = get_clipboard()?; - let solutions = dev_forge_core::analyze(&clipboard)?; - - println!("🔍 Found {} solutions:\n", solutions.len()); - for (i, sol) in solutions.iter().enumerate() { - println!("{}. {} (confidence: {}%)", - i + 1, - sol.description, - (sol.confidence * 100.0) as u32 - ); - } - - // Interactive picker - let choice = prompt_user_choice(solutions.len())?; - set_clipboard(&solutions[choice].code)?; - println!("✅ Solution copied to clipboard!"); - } - Commands::Fix { file } => { - // TODO: Implement file analysis - println!("Analyzing file: {}", file); - } - } - - Ok(()) -} - -fn get_clipboard() -> anyhow::Result { - use clipboard::{ClipboardProvider, ClipboardContext}; - let mut ctx: ClipboardContext = ClipboardProvider::new()?; - Ok(ctx.get_contents()?) -} - -fn set_clipboard(text: &str) -> anyhow::Result<()> { - use clipboard::{ClipboardProvider, ClipboardContext}; - let mut ctx: ClipboardContext = ClipboardProvider::new()?; - Ok(ctx.set_contents(text.to_string())?) -} - -fn prompt_user_choice(max: usize) -> anyhow::Result { - use std::io::{self, Write}; - - print!("Choose solution (1-{}): ", max); - io::stdout().flush()?; - - let mut input = String::new(); - io::stdin().read_line(&mut input)?; - - let choice: usize = input.trim().parse()?; - anyhow::ensure!(choice > 0 && choice <= max, "Invalid choice"); - - Ok(choice - 1) -} -``` - -```rust -// crates/dev-forge-core/src/lib.rs -pub struct Solution { - pub description: String, - pub code: String, - pub confidence: f32, -} - -pub fn analyze(error_text: &str) -> anyhow::Result> { - // Pattern matching ultra-simple pour commencer - - if error_text.contains("cannot borrow") && error_text.contains("as mutable") { - return Ok(vec![ - Solution { - description: "Clone the value instead of borrowing".into(), - code: "// TODO: Generate actual code based on context".into(), - confidence: 0.85, - }, - Solution { - description: "Split into separate scopes".into(), - code: "// TODO: Scope split code".into(), - confidence: 0.95, - }, - ]); - } - - Ok(vec![]) -} -``` - -**Dépendances** : - -```toml -# crates/dev-forge-cli/Cargo.toml -[dependencies] -dev-forge-core = { path = "../dev-forge-core" } -anyhow = "1.0" -clap = { version = "4.5", features = ["derive"] } -clipboard = "0.5" -``` - -**Test immédiat** : - -```bash -cargo run --bin dev-forge fix-clipboard -``` - ---- - -### **Semaine 2 : Pattern detection qui marche** - -**Objectif** : Détecter 3-5 patterns courants que TU rencontres - -```rust -// crates/dev-forge-core/src/patterns/mod.rs -pub mod borrow_checker; - -use syn::File; - -pub trait Pattern { - fn detect(&self, code: &str) -> Option; - fn solutions(&self, match_: &PatternMatch) -> Vec; -} - -pub struct PatternMatch { - pub location: Location, - pub context: Context, -} - -// crates/dev-forge-core/src/patterns/borrow_checker.rs -pub struct ImmutableMutableConflict; - -impl Pattern for ImmutableMutableConflict { - fn detect(&self, code: &str) -> Option { - let syntax = syn::parse_str::(code).ok()?; - - // Détecte le pattern: - // let mut x = ...; - // let r = &x; - // x.push(...); - - // Pour l'instant: regex simple - if code.contains("let mut ") && - code.contains("&") && - code.contains(".push(") { - return Some(PatternMatch { - location: Location::default(), - context: Context::from_code(code), - }); - } - - None - } - - fn solutions(&self, match_: &PatternMatch) -> Vec { - vec![ - Solution { - description: "Clone the value".into(), - code: generate_clone_fix(match_), - confidence: 0.85, - }, - Solution { - description: "Use scope split".into(), - code: generate_scope_split(match_), - confidence: 0.95, - }, - ] - } -} - -fn generate_clone_fix(match_: &PatternMatch) -> String { - // Template-based generation - format!( - "let value = original[0]; // Clone instead of &original[0]" - ) -} - -fn generate_scope_split(match_: &PatternMatch) -> String { - format!( - r#"{{ - let reference = &data[0]; - // Use reference here -}} // reference dropped -data.push(4); // Now OK"# - ) -} -``` - -**Amélioration du CLI** : - -```rust -// Mode interactif pour voir le code avant/après -Commands::FixClipboard => { - let code = get_clipboard()?; - let solutions = analyze(&code)?; - - for (i, sol) in solutions.iter().enumerate() { - println!("\n{}. {} ({}%)", i+1, sol.description, - (sol.confidence * 100.0) as u32); - println!("\n--- Fixed code ---"); - println!("{}", sol.code); - println!("------------------"); - } - - // User picks -} -``` - ---- - -### **Semaine 3 : rust-analyzer integration (début)** - -**Objectif** : Voir tes fixes dans VS Code - -**Setup minimal** : - -```bash -# Fork rust-analyzer -cd .. -git clone https://github.com/rust-lang/rust-analyzer -cd rust-analyzer - -# Crée un lien vers ton dev-forge -# crates/rust-analyzer/Cargo.toml -[dependencies] -dev-forge-core = { path = "../../../dev-forge/crates/dev-forge-core" } -``` - -```rust -// crates/ide-assists/src/handlers/dev_forge.rs -use dev_forge_core::{analyze, Pattern}; -use ide_db::assists::{Assist, AssistContext, Assists}; - -pub fn register_dev_forge_assists(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { - let source = ctx.source_file().to_string(); - - // Utilise TON analyzer - let solutions = dev_forge_core::analyze(&source).ok()?; - - for solution in solutions { - acc.add( - AssistId("dev_forge.fix", AssistKind::QuickFix), - solution.description, - ctx.selection_range(), - |builder| { - builder.replace(ctx.selection_range(), solution.code); - } - ); - } - - Some(()) -} -``` - -**Build & test** : - -```bash -cd rust-analyzer -cargo build --release -cargo xtask install -``` - -**Maintenant dans VS Code** : Tes fixes apparaissent ! 🎉 - ---- - -## 🎯 Roadmap réaliste pour pas te noyer - -### **Phase 1 : MVP utilisable (Mois 1)** - -``` -Semaine 1: CLI clipboard tool - ├─ Detect 1 pattern (regex-based) - ├─ Generate 2 solutions (template) - └─ Interactive picker - -Semaine 2: Pattern detection - ├─ Parse AST avec syn - ├─ Detect 3-5 patterns courants - └─ Better code generation - -Semaine 3: rust-analyzer basic - ├─ Fork & integrate - ├─ 1 assist working - └─ Test in VS Code - -Semaine 4: Polish v0.1 - ├─ Tests - ├─ README - └─ Release -``` - -### **Phase 2 : Symbolic solver (Mois 2-3)** - -``` -Semaine 5-6: Constraint extraction - ├─ Extract borrow constraints from code - ├─ Lifetime constraints - └─ Type constraints - -Semaine 7-8: Constraint solver - ├─ Basic SAT solver - ├─ Constraint propagation - └─ Solution generation - -Semaine 9-10: Integration - ├─ Replace pattern matching with solver - ├─ Better ranking - └─ More patterns - -Semaine 11-12: Rules compiler - ├─ .toml → .bin - ├─ Rule engine - └─ v0.2 release -``` - ---- - -## 📦 Cargo.toml workspace complet - -```toml -[workspace] -members = [ - "crates/dev-forge-core", - "crates/dev-forge-cli", -] -resolver = "2" - -[workspace.package] -version = "0.1.0" -edition = "2021" -license = "MIT OR Apache-2.0" -authors = ["Ton Nom "] -repository = "https://github.com/TON-USERNAME/dev-forge" - -[workspace.dependencies] -# Core -anyhow = "1.0" -thiserror = "1.0" - -# Parsing -syn = { version = "2.0", features = ["full", "extra-traits"] } -quote = "1.0" -proc-macro2 = "1.0" - -# Serialization -serde = { version = "1.0", features = ["derive"] } -serde_json = "1.0" -bincode = "2.0" -toml = "0.8" - -# CLI -clap = { version = "4.5", features = ["derive"] } -clipboard = "0.5" -colored = "2.1" - -# Future: Constraint solving -# egg = "0.9" - -[profile.release] -opt-level = 3 -lto = true -codegen-units = 1 -``` - ---- - -## 🎬 Commandes pour démarrer MAINTENANT - -```bash -# 1. Crée la structure -mkdir -p dev-forge/crates -cd dev-forge - -# 2. Init workspace -cat > Cargo.toml << 'EOF' -[workspace] -members = [ - "crates/dev-forge-core", - "crates/dev-forge-cli", -] -resolver = "2" -EOF - -# 3. Crée les crates -cargo new --lib crates/dev-forge-core -cargo new --bin crates/dev-forge-cli - -# 4. Setup dependencies -cd crates/dev-forge-cli -cargo add anyhow clap --features clap/derive -cargo add clipboard -cargo add dev-forge-core --path ../dev-forge-core - -# 5. Code le MVP (copie le code de "Semaine 1" ci-dessus) - -# 6. Test -cargo run -- fix-clipboard -``` - ---- - -## 🎯 Checklist "pas te noyer" - -### **Pour rester focus** : - -- [ ] ✅ **Semaine 1** : CLI qui marche avec clipboard -- [ ] ✅ **Utilise ton outil** : Dogfood pendant que tu codes -- [ ] ⚠️ **NE PAS** : Coder un solver complexe tout de suite -- [ ] ⚠️ **NE PAS** : Vouloir tout implémenter d'un coup -- [ ] ✅ **Itère** : 1 pattern → test → améliore → next pattern - -### **Pour automatiser TON workflow** : - -```bash -# Script helper personnel -# dev-forge/scripts/dev.sh -#!/bin/bash - -# Watch & rebuild -cargo watch -x 'build --release' -x 'install --path crates/dev-forge-cli' - -# Maintenant tu as toujours la dernière version installée -``` - ---- - -## 💡 Tips anti-noyade - -### **1. Commence par le plus simple** - -```rust -// ❌ NE COMMENCE PAS par: -struct SymbolicSolver { - constraints: Vec, - sat_solver: SATSolver, - unification_table: UnificationTable, -} - -// ✅ COMMENCE par: -fn detect_simple_pattern(code: &str) -> bool { - code.contains("cannot borrow") && code.contains("mutable") -} -``` - -### **2. Hardcode au début** - -```rust -// ✅ C'est OK pour v0.1: -fn generate_fix(pattern: &str) -> String { - match pattern { - "immut_mut_conflict" => { - "let value = original.clone(); // Instead of &original".into() - } - _ => "// No fix available".into() - } -} - -// ⏳ Plus tard (v0.3): -// Template engine, constraint solver, etc. -``` - -### **3. Test sur TES propres erreurs** - -Crée un fichier `test-cases/` avec **tes vraies erreurs** : - -```rust -// test-cases/borrow-01.rs -fn example() { - let mut data = vec![1, 2, 3]; - let reference = &data[0]; - data.push(4); // ❌ Ton erreur réelle - println!("{}", reference); -} -``` - -```bash -dev-forge fix test-cases/borrow-01.rs -# Teste sur ton cas réel ! -``` - ---- - -## 🏆 Objectif Semaine 1 (ultra-concret) - -**Vendredi soir, tu dois pouvoir faire** : - -```bash -# 1. Tu codes dans dev-forge -# 2. Erreur borrow checker apparaît -# 3. Tu copies l'erreur (Ctrl+C) -# 4. Tu runs: -dev-forge fix-clipboard - -# 5. Output: -# 🔍 Found 2 solutions: -# -# 1. Clone the value (85%) -# 2. Split into scopes (95%) -# -# Choose solution (1-2): 2 -# -# ✅ Solution copied to clipboard! - -# 6. Tu colles (Ctrl+V) le fix dans ton code -# 7. Ça compile ! 🎉 -``` - -**Si tu arrives à ça → SUCCESS** ✅ - -Pas besoin de solver complexe, de rules.bin, de rust-analyzer integration. - -**Just something that helps you NOW.** - ---- - -**Prêt à commencer ? On code le MVP clipboard tool ensemble ?** 🚀