You must login to view /gokrazy/tools/commit/fc2e1562e828390d362ade4052154a9a378df130?files=internal%2Fpacker.
The GitHub option should be usable for most people, it only links via username.

Files
tools/internal/gok/get.go
2025-12-06 08:37:24 +01:00

134 lines
3.5 KiB
Go

package gok
import (
"context"
"fmt"
"io"
"log"
"os"
"os/exec"
"strings"
"github.com/gokrazy/internal/config"
"github.com/gokrazy/internal/instanceflag"
"github.com/gokrazy/tools/packer"
"github.com/spf13/cobra"
)
// getCmd is gok get.
func getCmd() *cobra.Command {
cmd := &cobra.Command{
GroupID: "edit",
Use: "get",
Short: "Update the version of your Go program(s) using `go get`",
Long: "gok get runs `go get` to update the version of the specified Go programs" + `
in your gokrazy instance.
Examples:
# Update all packages on gokrazy instance scanner
% gok -i scanner get -u
# Update only the scan2drive program, keep gokrazy system as-is
% gok -i scanner get github.com/stapelberg/scan2drive/cmd/scan2drive
# Update only gokrazy system packages
% gok -i scanner get gokrazy
`,
RunE: func(cmd *cobra.Command, args []string) error {
return getImpl.run(cmd.Context(), args, cmd.OutOrStdout(), cmd.OutOrStderr())
},
}
cmd.Flags().BoolVarP(&getImpl.updateAll, "update_all", "u", false, "update all installed packages and gokrazy system packages")
instanceflag.RegisterPflags(cmd.Flags())
return cmd
}
type getImplConfig struct {
updateAll bool
}
var getImpl getImplConfig
func getGokrazySystemPackages(cfg *config.Struct) []string {
pkgs := append([]string{}, cfg.GokrazyPackagesOrDefault()...)
pkgs = append(pkgs, packer.InitDeps(cfg.InternalCompatibilityFlags.InitPkg)...)
pkgs = append(pkgs, cfg.KernelPackageOrDefault())
if fw := cfg.FirmwarePackageOrDefault(); fw != "" {
pkgs = append(pkgs, fw)
}
if e := cfg.EEPROMPackageOrDefault(); e != "" {
pkgs = append(pkgs, e)
}
return pkgs
}
func (r *getImplConfig) run(ctx context.Context, args []string, stdout, stderr io.Writer) error {
cfg, err := config.ApplyInstanceFlag()
if err != nil {
if os.IsNotExist(err) {
// best-effort compatibility for old setups
cfg = config.NewStruct(instanceflag.Instance())
} else {
return err
}
}
if err := os.Chdir(config.InstancePath()); err != nil {
return err
}
packages := args
if r.updateAll {
if len(packages) > 0 {
return fmt.Errorf("use either -u or specify package arguments, not both")
}
packages = append(getGokrazySystemPackages(cfg), cfg.Packages...)
} else {
filtered := make([]string, 0, len(packages))
for _, pkg := range packages {
if pkg == "gokrazy" {
// gokrazy is a special value that expands to all gokrazy system
// packages.
filtered = append(filtered, getGokrazySystemPackages(cfg)...)
} else {
filtered = append(filtered, pkg)
}
}
packages = filtered
}
for idx, pkgAndVersion := range packages {
pkg := pkgAndVersion
if idx := strings.IndexByte(pkg, '@'); idx > -1 {
pkg = pkg[:idx]
}
buildDir := packer.BuildDir(pkg)
_, err := os.Stat(buildDir)
if os.IsNotExist(err) {
// Common case, handle with a good error message
wd, _ := os.Getwd()
os.Stderr.WriteString("\n")
log.Printf("Error: build directory %q does not exist in %q", buildDir, wd)
log.Printf("Try 'gok -i %s add %s' followed by an update.", instanceflag.Instance(), pkg)
log.Printf("Afterwards, your 'gok get' command should work")
return nil
}
if err != nil {
return err
}
get := exec.CommandContext(ctx, "go", "get", pkgAndVersion)
get.Env = packer.Env()
get.Dir = buildDir
get.Stdout = os.Stdout
get.Stderr = os.Stderr
log.Printf("updating package %d of %d: %s", idx+1, len(packages), get.Args)
log.Printf(" in %s", buildDir)
if err := get.Run(); err != nil {
return fmt.Errorf("%v: %v", get.Args, err)
}
}
return nil
}