Getting started¶
Fetch the latest release of a tool from a forge, without importing that forge's SDK.
Resolve a provider and read a release¶
package main
import (
"context"
"fmt"
"log"
"gitlab.com/phpboyscout/go/forge"
// Blank imports register providers. Import only the forges you support.
_ "gitlab.com/phpboyscout/go/forge/direct"
)
func main() {
factory, err := forge.Lookup("direct")
if err != nil {
log.Fatal(err)
}
provider, err := factory(forge.ReleaseSourceConfig{
Repo: "mytool",
Params: map[string]string{
"url_template": "https://dl.example.com/{tool}/{version}/{tool}_{os}_{arch}.{ext}",
"pinned_version": "v1.2.3",
},
}, nil)
if err != nil {
log.Fatal(err)
}
rel, err := provider.GetLatestRelease(context.Background(), "acme", "mytool")
if err != nil {
log.Fatal(err)
}
fmt.Println(rel.GetTagName())
}
Three things to notice, because they shape everything else:
Your code never named a forge type. factory returns a forge.Provider.
Swapping "direct" for "gitlab" — and the blank import to match — changes
nothing below that line. That is
backend agnosticism, and it is the point.
No vendor SDK entered your build. The core imports none, and a guard test keeps it that way. You pay only for the providers you blank-import.
The source type is a plain string. "direct" is not an enum member. A forge
this module has never heard of works the same way, provided something registered
it.
Add a real forge¶
Provider modules are separate, so you take only what you use:
An unknown type returns ErrProviderNotFound with a hint listing what is
registered — which is usually the real problem: a missing blank import.
See providers for the supported forges, their source types, config keys and capabilities.
Where next¶
- Providers — supported forges, config keys, capabilities
- Author a provider — teach it a new forge, in your own module
- Authenticate to a forge — the credential chain
- Verify checksums and signatures — the safe update path
- Test against a forge — doubles, mocks, and the conformance harness