गो प्रोजेक्ट को लेआउट करने का एक समझदार तरीका है [बंद]


113

मेरे पास एक गो परियोजना है जो अधिक जटिल होने लगी है, और दर्द को कम करने के लिए इस तरह से फाइलसिस्टम को बाहर रखना चाहते हैं।

वहाँ कुछ अच्छे उदाहरण हैं जो समझ में आता है?

जवाबों:


132

मई 2013 को अपडेट करें: आधिकारिक दस्तावेज " कोड संगठन " अनुभाग में है

एक कार्यक्षेत्र के अंदर गो कोड रखना होगा ।
एक कार्यक्षेत्र एक निर्देशिका पदानुक्रम है जिसकी जड़ में तीन निर्देशिकाएं हैं:

  • src पैकेजों में संगठित गो स्रोत फाइलें शामिल हैं (प्रति निर्देशिका एक पैकेज),
  • pkg इसमें पैकेज ऑब्जेक्ट्स और हैं
  • bin निष्पादन योग्य आदेश शामिल हैं।

go toolस्रोत संकुल बनाता है और जिसके परिणामस्वरूप बाइनरी स्थापित करता है pkgऔर binनिर्देशिका।

srcउप-निर्देशिका आम तौर पर (जैसे Git या मर्क्युरियल के लिए) अनेक संस्करण नियंत्रण खजाने कि एक या अधिक स्रोत संकुल के विकास पर नज़र शामिल हैं।

bin/
    streak                         # command executable
    todo                           # command executable
pkg/
    linux_amd64/
        code.google.com/p/goauth2/
            oauth.a                # package object
        github.com/nf/todo/
            task.a                 # package object
src/
    code.google.com/p/goauth2/
        .hg/                       # mercurial repository metadata
        oauth/
            oauth.go               # package source
            oauth_test.go          # test source

अद्यतन जुलाई 2014: बेन जॉनसन से " गो में स्ट्रक्चुरिंग एप्लिकेशन " देखें

उस लेख में इस तरह के सुझाव शामिल हैं:

अपने आवेदन से अपने बाइनरी को अलग करें

main.goएक ही पैकेज में फ़ाइल और मेरे एप्लिकेशन तर्क के संयोजन के दो परिणाम हैं:

  • यह मेरे आवेदन को एक पुस्तकालय के रूप में अनुपयोगी बनाता है।
  • मेरे पास केवल एक आवेदन बाइनरी हो सकता है।

मुझे इसे ठीक करने के लिए सबसे अच्छा तरीका यह है कि cmdमैं अपनी परियोजना में केवल एक " " निर्देशिका का उपयोग करूं जहां इसकी प्रत्येक उपनिर्देशिका एक एप्लिकेशन बाइनरी है।

camlistore/
  cmd/
    camget/
      main.go
    cammount/
      main.go
    camput/
      main.go
    camtool/
      main.go

पुस्तकालय संचालित विकास

main.goअपनी जड़ से फ़ाइल को स्थानांतरित करने से आप अपने आवेदन को एक पुस्तकालय के परिप्रेक्ष्य से बना सकते हैं। आपका एप्लिकेशन बाइनरी आपके एप्लिकेशन की लाइब्रेरी का एक क्लाइंट है।

कभी-कभी आप चाहते हैं कि उपयोगकर्ता कई तरीकों से बातचीत कर सकें ताकि आप कई बायनेरिज़ बना सकें।
उदाहरण के लिए, यदि आपके पास एक " adder" पैकेज है जो उपयोगकर्ताओं को एक साथ संख्या जोड़ने देता है, तो आप कमांड लाइन संस्करण के साथ-साथ एक वेब संस्करण भी जारी करना चाह सकते हैं।
आप अपनी परियोजना को इस तरह व्यवस्थित करके आसानी से कर सकते हैं:

adder/
  adder.go
  cmd/
    adder/
      main.go
    adder-server/
      main.go

उपयोगकर्ता आपके "योजक" एप्लिकेशन बायनेरिज़ को एक दीर्घवृत्त का उपयोग करके "गो गेट" के साथ स्थापित कर सकते हैं:

$ go get github.com/benbjohnson/adder/...

और वोइला, आपके उपयोगकर्ता के पास " adder" और " adder-server" स्थापित है!

सबपैकेज के साथ पागल मत हो

आमतौर पर मेरी परियोजना के प्रकार सभी बहुत संबंधित हैं इसलिए यह प्रयोज्य और एपीआई दृष्टिकोण से बेहतर है।
ये प्रकार उन दोनों के बीच अनएक्सपोर्टेड कॉलिंग का भी लाभ उठा सकते हैं जो एपीआई को छोटा और स्पष्ट बनाए रखते हैं।

  1. समूह से संबंधित प्रकार और कोड प्रत्येक फ़ाइल में एक साथ। यदि आपके प्रकार और कार्य अच्छी तरह से व्यवस्थित हैं, तो मुझे लगता है कि फाइलें 200 और 500 एसएलओसी के बीच होती हैं। यह बहुत अच्छा लग सकता है, लेकिन मुझे नेविगेट करना आसान लगता है। 1000 SLOC आमतौर पर किसी एक फाइल के लिए मेरी ऊपरी सीमा है।
  2. फ़ाइल के शीर्ष पर सबसे महत्वपूर्ण प्रकार को व्यवस्थित करें और फ़ाइल के नीचे की ओर बढ़ते हुए महत्व में प्रकार जोड़ें।
  3. एक बार जब आपका आवेदन 10,000 SLOC से ऊपर होने लगता है, तो आपको गंभीरता से मूल्यांकन करना चाहिए कि क्या इसे छोटी परियोजनाओं में तोड़ा जा सकता है।

नोट: वह अंतिम अभ्यास हमेशा अच्छा नहीं होता है:

क्षमा करें, मैं अभी इस अभ्यास से सहमत नहीं हूँ।
फ़ाइलों को अलग करने से कोड प्रबंधन, पठनीयता, मुख्य योग्यता, परीक्षण क्षमता में मदद मिलती है।
यह एकल जिम्मेदारी और खुले / बंद सिद्धांत का पालन भी सुनिश्चित कर सकता है ...
परिपत्र निर्भरता की अनुमति नहीं देने का नियम यह है कि हमारे पास संकुल की स्पष्ट संरचना है।


(वैकल्पिक फरवरी 2013, srcकेवल के बारे में )
आप " गिटहब कोड लेआउट " में चित्रित क्लासिक लेआउट पा सकते हैं।

एप्लिकेशन और दोनों पुस्तकालयों Github पर रहते हैं, प्रत्येक अपने स्वयं के भंडार में।
$GOPATHपरियोजना की जड़ है - आपके प्रत्येक Github repos को नीचे कई फ़ोल्डर्स की जाँच की जाएगी $GOPATH

आपका कोड लेआउट इस तरह दिखेगा:

$GOPATH/
    src/
        github.com/
            jmcvetta/
                useless/
                    .git/
                    useless.go
                    useless_test.go
                    README.md
                uselessd/
                    .git/
                    uselessd.go
                    uselessd_test.go
                    README.md

के तहत प्रत्येक फ़ोल्डर src/github.com/jmcvetta/एक अलग गिट चेकआउट की जड़ है।

हालांकि इस लाल पृष्ठ में कुछ आलोचनाओं को आकर्षित किया गया है :

मैं अत्यधिक सलाह देता हूं कि आप जिस तरह से हैं, उस रेपो को संरचित न करें, यह " go get" टूट जाएगा , जो कि गो के बारे में सबसे उपयोगी चीजों में से एक है।
उन लोगों के लिए अपना कोड लिखना बेहतर है, जो गो को जानते हैं, क्योंकि वे सबसे अधिक संभावना रखते हैं कि वे इसे संकलित करें।
और जो लोग नहीं करते हैं, वे कम से कम भाषा के लिए एक महसूस करेंगे।

रेपो की जड़ में मुख्य पैकेज रखो।
एक उपनिर्देशिका में संपत्ति रखें (चीजों को साफ रखने के लिए)।
कोड के मांस को एक सबपैकेज में रखें (यदि कोई आपके बाइनरी के बाहर इसका पुन: उपयोग करना चाहता है)।
रेपो की जड़ में एक सेटअप स्क्रिप्ट शामिल करें ताकि इसे ढूंढना आसान हो।

यह अभी भी डाउनलोड करने, बनाने, स्थापित करने और सेटअप करने के लिए केवल दो चरण की प्रक्रिया है।

  • " go get <your repo path>": परिसंपत्तियों के लिए एक उप-संस्करण के साथ, गो कोड डाउनलोड और इंस्टॉल करता है
  • $GOPATH/<your repo path>/setup.sh: संपत्ति को सही स्थान पर वितरित करता है और सेवा स्थापित करता है

15
इसके साथ एक (बड़ी) समस्या setup.shयह है कि गो यथोचित रूप से क्रॉस-प्लेटफॉर्म है जबकि पोसिक्स शेल स्क्रिप्ट नहीं हैं।
कोस्टिक्स

Jmcvetta संरचना बेकार नहीं जाएगी , क्योंकि बेकार बेकार आयात करता है, जाओ जाओ दोनों जाओ जाओ के साथ स्थापित करेगा ... / बेकार। लेकिन मैं मानता हूं कि अगर बेकार एक पुस्तकालय विशेष रूप से बेकार के लिए बनाया गया है, तो इसे एक सब git रेपो में एक सबफ़ोल्डर या भाई-बहन के रूप में रखने के लिए अधिक समझ में आता है।
mna

@PuerkitoBio मैं सहमत हूँ। संस्करण नियंत्रण और घटक-आधारित प्रबंधन ( stackoverflow.com/a/933735/6309 ) में मेरा प्रशिक्षण मुझे रेपो प्रति एक घटक की ओर ले जाता है, इसलिए इस उत्तर का दूसरा भाग।
वॉन

7

मैं मानता हूं कि 'प्रोजेक्ट' से आपका मतलब गो पैकेज नहीं है, बल्कि आपके द्वारा विकसित सॉफ्टवेयर है। अन्यथा आप यहां और यहां मदद ले सकते हैं । हालाँकि यह गो के लिए पैकेज लिखने के लिए इतना अलग नहीं है: पैकेज का उपयोग करें, प्रत्येक पैकेज के लिए एक फ़ोल्डर बनाएं और उन पैकेजों को अपने आवेदन में संयोजित करें।

अपने आप को एक राय बनाने के लिए, आप github पर गो रिपॉजिटरी को ट्रेंडिंग में देख सकते हैं: https://github.com/trending/go । उल्लेखनीय उदाहरण सेले और ज़ीउस हैं

सबसे लोकप्रिय योजना शायद एक मुख्य गो फ़ाइल और कई मॉड्यूल और सबमॉड्यूल की अपनी निर्देशिकाओं में होना है। यदि आपके पास कई मेटा फाइलें (डॉक्टर, लाइसेंस, टेम्प्लेट, ...) हैं, तो आप स्रोत कोड को एक उपनिर्देशिका में रखना चाह सकते हैं। यही मैंने अब तक किया है।


@aussiegeek, मैं एक गो विशेषज्ञ नहीं हूं, लेकिन मैंने सफलतापूर्वक अपने ही कोड में प्रस्तावित नीमो को लागू किया - विचार यह है कि आपके पास अपनी परियोजना निर्देशिका के तहत मॉड्यूल हो सकते हैं , आपको बस उनके पूर्ण उपसर्ग का उपयोग करके उन्हें संदर्भित करना होगा - रिश्तेदार करने के लिए $GOPATH/srcया उनके उपयोग करते हुए go get-table नाम।
कोस्टिक्स

doozerdएक अच्छा उदाहरण नहीं है, यहां तक ​​कि इसके परीक्षण भी कमजोर हैं।
इनक गमस

@InancGumus मैं आपको बेहतर उदाहरण सुझाने के लिए प्रोत्साहित करता हूं।
नीमो

यह और यह देखें ।
इनक गमस

1

गोलांग के लेखकों से एक अनुशंसित दृष्टिकोण है जो यह बताता है कि अपने टूल को गो टूल्स के साथ सबसे अच्छा काम करने और सोर्स प्रोडक्ट्स को सपोर्ट करने के लिए अपने कोड को कैसे परिभाषित करें।


1
यह है कि लेआउट के लिए कैसे $GOROOT, src/<project>निर्देशिका के भीतर कोड नहीं ।
docwhat

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.