repos / dbin

📦 Poor man's package manager.
git clone https://github.com/xplshn/dbin.git

xplshn  ·  2025-08-13

main.go

Go
  1// PROGRAM: DBIN
  2// MAINTAINER: IDIOT (xplshn)
  3// PURPOSE: Package manager done right
  4// DESCRIPTION: A package manager that uses one-file packages (statically linked binaries, self-contained binaries)
  5package main
  6
  7import (
  8	"context"
  9	"fmt"
 10	"os"
 11	"path/filepath"
 12	"strconv"
 13	"strings"
 14
 15	"github.com/urfave/cli/v3"
 16)
 17
 18const (
 19	version            = 1.7
 20	maxCacheSize       = 15
 21	binariesToDelete   = 5
 22	// --------------------------------
 23	extraVerbose              uint8 = 4
 24	normalVerbosity           uint8 = 3
 25	silentVerbosityWithErrors uint8 = 2
 26	extraSilent               uint8 = 1
 27	// -------------------------------
 28)
 29
 30var verbosityLevel = normalVerbosity
 31
 32func main() {
 33	app := &cli.Command{
 34		Name:        "dbin",
 35		Usage:       "The easy to use, easy to get, software distribution system",
 36		Version:     strconv.FormatFloat(version, 'f', -1, 32),
 37		Description: "The easy to use, easy to get, software distribution system",
 38		Flags: []cli.Flag{
 39			&cli.BoolFlag{
 40				Name:  "verbose",
 41				Usage: "Run in extra verbose mode",
 42			},
 43			&cli.BoolFlag{
 44				Name:  "silent",
 45				Usage: "Run in silent mode, only errors will be shown",
 46			},
 47			&cli.BoolFlag{
 48				Name:  "extra-silent",
 49				Usage: "Run in extra silent mode, suppressing almost all output",
 50			},
 51		},
 52		Before: func(ctx context.Context, c *cli.Command) (context.Context, error) {
 53			switch {
 54			case c.Bool("extra-silent"):
 55				verbosityLevel = extraSilent
 56			case c.Bool("silent"):
 57				verbosityLevel = silentVerbosityWithErrors
 58			case c.Bool("verbose"):
 59				verbosityLevel = extraVerbose
 60			}
 61			return nil, nil
 62		},
 63		Commands: []*cli.Command{
 64			installCommand(),
 65			removeCommand(),
 66			listCommand(),
 67			searchCommand(),
 68			infoCommand(),
 69			runCommand(),
 70			updateCommand(),
 71			configCommand(),
 72		},
 73		EnableShellCompletion: true,
 74	}
 75
 76	pathDirs := strings.Split(os.Getenv("PATH"), string(os.PathListSeparator))
 77	found := false
 78	for _, dir := range pathDirs {
 79		if !found || len(pathDirs) == 0 {
 80			if dir == "." || dir == ".." {
 81				continue
 82			}
 83			if _, err := os.Stat(filepath.Join(dir, filepath.Base(os.Args[0]))); err == nil {
 84				found = true
 85				break
 86			}
 87		}
 88	}
 89
 90	if err := app.Run(context.Background(), os.Args); err != nil {
 91		fmt.Fprintf(os.Stderr, "%v\n", err)
 92		os.Exit(1)
 93	}
 94
 95	if !found {
 96		fmt.Fprintf(os.Stderr, "\n%swarning%s: dbin not in $PATH\n", yellowColor, resetColor)
 97	}
 98}
 99
100func fetchRepoIndex(config *config) ([]binaryEntry, error) {
101	uRepoIndex, err := decodeRepoIndex(config)
102	if err != nil {
103		return nil, fmt.Errorf("%v: Consider checking if DBIN_NOCONFIG=1 works, if so, consider modifying your config, your repository URLs may be outdated.\nAlso consider removing dbin's cache if the above fails", err)
104	}
105	return uRepoIndex, nil
106}