मुख्य सामग्री पर जाएँ

अलग रिपॉज़िटरी में ऐप और साझा लाइब्रेरी

यह पृष्ठ अंग्रेज़ी से अनुवादित है। अंग्रेज़ी पृष्ठ पढ़ें

Zeyn एक ही रिपॉज़िटरी में काम करता है, लेकिन कई टीमें हर ऐप को अपनी रिपॉज़िटरी में रखती हैं और साझा कोड (entity, सेवाएँ, पूरी feature) को ऐसी लाइब्रेरी में डालती हैं जिन्हें कई ऐप इस्तेमाल करते हैं। यह गाइड दिखाती है कि इसे कैसे सेट करें, और वह एक नियम जो इसे चलता रखता है।

क्या कहाँ जाता है

रिपॉज़िटरीकिससे बनीक्या रखती है
ऐपzeyn new billingmain.rs, app.rs, ऐप की feature, कॉन्फ़िग, ऐप के कैटलॉग
साझा लाइब्रेरीzeyn new acme-domain --libentity, सेवाएँ, feature, उनके कैटलॉग, CATALOGS

लाइब्रेरी की feature ऐप की feature जैसी ही है: मॉडल, action, Screen, अनुमतियाँ और अनुवाद एक फ़ोल्डर में साथ रहते हैं। ऐप तय करता है कि वह लाइब्रेरी की कौन सी feature माउंट करता है।

let i18n = I18n::new("en")
    .catalogs(acme_domain::CATALOGS)?
    .catalog("en", include_str!("../locales/en.json"))?
    .catalog("tr", include_str!("../locales/tr.json"))?;

App::new(t!("app.name"))
    .i18n(i18n)
    .service(acme_domain::customers::CustomerStore::default())
    .feature(acme_domain::customers::feature())

लाइब्रेरी कैटलॉग पहले लोड होते हैं, इसलिए ऐप वही कुंजी परिभाषित करके लाइब्रेरी की स्ट्रिंग ओवरराइड कर सकता है। लाइब्रेरी कुंजियों के आगे feature का नाम लगाएँ (customers.list) ताकि दो लाइब्रेरी कभी न टकराएँ।

examples/shared-domain ऐसी ही एक लाइब्रेरी है। examples/billing और examples/crm दोनों उसकी customers feature माउंट करते हैं; crm अपने कैटलॉग में "Customers" का नाम "Accounts" कर देता है।

लाइब्रेरी को क्या अपने पास रखना होगा

Rust का orphan नियम कहता है कि trait केवल उसी crate में लागू हो सकता है जो trait या टाइप को परिभाषित करता है। ऐप लाइब्रेरी के टाइप के लिए zeyn::Model या zeyn::Entity लागू नहीं कर सकता, इसलिए:

  • #[entity], #[model] और #[choice] को लाइब्रेरी में टाइप पर उसके नियमों के पास रखें।
  • सत्यापन नियम (#[rule(...)]) साझा टाइप पर रखें। तब हर ऐप एक ही तरह सत्यापित करता है।
  • जिस ऐप को अतिरिक्त व्यवहार चाहिए वह टाइप को लपेटता है (struct Invoice { customer: Customer, ... }) या अपना trait जोड़ता है। वह लाइब्रेरी का टाइप संपादित नहीं करता।

ऐप को लाइब्रेरी कैसे मिलती है

विकल्पअच्छाध्यान रखें
टैग के साथ Git निर्भरताकुछ चलाना नहीं, किसी भी Git सर्वर के साथ काम करता हैCargo पूरी रिपॉज़िटरी लाता है; हर ऐप URL सूचीबद्ध करता है
निजी Cargo रजिस्ट्री (Kellnr, GitLab package registry, अन्य)सामान्य version = "0.3" निर्भरताएँ, semver समाधानचलाने, बैकअप लेने और सुरक्षित करने के लिए एक सेवा
सबके लिए एक वर्कस्पेस रिपॉज़िटरीएक बिल्ड, एक Cargo.lock, एक कमिट में रीफ़ैक्टरहर टीम हर ऐप देखती है; एक्सेस नियंत्रण प्रति रिपॉज़िटरी है, प्रति फ़ोल्डर नहीं

Git टैग से शुरू करें। जब मुट्ठी भर से अधिक लाइब्रेरी हों या हाथ से संस्करण समाधान उबाऊ हो जाए तो रजिस्ट्री पर जाएँ। ऐप कोड नहीं बदलता; केवल Cargo.toml की पंक्तियाँ बदलती हैं।

[dependencies]
zeyn = { git = "https://git.example.com/platform/zeyn.git", tag = "v0.0.2" }
acme-domain = { git = "https://git.example.com/shared/acme-domain.git", tag = "v0.3.0" }

zeyn new डिफ़ॉल्ट रूप से zeyn = "<version>" लिखता है। जब तक Zeyn प्रकाशित नहीं होता, हर नए ऐप और लाइब्रेरी में उस पंक्ति को ऊपर के Git रूप में बदलें।

नियम: हर जगह एक Zeyn संस्करण

हर लाइब्रेरी और हर ऐप को ठीक एक ही Zeyn पर निर्भर होना चाहिए। Git निर्भरताओं के साथ इसका अर्थ है वही URL और वही टैग।

Cargo दो अलग Zeyn स्रोतों को दो अलग crate मानता है। टैग v0.0.2 के विरुद्ध बनी लाइब्रेरी ऐसी zeyn::Feature लौटाती है जिसे v0.0.3 के विरुद्ध बना ऐप स्वीकार नहीं कर सकता, और कंपाइलर एक ही नाम वाली दो चीज़ों के बीच टाइप बेमेल बताता है। रजिस्ट्री इसे "वही semver संगत संस्करण" तक ढीला करती है, लेकिन नियम रहता है: प्रति बिल्ड एक Zeyn।

Zeyn अपग्रेड करने के लिए:

  1. हर लाइब्रेरी में टैग अपडेट करें, उसके टेस्ट चलाएँ, नया लाइब्रेरी टैग जारी करें।
  2. हर ऐप में Zeyn और लाइब्रेरी टैग साथ में, एक कमिट में, अपडेट करें।

cargo tree -d -i zeyn डुप्लिकेट सूचीबद्ध करता है। यदि यह एक से अधिक Zeyn छापे, तो कोई निर्भरता अब भी पुराने टैग की ओर इशारा करती है।

चरण दर चरण

  1. लाइब्रेरी बनाएँ और उसे उसकी अपनी रिपॉज़िटरी में पुश करें।
   zeyn new acme-domain --lib
   cd acme-domain
   cargo test
   git init && git add . && git commit -m "First version"
   git tag v0.1.0 && git push origin main --tags
  1. इसे ऐप के Cargo.toml में टैग के साथ जोड़ें, और इसके कैटलॉग, सेवाएँ और feature ऊपर दिखाए अनुसार माउंट करें।
  2. ऐप के CI को लाइब्रेरी पढ़ने दें। जनरेट की गई .gitlab-ci.yml https://<gitlab host>/ और ssh://git@<gitlab host>/ URL को जॉब टोकन इस्तेमाल करने के लिए फिर से लिखती है। GitLab में लाइब्रेरी प्रोजेक्ट खोलें, फिर CI/CD सेटिंग, Job token permissions, और ऐप प्रोजेक्ट को allowlist में जोड़ें।
  3. ऐप टेस्ट में app.check() चलाएँ (जनरेट की गई tests/app.rs यही करती है)। जब माउंट की गई feature में संरचनात्मक समस्याएँ हों, जैसे अनुवाद कुंजी जो किसी भाषा में छूटी हो, यह विफल होता है।

लाइब्रेरी और ऐप पर एक साथ काम करना

Cargo.toml संपादित किए बिना ऐप को अपने स्थानीय चेकआउट की ओर इंगित करें। इसे ऐप की .cargo/config.toml में रखें और उस फ़ाइल को Git से बाहर रखें:

[patch."https://git.example.com/shared/acme-domain.git"]
acme-domain = { path = "../acme-domain" }

बदलाव पूरा होने पर इसे हटाएँ, लाइब्रेरी को टैग करें और ऐप में टैग बढ़ाएँ।

लाइब्रेरी जारी करना

  1. Cargo.toml में version बढ़ाएँ।
  2. यदि cargo semver-checks इंस्टॉल है तो उसे चलाएँ। यह सार्वजनिक API बदलाव बताता है जो कॉलर को तोड़ते हैं। जब तक लाइब्रेरी 1.0 से नीचे है, तोड़ने वाले बदलाव को नया minor संस्करण चाहिए।
  3. कमिट करें, v<version> टैग करें, टैग पुश करें। जब टैग और Cargo.toml असहमत हों तो CI जॉब tag-matches-version विफल होता है।