গোপথ ছাড়াই কীভাবে স্থানীয় প্যাকেজ আমদানি করা যায়


171

আমি ব্যবহার করেছি GOPATHতবে এই বর্তমান সমস্যার জন্য আমি এটির মুখোমুখি হচ্ছি না। আমি কোনও প্রকল্পের জন্য নির্দিষ্ট প্যাকেজগুলি তৈরি করতে সক্ষম হতে চাই:

myproject/
├── binary1.go
├── binary2.go
├── package1.go
└── package2.go

আমি একাধিক উপায়ে চেষ্টা করেছিলেন কিন্তু আমি কিভাবে পাবো? package1.goকাজ করার binary1.goবা binary2.goএবং তাই?

উদাহরণ স্বরূপ; আমি সক্ষম হতে চাই import "package1"এবং তারপরে চালাতে সক্ষম হয়েছি go build binary1.goএবং ত্রুটি না ফেলে সমস্ত কিছু ঠিকঠাক কাজ করে যা প্যাকেজটিতে পাওয়া যায় না GOROOTবা পাওয়া যায় না GOPATH। আমার এই ধরণের কার্যকারিতাটির কারণ বড় আকারের প্রকল্পগুলির জন্য; আমি একাধিক অন্যান্য প্যাকেজগুলি রেফারেন্স করতে বা এটিকে একটি বড় ফাইলে রাখতে চাই না।


2
আপনি প্রতিটি বাইনারি এর নিজস্ব ফাইলগুলি নিজস্ব ডিরেক্টরিতে রেখে দেওয়ার কথা supposed
ফুজ

.goএকটি একক ডিরেক্টরিতে থাকা সমস্ত ফাইলই একই প্যাকেজের অংশ এবং আপনার importএকই প্যাকেজটিতে (যেমন, একই ডিরেক্টরি) ফাইল করার দরকার নেই । আপনি গোপথের বাইরে কাজ করার কথা উল্লেখ করেছেন যা নতুন গো মডিউল সিস্টেমের অন্যতম ক্ষমতা capabilities এই উত্তরে মডিউল কাঠামো, স্থানীয় প্যাকেজগুলি আমদানি করা, মডিউলটির মধ্যে প্যাকেজগুলি সাজানো, একক সংগ্রহস্থলে একাধিক মডিউল থাকবে কি না ইত্যাদি ইত্যাদির অন্তর্ভুক্ত রয়েছে
182

3
এবং এই আচরণ সবার সাথে ঠিক আছে? আপনি পুরো git/repo/to/my/projectপথটি নির্দিষ্ট না করে আপনি মূলত আপনার স্থানীয় সাব-প্যাকেজগুলি আমদানি করতে পারবেন না ? আমি কেন এই আচরণটি চাইবে তা কারণ দেখছি না। যদি আপনি আপনার প্রকল্পটি অন্য কোনও স্থানে (অর্থাত্ ডকার চিত্র) এ সরিয়ে নিয়ে যান, তবে আপনাকে আবার সমস্ত পাথ পরিবর্তন করতে হবে? আমি কেন এটি এত জটিল তা উত্তর খুঁজছি।
milosmns

@milosmns আমার উত্তর দেখুন stackoverflow.com/a/60915633/175071
টিমো Huovinen

উত্তর:


176

নির্ভরতা পরিচালনার সারসংক্ষেপ যান:

  • vgo যদি আপনার গো সংস্করণটি হয়: x >= go 1.11
  • depবা vendorযদি আপনার গো সংস্করণটি হয়:go 1.6 >= x < go 1.11
  • আপনার গো সংস্করণটি যদি ম্যানুয়ালি হয়: x < go 1.6

সম্পাদনা 3: যান 1.11 এর একটি বৈশিষ্ট্য রয়েছে vgoযা প্রতিস্থাপন করবে dep

ব্যবহার করতে vgo, মডিউল ডকুমেন্টেশন দেখুন। টিএলডিআর নীচে:

export GO111MODULE=on
go mod init
go mod vendor # if you have vendor/ folder, will automatically integrate
go build

এই পদ্ধতিটি go.modআপনার প্রকল্প ডিরেক্টরিতে ডাকা একটি ফাইল তৈরি করে । তারপরে আপনি আপনার প্রকল্পটি তৈরি করতে পারেন go build। যদি GO111MODULE=autoসেট করা থাকে, তবে আপনার প্রকল্পটি এতে থাকতে পারে না $GOPATH


সম্পাদনা 2: বিক্রেতার পদ্ধতিটি এখনও বৈধ এবং ইস্যু ছাড়াই কাজ করে। vendorমূলত একটি ম্যানুয়াল প্রক্রিয়া, এই কারণে হয় depএবং vgoতৈরি করা হয়েছিল।


সম্পাদনা 1: আমার পুরানো পথটি কাজ করার সময় এটি করার জন্য এটি আর "সঠিক" উপায় নয়। আপনার বিক্রেতার ক্ষমতাগুলি ব্যবহার করা উচিত vgo, বা dep(এখনের জন্য) যা Go 1.6 এ ডিফল্টরূপে সক্ষম হয়েছে; দেখতে । আপনি মূলত ডিরেক্টরিতে আপনার "বাহ্যিক" বা "নির্ভরযোগ্য" প্যাকেজ যুক্ত করেন vendor; সংকলনের পরে সংকলক প্রথমে এই প্যাকেজগুলি ব্যবহার করবে।


পাওয়া গেছে। আমি সক্ষম আমদানি স্থানীয় প্যাকেজ ছিল GOPATHএকটি subfolder তৈরি করে package1এবং তারপর সঙ্গে আমদানি import "./package1"মধ্যে binary1.goএবং binary2.goএই মত স্ক্রিপ্ট:

binary1.go

...
import (
        "./package1"
      )
...

সুতরাং আমার বর্তমান ডিরেক্টরি কাঠামো এর মত দেখাচ্ছে:

myproject/
├── binary1.go
├── binary2.go
├── package1/
   └── package1.go
└── package2.go

আমার এও লক্ষ্য করা উচিত যে আপেক্ষিক পাথগুলি (কমপক্ষে 1.5 তে যান) এছাড়াও কাজ করে; উদাহরণ স্বরূপ:

import "../packageX"

4
আপনার ঠিক একজনের সাথে অন্য দুটি সাবফোল্ডার না পাওয়া পর্যন্ত এটি কাজ করে। উদাহরণস্বরূপ, যদি প্যাকেজ 2 একটি সাবফোল্ডারও ছিল এবং এটির জন্য প্যাকেজ 1 দরকার হয় তবে সিস্টেমটি ব্রেক হয়ে যায়।
কার্ল

7
import "../package1"
ফেলিক্স রাবে 11

12
আপেক্ষিক আমদানির পাথগুলি একটি খারাপ ধারণা
ডেভ সি

1
যদি # লিওলং 'নেমস্পেস' সরবরাহ করে, আমি আপনার সাথে সম্মত হতে পারি যে 'আপেক্ষিক আমদানি পথ' বা 'সাব-প্যাকেজগুলি' একটি খারাপ ধারণা।
mission.liao

1
ফাংশনটির নাম ক্যাপিটিলাইজড কীওয়ার্ড দিয়ে শুরু করা উচিত
কোকেমোমেকে

71

"স্থানীয় প্যাকেজ" এর মতো কোনও জিনিস নেই। ডিস্কে প্যাকেজগুলির সংস্থাগুলি প্যাকেজগুলির যে কোনও পিতামাতার / সন্তানের সম্পর্কের ক্ষেত্রে অরথোগোনাল। প্যাকেজগুলির দ্বারা গঠিত প্রকৃত স্তরক্রম হ'ল নির্ভরতা ট্রি, যা সাধারণ ক্ষেত্রে ডিরেক্টরি ট্রি প্রতিফলিত করে না।

শুধু ব্যবহার

import "myproject/packageN"

এবং বিনা কারণে কোনও কারণেই বিল্ড সিস্টেমের বিরুদ্ধে লড়াই করবেন না। কোনও তুচ্ছ প্রোগ্রামে আমদানি করে এক ডজন অক্ষর সংরক্ষণ করা ভাল কারণ নয়, কারণ উদাহরণস্বরূপ, আপেক্ষিক আমদানি পথের প্রকল্পগুলি গেটে পাওয়া যায় না।

আমদানি পথের ধারণার কয়েকটি গুরুত্বপূর্ণ বৈশিষ্ট্য রয়েছে:

  • আমদানি পথগুলি বিশ্বব্যাপী অনন্য হতে পারে।
  • GOPATH এর সাথে একত্রে, আমদানির পাথটি একটি নির্বিঘ্নে ডিরেক্টরি পথে অনুবাদ করা যেতে পারে।
  • GOPATH এর অধীনে যে কোনও ডিরেক্টরি পাথ কোনও ইম্পোর্ট পথে অনিবার্যভাবে অনুবাদ করা যেতে পারে।

উপরের সমস্তগুলি আপেক্ষিক আমদানি পথ ব্যবহার করে নষ্ট হয়ে গেছে। এটি করবেন না.

পিএস: গো সংকলক পরীক্ষাগুলিতে লিগ্যাসি কোডের কয়েকটি জায়গা রয়েছে যা আপেক্ষিক আমদানি ব্যবহার করে। এটিএম, আপেক্ষিক আমদানি মোটেই সমর্থন করার কারণ এটি।


2
আরও ভাল করে বোঝার জন্য আমি এই ইন্ট্রো ভিডিওটিতে একবার দেখার পরামর্শ দিই প্যাকেজগুলি এবং গোপ্যাথ সম্পর্কে দিইyoutube.com/watch?v=XCsL89YtqCs
জোশুয়া পিন্টার

7
আমি মনে করি এটি খারাপ পরামর্শ। যদি আপনি সংস্করণটির জন্য gopkg.in ব্যবহার করে শেষ করেন, উদাহরণস্বরূপ, আপনি উপরে বর্ণিত হিসাবে আপনার "মিনি" প্যাকেজগুলির জন্য নিখুঁত আমদানি পথগুলি নিয়ে ভাগ্যের বাইরে রয়েছেন। হয় আপনি সোর্স রেপো ভেঙে ফেলেন বা সংস্করণযুক্তটি অকেজো হয়ে যায়।
গ্রেগ

import "myproject/packageN"myprojectআমার প্রকল্পটি ধারণ করে ফোল্ডারের নাম?
সুরক্ষিত

এটি সম্পূর্ণরূপে ভুল, আমি এখন এটি ব্যক্তিগত সংগ্রহস্থলগুলির সাথে কীভাবে ব্যবহার করব?
agilob

44

সম্ভবত আপনি নিজের প্যাকেজটি আধুনিকীকরণের চেষ্টা করছেন। আমি ধরে নিচ্ছি package1এবং package2এটি একরকম একই প্যাকেজের অংশ তবে পাঠযোগ্যতার জন্য আপনি সেগুলি একাধিক ফাইলে বিভক্ত করছেন।

পূর্ববর্তী কেসটি যদি আপনার হয়, আপনি সেই গুণক ফাইলগুলিতে একই প্যাকেজটির নামটি ব্যবহার করতে পারতেন এবং একই ফাইলটি থাকলে এটির মতো হবে।

এটি একটি উদাহরণ:

add.go

package math

func add(n1, n2 int) int {
   return n1 + n2
}

subtract.go

package math

func subtract(n1, n2 int) int {
    return n1 - n2
}

donothing.go

package math

func donothing(n1, n2 int) int {
    s := add(n1, n2)
    s = subtract(n1, n2)
    return s
}

আমি গো বিশেষজ্ঞ নই এবং স্ট্যাকওয়েফ্লোতে এটি আমার প্রথম পোস্ট, তাই আপনার যদি কিছু পরামর্শ থাকে তবে এটি ভালভাবে গৃহীত হবে।


23

আমার অনুরূপ সমস্যা রয়েছে এবং আমি বর্তমানে যে সমাধানটি ব্যবহার করছি তা Go 1.11 মডিউলগুলি ব্যবহার করে। আমি নিম্নলিখিত কাঠামো আছে

- projects
  - go.mod
  - go.sum
  - project1
    - main.go
  - project2
    - main.go
  - package1
    - lib.go
  - package2
    - lib.go

এবং আমি ব্যবহার করে প্রকল্প 1 এবং প্রকল্প 2 থেকে প্যাকেজ 1 এবং প্যাকেজ 2 আমদানি করতে সক্ষম হয়েছি

import (
    "projects/package1"
    "projects/package2"
)

দৌড়ানোর পরে go mod init projects। আমি go buildপ্রকল্প 1 এবং প্রকল্প 2 ডিরেক্টরি থেকে ব্যবহার করতে পারি বা আমি go build -o project1/exe project1/*.goপ্রকল্প ডিরেক্টরি থেকে করতে পারি ।

এই পদ্ধতির খারাপ দিকটি হ'ল আপনার সমস্ত প্রকল্পগুলি go.mod এ একই নির্ভরতা তালিকা ভাগ করে নেবে। আমি এখনও এই সমস্যার সমাধান খুঁজছি, তবে দেখে মনে হচ্ছে এটি মৌলিক হতে পারে।


9

Go.mod প্রবর্তনের পর থেকে , আমি মনে করি স্থানীয় এবং বাহ্যিক উভয়ই প্যাকেজ পরিচালনা সহজ হয়ে যায়। Go.mod ব্যবহার করে, GOPATH এর বাইরেও প্রকল্প নেওয়া সম্ভব।

স্থানীয় প্যাকেজ আমদানি করুন:

ফোল্ডারটি ডেমোপ্রজেক্ট তৈরি করুন এবং go.mod ফাইল তৈরি করতে নিম্নলিখিত কমান্ডটি চালান

go mod init demoproject

ডেমোপ্রজেক্ট ডিরেক্টরিতে আমার নীচের মতো একটি প্রকল্প কাঠামো রয়েছে ।

├── go.mod
└── src
    ├── main.go
    └── model
        └── model.go

ডেমো উদ্দেশ্যে, মডেল.গো ফাইলটিতে নিম্নলিখিত কোডটি সন্নিবেশ করুন।

package model

type Employee struct {
    Id          int32
    FirstName   string
    LastName    string
    BadgeNumber int32
}

ইন main.go , আমি "demoproject / src / মডেল" থেকে আখ্যা কর্মচারী মডেল আমদানি করা

package main

import (
    "demoproject/src/model"
    "fmt"
)

func main() {
    fmt.Printf("Main Function")

    var employee = model.Employee{
        Id:          1,
        FirstName:   "First name",
        LastName:    "Last Name",
        BadgeNumber: 1000,
    }
    fmt.Printf(employee.FirstName)
}

বাহ্যিক নির্ভরতা আমদানি করুন:

go getপ্রকল্প ডিরেক্টরিতে কেবল কমান্ড চালান run

উদাহরণ স্বরূপ:

go get -u google.golang.org/grpc

এটি go.mod ফাইলের মধ্যে মডিউল নির্ভরতা অন্তর্ভুক্ত করা উচিত

module demoproject

go 1.13

require (
    golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa // indirect
    golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9 // indirect
    golang.org/x/text v0.3.2 // indirect
    google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150 // indirect
    google.golang.org/grpc v1.26.0 // indirect
)

https://blog.golang.org/using-go-modules


can't load package: package .: no Go files in...(go.mod এর ফোল্ডারে যান)
Sebi2020

এ জাতীয় নিষেধাজ্ঞার উত্তর খুঁজে পেতে আমার বিব্রতকর সময় লেগেছিল এবং আপনার পোস্টটি সর্বাধিক সুস্পষ্ট ও কার্যকর। ধন্যবাদ!
হ্যারল্ড ক্যাভেনডিশ

8

আপনার প্রকল্পে "স্থানীয়" প্যাকেজ যুক্ত করতে একটি ফোল্ডার যুক্ত করুন (উদাহরণস্বরূপ "প্যাকেজ_নাম")। এবং আপনার প্রয়োগকারী ফাইলগুলি সেই ফোল্ডারে রাখুন।

src/github.com/GithubUser/myproject/
 ├── main.go
 └───package_name
       └── whatever_name1.go
       └── whatever_name2.go

আপনার এটি package mainকরতে:

import "github.com/GithubUser/myproject/package_name"

কোথায় package_nameফোল্ডারের নামটি এবং এটি অবশ্যই_নাম 1.go এবং যাইহোক_নাম 2.go ফাইলগুলিতে ব্যবহৃত প্যাকেজের নামের সাথে মেলে। অন্য কথায় সাব ডিরেক্টরি সহ সমস্ত ফাইল একই প্যাকেজের হওয়া উচিত।

আপনি যতক্ষণ না আমদানিতে প্যারেন্ট ফোল্ডারে পুরো পথটি নির্দিষ্ট করেন ততক্ষণ আপনি আরও নীড় ডিরেক্টরিতে বাসাতে পারেন।


2
এটি একটি সূক্ষ্ম পরামর্শ, যে কোনও কার্নেল আতঙ্কের সময় বাইনারি থেকে ফেলে দেওয়া স্ট্যাক ট্রেসটি গিথুব ডট কম দেখায় উদাহরণস্বরূপ, সর্বদা সবচেয়ে পছন্দসই আচরণ নয়। এটি দমন করার জন্য পতাকা রয়েছে, তবে এটি কেবল সহজ প্যাকেজ সংস্থা অর্জনের জন্য প্রয়োজন হবে না এবং আমি খুঁজে পেয়েছি যে এটি উপলক্ষে ব্যর্থ হয়।
কেনি পাওয়ারস 0

package myproject/package_name is not in GOROOT (/usr/lib/go-1.14/src/myproject/package_name)
Sebi2020

3

তুমি ব্যবহার করতে পার replace

go modo init example.com/my/foo

foo বিন্যাস / go.mod

module example.com/my/foo

go 1.14

replace example.com/my/bar => /path/to/bar

require example.com/my/bar v1.0.0

foo বিন্যাস / main.go

package main
import "example.com/bar"

func main() {
    bar.MyFunc()
}

বার / go.mod

module github.com/my/bar

go 1.14

বার / fn.go

package github.com/my/bar

import "fmt"

func MyFunc() {
    fmt.Printf("hello")
}

স্থানীয় প্যাকেজ আমদানি করা বাহ্যিক প্যাকাকেজ আমদানির মতো

go.mod ফাইলের অভ্যন্তর বাদে আপনি সেই বাহ্যিক প্যাকেজটির নাম স্থানীয় ফোল্ডারের সাথে প্রতিস্থাপন করেন।

ফোল্ডারে যাওয়ার পথটি পূর্ণ বা আপেক্ষিক "/ পাথ / থেকে / বার" বা ".. / বার" হতে পারে

https://github.com/golang/go/wiki/Modules#when-should-i-use-the-replace-directive https://thewebivore.com/using-replace-in-go-mod-to- point -to-আপনার-স্থানীয়-মডিউল /

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.