PromQL Module Missing - go

I am trying to use the promql package here
package main
import (
"fmt"
"github.com/prometheus/prometheus/promql/parser"
)
func main() {
fmt.Println("Hello")
parser.ParseExpr("foobar")
}
Having trouble importing. This is the error:
no required module provides package
github.com/prometheus/prometheus/promql/parser; to add it:
go get github.com/prometheus/prometheus/promql/parser (compile)
I tried to run go get github.com/prometheus/prometheus/promql/parser as suggested but it fails.
go get: module github.com/prometheus/prometheus#upgrade found
(v2.5.0+incompatible), but does not contain package
github.com/prometheus/prometheus/promql/parser
Here is my go.mod currently:
module foo.com/bar/parser
go 1.17
require github.com/prometheus/prometheus v2.5.0+incompatible // indirect

Use go get github.com/prometheus/prometheus#83032011a5d3e6102624fe58241a374a7201fee8 (that commit is the latest release at this point in time, v2.33.4)
The reason this is needed is that
This is a known issue with Go Modules. The semantic versioning of Prometheus versions the behavior of Prometheus as a server, not its code as a library. By changing the module path to v2, we would suggest that Prometheus obeys the contract of Go Modules as a library, but it doesn't, i.e. there are many breaking changes to expect even in a minor release.
and:
Prometheus was not intended to be used as a library. Now that has changed, and it is intended to be used as such, even if we do not accept all general-purpose contributions.
The error you are seeing is because go get is grabbing an old release v2.5.0 by default which was released back in 2018 and does not include the parser package. This happens because the versioning scheme used by Prometheus does not align with that assumed by Go.
See this issue for additional info.

Related

Go module is usable even after deleting the module repo from GitHub

I was learning go modules so I created a very basic module with an Add() function and published it on GitHub.
The repository was https://github.com/umermasood/nummanip (it throws 404) becaused I deleted the repo from GitHub.
But I am still able to use the calc package from the module.
package main
import (
"fmt"
"github.com/umermasood/nummanip/calc"
)
func main() {
fmt.Println(calc.Add(1, 2))
}
Output:
3
Above code in the Go Playground: https://go.dev/play/p/gMYD6Jirz_n
What is causing this behavior?
The Go Module Mirror is keeping your module downloadable.
See the FAQ item below.
I removed a bad release from my repository but it still appears in the mirror, what should I do?
Whenever possible, the mirror aims to cache content in order to avoid breaking builds for people that depend on your package, so this bad release may still be available in the mirror even if it is not available at the origin. The same situation applies if you delete your entire repository. We suggest creating a new version and encouraging people to use that one instead.
Source: https://proxy.golang.org/

Conflicting type in golang compilation [duplicate]

I'm trying to use this Golang Yelp API package. In some of its structs, it uses types defined in guregu's null package.
I want to declare a struct defined in the Yelp API package, where some of its fields have null.Float as a value (i.e. this struct, which im trying to use). So in my program, I import both the Yelp API package and guregu's null package and try to declare the struct, with ip.Lat and ip.Lat being float64s. (null.FloatFrom definition):
33 locationOptions := yelp.LocationOptions{
34 ip.Zip,
35 &yelp.CoordinateOptions{
36 Latitude: null.FloatFrom(ip.Lat),
37 Longitude: null.FloatFrom(ip.Lon),
38 },
39 }
But when I run the program, it tells me:
./cli.go:36: cannot use "github.com/guregu/null".FloatFrom(ip.Lat) (type
"github.com/guregu/null".Float) as type "github.com/JustinBeckwith/go-
yelp/yelp/vendor/github.com/guregu/null".Float in field value
I tried 2 things:
1) I did not import the null package, which caused Go to complain about null being undefined. 2) I also tried importing the vendored package directly, which caused Go to tell me use of vendored package not allowed.
Any Ideas on how to fix this?
The solution here seems to be that the library I'm trying to use needs to be reworked to prevent this kind of thing from happening.
The two possible ways to change the library seem to be
1) not vendor at all - this works if the dependency does not need to be a specific version.
2) vendored, but do not expose the vendored library to the public. Create some wrapper functions in the library so that people can create the types indirectly.
See this discussion about vendoring on reddit for more ideas/reasons why.
I had the same issue. As a work around, I deleted the associated package's vendor folder and moved their content to my $GOPATH folder.
Source of answer: promql Go import problem: use of vendored package not allowed
Just had a similar issue. Putting both libraries in /vendor resolved. Using govendor get xxxx
Had a similar issue while using Godep and I resolved by deleting /vendor and re-running godep save ./... - Hope it helps.

Can I override the endpoint prefix set in a Go GRPC client call?

I have a single protobuf which generates out C# and Go code.
The protobuf contains:
syntax = "proto3";
package myprotobuf;
option go_package = "gitlab.example.com/mycompany/myprotobuf.git";
I'm using go-micro and protoc-gen-micro for my Go GRPC. I'm using Go modules for my Go packages. I'm pushing generated Go code to my protobuf repository for a few reasons: (a) Git submodules can be painful to work with (b) a protobuf referencing a type in an external package requires that external package to have a defined absolute package URL and (c) that's how Google do it (ref e.g. structpb) so it seems like that's the "standard".
The C# server / client generated from that proto serve / hit an endpoint at "/myprotobuf.Service/Method", and work fine.
GRPC_TRACE for C# gives:
Decode: ':path: /myprotobuf.Service/Method', elem_interned=1 [1], k_interned=1, v_interned=1 (edited)
The Go / go-micro client calling the C# server gives:
Decode: ':path: /myprotobuf.git.Service/Method', elem_interned=0 [2], k_interned=1, v_interned=0
followed by an error. Note that the path is different. Breakpoints and Console.WriteLine's in the C# GRPC handler never get hit, which makes sense since we're not hitting a known endpoint.
What's the solution for this?
go get seems to require the .git at the end of the package URL.
go modules require the "module" and "package" definitions to match the URL.
C# won't like a "." in the namespace.
So it seems like Go and C# are both always going to prefix the endpoint with what the think the package / namespace is, and they're never going to agree on what the package / namespace should be.
Is there a way to override the namespace prefixed to the GRPC endpoint?
One workaround I've found is to sit the package a level under the protos in a "mypb" directory:
package mypb;
option go_package = "gitlab.example.com/mycompany/myprotobuf.git/mypb";
option csharp_namespace = "MyCompany.Protobuf.MyPB";
It's a bit of a hack, but I don't mind it too much, especially since it sits the generated code out of the way of the proto source that I actually care about. This way the generated C# and Go agree on the namespace / package that they prefix endpoints with. Thankfully the camel case MyPB vs lower case mypb doesn't seem to matter.

How to dynamically add imports

I want to dynamically create an HTTP router using custom plugins/middleware, currently, I am using a config.yml for example:
plugins:
- waf
- jwt
- cors
After parsing the yml file I create the routes like this:
route := violetear.New()
chain := middleware.New()
for _, plugin := range Plugins {
chain := chain.Append(plugin)
}
router.Handle("/test", chain.Then(myHandler))
log.Fatal(http.ListenAndServe(":8080", router))
For this to work, I would have to include all the plugins in the import section, something like:
import (
"net/http"
"github.com/nbari/violetear"
"github.com/nbari/violetear/midleware"
// How to deal with this
"github.com/example/waf"
"github.com/example/jwt"
"github.com/example/cors"
)
I would need to change the current config format to be something more useful/generic probably something like:
plugins:
- [github.com/foo, foo]
- [github.com/bar, bar]
But besides that what could be the best approach to "dynamically" create the imports or to generate the code the one later could be compiled?
Any ideas?
Go is a statically linked language. This means if a package is not referenced at compile time (from your .go source files), that package will not be linked / compiled into the executable binary, which implies it will not be availabe at runtime.
So the easiest is to just use imports.
If you want truly dynamic configuration, plugins introduced in Go 1.8 may be an option for you, but using plugins complicates things and I would only use that as a last resort. Also note that plugins currently only work on linux.
Related questions:
Dynamic loading in Golang?
Go Plugin variable initialization
go 1.8 plugin use custom interface

Using local packages with gb

I'm starting a new project and considering gb as my build tool but it doesn't appear to be integrating very well with vscode...
I've referenced 3rd party dependencies no problem using gb vendor fetch but as for creating local packages, this is proving a little trickier! Am I missing something obvious?
Here's my local src directory:
src
/cmd
/model
calc.go
/server
server.go
The following code compiles and creates a bin\server.exe file successfully but the import path isn't picked up, nor does gocode recognise it
Here's the server code:
package main
import (
"cmd/model" // not a happy reference...
"fmt"
)
func main() {
fmt.Println(model.Add(1, 2))
}
Here's the model code:
package model
func Add(a int, b int) int {
return a + b
}
I've found what appears to be a similar issue on Github (https://github.com/joefitzgerald/go-plus/issues/325) and while nsf's solution sorts out auto-complete (post import), the import statement itself still claims to be searching in the GOROOT and GOPATHs.
Any ideas?
Thanks to an answer from lukehoban here https://github.com/Microsoft/vscode-go/issues/249 I was able to get my environment working.
I simply created a settings.json file under the .vscode directory (which will now have to be checked in) into which I've configured:
{
"go.gopath": "${workspaceRoot}"
}
This makes me feel unclean and it still doesn't provide a way to reference both 3rd party dependencies and local packages together...
Do not try to work against Go, work with Go.
First of all give all your packages fully qualified import paths. Go is designed around global import paths, do not try to force Go into using flat hierarchies or even relative paths.
You can point to your import path repository endpoints either directly or by using Go's remote import path mechanism. BTW, if you happen to run a self-hosted GitLab instance, it supports remote import path meta tags out of the box.
I prefer glide, but maybe the following is possible with gb, too. Certainly something simililar will be possible with the upcoming go dep: You can point to ssh+git endpoints and others using glide's repo stanza. Frankly I have no idea if gb supports an equivalent mechanism, but if it doesn't this is a good reason to reconsider.

Resources