لماذا سير عمل Git هو المنقذ لمشروع Rust (ولصحتك النفسية)
\n\nهل سبق لك أن حاولت التراجع عن commit "مكسور" في مشروع Rust، والذي أثر بالخطأ على src/main.rs وCargo.toml وثلاث وحدات أخرى؟ مألوف؟ إذا كان الأمر كذلك، فأنت بالتأكيد لست وحدك. تشتهر Rust بصرامتها، ولكن بدون سير عمل Git منظم، حتى أفضل كود يتحول إلى فوضى.
في هذه المقالة، سأوضح لك كيفية بناء سير عمل باستخدام Git سيوفر لك ساعات من التصحيح والأعصاب. سنستعرض أمثلة حقيقية على Rust، ونتحدث عن CI/CD ومراجعة الكود، وكيف لا تفقد ماء وجهك أمام زملائك. هيا بنا!
\n\nأساسيات سير عمل Git لمطوري Rust: من أين تبدأ
\n\nقبل الغوص في التفاصيل، دعنا نحدد الأساسيات. لمشاريع Rust، أوصي باستخدام GitHub Flow أو Git Flow - حسب حجم الفريق. لكن هناك خصوصية واحدة: Rust تتطلب كتابة صارمة واختبارات، لذلك يجب أن يكون سير عملك مخصصًا لـ cargo test و cargo clippy.
هيكل الفروع لمشاريع Rust
\n\nإليك الحد الأدنى من الفروع التي أستخدمها في مشاريعي:
\n\n- \n
main- إصدار مستقر، جاهز دائمًا للنشر \n develop- فرع تكامل للميزات الجديدة \n feature/اسم-الميزة- كل ميزة جديدة معزولة \n hotfix/الاسم- للإصلاحات العاجلة \n
لماذا هذا مهم لـ Rust؟ لأن cargo check و cargo build يمكن أن يكشفا عن تعارضات في التبعيات، والتي يسهل حلها في فرع معزول بدلاً من فرع مشترك.
مثال: إنشاء فرع ميزة لوظيفة جديدة
\n\nلنفترض أنك تكتب محلل JSON بلغة Rust. تبدأ من الفرع main:
git checkout main\ngit pull origin main\ngit checkout -b feature/json-parser\n\nالآن تكتب الكود. إليك مثال بسيط لدالة تضيفها إلى src/parser.rs:
use serde_json::Value;\n\npub fn parse_json(input: &str) -> Result<Value, String> {\n serde_json::from_str(input).map_err(|e| e.to_string())\n}\n\nقبل عمل commit، تأكد من تشغيل الاختبارات:
\n\ncargo test\ncargo clippy -- -D warnings\n\nإذا كان كل شيء على ما يرام - قم بعمل commit:
\n\ngit add src/parser.rs Cargo.toml\ngit commit -m "feat: إضافة محلل JSON أساسي مع معالجة الأخطاء"\n\nلاحظ تنسيق الـ commit: feat: - هذا جزء من Conventional Commits، والتي تعمل بشكل رائع مع مشاريع Rust، خاصة إذا كنت تستخدم سجل التغييرات التلقائي.
CI/CD لمشاريع Rust: الفحص التلقائي للكود
\n\nبدون CI، سير عمل Git الخاص بك هو مجرد مجموعة من الفروع. بالنسبة لـ Rust، أوصي بشدة بإضافة ملف .github/workflows/ci.yml إلى جذر المشروع (إذا كنت تستخدم GitHub):
name: Rust CI\n\non:\n push:\n branches: [ "main", "develop" ]\n pull_request:\n branches: [ "main" ]\n\nenv:\n CARGO_TERM_COLOR: always\n\njobs:\n build:\n runs-on: ubuntu-latest\n\n steps:\n - uses: actions/checkout@v3\n - name: Build\n run: cargo build --verbose\n - name: Run tests\n run: cargo test --verbose\n - name: Lint\n run: cargo clippy -- -D warnings\n - name: Format check\n run: cargo fmt -- --check\n\nالآن، كل push إلى main أو develop سيشغل عملية البناء والاختبارات والفحص. إذا فشل CI، فلن يتم دمج الـ commit. هذه حماية حديدية من عبارة "إنه يعمل على جهازي".
لماذا سينقذ هذا مشروعك
\n\nتخيل: لقد نسيت تحديث Cargo.lock بعد إضافة تبعية جديدة. سيلاحظ CI ذلك فورًا - cargo build سيعطي خطأ. أو استخدمت unwrap() عن طريق الخطأ في كود الإنتاج - سيكتشفه clippy مع العلم -D warnings.