github.com/pdmccormick/importable-docker-buildx@v0.0.0-20240426161518-e47091289030/util/desktop/desktop.go (about)

     1  package desktop
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"io"
     7  	"os"
     8  	"path/filepath"
     9  	"sync"
    10  
    11  	"github.com/containerd/console"
    12  )
    13  
    14  var (
    15  	bbEnabledOnce sync.Once
    16  	bbEnabled     bool
    17  )
    18  
    19  func BuildBackendEnabled() bool {
    20  	bbEnabledOnce.Do(func() {
    21  		home, err := os.UserHomeDir()
    22  		if err != nil {
    23  			return
    24  		}
    25  		_, err = os.Stat(filepath.Join(home, ".docker", "desktop-build", ".lastaccess"))
    26  		bbEnabled = err == nil
    27  	})
    28  	return bbEnabled
    29  }
    30  
    31  func BuildDetailsOutput(refs map[string]string, term bool) string {
    32  	if len(refs) == 0 {
    33  		return ""
    34  	}
    35  	refURL := func(ref string) string {
    36  		return fmt.Sprintf("docker-desktop://dashboard/build/%s", ref)
    37  	}
    38  	var out bytes.Buffer
    39  	out.WriteString("View build details: ")
    40  	multiTargets := len(refs) > 1
    41  	for target, ref := range refs {
    42  		if multiTargets {
    43  			out.WriteString(fmt.Sprintf("\n  %s: ", target))
    44  		}
    45  		if term {
    46  			out.WriteString(hyperlink(refURL(ref)))
    47  		} else {
    48  			out.WriteString(refURL(ref))
    49  		}
    50  	}
    51  	return out.String()
    52  }
    53  
    54  func PrintBuildDetails(w io.Writer, refs map[string]string, term bool) {
    55  	if out := BuildDetailsOutput(refs, term); out != "" {
    56  		fmt.Fprintf(w, "\n%s\n", out)
    57  	}
    58  }
    59  
    60  func hyperlink(url string) string {
    61  	// create an escape sequence using the OSC 8 format: https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda
    62  	return fmt.Sprintf("\033]8;;%s\033\\%s\033]8;;\033\\", url, url)
    63  }
    64  
    65  type ErrorWithBuildRef struct {
    66  	Ref string
    67  	Err error
    68  	Msg string
    69  }
    70  
    71  func (e *ErrorWithBuildRef) Error() string {
    72  	return e.Err.Error()
    73  }
    74  
    75  func (e *ErrorWithBuildRef) Unwrap() error {
    76  	return e.Err
    77  }
    78  
    79  func (e *ErrorWithBuildRef) Print(w io.Writer) error {
    80  	var term bool
    81  	if _, err := console.ConsoleFromFile(os.Stderr); err == nil {
    82  		term = true
    83  	}
    84  	fmt.Fprintf(w, "\n%s\n", BuildDetailsOutput(map[string]string{"default": e.Ref}, term))
    85  	return nil
    86  }