Golang, importing packages from Github requests me to remember the Github URL? - github

I'm very new to Golang. I see that in Golang you can import packages directly from Github like:
import "github.com/MakeNowJust/heredoc"
Does that mean I have to remember this URL in order to use this package? IMHO this is not cool. What if later the author of the package removed it or changed the URL? Any ideas?

I would recommend you to read the How to Write Go Code documentation and this blog post.
The path you're seeing in your import line is not a url, but only the path the package is located in (normally relative to $GOROOT/src/pkg or $GOPATH/src). So your package heredoc is most probably located in the directory $GOPATH/src/github.com/MakeNowJust/heredoc.
The recommended way to use external packages is by downloading and installing them via go get. You might want to check out the documentation of go get by go get --help.

The path that import statement refers is just appended to $GOPATH/src. So that import statement basically says "import the package located at $GOPATH/src/github.com/MakeNowJust/heredoc"
What if later the author of the package removed it or changed the URL?
As long as you already have the source files for that package at the expected location, it should be included even if the repo has moved.

dont worry man! you can use glide tool for package management

Related

Integrating a remote Swift Package that has local Swift Packages: how to avoid invalidManifestFormat errors?

The situation:
I have a Swift Package, call it lib. lib lives in its own repository. In lib's repository, there are a bunch of local Packages; that is, these are packages that are defined, in lib, using the local-path dependency format, .package(path: "CursorPackage"), and whatnot.
All of this is fine as long as I'm locally importing lib into my actual application repository. The moment I try to import lib into my repo using SPM's remote options, which is obviously the way to go for doing things with CI, it throws the following error:
invalidManifestFormat("'CursorPackage' is not a valid path for path-based dependencies; use relative or absolute path instead.")
This error persists whether I use CursorPackage or ./CursorPackage. Obviously I don't want to try to use an absolute path, because I'm on CI, so that would involve either hard-coding things or ingesting an environment variable somehow that contains PWD.
What am I missing? This seems like it should just work. Is this just a bug in SPM that I should be reporting to Apple?
This isn't intended to be possible. If you look at the 5th bullet in the Proposed Solution section of the local packages proposal (https://github.com/apple/swift-evolution/blob/main/proposals/0201-package-manager-local-dependencies.md) it says that it's not intended for a remote package to be allowed to depend on a local package.
I expect its because there's the possibility that you could have both a versioned package with a given name and a local package with the same name; if so how would SPM resolve the conflict?
It is unfortunate though since allowing this would allow for more options in how people organize their packages, I agree.

Upload a NuGet package that is not mine

I have found a dll that is provided via Google Code and I couldn't find it in NuGet. I want this package to be available via a NuGet install, because I want to reuse it in several packages and NuGet seems like the perfect way to do this.
https://code.google.com/p/protobuf-remote/downloads/list
Is it possible for me to generate a nupkg out of these dll's and publish it to NuGet.org? What are the legal limitations to this action?
There are a number of other users that have run into this issue. It seems like the common solution is to create an "Unofficial" package and reference that for the time being (until Google publishes their library as a NuGet). Just make sure to very clearly label the package as unofficial. See these examples.
As for the legal ramifications...
Please look through protobuf-remote license and review the distribution and derived works details. Currently the license is GNU Lesser GPL. Sorry, but you'll have to make your own call on if publishing the NuGet package would be permitted under this license. ;)
I would recommend you instead create a local NuGet package source by pointing to a file share. This can be local on your computer or on a network file share.
Also, if you don't want to update every workstation, you can update the NuGet.config file in your project to point to this source and commit that config file in your source control repository for all users to get automatically. Just note that any change to a NuGet.config file requires you to restart Visual Studio.
And FYI, take a look at how you can chain multiple NuGet.config files.

Golang Importing Issue

I'm trying to use import a package for internal use, but I have been having some issues.
My directory structure looks like this:
app/
model/
file1.go
file2.go
...
main.go
When I try to build the program, I get an error that looks something like this:
/usr/local/go/src/pkg/model (from $GOROOT)
I want to be able to call the model programs in any of my other programs in the app simply using:
import "app/model"
What are my options when it comes to doing this?
You import from GOPATH level .. all of your packages should live there.
For example, assuming your application is here:
$GOPATH/src/dtrinh100/app/
..and your package you wish to import is here:
$GOPATH/src/github.com/other/package
Your import would be:
import "github.com/other/package"
You should review the literature around what the GOPATH environment variable is all about. When beginning Go, it is important you understand its purpose and initially, you should place all of your projects/packages inside of the GOPATH.
When you import a custom package, Go looks for its definition in each workspace listed in the GOPATH environment variable. Your custom package should be defined in a src subdirectory.
If you keep your code in a source repository somewhere, then you should use the root of that source repository as your base path. For instance, if you have a GitHub account at github.com/user, that should be your base path.
Note that you don't need to publish your code to a remote repository before you can build it. It's just a good habit to organize your code as if you will publish it someday. In practice you can choose any arbitrary path name, as long as it is unique to the standard library and greater Go ecosystem.
You should use github.com/user as our base path. Create a directory inside your workspace in which to keep source code:
$ mkdir -p $GOPATH/src/github.com/user
You can look at How to Write Go Code for more details.

Go, Golang : external package import with GOROOT

Go, Golang : does not make sense that I have to have files before import
I am trying to go to next step but keep getting errors
I have the package that I want to import ready.
All I need to do is to import the external package from github and be able to use it on any code.
So this is what I did.
mkdir $HOME/go
export GOPATH=$HOME/go
go get github.com/user/project
This runs successfully. I downloaded it onto here with source code files from github
/Users/user/go/src/github.com/user/project/project.go
So to use this package that I just import I do
go run /Users/user/Desktop/code.go
But I am getting the following errors
MacBook-Air:~ user$ go run /Users/user/Desktop/code.go
Desktop/code.go:32:8: cannot find package "project" in any of:
/usr/local/go/src/pkg/project (from $GOROOT)
/Users/user/go/src/project (from $GOPATH)
What should I do? AM I missing something? Thanks in advance and please help me. I wrote a lot of code but being very frustrated not being able to distribute it because of this.
The error message says at line 32 in your code.go it can't find package "goling".
Assuming that is a local package you want to use, you need to make sure it is in your GOPATH.
If you set GOPATH then you should develop your code within it, so moving the "goling" directory into /Users/user/go/src is the right thing to do.
Alternatively "goling" could be a typo, so check the imports in code.go. If you want to import an project from github the import should say
import "github.com/user/project"
And you then use the parts of project with a prefix of project.
If that doesn't help you get it working, then post the imports section of code.go.
It looks like you've got the external package in the same folder as your main package which uses it. In go, all packages must be in separate directories. It looks like the github project itself is actually doing that. If you separate the packages into different directories it should work properly.

Relative import from parent directory

How does one do a relative import from a parent directory?
From meme/cmd/meme:
import "../../../meme"
This gives an ambiguous error:
matt#stanley:~/gopath/src/bitbucket.org/anacrolix/meme/cmd/meme$ go get bitbucket.org/anacrolix/meme/cmd/meme
can't load package: /home/matt/gopath/src/bitbucket.org/anacrolix/meme/cmd/meme/main.go:8:2: local import "../../../meme" in non-local package
matt#stanley:~/gopath/src/bitbucket.org/anacrolix/meme/cmd/meme$ echo $GOPATH
/home/matt/gopath
How do I import locally from a parent directory?
Edit: Relative import paths are not the way to go in Go. Lack of documentation shows something about popularity of relative paths, and I don't see a reason for using them. Go's recommended code organization works pretty well. Every package should have a unique import path and be imported everywhere using that same import path.
See how a package like github.com/ha/doozerd/peer imports its neighbors. This is a common practice among Go projects and I've seen it a lot of times. Package camlistore.org/pkg/auth (also on GitHub; written by one of the main authors of Go) imports camlistore.org/pkg/netutil by full path.
Even if you are having both commands and libraries in the same project this approach works. In your original questions you wisely asked for best practices. I did my best in explaining best practices on this matter.
Import paths can't be relative in Go. I recommend reading How to Write Go Code, the essential reading on organizing Go projects. Here's a short overview:
Make a directory like ~/go for your Go development. Then say:
$ export GOPATH=~/go
$ mkdir $GOPATH/{src,bin,pkg}
$GOPATH/src holds source code for all your Go packages, even the ones your download with go get. bin and pkg keep output of compilations. Packages with package name main are commands and yield to executable binaries which go to $GOPATH/bin. Other packages are libraries and their compiled object files are put in $GOPATH/pkg.
Now if you put your code in $GOPATH/src/matt/meme, you can import it by import "matt/meme". It's recommended to use a prefix for your package names and leave short package names for standard libraries. That's why I used $GOPATH/src/matt/meme instead of $GOPATH/src/meme.
Organize your code around this idea.
Thanks for adding to your question. First, an answer, then some explanation. I built your code by,
go get, just as you had it. (I ignored the error messages.)
setting the import line in main.go back to "../../../meme", as you wanted to do.
(commenting out a little bit of code containing an unused variable.)
then in the meme/cmd/meme directory, either go run main.go or go build main.go worked.
I was wrong in my comment earlier when I said go install works; I should have said go build.
The key however is that go build alone does not work; you must type go build main.go. This is because the go command does not allow "local imports in non-local packages." You are right that spec is of little help here. It weasels out saying, "The interpretation of the ImportPath is implementation-dependent." The current implementation behavior was set with CL 5787055, which was subsequently debated at length on Go-nuts.
"Local" means indicated with a file system relative path. Obviously a relative path starting with .. is local, so the trick is just getting the go command to treat main as a local package as well. It apparently doesn't do this when you type go build, but does when you type go build main.go.
Relarive imports are supported when manually using the compiler, linker, ... directly. The 'go' (build) tool doesn't support the same (somehow comparable to eg Java).
This may not answer the original question, but I was trying to do the above when I didn't really need to, all I needed to do was update go.mod temporarily with a replace :
module github.com/pselle/foo
replace github.com/pselle/bar => /Users/pselle/Projects/bar
require (
github.com/pselle/bar v1.0.0
)
reference:
https://thewebivore.com/using-replace-in-go-mod-to-point-to-your-local-module/