परिचय
मोनोरेपॉजिटरी (monorepo) स्रोत कोड प्रबंधन का एक दृष्टिकोण है, जिसमें कई प्रोजेक्ट्स (लाइब्रेरी, एप्लिकेशन, सेवाएँ) एक ही रिपॉजिटरी में संग्रहीत होते हैं। Rust पारिस्थितिकी तंत्र में, इस दृष्टिकोण को Cargo Workspace तंत्र के माध्यम से शक्तिशाली समर्थन प्राप्त है। इस लेख में, हम Rust पर मोनोरेपॉजिटरी को प्रभावी ढंग से व्यवस्थित करने का तरीका समझेंगे, संरचना, निर्भरता प्रबंधन और सर्वोत्तम अभ्यासों पर विचार करेंगे।
Rust प्रोजेक्ट्स के लिए मोनोरेपॉजिटरी क्यों उपयोगी है? यह अनुमति देता है:
- कई क्रेट्स (लाइब्रेरी और बाइनरी) के बीच कोड का पुन: उपयोग।
- संस्करण और CI/CD को सरल बनाना।
- परिवर्तनों की परमाणुता सुनिश्चित करना (एक कमिट कई क्रेट्स को अपडेट कर सकता है)।
- निर्भरता प्रबंधन की जटिलता को कम करना।
Cargo Workspace की मूल बातें
Cargo Workspace मोनोरेपॉजिटरी प्रबंधन के लिए Rust का अंतर्निहित तंत्र है। यह एक सामान्य शीर्ष-स्तरीय Cargo.toml फ़ाइल के अंतर्गत कई क्रेट्स (crates) को एकीकृत करता है।
Workspace बनाना
आरंभ करने के लिए, एक प्रोजेक्ट निर्देशिका और रूट में Cargo.toml फ़ाइल बनाएँ:
# Cargo.toml (रूट)[workspace]members = [ "core", "cli", "web-api", "utils"]
[workspace.dependencies]serde = { version = "1.0", features = ["derive"] }tokio = { version = "1.37", features = ["full"] }यहाँ हमने चार क्रेट्स परिभाषित किए हैं: core, cli, web-api और utils। मुख्य बिंदु [workspace.dependencies] है। यह workspace के सभी क्रेट्स के लिए सामान्य निर्भरताएँ सेट करने की अनुमति देता है। प्रत्येक क्रेट संस्करणों को दोहराए बिना उन्हें संदर्भित कर सकता है।
निर्देशिका संरचना
Rust पर मोनोरेपॉजिटरी की विशिष्ट संरचना इस प्रकार दिखती है:
my-monorepo/├── Cargo.toml # रूट workspace├── Cargo.lock # सामान्य lock फ़ाइल├── core/│ ├── Cargo.toml│ └── src/│ └── lib.rs├── cli/│ ├── Cargo.toml│ └── src/│ └── main.rs├── web-api/│ ├── Cargo.toml│ └── src/│ └── main.rs├── utils/│ ├── Cargo.toml│ └── src/│ └── lib.rs└── README.mdप्रत्येक उपनिर्देशिका अपने स्वयं के Cargo.toml के साथ एक अलग क्रेट है। क्रेट्स लाइब्रेरी (lib.rs) या निष्पादन योग्य एप्लिकेशन (main.rs) दोनों हो सकते हैं।
निर्भरता प्रबंधन और कोड पुन: उपयोग
आंतरिक निर्भरताएँ
Workspace के अंदर क्रेट्स स्थानीय पथों के माध्यम से एक-दूसरे को संदर्भित कर सकते हैं। उदाहरण के लिए, cli core और utils पर निर्भर हो सकता है:
# cli/Cargo.toml[package]name = "cli"version = "0.1.0"edition = "2021"
[dependencies]core = { path = "../core" }utils = { path = "../utils" }serde = { workspace = true }tokio = { workspace = true }सिंटैक्स { workspace = true } पर ध्यान दें - यह रूट Cargo.toml में घोषित सामान्य निर्भरताओं का उपयोग करने की अनुमति देता है। यह सुनिश्चित करता है कि सभी क्रेट्स लाइब्रेरी के एक ही संस्करण का उपयोग करें।
उदाहरण: सामान्य लाइब्रेरी core
एक सरल लाइब्रेरी core बनाएँ जिसमें व्यावसायिक तर्क होगा:
// core/src/lib.rsuse serde::{Serialize, Deserialize};
#[derive(Debug, Clone, Serialize, Deserialize)]pub struct User { pub id: u64, pub name: String, pub email: String,}
pub fn create_user(name: String, email: String) -> User { User { id: rand::random(), name, email, }}
pub fn greet(user: &User) -> String { format!("Hello, {}!", user.name)}अब क्रेट cli इस लाइब्रेरी का उपयोग कर सकता है:
// cli/src/main.rsuse core::{create_user, greet};
fn main() { let user = create